How to execute Ansible tasks in IF ELSE mode?

65 Views Asked by At

I have following code where in I want to implement conditional logic like if-else construct:

- name: Download katello agent package
  get_url:
    url: "{{ abc_url }}/pub/yyy.rpm"
    dest: "{{ tmp_dir }}"

when: 'rt' in group_names url = abc_url, when: 'rt' not in group_names url = def_url, based on group_names, my URL changes.

2

There are 2 best solutions below

1
U880D On BEST ANSWER

I want to implement conditional logic like if-else construct

It depends on the circumstances. But in the Use Case shown, no, one won't to do so in Ansible. It is not recommended to implement a conditional logic in such a case. Instead one should use the inventory and group_vars.

For an inventory file example.com

[rt]
a.example.com
b.example.com
c.example.com

[def]
d.example.com
e.example.com
f.example.com

and group_vars files

tree group_vars/
group_vars/
├── def
│   └── katello
├── rt
│   └── katello
└── all

with content of

cat group_vars/rt/katello

URL: abc.example.com

cat group_vars/def/katello

URL: def.example.com

a minimal example playbook

---
- hosts: all
  become: false
  gather_facts: false

  tasks:

  - debug:
      msg: "{{ URL }}"

called via

ansible-playbook --inventory example.com main.yml

will result into an output of

TASK [debug] *********
ok: [a.example.com] =>
  msg: abc.example.com
ok: [c.example.com] =>
  msg: abc.example.com
ok: [b.example.com] =>
  msg: abc.example.com

ok: [d.example.com] =>
  msg: def.example.com
ok: [f.example.com] =>
  msg: def.example.com
ok: [e.example.com] =>
  msg: def.example.com

As one can see from the output, no IF THEN ELSE, no Conditionals or when, no set_fact or tasks, no code, no programming at all. Just and only How to build your inventory.

Further Reading and Documentation

  • Things to know about programming using Ansible

    Ansible is not a language: If Ansible isn't a programming language, then what is it? Ansible is a tool written in Python, and it uses the declarative markup language YAML to describe the Desired State of devices and configuration. ... You declare aspects you want to be configured on a target device, such as that a file or directory exists, a package is installed, a service is running, and so on.

  • Ansible Best Practices: The Essentials

    Think declaratively: Ansible is a Desired State Engine by design. If you’re trying to “write code” in your plays and roles, you’re setting yourself up for failure. Our YAML-based playbooks were never meant to be for programming.

  • What is the XY problem?

5
DrJay On

To insert the conditional logic inline:

- name: Download katello agent package
  get_url:
    url: "{{ 'abc_url' if 'rt' in group_names else 'def_url' }}/pub/yyy.rpm"
    dest: "{{ tmp_dir }}"

Though this should work, you can use the inventory and group_vars. Set up an INI file e.g. inventory.ini

[rt_group] 
rt_host ansible_host=your_rt_host

[other_group] 
other_host ansible_host=your_other_host

[all:vars] 
abc_url=http://example.com/abc
def_url=http://example.com/def 
tmp_dir=/path/to/destination

And your playbook (your_playbook.yml):

- name: Download katello agent package   
  hosts: all

  tasks:

  - name: Set URL based on group
    set_fact:
      download_url: "{{ abc_url }}"
    when: "'rt_group' in group_names"

  - name: Set URL based on group
    set_fact:
      download_url: "{{ def_url }}"
    when: "'rt_group' not in group_names"

  - name: Download package
    get_url:
      url: "{{ download_url }}/pub/yyy.rpm"
      dest: "{{ tmp_dir }}"