Ansible snippets and tips

Contents

Accessing variables programatically

The Ansible FAQ details how to build up varibles programatically.

{{ hostvars[inventory_hostname]['ansible_' + which_interface]['ipv4']['address'] }}

In order to access concatenated variables they need to be in the inventory. This doesn’t happen with vars inline in the playbook but does work if you use include_vars

1
2
3
4
5
6
7
8
- hosts: localhost
  connection: local
  vars:
    test_app: admin
  tasks:
    - include_vars: concat_vars.yml
    - debug:
        msg: "admin port from inventory = {{ hostvars[inventory_hostname][test_app+'_port'] }}
admin_port: 1000
TASK: [debug ] ****************************************************************
ok: [localhost] => {
    "msg": "admin port from inventory = 1000"
}

Dictionaries

The following example shows how you can iterate over a dict and access directly

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- hosts: localhost
  connection: local
  vars:
    apps:
      admin:
        service: admin
        handler: /admin
        port: 1200
      rpt:
        service: rpt
        handler: /rpt
        port: 1234
  tasks:
    - debug:
        msg: "{{ item.key }} -- {{ item.value.service }} {{ item.value.port }}"
      with_dict: apps

    - debug:
        msg: "{{ apps.admin.service }}"
TASK: [debug ] ****************************************************************
ok: [localhost] => (item={'key': 'admin', 'value': {'handler': '/admin', 'port': 1200, 'service': 'admin'}}) => {
    "item": {
        "key": "admin",
        "value": {
            "handler": "/admin",
            "port": 1200,
            "service": "admin"
        }
    },
    "msg": "admin -- admin 1200"
}
ok: [localhost] => (item={'key': 'rpt', 'value': {'handler': '/rpt', 'port': 1234, 'service': 'rpt'}}) => {
    "item": {
        "key": "rpt",
        "value": {
            "handler": "/rpt",
            "port": 1234,
            "service": "rpt"
        }
    },
    "msg": "rpt -- rpt 1234"
}

Looping over dictionaries

Sometimes its necessary to loop over a list of dictionaries. The following example has a dictionary with 3 keys

- name: Configure environment
  template: src={{ item.src }} dest={{ item.dest }} mode={{ item.mode }} owner=root group=root
  with_items:
    - { src: 'hosts.equiv.j2',   dest: '/etc/hosts.equiv',                mode: '0644' }
    - { src: 'informix.conf.j2', dest: '/etc/ld.so.conf.d/informix.conf', mode: '0444' }
    - { src: 'informix.csh.j2',  dest: '/etc/profile.d/informix.csh',     mode: '0644' }
    - { src: 'informix.init.j2', dest: '/etc/init.d/informix',            mode: '0755' }
    - { src: 'informix.sh.j2',   dest: '/etc/profile.d/informix.sh',      mode: '0644' }
  notify:
    - Reload ldconfig

Checking if a value is in a multiple lists

We have a situation where we want to install applications on a number of hosts. This information needs to be available to all hosts as its used by Apache in the web tier and on the db tier. The information is stored in group_vars/all to allow global access.

app_layout:
  admin:
    groups: ['group-boapp-layout-A', 'group-boapp-layout-B']
  rpt:
    groups: ['group-boapp-layout-A']
- name: Establish if application can be installed on host
  set_fact:
    install_app: true
  when: inventory_hostname in groups[item]
  with_flattened: app_layout.groups

- include: app.yml
  when: install_app == true

The fact install_app will only be set if the current inventory_hostname is in each of the lists. group-boapp-layout-A and group-boapp-layout-B expand to

"all": [
      "ec2-test-boapp03",
      "ec2-test-boapp04",
      "ec2-test-boapp01",
      "ec2-test-boapp02"
  ],
  "group-boapp-layout-A": [
      "ec2-test-boapp01",
      "ec2-test-boapp02"
  ],
  "group-boapp-layout-B": [
      "ec2-test-boapp03",
      "ec2-test-boapp04"
  ],
TASK: [app-appserv | Establish if application can be installed on host] ***
skipping: [ec2-test-boapp03] => (item=group-boapp-layout-A)
skipping: [ec2-test-boapp04] => (item=group-boapp-layout-A)
ok: [ec2-test-boapp02] => (item=group-boapp-layout-A)
ok: [ec2-test-boapp03] => (item=group-boapp-layout-B)
skipping: [ec2-test-boapp02] => (item=group-boapp-layout-B)
ok: [ec2-test-boapp01] => (item=group-boapp-layout-A)
ok: [ec2-test-boapp04] => (item=group-boapp-layout-B)
skipping: [ec2-test-boapp01] => (item=group-boapp-layout-B)

comments powered by Disqus