How to check if an IP address is within a range in Ansible Playbook
Tags: ansible
Published: 2019-11-09 14:59:08

I was trying to have tasks for each site and multiple regions in Cloud respectively.
My idea was to use the IP address to determine where the host is, but it was kind of struggling to create the condition.
So here is my memo down below.

## TL;DR

This when statement checks if the IP address is within the specified range.

```
- name: test
  debug:
    msg: work
  when: ansible_default_ipv4.address | ipaddr('10.0.2.0/24') | ipaddr('bool')
```

This task prints "work" if ansible_default_ipv4.address is within 10.0.2.0/24

## Explanation

I am using ipaddr filter
https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters_ipaddr.html

### First half

```
[IP list] | ipaddr('172.30.0.0/16')
```

Above syntax extracts IP addresses in [IP list] which is within 172.30.0.0/16


```
% cat test.yml
---
- hosts: Vag1
  gather_facts: True
  tasks:
    - set_fact:
        testip:
          - "192.168.1.2"
          - "10.0.2.15"

    - name: test
      debug:
        msg: "{{ testip | ipaddr('10.0.2.0/24') }}"
```

By Running test.yml above.

```
[koh@kohs-MacBook-Pro] ~/vag_test
% ansible-playbook test.yml
PLAY [Vag1] ***************************************************************************************************************************

TASK [set_fact] ***********************************************************************************************************************
ok: [Vag1]

TASK [test] ***************************************************************************************************************************
ok: [Vag1] => {
    "msg": [
        "10.0.2.15"
    ]
}

PLAY RECAP ****************************************************************************************************************************
Vag1                       : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[koh@kohs-MacBook-Pro] ~/vag_test
%
```

There are 2 IPs in testip and only 10.0.2.15 was printed since it is within 10.0.2.0/24

### The second half

```
[IP address] | ipaddr('bool')
```

It returns True if [IP address] is a valid IP address.

```
% cat test2.yml
---
- hosts: Vag1
  gather_facts: True
  tasks:
    - set_fact:
        testip:
          - "192.168.1.2"
          - "10.0.2.15.14.22"
          - "hogehoge"
          - ""

    - name: test
      debug:
        msg: "{{ item | ipaddr('bool')  }}"
      with_items: "{{ testip }}"
```

By Running test2.yml above.

```
[koh@kohs-MacBook-Pro] ~/vag_test
% ansible-playbook test2.yml

PLAY [Vag1] ****************************************************************************************************************************

TASK [set_fact] ****************************************************************************************************************************
ok: [Vag1]

TASK [test] ****************************************************************************************************************************
ok: [Vag1] => (item=192.168.1.2) => {
    "msg": true
}
ok: [Vag1] => (item=10.0.2.15.14.22) => {
    "msg": false
}
ok: [Vag1] => (item=hogehoge) => {
    "msg": false
}
ok: [Vag1] => (item=) => {
    "msg": false
}

PLAY RECAP ****************************************************************************************************************************
Vag1                       : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[koh@kohs-MacBook-Pro] ~/vag_test
%
```

With these 2 syntaxes, you can check if an IP address of hosts is within a range automatically.
 
## Reference 

https://stackoverflow.com/questions/38725204/regular-expression-matching-for-ip-range-in-ansible-playbooks-for-grouping