I'm trying to replicate the first with_item example from ansible docs, but I'm facing this error:
fatal: [user#my-vm]: FAILED! => {"msg": "The task includes an option with an undefined variable.
The error was: 'item' is undefined\n\nThe error appears to be in 'path/ansible/playbooks/android-dev.yml': line 4,
column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\n
The offending line appears to be:\n\n tasks:\n - name: Debugging with items\n ^ here\n"}
My code is:
- hosts: test
tasks:
- name: Debugging with items
debug:
msg: "An item: {{ item }}"
with_items:
- 1
- 2
- 3
I'm following the first example of this page to build the task: https://docs.ansible.com/ansible/latest/plugins/lookup/items.html
I've started using ansible now and it may be a simple issue to fix, but I really can't find any solution online
The indentation is wrong. Fix it
- hosts: test
tasks:
- name: Debugging with items
debug:
msg: "An item: {{ item }}"
loop:
- 1
- 2
- 3
Use loop instead of with_items.
Related
wondering if anyone can help us with this.
The end goal is to refresh the variables back into the play from a YAML file which was generated previously if the file exists.
I'm using stat to check if the files exist and this works - 'name: Registering if file exists'. If i debug filecheck i can see the 2 entries in the dataset.
Next im trying to reload the vars from the file -final-dataset-file-1 if the file exists using the when condition - filecheck.stat.exists
- name: Registering if file exists
stat:
path: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}/final-dataset-{{ item }}.yml"
loop:
- file-1
- file-2
register: filecheck
- name: IOS - Refreshing final-dataset variables generated by the above tasks in order to service any subsequent tasks
include_vars:
file: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}/final-dataset-{{ item }}.yml"
loop:
- file-1
- file-2
when: filecheck.stat.exists
This is the error i'm seeing
fatal: [router]: FAILED! => {"msg": "The conditional check 'filecheck.stat.exists' failed. The error was: error while evaluating conditional (filecheck.stat.exists): 'dict object' has no attribute 'stat'\n\nThe error appears to be in '/ansible/roles/roles_nane/tasks/report.yml': line 94, 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: IOS - Refreshing final-dataset variables generated by the above tasks in order to service any subsequent tasks\n ^ here\n"}
Its like we need to loop through filecheck for each file/item and match these against the files that are a part of the include_vars items but i'm not sure how to do this.
Any comments would be appreciated.
Cheers
Iterate the results from the previous task e.g.
- include_vars: "{{ item.stat.path }}"
loop: "{{ filecheck.results }}"
when: item.stat.exists
Following is the piece of code, which is retrieving list of local zones and trying to enter rescue block if any one of the local zones is not in RUNNING state.
But the rescue block is failing, at 'Check if the zones are in running state'
Expectation is to send an email with the task name. But it is working well with other failed tasks.Can anyone please guide?
FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'item' is undefined\n\nThe error appears to be in '/etc/ansible/playbooks/misc/test1404.yml': line 23, column 9, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n rescue:\n - name: Sending an e-mail from Ansible controller node\n ^ here\n"}
- '{{ host }}'
tasks:
- block:
- name: Retrieve list of local zones
shell: /usr/sbin/zoneadm list | grep -v global
register: lzones
tags:
- local_zone_list
- debug:
msg: "{{ item }}"
with_items: "{{lzones.stdout_lines}}"
- name: Check if the zones are in running state
shell: /usr/sbin/zoneadm list | grep -v global | grep "{{ item }}" | awk '{print$3}'
register: status
with_items: "{{lzones.stdout_lines}}"
failed_when: status.stdout.find('running') == -1
< few other tasks>
rescue:
- name: Sending an e-mail from Ansible controller node
mail:
host: localhost
port: 25
to: xyz#abc.com
subject: Reboot Failed
body: Reboot FAILED at TASK - {{ ansible_failed_task.name }} with ERROR {{ ansible_failed_result }}
delegate_to: localhost
Well that was an absolutely fascinating rabbit hole.
Because in ansible jinja2 templates are rendered recursively, when it tries to render the failed message, which contains the failed template, it tries to re-render the failed template again, re-causing the error
This appears to be impacting you by the inclusion of the ansible_failed_task variable, since -- inexplicably -- it appears to be safe to include ansible_failed_result in the body
As best I can tell by experimenting with ansible 2.9.6, one must determine if it is possible to safely output the a*_task flavor variable before touching it, because I was wholly unable to find any combination of | string or |regex_replace or anything that allowed jinja2 to touch that variable so long as it contains the bogus variable reference:
- block:
- debug:
msg: this explodes {{ nope_not_a_var }}
rescue:
- set_fact:
is_undefined_error: '{{ "undefined variable" in ansible_failed_result.msg }}'
- name: variable is unsafe version
debug:
msg: >-
failed task action has an undefined variable in the task,
so we cannot show you the task, but here is the result: {{ ansible_failed_result }}
when: is_undefined_error
- name: variable is safe to output version
debug:
msg: Reboot FAILED at TASK - {{ ansible_failed_task.name }} with ERROR {{ ansible_failed_result }}
when: not is_undefined_error
It may be safe to inline that test of "..." in ansible_failed_result.msg into the when: lines directly, but since it (should) produce the same answer both times, there's no really good reason to evaluate it twice
This appears to me to be an ansible bug, but I don't have the emotional energy to take it up with their community -- however, I encourage you to file a bug with them
I currently want to select specifically the Windows adapter name ONLY from the ansible facts.
So my problem is that I cannot retrieve this value only.
Ansible 2.8.2_1 with Winrm & Kerberos Authentication are running on the server.
I've tried to launch this playbook :
- hosts: win_clients
gather_facts: true
strategy: free
tasks:
- name: Get Ansible network facts
debug:
msg: "{{ ansible_facts['interfaces'] }}"
and it works fine but I have all the informations about the interfaces. I just want the "connection_name".
When I put this line in the playbook :
msg: "{{ ansible_facts['interfaces']['connection_name'] }}"
It shows this message at the execution :
FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'list object' has no attribute 'connection_name'\n\nThe error appears to be in '/home/sopra/git/rnd-windows/automation/playbooks/Dns/test.yaml': line 5, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: Get Ansible network facts\n ^ here\n"}
I don't understand because the variable "connection_name" is well defined.
Can somebody help me? Thanks.
Have a good day !
If you want to list the connection_name, use below, as ansible_facts['interfaces'] is an array
- hosts: win_clients
gather_facts: true
strategy: free
tasks:
- name: Get Ansible network facts
debug:
msg: "{{ item.connection_name }}"
with_items:
- "{{ ansible_facts['interfaces'] }}"
Thank you very much for your support. I did resolve my problem.
Basically, my playbook consists in changing the DNS configuration if the occurrence of one (old) DNS's IP if found.
# tasks file for configureDnsServerAddresses
# Get the configuration state about DNS
# If one occurrence of 'old_dnsserver' is found...
- name: Get DNS configuration
win_shell: ipconfig /all | findstr {{ old_dnsserver }}
register: check_old_dns
changed_when: false
# '.rc' means the return code
failed_when: check_old_dns.rc != 0 and check_old_dns.rc != 1
# ... it will be replaced by 2 new ones
- name: Change the DNS only if the IP {{ old_dnsserver }} is found
win_dns_client:
adapter_names: "{{ item.connection_name }}"
ipv4_addresses:
- "{{ dnsserver1 }}"
- "{{ dnsserver2 }}"
# Array based on Ansible facts
with_items:
- "{{ ansible_facts['interfaces'] }}"
# Apply only if 'check_old_dns' is not empty, which means that the old DNS is found
when: check_old_dns.stdout | length > 0
This playbook is role-based, so the variables are stored in a "defaults" folder.
The code mentioned above was intended for testing purposes.
Ansible Version: 2.4.2.0
From here and here, I was able write below playbook
$ cat test.yml
- name: Finding Master VMs
hosts: all-compute-host
remote_user: heat-admin
tasks:
- name: Getting master VM's hostname
shell: hostname
register: hostname_output
- name: Access in different play
hosts: localhost
connection: local
tasks:
- name: Testing vars
debug: var='{{ hostvars[item]['hostname_output']['stdout'] }}'
with_items: groups['all-compute-host']
I don't want use gather_facts: true and access hostname from it. Getting below error when I try to above playbook
-----------OUTPUT REMOVED----------------
TASK [Testing vars] *******************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: u\"hostvars['groups['all-compute-host']']\" is undefined\n\nThe error appears to have been in '/tmp/test.yml': line 18, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: Testing vars\n ^ here\n\nexception type: <class 'ansible.errors.AnsibleUndefinedVariable'>\nexception: u\"hostvars['groups['all-compute-host']']\" is undefined"}
to retry, use: --limit #/tmp/test.retry
-----------OUTPUT REMOVED----------------
I tried below things
debug: var=hostvars[item]['hostname_output']['stdout']
debug: var=hostvars.item.hostname_output.stdout'
I have also tried direct host group instead of iterating item like below
debug: var=hostvars.all-compute-host.hostname_output.stdout'
debug: var=hostvars['all-compute-host']['hostname_output']['stdout']
ok: [localhost] => {
"hostvars['all-compute-host']['hostname_output']['stdout']": "VARIABLE IS NOT DEFINED!"
}
I have also try direct host name.But no use
debug: var='hostvars.compute01.hostname_output.stdout'
The problem is with your debug statement:
tasks:
- name: Testing vars
debug: var='{{ hostvars[item]['hostname_output']['stdout'] }}'
with_items: groups['all-compute-host']
There are two issues:
The value of the var argument to the debug module is evaluated in a Jinja templating context. That means you must not use the {{...}} template markers.
On the hand, the argument to with_items does need the {{...}} markers; without that, you're iterating over a list consisting of a single item, the literal string groups['all-compute-host'].
With both of those problems fixed (and a few minor stylistic changes), you get:
tasks:
- name: Testing vars
debug:
var: hostvars[item].hostname_output.stdout
with_items: "{{ groups['all-compute-host'] }}"
I'm currently creating a possibility to auto-obtain a Letsencrypt certificate using my ansible-playbook.
I'd like to check if the /etc/letsencrypt/domain.tld directory exists, when it doesn't, I need to obtain a certificate.
---
- name: LETSENCRYPT | Checking for existing certificates
stat:
path: /etc/letsencrypt/live/{{ item.value.server_name }}
register: le_cert_exists
with_dict: "{{ sites }}"
when: item.value.letsencrypt | default(false) | bool
- name: DEBUG | Output result of le cert exists
debug:
var: le_cert_exists
- name: LETSENCRYPT | Output sites that need a new certificate
debug:
msg: Obtain certificate here
var: item.item
with_items: le_cert_exists.results
when: item.stat.exists is defined and not item.stat.exists
So far it is working, except for the last function. The last task just keeps getting skipped or fails with the following error:
fatal: [-]: FAILED! => {"msg": "The conditional check 'item.stat.exists is defined and not item.stat.exists' failed. The error was: error while evaluating conditional (item.stat.exists is defined and not item.stat.exists): 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'stat'\n\nThe error appears to have been in '/path/to/main.yml': line 13, 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: LETSENCRYPT | Output sites that need a new certificate\n ^ here\n"}
Does anyone has an example of how this could be done easily?
I just need to execute a command when a directory does not exists.
This with_items: le_cert_exists.results is wrong,
this with_items: "{{ le_cert_exists.results }}" is correct.