0

I'm writing a playbook to everyone and I want to implement verification by IP address and depending on which subnet perform actions.

---
- name: Install package
  hosts: "{{ myhosts }}"
  remote_user: user
  become_method: sudo
  become: yes

  tasks:
  - name: check
    #debug: var=ansible_default_ipv4.address
    shell: /usr/sbin/ip -4 a | egrep '10.50.0.|10.77.12.'
    register: check_ip

  - name: Example 1
    debug:
      msg: bla bla
    when: check_ip.stdout = 0

  - name: Example 2
    debug:
      msg: bla bla
    when: check_ip.stdout != 0

Is there is a more elegant solution? And how can mistakes be missed in these conditions? After all, one of the conditions will definitely be false.

U880D
  • 8,601
  • 6
  • 24
  • 40

1 Answers1

2

Is there is a more elegant solution?

At a first step you may start to get familiar with Ansible facts with a minimal example playbook

---
- hosts: localhost
  become: false
  gather_facts: true
  gather_subset:
    - "!all"
    - "!min"
    - "default_ipv4"

  tasks:

  - name: Show Gathered Facts
    ansible.builtin.debug:
      msg: "{{ ansible_facts }}"

  - name: Show interface and address
    ansible.builtin.debug:
      msg: "{{ ansible_facts.default_ipv4.interface }} has {{ ansible_facts.default_ipv4.address }}"

resulting into an output of

TASK [Show interface and address] ******
ok: [localhost] =>
  msg: eth0 has 192.0.2.0

Further Reading

Similar Q&A


I want to implement verification by IP address.

As a second steps you may start to get familiar with Conditionals and with a minimal example playbook

---
- hosts: localhost
  become: false
  gather_facts: true
  gather_subset:
    - "!all"
    - "!min"
    - "default_ipv4"

  tasks:

  - name: Is IP in correct network block?
    debug:
      msg: "[OK] YES, IP is in RFC5737 TEST-NET-1 block (use in documentation)."
    when: ansible_facts.default_ipv4.address.startswith('192.0.2')

Further Reading


Apart from the above examples

After all, one of the conditions will definitely be false.

right, this is because of the Common Return Values and specifically the shell Return Code.

Have a look at

/usr/sbin/ip -4 a | egrep '10.50.0.|10.77.12.'; echo $?

and your example

- name: Check IP block
    shell: /usr/sbin/ip -4 a | egrep '10.50.0.|10.77.12.'
    register: check_ip
    # Since it is a reporting task set
    failed_when: check_ip.rc != 0 and check_ip.rc != 1 # .rc > 1
    changed_when: false
    check_mode: false

because that's what is returned by egrep depending on

  - name: IP block found
    debug:
      msg: FOUND
    when: check_ip.rc = 0

  - name: IP block not found
    debug:
      msg: NOT FOUND
    when: check_ip.rc = 1

If you like to utilize stdout, or in general, it might be better to change the command to count the result lines instead of depending on the Return Code (RC) in order to check if something was found or not

    shell: /usr/sbin/ip -4 a | egrep '10.50.0.|10.77.12.' | wc -l

because that will leave you with result of stdout of 0 or greater than that and you could use

when: check_ip.stdout | int = 0 # found nothing

# or

when: check_ip.stdout | int > 0 # found something
U880D
  • 8,601
  • 6
  • 24
  • 40