So, I have this list:
ip_range:
- "1.x.x.x/24"
- "2.x.x.x/24"
And I'm trying to pass it on to an AWS cli command as a valid JSON:
- name: list of IPs
set_fact:
allowed_cidrs: "{{ ip_range | ipaddr('network/prefix') }}"
- debug:
msg: "{{ allowed_qualys_cidrs | to_json }}"
- name: send command
command: >
aws wafv2 update-ip-set
--addresses "{{ allowed_cidrs | to_json }}"
That debug prints:
["1.x.x.x/24", "2.x.x.x/24"]
But what the command tries to send is:
"cmd": [
"aws",
"wafv2",
"update-ip-set",
"--addresses",
"[1.x.x.x/24, 2.x.x.x/24]",
]
Which, because the double quotes are gone, is not a valid JSON.
I already tried every possible approach with Ansible and Jinja2, but I can't figure out a way to send that command with a valid JSON.
Use single quotes in your command rather than double quotes:
- name: list of IPs
set_fact:
allowed_cidrs: "{{ ip_range | ipaddr('network/prefix') }}"
vars:
ip_range:
- "1.1.1.1/24"
- "2.2.2.2/24"
- name: send command
command: >-
aws wafv2 update-ip-set
--addresses '{{ allowed_cidrs | to_json }}'
register: _cmd
- debug:
var: _cmd.cmd
Yields:
TASK [list of IPs] **********************************************************
ok: [localhost]
TASK [send command] *********************************************************
changed: [localhost]
TASK [debug] ****************************************************************
ok: [localhost] => {
"_cmd.cmd": [
"aws",
"wafv2",
"update-ip-set",
"--addresses",
"[\"1.1.1.0/24\", \"2.2.2.0/24\"]"
]
}
Related
I have this following file var/Hendrix.yml
last: Hendrix
fullname: "Jimi {{ last }}"
And the following playbook
- name:
hosts: localhost
tasks:
- name: include
include_vars: "{{ choice }}.yml"
- name: debug
debug:
msg: "include_vars {{ choice }}, {{ fullname }}"
tags: simpleinc
- name:
hosts: localhost
tags: builtininc
tasks:
- name: include
ansible.builtin.include_vars:
file: "{{ choice }}.yml"
- name: debug
debug:
msg: "ansible.builtin.include_vars {{ choice }}, {{ fullname }}"
running with tags simpleinc or builtininc does not show the same result
ansible-playbook test.yml --extra-vars "choice=Hendrix" --tags simpleinc
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "include_vars Hendrix, Jimi Hendrix"
}
ansible-playbook test.yml --extra-vars "choice=Hendrix" --tags builtininc
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "ansible.builtin.include_vars Hendrix, Jimi {{ last }}"
}
I read that using full name of task is a good practice, but here it puzzeld me a bit, maybe this is due to file parameter, but I don't see any template
I have a variable that is set from a Tower survey and I am using it to retrieve an associated IP address in netbox. I am not able to get it to match when I use square brackets and when I use {{ or ' or " everything is matched and my whole IPAM database is returned.
vars:
location: "{{ LOCATION }}"
c_description: "{{CIRCUIT_DESC}}"
prefix_length: "{{PREFIX}}"
tasks:
- name: "Print IP"
debug:
msg: "{{ query('netbox.netbox.nb_lookup', 'ip-addresses', api_filter= 'description=
[c_description]', api_endpoint='http://netbox', token='', validate_certs='False') }}"
Here is my output:
TASK [Print IP] ****************************************************************
ok: [localhost] => {
"msg": []
}
Solved in another forum using a tilda:
- name: "Print IP"
debug:
msg: "{{ query('netbox.netbox.nb_lookup', 'ip-addresses', api_filter='description=' ~ c_description,
api_endpoint='http://netbox.', token='', validate_certs='False') }}"
How to get the sum of two hosts with Jinja2 filtering ansible
host1 and host 2
---
- name: Count Check
hosts: MYGROUP
gather_facts: true
user: sv_admin
tasks:
- name: count check
shell: cat /etc/hosts | wc -l
register: command_result
- debug:
var: command_result.stdout
- set_fact:
total_result: "{{ command_result.stdout | map('int') | sum(start=0) }}"
- debug:
msg: "Total count: {{ total_result }}"
Playbook Output
TASK [debug] *****************************************************************
ok: [Host-01] => {
"msg": "Total count: 134"
}
ok: [Host-02] => {
"msg": "Total count: 133"
}
Use extract and sum. For example, the playbook below
shell> cat playbook.yml
- hosts: test_01:test_03
gather_facts: false
tasks:
- shell: cat /etc/hosts | wc -l
register: command_result
- debug:
var: command_result.stdout
- set_fact:
total_result: "{{ ansible_play_hosts_all|
map('extract', hostvars, ['command_result', 'stdout'])|
map('int')|
sum }}"
run_once: true
- debug:
var: total_result
gives (abridged)
shell> ansible-playbook playbook.yml
PLAY [test_01:test_03] ****
TASK [shell] ****
changed: [test_01]
changed: [test_03]
TASK [debug] ****
ok: [test_01] => {
"command_result.stdout": " 62"
}
ok: [test_03] => {
"command_result.stdout": " 31"
}
TASK [set_fact] ****
ok: [test_01]
TASK [debug] ****
ok: [test_03] => {
"total_result": "93"
}
ok: [test_01] => {
"total_result": "93"
}
See serial
See the difference between ansible_play_hosts and ansible_play_hosts_all
You can use custom stats to do that: https://docs.ansible.com/ansible/latest/modules/set_stats_module.html
So for your case it would look like
---
- name: Count Check
hosts: MYGROUP
gather_facts: true
user: sv_admin
tasks:
- name: count check
shell: cat /etc/hosts | wc -l
register: command_result
- debug:
var: command_result.stdout
- set_fact:
host_result: "{{ command_result.stdout }}"
- debug:
msg: "Count for this host: {{ host_result }}"
- set_stats:
data: "{{ { 'total_count': host_result | int } }}"
Then if you run it with ANSIBLE_SHOW_CUSTOM_STATS=yes it will show you the result at the end:
$ ANSIBLE_SHOW_CUSTOM_STATS=yes ansible-playbook -i inventory pb.yml
... (usual output)
CUSTOM STATS: *************************************************************
RUN: { "total_count": 267}
The set_stats task adds results together from all the hosts by default, which is what you are looking for. You need to make sure the values are integers though, because if they are strings it will just concatenate them and you will end up with something like RUN: { "total_count": "134133"}. That's why I have put the data: bit the way I have - if you try to create the dictionary in regular yaml, like
data:
total_count: "{{ host_result | int }}"
you will see that the value is still a string (due to the way yaml/jinja works) and it won't work properly.
I have a file with the following content:
AWS_ACCESS_KEY_ID=xxxxxxx
AWS_SECRET_ACCESS_KEY=yyyyyy
AWS_SESSION_TOKEN=zzzzzzzz
How do I read this file, split the line based on "=" and set the values of the variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN) so that I can use these variables in the script for later use?
Q: How do I read this file, split the line based on "=" and set the values of the variables?
A: Use ini lookup plugin. For example the tasks below
- set_fact:
AWS_ACCESS_KEY_ID: "{{ lookup('ini', 'AWS_ACCESS_KEY_ID type=properties file=conf.ini') }}"
- debug:
var: AWS_ACCESS_KEY_ID
give
"AWS_ACCESS_KEY_ID": "xxxxxxx"
It is possible to use a list of variables. For example the play below
- hosts: localhost
vars:
my_vars_keys: [AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN]
tasks:
- set_fact:
my_vars: "{{ my_vars|default({})|
combine({item:
lookup('ini',
item ~ ' type=properties file=conf.ini')})
}}"
loop: "{{ my_vars_keys }}"
- debug:
msg: "{{ my_vars[item] }}"
loop: "{{ my_vars_keys }}"
gives
ok: [localhost] => (item=AWS_ACCESS_KEY_ID) => {
"msg": "xxxxxxx"
}
ok: [localhost] => (item=AWS_SECRET_ACCESS_KEY) => {
"msg": "yyyyyy"
}
ok: [localhost] => (item=AWS_SESSION_TOKEN) => {
"msg": "zzzzzzzz"
}
Q: How do I make sure that above set_fact runs on the hosts and not on the ansible tower?
A: The set_fact uses Lookup Plugins. Quoting
Like all templating, these plugins are evaluated on the Ansible control machine, not on the target/remote.
I am trying fetch to distinct groups in the inventory through a variable.this is the command am trying to run in the playbook to add hosts to the Nagios XI. Am trying to do this using Rest API through CURL command. Am getting error as Incorrect pattern. Can some one please advise about the issue. or help me out with how we can call two groups from the inventory in the same command.
- name: add host to nagios XI.
shell: curl -XPOST "http://16.231.22.60/nagiosxi/api/v1/config/host?apikey=qfOQpKFORCNo7HPunDUsSjW7f2rNNmrdVv3kvYpmQcNdSS2grV2jeXKsgbv3QgfL&pretty=1" -d "host_name={{ item.hostname }}&address={{ item.address }}&use=xiwizard_ncpa_host&max_check_attempts=5&check_period=xi_timeperiod_24x7¬ification_interval=60¬ification_period=xi_timeperiod_24x7¬ifications_enabled=0&contacts=nagiosadmin&contact_groups=Candle Admins,Candle-L1-L2-Internal&applyconfig=1"
with_items:
- { hostname: "{{ groups['grp1'] }}", address: "{{ groups['grp2'] }}"}
EDIT: code formatting
Understanding that your hostname and address from each group match each other you can do the following:
Inventory:
[grp1]
host1
host2
host3
[grp2]
10.100.10.1
10.100.10.2
10.100.10.3
Play:
---
- name: Debug Together
hosts: localhost
gather_facts: False
tasks:
- name: Add host to nagios XI
shell: shell: curl -XPOST "http://16.231.22.60/nagiosxi/api/v1/config/host?apikey=qfOQpKFORCNo7HPunDUsSjW7f2rNNmrdVv3kvYpmQcNdSS2grV2jeXKsgbv3QgfL&pretty=1" -d "host_name={{ item.0 }}&address={{ item.1 }}&use=xiwizard_ncpa_host&max_check_attempts=5&check_period=xi_timeperiod_24x7¬ification_interval=60¬ification_period=xi_timeperiod_24x7¬ifications_enabled=0&contacts=nagiosadmin&contact_groups=Candle Admins,Candle-L1-L2-Internal&applyconfig=1"
with_together:
- "{{ groups['grp1'] }}"
- "{{ groups['grp2'] }}"
You will get something like:
TASK [debug] ******************************************************************************************************************
ok: [localhost] => (item=None) => {
"item.0, item.1": "(u'host1', u'10.100.10.1')"
}
ok: [localhost] => (item=None) => {
"item.0, item.1": "(u'host2', u'10.100.10.2')"
}
ok: [localhost] => (item=None) => {
"item.0, item.1": "(u'host3', u'10.100.10.3')"
}
Comming from my test:
- name:
debug:
var: item.0, item.1
with_together:
- "{{ groups['grp1'] }}"
- "{{ groups['grp2'] }}"