Ansible tips & tricks

Ansible data types

integer: 3211241
boolean: true/false
float: 3.141592653
string: "qwerty"
list:
- "item 1"
- "item 2"
dictionary:
key1: "value 1"
key2: "value 2"

YAML syntax

Split long lines

Use a backslash (\) to split long lines:

    - set_fact:
        msg: "This is the first part \
              and second part of the string"

    - debug:
        var: msg

Results in:

"msg": "This is the first part and second part of the string". Note that the space between 'part' and 'and' is before the backslash.

Use a greater-than sign (>) to split long lines, without interior line breaks:

    - set_fact:
        msg: >
          This is the first part
          and second part of the string

    - debug:
        var: msg

Results in:

"msg": "This is the first part and second part of the string\n"

Use a pipe sign (|) to split long lines, preserving interior line breaks:

    - set_fact:
        msg: |
          This is the first part
          and second part of the string

    - debug:
        var: msg

Results in:

"msg": "This is the first part \nand second part of the string\n"

Add a minus sign (-) after a greater-than or pipe symbol to remove the line break at the end of the line (use >- or |-)

See: https://stackoverflow.com/questions/3790454/how-do-i-break-a-string-in-yaml-over-multiple-lines

Dump all variables

---
- name: dump all
  hosts: all
 
  tasks:
    - name: Print some debug information 
      vars: 
        msg: |
          Module Variables ("vars"):
          --------------------------------
          {{ vars | to_nice_json }} 
          
          Environment Variables ("environment"):
          --------------------------------
          {{ environment | to_nice_json }} 
          
          GROUP NAMES Variables ("group_names"):
          --------------------------------
          {{ group_names | to_nice_json }}
          
          GROUPS Variables ("groups"):
          --------------------------------
          {{ groups | to_nice_json }}
          
          HOST Variables ("hostvars"):
          --------------------------------
          {{ hostvars | to_nice_json }} 

      debug:
        msg: "{{ msg.split('\n') }}"

Magic variables

See: Special Variables

manipulating data

Convert date to Unix time (epoch)

Use "{{ ('2023-02-28' | to_datetime('%Y-%m-%d')).strftime('%s') }}"

Extract subitems from list of dictionaries

Use "{{ variable | map(attribute='key_name') | list }}"

Select items from list of dictionaries

Use "{{ variable | selectattr('key_name', 'match', 'value') | list }}"

Instead of selectattr, you can also use rejectattr.

Instead of match, you can also use search or regex. See: https://docs.ansible.com/ansible/latest/user_guide/playbooks_tests.html#testing-strings

See the Jinja2 documentation for a list of available tests: https://jinja.palletsprojects.com/en/2.9.x/templates/#list-of-builtin-tests

Apply a filter to a list of items

Use "{{ variable | map('filter_name', 'filter_option1', 'filter_option2') | list }}"

For example:

"{{ output.stdout_lines | map('regex_replace', '^(\S+)\s.*$', '\\1') | list }}"

Be careful on the context in which you use this. In some cases you must use a single backslash (displaying a variable with debug for example): '\1'

Filter a list of strings

Use "{{ variable | select('match', 'some string') | list }}"

Instead of match, you can also use search or regex. See: https://docs.ansible.com/ansible/latest/user_guide/playbooks_tests.html#testing-strings

Sort list of dictionaries by subitem

Use "{{ variable | sort(attribute='key_name') }}"

Searching a string in a when statement

Use: when: my_string is match(pattern)

Instead of match, you can also use search or regex. See: https://docs.ansible.com/ansible/latest/user_guide/playbooks_tests.html#testing-strings

Add a string to a string

Use "{{ string1 + string2 }}"

Or: "{{ string1 + ', ' + string2 }}"

Add item to list

Use "{{ variable | default([]) + [item] }}"

Add item to dictionary

Use "{{ variable | default({}) | combine({key_name: key_value}) }}"

Replace multiple lines using replace module (lineinfile does not support multi-line regexp)

Example:

- name: Comment out hint zone "." in named.conf
  replace:
    path: "/etc/named.conf"
    regexp: '^(zone\s+"\."\s+IN\s+{[^\n]*)\n(\s*type\s+hint;[^\n]*)\n(\s*file\s+"named\.ca";[^\n]*)\n(};)'
    replace: '# \1\n# \2\n# \3\n# \4'

Loop over network interfaces

Example, showing MTU size:

- debug:
    msg: "{{ ansible_facts[item]['mtu'] }}"
  with_items: "{{ ansible_interfaces }}"

Fixing incorrect module names

Run ansible-playbook with -vvv and look for lines containing redirecting.

-- Ivo van Geel - 21 Sep 2021

Edit | Attach | Watch | Print version | History: r19 < r18 < r17 < r16 < r15 | Backlinks | Raw View | More topic actions
Topic revision: r19 - 05 Jul 2023 - IvoVanGeel
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2010-2019 by LANIS