Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible how to set_fact with condition or var base on condition

Tags:

ansible

I have 3 types of servers: dev, qa and prod. I need to send files to server specific home directories, i.e:

Dev Home Directory: /dev/home

QA Home Directory:/qa/home

PROD Home Directory: /prod/home

I have var set as boolean to determine the server type and think of using set_fact with condition to assign home directories for the servers. My playbook looks like this:

---
- hosts: localhost
  var:
    dev: "{{ True if <hostname matches dev> | else False }}"
    qa: "{{ True if <hostname matches qa> | else False }}"
    prod: "{{ True if <hostname matches prod> | else False }}"

  tasks:
  - set_facts:
      home_dir: "{{'/dev/home/' if dev | '/qa/home' if qa | default('prod')}}"

However, then I ran the playbook, I was getting error about 'template expected token 'name', got string> Anyone know what I did wrong? Thanks!

like image 455
coding Avatar asked Sep 02 '25 04:09

coding


1 Answers

Use match test. For example, the playbook

shell> cat pb.yml
- hosts: localhost
  vars:
    dev_pattern: '^dev_.+$'
    qa_pattern: '^qa_.+$'
    prod_pattern: '^prod_.+$'
    dev: "{{ hostname is match(dev_pattern) }}"
    qa: "{{ hostname is match(qa_pattern) }}"
    prod: "{{ hostname is match(prod_pattern) }}"
  tasks:
    - set_fact:
        home_dir: /prod/home
    - set_fact:
        home_dir: /dev/home
      when: dev|bool
    - set_fact:
        home_dir: /qa/home
      when: qa|bool
    - debug:
        var: home_dir

gives (abridged)

shell> ansible-playbook pb.yml -e hostname=dev_007

  home_dir: /dev/home

Notes:

  • The variable prod is not used because /prod/home is default.
  • prod/home is assigned to home_dir first because it's the default. Next tasks can conditionally overwrite home_dirs.
  • Without the variable hostname defined the playbook will crash.

A simpler solution that gives the same result is creating a dictionary of 'pattern: home_dir'. For example

- hosts: localhost
  vars:
    home_dirs:
      dev_: /dev/home
      qa_: /qa/home
      prod_: /prod/home
  tasks:
    - set_fact:
        home_dir: "{{ home_dirs|
                      dict2items|
                      selectattr('key', 'in' , hostname)|
                      map(attribute='value')|
                      list|
                      first|default('/prod/home') }}"
    - debug:
        var: home_dir
like image 92
Vladimir Botka Avatar answered Sep 05 '25 00:09

Vladimir Botka