ansiblebind9

Ansible multiple vars/value


I need to role which adds records to my zones (bind9)

In hostvars I created vars like as below:

zones:
    zone.name1:
      - [ type: A, name: mike, ip: 192.168.1.10 ]
      - [ type: A, name: bob, ip: 192.168.1.11 ]

    zone.name2:
      - [ type: A, name: alice, ip: 192.168.1.12 ]
      - [ type: A, name: joanne, ip: 192.168.1.13 ]

In role/tasks/main.yaml

- lineinfile:
    path: "/etc/bind/zones/{{ item }}.zone"
    line: '@   IN   "{{ item.value.type }}"   "{{ item.value.name }}" "{{ item.value.i }}"'
  with_items: "{{ zones | dict2items }}"

How to get a result which adds a new record to the zone file?


Solution

  • There is couple of things wrong here.

    1. You are using list notation for dict ([ type: A, name: mike, ip: 192.168.1.10 ] should be { type: A, name: mike, ip: 192.168.1.10 })
    2. Your data structure requires two loops which you cannot do directly in the playbook.
    3. You probably also want to have the freedom to remove records when they are not needed which doesn't work just like that when using lineinfile.

    The following solution fixes all the above problems:

    # main.yaml
    
    ---
    
    - hosts: all
      gather_facts: no
      connection: local
      vars:
        zones:
          zone.name1:
            - { type: A, name: mike, ip: 192.168.1.10 }
            # Remove this record
            - { type: A, name: bob,  ip: 192.168.1.11, state: absent }
          zone.name2:
            - { type: A, name: alice,  ip: 192.168.1.12 }
            - { type: A, name: joanne, ip: 192.168.1.13 }
      tasks:
        - include_tasks: lines.yaml
          loop: "{{ zones | dict2items }}"
          loop_control:
            loop_var: records
    

    Another task file which we loop through:

    # lines.yaml
    
    ---
    
    - lineinfile:
        path: /tmp/{{ records.key }}.zone
        line: >-
          @   IN   "{{ item.type }}"   "{{ item.name }}" "{{ item.ip }}"
        regexp: >-
          ^@\s+IN\s+"{{ item.type }}"\s+"{{ item.name }}"\s+"{{ item.ip }}"$
        state: >-
          {{ 'present' if 'state' not in item or item.state == 'present' else 'absent' }}
      loop: "{{ records.value }}"
    

    Execute it with this command:

    ansible-playbook -i localhost, --diff main.yaml