Ansible looping Ansible_net_interfaces isn't seeing item.key as defined - networking

No matter how I call the items in the ansible_net _interfaces dictionary it keeps telling me "item" isn't defined. I did a debug and the dictionary has all the values I want just can't call them in the parents line here. Any ideas what I'm doing wrong?
- name: Un-Apply the policy-map sed-input-mark
ios_config:
lines:
- no policy-map sed-input-mark
parents: interface {{ item.key }}
with_dict: "{{ ansible_net_interfaces }}"
Here is Error message:
fatal: [192.168.50.4]: FAILED! => {
"msg": "The task includes an option with an undefined variable. The error was: 'item' is undefined\n\nThe error appears to have been in '/home/drojas/networkautorepo/plays/QoSSed/qossedpolicy.yml': line 96, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Un-Apply the policy-map sed-input-mark\n ^ here\n"

Related

How to add nested dictionary to dynamic host in Ansible

I have application details in respective vars like below. For example, myapp1 in "QA" environment would look like the below:
cat myapp1_QA.yml
---
APP_HOSTS:
- myapphost7:
- logs:
- /tmp/web/apphost7_access
- /tmp/web/apphost7_error
- myapphost9:
- logs:
- /tmp/web/apphost9_access
- /tmp/web/apphost9_error
- /tmp/web/apphost9_logs
WEB_HOSTS:
- mywebhost7:
- logs:
- /tmp/webserver/webhost7.pid
In this example I wish to create a dynamic host containing the 3 hosts
myapphost7
myapphost9
mywebhost7
and each host has variable log which can be looped to get the file paths:
Below is my ansible play:
---
- hosts: localhost
tasks:
- include_vars:
file: "{{ playbook_dir }}/{{ appname }}_{{ myenv }}.yml"
- name: Dsiplay dictionary data
debug:
msg: "{{ item[logs] }}"
loop: "{{ APP_HOSTS }}"
I get the below error:
ansible-playbook read.yml -e appname=myapp1 -e myenv=QA
TASK [Dsiplay dictionary data] *********************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'logs' is undefined\n\nThe error appears to be in '/root/read.yml': line 8, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Dsiplay dictionary data\n ^ here\n"}
My requirement is to store "myapphost7", "myapphost9", "mywebhost7" in group using add_hosts: hosts: while a variable logs: having the list of log files.
Note: if no hosts mywebhost7 is defined under WEB_HOSTS: or APP_HOSTS: then nothing should be added to the dynamic host.
Can you please suggest?

Dictionary value access using ansible

I have a situation where we have 2 dictionary defined in ansible role default and the selection of dictionary is based of an input variable. I want to set the fact with one of the dict's specific key value.
Below is the example code:
test.yml paybook content:
- hosts: localhost
gather_facts: true
roles:
- role1
tags: ['role1']
roles/role1/tasks/main.yml content:
- name: set fact
set_fact:
node_vip: "{% if node_vip_run == 'no' %}node_vip_no{% elif node_vip_run == 'yes' %}node_vip_yes{% endif %}"
- debug:
var: node_vip
verbosity: 1
- debug:
var: "{{ node_vip }}.ece_endpoint"
verbosity: 1
- name: set fact
set_fact:
ece_endpoint_fact: "{{ node_vip[ece_endpoint] }}"
- debug:
var: ece_endpoint
verbosity: 1
roles/role1/defaults/main.yml content:
node_vip_yes:
ece_endpoint: "https://1.1.1.1:8080"
cac_endpoint: "https:2.2.2.2:8080"
node_vip_no:
ece_endpoint: "http://3.3.3.3:8080"
cac_endpoint: "http:4.4.4.4:8080"
Run playbook:
ansible-playbook test.yaml --extra-vars 'node_vip_run=no' -v
The set fact of variable "ece_endpoint_fact" should have value "https://1.1.1.1:8080 OR http://3.3.3.3:8080" depending on the parameter input in ansible command. But I keep on getting below error:
TASK [role1 : set fact] *******************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'unicode object' has no attribute u'http://3.3.3.3:8080'\n\nThe error appears to be in '/root/roles/role1/tasks/main.yml': line 46, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: set fact\n ^ here\n"}
Please suggest what needs to be done to resolve this.
Thanks
Right now, you set node_vip to either the literal string "node_vip_no" or "node_vip_yes". But if you change it to do {{ node_vip_no }} / {{ node_vip_yes }}, then node_vip will have the value of the variable node_vip_no / node_vip_yes instead of being a literal string.
- name: set fact
set_fact:
node_vip: "{% if node_vip_run == 'no' %}{{ node_vip_no }}{% elif node_vip_run == 'yes' %}{{ node_vip_yes }}{% endif %}"
This will have node_vip's value be something like:
TASK [debug] ***************************************************************
ok: [localhost] => {
"node_vip": {
"cac_endpoint": "https:2.2.2.2:8080",
"ece_endpoint": "https://1.1.1.1:8080"
}
}
Then in your other set_fact, it should work if you put quotes around the property name:
- name: set fact
set_fact:
ece_endpoint_fact: "{{ node_vip['ece_endpoint'] }}"
# Added quotes ^ ^

The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'data'\n

I have simple playbook where fetching some data from Vault server using curl.
tasks:
- name: role_id
shell: 'curl \
--header "X-Vault-Token: s.ddDblh8DpHkOu3IMGbwrM6Je" \
--cacert vault-ssl-cert.chained \
https://active.vault.service.consul:8200/v1/auth/approle/role/cpanel/role-id'
register: 'vault_role_id'
- name: test1
debug:
msg: "{{ vault_role_id.stdout }}"
The output is like this:
TASK [test1] *********************************************************************************************************************************************************************
ok: [localhost] => {
"msg": {
"auth": null,
"data": {
"role_id": "65d02c93-689c-eab1-31ca-9efb1c3e090e"
},
"lease_duration": 0,
"lease_id": "",
"renewable": false,
"request_id": "8bc03205-dcc2-e388-57ff-cdcaef84ef69",
"warnings": null,
"wrap_info": null
}
}
Everything is ok if I am accessing first level attribute, like .stdout in previous example. I need deeper level attribute to reach, like vault_role_id.stdout.data.role_id. When I try this it is failing with following error:
"The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'data'\n\n
Do you have suggestion what I can do to get properly attribute values from deeper level in this object hierarchy?
"The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'data'\n\n
Yes, because what's happening is that rendering it into msg: with {{ is coercing the JSON text into a python dict; if you do want it to be a dict, then use either msg: "{{ (vault_role_id.stdout | from_json).data.role_id }}" or you can use set_fact: {vault_role_data: "{{vault_role_id.stdout}}"} and then vault_role_data will be a dict for the same reason it was coerced by your msg
You can see the opposite process by prefixing the msg with any characters:
- name: this one is text
debug:
msg: vault_role_id is {{ vault_role_id.stdout }}
- name: this one is coerced
debug:
msg: '{{ vault_role_id.stdout }}'
while this isn't what you asked, you should also add --fail to your curl so it exists with a non-zero return code if the request returns non-200-OK, or you can use the more ansible-y way via - uri: and set the return_content: yes parameter

Correct syntax for if statement in saltstack

Running following command:
salt host1 file.check_perms /xxx/zzz '{}' root sudo 0750
I will get True,
I like add this to my state, but can't find the correct syntax.
{% if not salt['file.check_perms']('/xxx/zzz/', '{}',['root'],['sudo'],['0750']) %
Set group ownership and permissions:
file.directory:
- name: /xxx/zzz/
- user: root
- group: sudo
- dir_mode: 750
- file_mode: 750
- recurse:
- user
- group
- mode
{% endif %}
Traceback:
Data failed to compile:
----------
Rendering SLS 'base:certbot.cert' failed: Jinja error: string indices must be integers, not unicode
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/salt/utils/templates.py", line 392, in render_jinja_tmpl
output = template.render(**decoded_context)
File "/usr/lib/python2.7/dist-packages/jinja2/environment.py", line 1008, in render
return self.environment.handle_exception(exc_info, True)
File "/usr/lib/python2.7/dist-packages/jinja2/environment.py", line 780, in handle_exception
reraise(exc_type, exc_value, tb)
File "<template>", line 13, in top-level template code
File "/usr/lib/python2.7/dist-packages/salt/modules/file.py", line 4469, in check_perms
orig_comment = ret['comment']
TypeError: string indices must be integers, not unicode
Could anyone help me?
I found the solution myself, following syntax is works:
{% if salt['file.check_perms']('/xxx/zzz/', {},('root'),('sudo'),('0750')) != 'True' %}
Set group ownership and permissions:
file.directory:
- name: /zzz/zzz/
- user: root
- group: sudo
- dir_mode: 750
- file_mode: 750
- recurse:
- user
- group
- mode
{% endif %}

Syntax error in SaltStack state file

I am newbie with SaltStack. I have an error in one of my first state files.
The state file is:
openvpn:
pkg.installed: []
/etc/openvpn:
file.recurse:
- source: salt://myvpn/openvpn-files
service.running: []
And the error: State 'openvpn' in SLS u'myvpn' is not formed as a list
Could you say me where is the fail?
I found the error. It can't define a state inside other state (/etc/openvpn: inside openvpn:)
I've fixed this way:
openvpn:
pkg.installed: []
file.recurse:
- name: /etc/openvpn
- source: salt://myvpn/openvpn-files
service.running: []

Resources