variablesansiblestring-interpolation

Variable interpolation


I am trying to interpolate variables within an Ansible play. I have the following variables:

target_hostname
user_account
account_password

user_account_password is in a vault, and the variable is named target_hostname.user_account.user_account_password, e.g., myhost.username.thepassword.

The variables defined:

build:
  common:
    system_accounts:
      - name: 'ansible'
        group: 'ansible'
        uid: '5000'
        gid: '5000'
      - name: 'sysadm'
        group: 'sysadm'
        uid: '5001'
        gid: '5001'

And the entries in the vault:

target_hostname:
  bootloader_password: bootloader123
  root.account_password: root123
  sysadm.account_password: sysadm123
  ansible.account_password: ansible123

Tried using varying types of interpolation:

- name: Ensure users exist with appropriate UID
  ansible.builtin.user:
    name: "{{ system_account_items.name }}"
    uid: "{{ system_account_items.uid }}"
    umask: "022"
    group: "{{ system_account_items.group }}"
    password: "{{ target_hostname.[{{ system_account_items.name }}].account_password | password_hash('sha512') }}"
    update_password: always
  with_items: "{{ build.common.system_accounts }}"
  loop_control:
    loop_var: system_account_items

Solution

  • For example,

        - debug:
            msg: |
              name:  "{{ item.name }}"
              uid:   "{{ item.uid }}"
              group: "{{ item.group }}"
              password: "{{ target_hostname[key] }}"
          loop: "{{ build.common.system_accounts }}"
          vars:
            key: "{{ item.name }}.account_password"
    

    gives

    ok: [localhost] => (item={'name': 'ansible', 'group': 'ansible', 'uid': 5000, 'gid': 5000}) => 
        msg: |-
            name:  "ansible"
            uid:   "5000"
            group: "ansible"
            password: "ansible123"
    ok: [localhost] => (item={'name': 'sysadm', 'group': 'sysadm', 'uid': 5001, 'gid': 5001}) => 
        msg: |-
            name:  "sysadm"
            uid:   "5001"
            group: "sysadm"
            password: "sysadm123"
    

    Example of a complete playbook for testing

    - hosts: localhost
    
      vars:
    
        build:
          common:
            system_accounts:
              - name: ansible
                group: ansible
                uid: 5000
                gid: 5000
              - name: sysadm
                group: sysadm
                uid: 5001
                gid: 5001
    
        target_hostname:
          bootloader_password: bootloader123
          root.account_password: root123
          sysadm.account_password: sysadm123
          ansible.account_password: ansible123
    
      tasks:
    
        - debug:
            msg: |
              name:  "{{ item.name }}"
              uid:   "{{ item.uid }}"
              group: "{{ item.group }}"
              password: "{{ target_hostname[key] }}"
          loop: "{{ build.common.system_accounts }}"
          vars:
            key: "{{ item.name }}.account_password"