Joe Teumer
Joe Teumer

Reputation: 43

How to reference a variable using the builtin vars plugin?

Is it possible to reference a variable in a task using the builtin vars plugin?

When I use the "{{ variable }}" syntax it is treated like a string.

- name: Get the active network interface name
  shell: ip route get 1.1.1.1 | grep -Po '(?<=dev\s)\w+' | cut -f1 -d ' '
  register: interface_name
  
  ## Example: interface_name: enp33s0f0

- name: Update netplan
  set_fact:
    mydata: "{{ mydata | combine(newdata, recursive=True) }}"
  vars:
    newdata:
      network:
        ethernets:
          "{{ interface_name.stdout }}":
            dhcp4: true
            critical: true
            nameservers:
              addresses: 
              - 2.2.2.2
              search: [test.local]

- name: Write back to a file
  copy:
    content: "{{ mydata | to_nice_yaml }}"
    dest: /etc/netplan/00-installer-config.yaml
  register: update
cat 00-installer-config.yaml
network:
    ethernets:
        '{{ interface_name.stdout }}':
            critical: true
            dhcp4: true
            nameservers:
                addresses:
                - 2.2.2.2
                search:
                - test.local

If this is not possible is there an alternative?

Upvotes: 1

Views: 247

Answers (1)

β.εηοιτ.βε
β.εηοιτ.βε

Reputation: 39264

You can declare your variable in the set_fact task itself, in order to make Ansible template the dictionary keys:

- set_fact:
    mydata: >-
      {{ 
        mydata | default({}) | combine(
          {
            'network': {
              'ethernets': {
                interface_name.stdout: {
                  'dhcp': true,
                  'critical': true,
                  'nameservers': {
                    'addresses': ['2.2.2.2'],
                    'search': ['test.local']
                  }
                }
              }
            }
          }, recursive=True
        ) 
      }}

Given the playbook:

- hosts: localhost
  gather_facts: no
  vars:
    interface_name:
      stdout: enp33s0f0

  tasks:
    - set_fact:
        mydata: >-
          {{ 
            mydata | default({}) | combine(
              {
                'network': {
                  'ethernets': {
                    interface_name.stdout: {
                      'dhcp': true,
                      'critical': true,
                      'nameservers': {
                        'addresses': ['2.2.2.2'],
                        'search': ['test.local']
                      }
                    }
                  }
                }
              }, recursive=True
            ) 
          }}
    
    - debug:
        var: mydata

This yields:

TASK [set_fact] *************************************************************
ok: [localhost]

TASK [debug] ****************************************************************
ok: [localhost] => 
  mydata:
    network:
      ethernets:
        enp33s0f0:
          critical: true
          dhcp: true
          nameservers:
            addresses:
            - 2.2.2.2
            search:
            - test.local

Upvotes: 2

Related Questions