Warm tip: This article is reproduced from serverfault.com, please click

Set variables depending on Ansible facts

发布于 2020-11-30 13:11:24

Afternoon,

I am writing playbook for to run basic setup of Linux hosts across multiple domains. Let’s say we have domains aaa.com, bbb.com and ccc.com. Each domain has different DNS, NTP, etc. What I am doing is basically using set_fact module in main.yml -

- name: Set aaa.com variables
  set_fact:
    ntp1: 10.1.1.10
    ntp2: 10.1.1.11
  when: ansible_domain == 'aaa.com' 

 - name: Set bbb.com variables
  set_fact:
    ntp1: 10.2.1.10
    ntp2: 10.2.1.11
  when: ansible_domain == 'bbb.com'

 - name: Set ccc.com variables
  set_fact:
    ntp1: 10.3.1.10
    ntp2: 10.3.1.11
  when: ansible_domain == 'ccc.com'  

Afterwards I am using templates to call variables.

All works well but I have a feeling that this can be solved better. What is the best approach for this case? And how I can set default variable if domain is not defined on the list?

Appreciate the response!

Questioner
Andy A.
Viewed
0
Vladimir Botka 2020-11-30 22:28:19

Put the data into a dictionary. For example

- hosts: localhost
  vars:
    my_domains:
      aaa.com:
        ntp1: 10.1.1.10
        ntp2: 10.1.1.11
      bbb.com:
        ntp1: 10.2.1.10
        ntp2: 10.2.1.11
      ccc.com:
        ntp1: 10.3.1.10
        ntp2: 10.3.1.11
  tasks:
    - debug:
        msg: "domain: {{ item }}
              ntp1: {{ my_domains[item].ntp1 }}
              ntp2: {{ my_domains[item].ntp2 }}"
      loop: "{{ my_domains.keys()|list }}"

gives (abridged)

    "msg": "domain: aaa.com ntp1: 10.1.1.10 ntp2: 10.1.1.11"
    "msg": "domain: bbb.com ntp1: 10.2.1.10 ntp2: 10.2.1.11"
    "msg": "domain: ccc.com ntp1: 10.3.1.10 ntp2: 10.3.1.11"

Then, the task below simplifies the declaration of the variables

    - set_fact:
        ntp1: "{{ my_domains[ansible_domain].ntp1 }}"
        ntp2: "{{ my_domains[ansible_domain].ntp2 }}"

The code can be further simplified by putting the data into the group_vars. For example

shell> cat group_vars/all.yml 
my_domains:
  aaa.com:
    ntp1: 10.1.1.10
    ntp2: 10.1.1.11
  bbb.com:
    ntp1: 10.2.1.10
    ntp2: 10.2.1.11
  ccc.com:
    ntp1: 10.3.1.10
    ntp2: 10.3.1.11
ntp1: "{{ my_domains[ansible_domain].ntp1 }}"
ntp2: "{{ my_domains[ansible_domain].ntp2 }}"

Then the inventory (you will probably let Ansible discover ansible_domain)

shell> cat hosts
srv1.aaa.com ansible_domain=aaa.com
srv1.bbb.com ansible_domain=bbb.com

and the playbook

- hosts: srv1.aaa.com,srv1.bbb.com
  tasks:
    - debug:
        msg: "{{ ntp1 }} {{ ntp2 }}"

gives (abridged)

ok: [srv1.aaa.com] => {
    "msg": "10.1.1.10 10.1.1.11"

ok: [srv1.bbb.com] => {
    "msg": "10.2.1.10 10.2.1.11"