hydrian
hydrian

Reputation: 115

How can I access a top level variable containing a dot in Ansible?

I am trying to get a when condition to match a string value in a list of strings in Ansible. I'm defining my list variables in the all host inventory group. I call these list variables from many of play, playbooks and roles.

all:
  vars:
    ubuntu_18.04_codenames:
      - 'bionic'
      - 'tara'
      - 'tessa'
      - 'tina'
      - 'tricia'
    ubuntu_20.04_codenames:
      - 'focal'
      - 'ulyana'
      - 'ulyssa'
      - 'uma'
      - 'una'
    ubuntu_22.04_codenames: 
      - 'jammy'
      - 'vera'
      - 'vanessa'
      - 'Victoria'

I define my task's when condition like this:

- name: "Adding Docker 20.04 APT repository"
  apt_repository:
    repo: deb https://download.docker.com/linux/ubuntu focal stable
  when: 'ansible_lsb.codename in ubuntu_20.04_codenames'

I get the error:

FAILED! => {"msg": "The conditional check 'ansible_lsb.codename in ubuntu_22.04_codenames' failed. The error was: template error while templating string: expected token 'end of statement block', got 'integer'. String: {% if ansible_lsb.codename in ubuntu_22.04_codenames %} True {% else %} False {% endif %}. expected token 'end of statement block', got 'integer'

I'm using ansible_lsb.codname with my list variable ubuntu_20.04_codenames. I keep on getting syntax errors, no matter what I try.

Upvotes: 1

Views: 556

Answers (2)

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

Reputation: 39119

Because the . has a meaning in Ansible — namely it helps access an attribute of a dictionary — using it in a top level variable is going to give you a little bit of trouble.

If you where in a second level attribute, i.e.:

ubuntu:
  18.04_codenames:
    - bionic

You could just get away using the array notation:

when: "ansible_lsb.codename in ubuntu['18.04_codenames']"

But, since you are at the top level of variables, you will have to resort to using the vars lookup:

when: "ansible_lsb.codename in lookup('vars', 'ubuntu_18.04_codenames')"

Given the inventory:

all:
  vars:
    ubuntu_18.04_codenames:
      - bionic

And the task:

- debug:
    var: lookup('vars', 'ubuntu_18.04_codenames')
  when: "'bionic' in lookup('vars', 'ubuntu_18.04_codenames')"

This yields:

ok: [localhost] => 
  lookup('vars', 'ubuntu_18.04_codenames'):
  - bionic

Upvotes: 0

U880D
U880D

Reputation: 12029

Please take note first about Creating valid variable names as your current example would result into

ERROR! Invalid variable name in vars specified for Play: 'ubuntu_18.04_codenames' is not a valid variable name

... when condition to match a string value in a list of strings ...

A minimal example playbook using contains test – does the list contain this element

Checks the supplied element against the input list to see if it exists within it.

---
- hosts: localhost
  become: false
  gather_facts: false

  vars:

    ubuntu_18_04_codenames:
      - 'bionic'
      - 'tara'
      - 'tessa'
      - 'tina'
      - 'tricia'
    ubuntu_20_04_codenames:
      - 'focal'
      - 'ulyana'
      - 'ulyssa'
      - 'uma'
      - 'una'
    ubuntu_22_04_codenames:
      - 'jammy'
      - 'vera'
      - 'vanessa'
      - 'victoria'

    codename: focal

  tasks:

  - debug:
      msg: "Yes. Contains ..."
    when: ubuntu_20_04_codenames is contains(codename)

will result into an output of

TASK [debug] ***********
ok: [localhost] =>
  msg: Yes. Contains ...

I keep on getting syntax errors.

If interested into reproducing the mentioned syntax error message, just change the condition to

    when: ubuntu_20.04_codenames is contains(codename)

containing an invalid variable name. It will result into

TASK [debug] ******************************************************************************************************
fatal: [localhost]: FAILED! =>
  msg: |-
    The conditional check '{{ ubuntu_20.04_codenames is contains(codename) }}' failed. The error was: template error while templating string: expected token 'end of print statement', got '_codenames'. String: {{ ubuntu_20.04_codenames is contains(codename) }}

Upvotes: 1

Related Questions