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 }}"
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
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()) }}"
Below is my playbook that works fine.
---
- hosts: "PROD_SERVERS"
user: "{{USER}}"
tasks:
- name: Check if all hosts are reachable
fail:
msg: "Server is UNREACHABLE."
when: "hostvars[item].ansible_facts|list|length == 0"
with_items: "{{ groups.PROD_SERVERS }}"
However, can you help me with the syntax when the host is presented as wildcard i.e {{ENV}}_*?
---
- hosts: "{{ENV}}_*"
user: "{{USER}}"
tasks:
- name: Check if all hosts are reachable
fail:
msg: "Server is UNREACHABLE."
when: "hostvars[item].ansible_facts|list|length == 0"
with_items: "{{ groups.{{ENV}}_* }}" <------- Need help with this part of the code
There are special variables also called as "magic variables" to identify the hosts in the current play. They are:
ansible_play_hosts
ansible_play_batch
You can use one of these variables to loop with instead of the inventory group name.
Example with ansible_play_hosts:
- fail:
msg: "Server is UNREACHABLE."
when: hostvars[item].ansible_facts|list|length == 0
with_items: "{{ ansible_play_hosts }}"
Update:
Changed the example for Ansible version "2.4.x", the loop should be performed with with_items rather than loop. Quoting from official documentation
We added loop in Ansible 2.5. It is not yet a full replacement for with_<lookup>, but we recommend it for most use cases.
Note: For Ansible "2.9.16" and "2.10.2" loop works as well.
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