3

I use command module with creates on an ansible 2.9 role.

However, sometimes I need to ignore the creates arg and re-run the command multiple times.

Is there any way I can override the default behaviour and force the execution of the tasks?

6

One very basic solution. In your task:

- name: Do command optionally ignoring create option
  command:
    cmd: touch /tmp/toto.txt
    creates: "{{ ignore_creates | default(false) | bool | ternary('', '/tmp/toto.txt') | default(omit, true) }}"

Then you can launch your playbook with the the extra var -e ignore_creates=true to force the task to run even if the file exists. Removing the extra var in your command will turn the condition on again.

3
  • Thanks! However, since I have many tasks with different creates it would require great effort to change this. I was wondering for an option that would ignore all similar conditions. Otherwise a major rewrite is unavoidable. – trikelef Apr 9 at 14:11
  • You could write a custom filter which would ease the rewrite (to something like creates: "{{ 'my/file.txt' | skip_if_var_present }}"). Meanwhile 1) I currently have no idea how to return omit from there (and not even if it is possible). 2) you will still have to rewrite all of your creates. An other track you might want to explore is to write a custom module with a corresponding action plugin to call command – Zeitounator Apr 9 at 14:26
  • 1
    If you are writing a custom module, don't wrap the command module. Run it directly from your module, such as with ansible.module_utils.basic.AnsibleModule.run_command Many examples of this in existing Ansible modules. – John Mahowald Apr 9 at 15:35
2

Repeating expressions can be a practical sometimes, don't try too hard to comply to DRY. Although you can reuse an expression with variables.

- name: Testing creates parameter
  hosts: localhost
  vars:
    # Long expression for reuse in command tasks
    # Special value "omit" can be returned
    # from any expression, including ternary filter
    creates: "{{ ignore_creates | default(false) | bool | ternary(omit, creates_file) }}"

  tasks:
  - name: Do command optionally ignoring create option
    command:
      cmd: touch {{ creates_file }}
      creates: "{{ creates }}"
    vars:
      # Task level var to for use in the creates expression
      # Still a lot of typing, 
      # but perhaps you don't want to retype the filter
      ignore_creates: false
      creates_file: /tmp/ansiblecreatestest.txt

  - command:
      cmd: touch {{ creates_file }}
      creates: "{{ creates }}"
    vars:
      ignore_creates: true
      creates_file: /tmp/ansiblecreatestest.txt

Writing fancy logic into the playbook, wrapping more generic modules, will get tedious and repetitive whatever you do.

Instead, consider writing a custom module to run the commands. Write the logic for when the commands need to be re-run into the module.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.