How do I register variables dynamically with Ansible?

I want to define an Ansible role and register dynamic variables:

---
- name: Check for {{ package }}
  stat: path=/opt/packages/{{ package }}
  register: "{{ package | regex_replace('-', '_') }}"
- name: Install {{ package }} {{ package_version }}
  command: "custom-package-installer {{ package }} {{ package_version }}"
  when: "not {{ package | regex_replace('-', '_') }}.stat.exists"

      

Usage looks like this:

- include: install_package.yml package=foo package_version=1.2.3

      

However, Ansible does not recognize the conditional expression:

TASK: [example | Install foo 1.2.3] *********************************** 
fatal: [my-server] => error while evaluating conditional: not foo.stat.exists

FATAL: all hosts have already failed -- aborting

      

How can I define variables dynamically by expanding {{

}}

?

+3


source to share


3 answers


Unable to register dynamic variable. There is no place in the register for a placeholder {{ var }}

. However, there is a much cleaner way to accomplish what I think you are trying to achieve: Ansible: that's a fact .

Short description:

You can write a simple script that prints JSON as:

#!/bin/python #or /bin/bash or any other executable
....

print """{ "ansible_facts": {
              "available_packages": ["a", "b", "c"]
               }
          }"""

      



and put it in your local facts folder on your computer (like an executable script with completion .fact

):

Your second task would then look like:

- name: Install {{ package }} {{ package_version }}
  command: "custom-package-installer {{ package }} {{ package_version }}"
  when: "not package in ansible_facts['available_packages']"

      

Unrelated fact documents .

+4


source


In this case, you don't need a dynamic variable:

---
- name: Check for {{ package }}
  stat: path=/opt/packages/{{ package }}
  register: current_package

- name: Install {{ package }} {{ package_version }}
  command: "custom-package-installer {{ package }} {{ package_version }}"
  when: not current_package.stat.exists

      



fine...

+2


source


As with many things, it is possible if you really want to do it, but initially impossible.

However, ansible is written in python and you can call playbooks directly in python code. The way I do this is to dynamically generate books to play and then execute them in a two step process.

Basically, it looks like dynamic playbooks. So, to sum up ...

  • Create a playbook using any logic.
  • Play in play mode without using.
0


source







All Articles