Skip to content

Instantly share code, notes, and snippets.

@oskaralmlov
Created September 18, 2021 13:32
Show Gist options
  • Select an option

  • Save oskaralmlov/3f4d4f515a6df91f37fcdb88161f8ff9 to your computer and use it in GitHub Desktop.

Select an option

Save oskaralmlov/3f4d4f515a6df91f37fcdb88161f8ff9 to your computer and use it in GitHub Desktop.
ansible-args-keyword

Most Ansible users have come across the args keyword when using the ansible.builtin.command module. In this case the args keyword is used to pass a named parameter such as chdir or creates to the module that accepts a "free form" parameter.

Example:

- ansible.builtin.command: touch filename #Run this command
  args:
    chdir: /some/path            # Change to this path before running command
    creates: /some/path/filename # The command creates this file

What you might not know is that the args keyword can be used on any module for a number of different use cases . Here are some examples:

Clean loops

Let's say that you need to create a bunch of different files the same owner but different permissions. To do this you are using the ansible.builtin.file module and a loop.

Not using args:

- ansible.builtin.file:
    path: "{{ item.path }}"        # This 
    owner: "{{ item.user }}"       # is 
    group: "{{ item.group }}"      # a lot
    mode: "{{ item.permissions }}" # of typing
  loop:
    - path: /tmp/test1
      user: root
      group: root
      permissions: 0600
    - path: /tmp/test2
      user: root
      group: root
      permissions: 0644

Using args:

- ansible.builtin.file:
    owner: root
    group: root
  args: "{{ item }}"
  loop:
    - path: /tmp/test2
      mode: 0600
    - path: /tmp/test2
      mode: 0644

In this case items that we are looping over will be passed to the module as arguments, just like if they had been written at the "normal" location. All files will have root as user & group but the path and mode will be different for each file.

Replacing omit

Have you ever had to support a task where the input to that task is varying and you find yourself having to use | default(omit) everywhere? args can solve that and make the task more readable.

Not using args:

- ansible.builtin.cron:
    name: "{{ item.name | default(omit) }}"
    user: "{{ item.user | default(omit) }}"
    job: "{{ item.job | default(omit) }}"
    special_time: "{{ item.special_time | default(omit) }}"
    month: "{{ item.month | default(omit) }}"
    weekday: "{{ item.weekday | default(omit) }}"
    hour: "{{ item.hour | default(omit) }}"
    minute: "{{ item.minute | default(omit) }}"
    etc.. etc..
  loop:
    - name: Job 1
      user: root
      job: /usr/bin/job 1
      weekday: 5
      hour: 5
    - name: job 2
      user: ovysxcczso
      job: /usr/bin/job 2
      minute: 2
    - job: /user/bin/job 3
      special_time: annually

Using args:

- ansible.builtin.cron:
  args: "{{ item }}"
  loop:
    - name: Job 1
      user: root
      job: /usr/bin/job 1
      weekday: 5
      hour: 5
    - name: job 2
      user: ovysxcczso
      job: /usr/bin/job 2
      minute: 2
    - job: /user/bin/job 3
      special_time: annually

Combining tasks

Under special circumstances you find yourself wanting to use the same module with some arguments in one iteration and without those arguments in the next. Say for example that you want to set file permissions for a directory and the files in that directory, only that you want the directory and the contained files to have different permissions.

Not using args:

- name: Set file permissions
  ansible.builtin.file:
    path: /some/path
    state: directory
    recurse: true
    mode: 0600

- name: Set directory permissions
  ansible.builtin.file:
    path: /some/path
    state: directory
    mode: 0644

Using args:

- name: Set file & directory permissions
  ansible.builtin.file:
    path: /some/path
    state: directory
  args: "{{ item }}"
  loop:
    - mode: 0644
      recurse: true
    - mode: 0600

You could argue that in this example it might be better to have 2 separate tasks to clearly signal the intent of what you are doing, and I'd be inclined to agree. But this method can be used in many different scenarios that might be a better use case than this example.

----

Of course args isn't a silver bullet for every type of problem, but it makes some problems easier to solve and in other cases increases readability.

Hope you learned something new :)

@StCyr
Copy link

StCyr commented Oct 16, 2025

Thanks for the clear explanation 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment