Reason for question
I have a requirement to check for any hard-coded IP address which may have been left within the Playbooks in our environment.
Scenario
The following code which will find files containing IPv4 addresses and store them in playbook_files
.
- hosts: localhost
tasks:
- name: Loop through Playbooks
find:
paths: "{{ playbook_dir }}/.."
file_type: file
recurse: yes
contains: ^.*(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
register: playbook_files
- name: "Test-1"
- debug:
msg:
- "{{ playbook_files.files | type_debug }}"
- "{{ playbook_files.files }}"}}"
- name: "Test-2"
debug:
msg: "Path: {{ item }}"
loop: "{{ playbook_files.files | map(attribute='path') | list }}"
- set_fact:
files_with_hardcoded_ips:
- "/home/ansible/playbooks/README.md"
- "/home/ansible/playbooks/test/vars.yml"
- name: "Test 3"
debug:
msg:
- "files_with_hardcoded_ips: {{ files_with_hardcoded_ips | type_debug }}"
- "{{ files_with_hardcoded_ips }}"
The result of that being:
TASK 1/5 [Loop through Playbooks] *******************************************************************************************
ok: 1/1 [localhost] => {"changed": false, "examined": 295, "files": [{"atime": 1677573594.1507878, "ctime": 1677573594.1507878, "dev": 66305, "gid": 1009, "gr_name": "ec2_user", "inode": 13302670, "isblk": false, "ischr": false, "isdir": false, "isfifo": false, "isgid": false, "islnk": false, "isreg": true, "issock": false, "isuid": false, "mode": "0775", "mtime": 1677573594.1507878, "nlink": 1, "path": "/home/ansible/playbooks/README.md", "pw_name": "ec2_user", "rgrp": true, "roth": true, "rusr": true, "size": 5571, "uid": 1009, "wgrp": true, "woth": false, "wusr": true, "xgrp": true, "xoth": true, "xusr": true},
{"atime": 1677573594.1507878, "ctime": 1677573594.1507878, "dev": 66305, "gid": 1009, "gr_name": "ec2_user", "inode": 16787335, "isblk": false, "ischr": false, "isdir": false, "isfifo": false, "isgid": false, "islnk": false, "isreg": true, "issock": false, "isuid": false, "mode": "0775", "mtime": 1677573594.1507878, "nlink": 1, "path": "/home/ansible/playbooks/test/vars.yml", "pw_name": "ec2_user", "rgrp": true, "roth": true, "rusr": true, "size": 232, "uid": 1009, "wgrp": true, "woth": false, "wusr": true, "xgrp": true, "xoth": true, "xusr": true}], "matched": 30, "msg": ""}
TASK 2/5 [Test-1] ***********************************************************************************************************
ok: 1/1 [localhost] => {
"msg": [
"list",
[
{
"atime": 1677573594.1507878,
"ctime": 1677573594.1507878,
"dev": 66305,
"gid": 1009,
"gr_name": "ansible",
"inode": 13302670,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"mode": "0775",
"mtime": 1677573594.1507878,
"nlink": 1,
"path": "/home/ansible/playbooks/README.md",
"pw_name": "ansible",
"rgrp": true,
"roth": true,
"rusr": true,
"size": 5571,
"uid": 1009,
"wgrp": true,
"woth": false,
"wusr": true,
"xgrp": true,
"xoth": true,
"xusr": true
},
{
"atime": 1677573594.1507878,
"ctime": 1677573594.1507878,
"dev": 66305,
"gid": 1009,
"gr_name": "ansible",
"inode": 16787335,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"mode": "0775",
"mtime": 1677573594.1507878,
"nlink": 1,
"path": "/home/ansible/playbooks/test/vars.yml",
"pw_name": "ansible",
"rgrp": true,
"roth": true,
"rusr": true,
"size": 232,
"uid": 1009,
"wgrp": true,
"woth": false,
"wusr": true,
"xgrp": true,
"xoth": true,
"xusr": true
}
]
]
}
TASK 3/5 [Test-2] ***********************************************************************************************************
ok: 1/1 [localhost] => {
TASK 4/5 [set_fact] *********************************************************************************************************
ok: 1/1 [localhost] => {"ansible_facts": {"files_with_hardcoded_ips": ["/home/ansible/playbooks/README.md", "/home/ansible/playbooks/test/vars.yml"]}, "changed": false}
TASK 5/5 [Test 3] ***********************************************************************************************************
ok: 1/1 [localhost] => {
"msg": [
"files_with_hardcoded_ips: list",
[
"/home/ansible/playbooks/README.md",
"/home/ansible/playbooks/test/vars.yml"
]
]
}
Test-1:
Shows the data_type and the file information.
Test-2:
Unsuccessfully attempts to loop through the list of files found.
Test-3:
Shows what I'd like to achieve.
Symptom
I am unable to loop through the list of files found to contain IP address and make use of the results.
The output from Test-1
shows the playbook_files.files
is a list, and gives me a list of two objects detailing the files found.
However, when I try and loop through the list to display just the path
value, I get nothing. I think this is because playbook_files.files
is a list of dictionaries.
Required Result
I would like to be able to loop through playbook_files.files
and do the following:
Ignore files
README.md
files.Register the fact:
files_with_hardcoded_ips:
containing the path to the files withinplaybook_files.files
Resulting example:
ok: 1/1 [localhost] => {
"msg": [
[
"/home/ansible/playbooks/README.md",
"/home/ansible/playbooks/test/vars.yml"
]
]
}
- Output the line(s) containing the hardcoded IP with the file.
Resulting example:
In this example the vars.yml
file has two lines containing an IP. One is a comment the other is not.
ok: 1/1 [localhost] => {
"test4": {
"home/ansible/playbooks/test/vars.yml": [
"# Example IP Address 192.168.1.20",
" ip: 192.168.1.20"
]
}
}
As always, your expert help is very much appreciated!
Simon.
Thank you to @Zeitounato, the selection method suggested by works a treat, as does:
- set_fact:
files_with_hardcoded_ips: "{{ playbook_files | json_query('files[*].path') }}"
However, when I try to loop over the files_with_hardcoded_ips
list it fails, see below.
- hosts: localhost
tasks:
- name: Loop through Playbooks
find:
paths: "{{ playbook_dir }}/.."
file_type: file
recurse: yes
contains: ^.*(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
register: playbook_files
- name: store file paths containing ips excluding any README.md in a fact
set_fact:
files_with_hardcoded_ips: "{{ playbook_files.files | map(attribute='path') | reject('search', 'README.md') }}"
- name: Show list of files and data type.
debug:
msg:
- "{{ files_with_hardcoded_ips | type_debug }}"
- "{{ files_with_hardcoded_ips }}"
- name: Loop over list of files and show data type.
debug:
msg: "{{ item }} {{ item | type_debug }}"
loop: "{{ files_with_hardcoded_ips }}"
Resulting in:
TASK [store file paths containing ips excluding any README.md in a fact] **************************************************************************************************************************
task path: /home/ansible/playbooks/test/test_hardcoded_ips.yml:23
ok: 1/1 [localhost] => {
"ansible_facts": {
"files_with_hardcoded_ips": [
"/home/ansible/playbooks/test/vars.yml"
"/home/ansible/playbooks/test-play-2/test-play-2.yml"
]
},
"changed": false
}
TASK [Show list of files.] ************************************************************************************************************************************************************************
task path: /home/ansible/playbooks/test/test_hardcoded_ips.yml:27
What I'm not understanding now is why I cannot loop over the files_with_hardcoded_ips
list, and display or use those files. It's really really odd!