Can't seem to get my second play to catch the package and print that it is not installed. Here is my playbook:
---
- hosts: all
vars:
packages:
- httpd
- unzip
- yum
- nmap
tasks:
- name: getting package facts
package_facts:
manager: auto
- name: Check whether our packages are installed
debug:
msg: "{{ ansible_facts.packages[item][0].name }} {{ ansible_facts.packages[item][0].version }}"
loop: "{{ packages }}"
register: pkgcheck
- name: Display packages not installed
debug:
msg: "{{ pkgcheck }} is not installed"
when: '"pkgcheck" is not defined'
loop: "{{ packages }}"
Use filter difference, e.g.
pkg_not_installed: "{{ packages|difference(ansible_facts.packages.keys()) }}"
For example, use the list in the loop
- name: Display packages not installed
debug:
msg: "{{ item }} is not installed"
loop: "{{ packages|difference(ansible_facts.packages.keys()) }}"
Q: "Is there a way to get both tasks to print my list of installed and not installed?"
A: Use intersect to print installed packages, e.g.
- name: Display installed packages
debug:
msg: "{{ item }} is installed"
loop: "{{ packages|intersect(ansible_facts.packages.keys()) }}"
Related
Using community.vmware.vmware_guest module to create VM from template by ansible playbook and passing all variables in it as required.
But after creation of VM, it showing dynamic value for mac instead of static value passed and also taking only one ip from list for adapter 1. Remaining IP not getting assigned.
For this situation I can delete mac by using module vmware_guest_network module but still I'm not able to assign IP to it.
Question: Need to have static/dynamic mac with multiple ip on single NIC. Also as per need we can modify value.
Below code but it not working as expected.
(task)
==========
- name: Create VM
community.vmware.vmware_guest:
hostname: "{{ hostname }}"
username: "{{ username }}"
password: "{{ password }}"
datacenter: "{{ center }}"
validate_certs: False
folder: "/{{ center }}/vm"
name: VM1
template: "{{ template }}"
networks:
- name: "{{ network}}
mac: "{{ mac }}"
gateway: "{{ gateway }}"
ip: "{{ nics[0].ips }}"
netmask: "{{ netmask }}"
dns_servers: "{{ dns }}"
state: "{{ vm_state }}"
loop: "{{ nics }}"
delegate_to: localhost
(vars) Value below are for example only
===========================================
nics:
- name: Network Adapter 1
mac: 00:00:00:00:00:00
ips:
- 192.168.1.4
- 192.168.1.9
I'm trying to look for a pattern in Postgres configuration files, and
only wants to find changed files that match the search pattern.
---
- name: Query postgres pattern matched files
hosts: pghosts
gather_facts: false
tasks:
- name: "Find postgres conf files"
find:
paths: "/srv/postgresql/config/conf.d"
patterns: "*.conf"
file_type: "file"
register: search_files
- name: "grep postgres conf files with searchpattern"
shell: "grep -i 'pg_show_plans' {{ item.path | basename }}"
args:
chdir: "/srv/postgresql/config/conf.d"
loop: "{{ search_files.files }}"
loop_control:
label: "{{ item.path | basename }}"
ignore_errors: true
- name: "find changed files"
debug:
msg: "{{ search_files.files |map(attribute='path') }}"
These are the changed files:
changed: [pgsql14.techlab.local] => (item=00_global_default.conf)
...ignoring
changed: [pgsql13.techlab.local] => (item=00_global_default.conf)
...ignoring
How do I get only those filenames, which realy have changed, and passed the pattern test.
Thanks a lot for your help
I do now have simplified the code which works for me:
- name: read the postgres conf file
shell: cat /srv/postgresql/config/conf.d/00_global_default.conf
register: user_accts1
- name: a task that only happens if the string exists
when: user_accts1.stdout.find('pg_show_plans') != -1
ansible.builtin.copy:
content: "{{ user_accts1.stdout }}"
dest: 'fileresults/{{ inventory_hostname }}.00_global_default.out'
delegate_to: localhost
- name: read the postgres conf file
shell: cat /srv/postgresql/config/conf.d/01_sizing_specific.conf
register: user_accts2
- name: a task that only happens if the string exists
when: user_accts2.stdout.find('pg_show_plans') != -1
ansible.builtin.copy:
content: "{{ user_accts2.stdout }}"
dest: 'fileresults/{{ inventory_hostname }}.01_sizing_specific.out'
delegate_to: localhost
- name: read the postgres conf file
shell: cat /srv/postgresql/config/conf.d/02_local_overrides.conf
register: user_accts3
- name: a task that only happens if the string exists
when: user_accts3.stdout.find('pg_show_plans') != -1
ansible.builtin.copy:
content: "{{ user_accts3.stdout }}"
dest: 'fileresults/{{ inventory_hostname }}.02_local_overrides.out'
delegate_to: localhost
I have an ansible playbook that is reading in a list of files, and setting a register for those values. I want to then pass the list of files into an include_role task. Below is my current code.
- name: Get list of files
command: "sh -c 'find playbooks/vars/files/*.yml'"
register: find_files
- include_vars:
file: "{{ item }}"
loop: "{{ find_files.stdout_lines }}"
register: result
- name: call role
include_role:
name: myRole
loop: "{{ result.results }}"
When the playbook runs, its finds two files in the directory; file1.yml and file2.yml. But when it runs through the include_role loop, its passes file1.yml twice and never passes file2.yml. Trying to determine how I can ensure file2.yml gets passed to the role as well.
I was able to find the correct my issue by constructing an array and then feeding it into include_role and using the find module instead of shell.
- name: Recursively find yml files
find:
paths: ~/vars
recurse: yes
register: find_files
- name: Construct file array
set_fact:
file_arr: "{{ file_arr|default([]) + [file.path] }}"
with_items: "{{ find_files.files }}"
loop_control:
loop_var: file
- name: Topic Management
include_role:
name: kafkaTopicManagement
vars:
kafkaFiles: "{{ item }}"
with_items: "{{ file_arr }}"
This now feeds the the files into include_role.
Below is the playbook with import_tasks get_hosts.yml for building dynamic hosts in a nested loop. However, I get syntax error running the playbook.
{{ item.split('\t')[0] }} will have ip addresses separated by commas , and then a string seperated by /t
---
- name: "Play 1"
hosts: localhost
tasks:
- name: "Search database"
command: > mysql --user=root --password=p#ssword deployment
--host=localhost -Ns -e "SELECT dest_ip,file_dets FROM deploy_dets"
register: command_result
- name: Add hosts
include_tasks: "{{ playbook_dir }}/gethosts.yml"
dest_ip: "{{ item.split('\t')[0] }}"
groups: dest_nodes
file_dets: "{{ item.split('\t')[1] }}"
ansible_host: localhost
ansible_connection: local
with_items: "{{ command_result.stdout_lines }}"
And below is my get_hosts.yml file
add_host:
name: "{{ item }}"
with_items: "{{ dest_ip.split(',') }}"
Output:
$ ansible-playbook testinclude.yml
ERROR! Syntax Error while loading YAML. did not find expected key
The error appears to be in '/app/deployment/testinclude.yml': line 23, column 8, but may be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
include_tasks: "{{ playbook_dir }}/gethosts.yml"
dest_ip: "{{ item.split('\t')[0] }}"
^ here We could be wrong, but this one looks like it might be an issue with missing quotes. Always quote template expression brackets when they start a value. For instance:
with_items:
- {{ foo }}
Should be written as:
with_items:
- "{{ foo }}"
Can you please suggest
Perhaps you forgot vars parameter, so:
include_tasks: "{{ playbook_dir }}/gethosts.yml"
vars: # <------------------------------------------- HERE
dest_ip: "{{ item.split('\t')[0] }}"
groups: dest_nodes
I have the below vars file and Ansible task which allows some ports for a specific source IPs on the firewall.
But for some reason, whenever I run the task I got this error:
FAILED! => {"msg": "The task includes an option with an undefined variable.
Even though I'm able to echo out these variables using debug Ansible module, so basically I'm just unable to use these variable specifically in this task.
Ansible Task:
---
- name:
firewalld:
permanent: yes
port: "{{ item.0 }}"
state: enabled
zone: public
source: "{{ item.1 }}"
with_nested:
- "{{ ports }}"
- "{{ ips }}"
Vars File:
ports:
- "8000/tcp"
- "9997/tcp"
- "8181/tcp"
- "8080/tcp"
- "8191/tcp"
- "8088/tcp"
- "8065/tcp"
ips:
- "192.168.210.30/32"
- "192.168.210.35/32"
- "192.168.210.40/32"
- "192.168.210.31/32"
- "192.168.210.36/32"
- "192.168.210.41/32"
- "192.168.210.42/32"
- "192.168.210.37/32"
The indentation of with_nested is wrong. Correct syntax is
- name:
firewalld:
permanent: yes
port: "{{ item.0 }}"
state: enabled
zone: public
source: "{{ item.1 }}"
with_nested:
- "{{ ports }}"
- "{{ ips }}"