I have below ospf process:
msg: ' OSPF Process: [''T1'', ''T2'', ''T3'']'
ospf_process:
- T1
- T2
- T3
I have below task to shut ospf process but isn't working. ansible is throwing error.
- name: Shut OSPF process
cisco.nxos.nxos_config:
lines:
- shutdown
parents: router ospf {{item}}
with_items: "{{ ospf_process }}"
save_when: modified
Error is:
The task includes an option with an undefined variable. The error was: 'item' is undefined
how to fix it?
You have a syntax error, with_items should be an argument to the task, not the nxos_config module. You need:
- name: Shut OSPF process
cisco.nxos.nxos_config:
lines:
- shutdown
parents: router ospf {{item}}
save_when: modified
with_items: "{{ ospf_process }}"
Related
If the user passes perform_action parameter as any of these telnetcurlnslookuptracerouteget_ip_address then i want the play to run on localhost else it should run on remotehosts
ansible-playbook test.yml -e perform_action='nslookup'
- name: "Play 1"
hosts: localhost
tasks:
- set_fact:
final_delegate: "{{ 'localhost' if perform_action in 'telnetcurlnslookuptracerouteget_ip_address' else 'remotehosts' }} "
- debug:
msg: "Play needs to run on {{ final_delegate }}"
- name: "Play 2"
hosts: "{{ final_delegate }}"
tasks:
- debug:
msg: "Im running on {{ inventory_hostname }}"
Output:
The Play needs to run on localhost
However, Play 2 fails with the below error:
ERROR! The field 'hosts' has an invalid value, which includes an undefined variable. The error was: 'final_delegate' is undefined
Can this condition be set with the play as i m doing or is it possible only by putting a condition on -e parameter?
Your problem is that at the moment of evaluating which hosts to run play 2 on, you are polling a variable which is only defined for localhost. It's the chicken or the egg thing. It's technically not running on localhost, so it doesn't know which host to check the variable on, to find that it should run on localhost.
I would try...
hosts: "{{ hostvars['localhost']['final_delegate'] }}"
That might work for you. The templating for host patterns can be a little picky about things.
On an Ansible playbook, I'm trying to execute a shell command only if a service exist on the remote server.
I have 3 tasks :
service_facts
execution of shell command if tomcat is installed
display the output of the shell command if tomcat is installed
Here is my code :
- name: Get Infos
hosts: all
gather_facts: yes
become: false
remote_user: [MY_USER]
tasks:
- name: Get the list of services
service_facts:
- name: Get version of Tomcat if installed
become: true
shell: 'java -cp /opt/tomcat/lib/catalina.jar org.apache.catalina.util.ServerInfo | grep "Server version"'
register: tomcat_version
when: "'tomcat.service' in services"
- debug: msg="{{ tomcat_version.stdout_lines }}"
when: "'tomcat.service' in services"
The problem is on certains servers the service name is, for example, tomcat-8.1
How can i use regex in the when condition?
I tried regex(), regex_search(), either I'm doing it wrong or I don't know how to do it.
Have you any idea how to do it?
Thanks in advance!
Count matching items. For example
- service_facts:
- block:
- shell: smartctl --version | head -1
register: smart_version
- debug:
msg: "{{ smart_version.stdout_lines }}"
when: _srvcs|length > 0
vars:
_regex: '.*smart.*'
_srvcs: "{{ services|select('match', _regex) }}"
gives
msg:
- smartctl 7.1 2019-12-30 r5022 [x86_64-linux-5.4.0-73-generic] (local build)
The next option is to intersect the list of services, e.g.
when: _srvcs|length > 0
vars:
my_services:
- smartmontools.service
- smart-8.1
- smart-devel.0.0.1
_srvcs: "{{ my_services|intersect(services) }}"
Debug
Q: "It gives me a failure on the server where my service doesn't exist, cause the playbook still tries to execute the shell. Is it normal?"
A: No. It is not normal. Print debug and find out why the condition evaluates to true, i.e. what service(s) match either the regex or the list. For example
- debug:
msg: |
_srvcs:
{{ _srvcs|to_nice_yaml|indent(2) }}
when: debug|d(false)|bool
vars:
my_services:
- smartmontools.service
- smart-8.1
- smart-devel.0.0.1
_srvcs: "{{ my_services|intersect(services) }}"
gives
msg: |-
_srvcs:
- smartmontools.service
To enable the task run the playbook with the option -e debug=true.
I want to apply filter to the following log file. But I keep missing something
task.yml
- ansible_loop_var: item
changed: false
failed: true
invocation:
module_args:
policy_package: Package1
version: null
wait_for_task: true
wait_for_task_timeout: 30
item: PackageItem1
msg: Task Verify policy operation with task id 01234567-89ab-cdef-a422-xxxxxxxxx
failed. Look at the logs for more details
- ansible_loop_var: item
changed: false
failed: true
invocation:
module_args:
policy_package: Package2
version: null
wait_for_task: true
wait_for_task_timeout: 30
item: PackageItem2
msg: Task Verify policy operation with task id 01234567-89ab-cdef-a6c4-xxxxxxxx
failed. Look at the logs for more details
Here is my playbook
filter.yml
---
- name: sftp-domain
hosts: check_point
connection: httpapi
gather_facts: False
vars_files:
- 'credentials/my_var.yml'
- 'credentials/login.yml'
tasks:
- name: set-details
set_fact:
filter: "{{ lookup('file', 'tmp/task.yml') }}"
- name: create list to loop through
set_fact:
new_list: "{{ filter | map(attribute='msg') | flatten }}"
- name: copy-file-to-log
local_action:
module: copy
content: "{{ new_list | to_nice_yaml }}"
dest: tmp/task2.yml
I get an error message saying
PLAY [sftp-domain] *******************************************************************************************************************************************
TASK [set-details] *******************************************************************************************************************************************
ok: [checkpoint]
TASK [create list to loop through] ***************************************************************************************************************************
fatal: [checkpoint]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'unicode object' has no attribute 'msg'\n\nThe error appears to be in '/home/tdeveu0/project/fwp_automation/filter.yml': line 15, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: create list to loop through\n ^ here\n"}
Here is actually the result I want after applying filter
- msg: Task Verify policy operation with task id 01234567-89ab-cdef-a6c4-xxxxxxxx
failed. Look at the logs for more details
- msg: Task Verify policy operation with task id 01234567-89ab-cdef-a422-xxxxxxxxx
failed. Look at the logs for more details
I want to get only the list of all the 'msg'
Use the filter from_yaml
- name: set-details
set_fact:
filter: "{{ lookup('file', 'tmp/task.yml')|from_yaml }}"
Let's take a simplified file to show the problem, e.g.
shell> cat task.yml
- a: 1
b: 2
- a: 3
b: 4
When you read the file into the variable the result is AnsibleUnsafeText, not a list
- set_fact:
filter: "{{ lookup('file', 'task.yml') }}"
- debug:
msg: "{{ filter|type_debug }}"
- debug:
var: filter.0
gives
msg: AnsibleUnsafeText
filter.0: '-'
The first item of the text is the dash '-'.
Use filter from_yaml to get the list
- set_fact:
filter: "{{ lookup('file', 'task.yml')|from_yaml }}"
- debug:
msg: "{{ filter|type_debug }}"
- debug:
var: filter.0
gives
msg: list
filter.0:
a: 1
b: 2
I am trying parse month,day and year from show clock output using regex_search, getting error.
from cli of a router i see this -
sh clock
16:22:12.975 PST Wed Jan 27 2021
- name: Run sh log
cisco.ios.ios_command:
commands:
- sh clock
register: output1
- name: sh clock output
debug:
msg: "{{ output1.stdout_lines | regex_search('(Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)^\s+\d{1,2}\s+\d{4}' }}"
error
The offending line appears to be:
debug:
msg: "{{ output1.stdout_lines | regex_search('(Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)\s+\d{1,2}\s+\d{4}' }}"
^ 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 }}"
desired/wanted debug msg is below ,i don't want time, just need month day and year
Jan 27 2021
Use regex_replace. Put the regex into a separate single-quoted variable. For example, the task below does the job
- name: sh clock output
debug:
msg: "{{ output1.stdout_lines|regex_replace(my_regex, my_replace) }}"
vars:
my_regex: '^(.*)(Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)\s+(\d{1,2})\s+(\d{4})$'
my_replace: '\2 \14 \15'
The splitting is simpler. For example, the task below gives the same result
- debug:
msg: "{{ arr[-3] }} {{ arr[-2] }} {{ arr[-1] }}"
vars:
arr: "{{ output1.stdout_lines.split() }}"
See Handling dates and times
I have a simple playbook that run Cisco nxos command, which the playbook ran successful.
Would like to know what is the code save all the result into a file regardless how many hosts I have and use Survey to input the filename.
Currently, here is my code:
---
- name: run multiple commands on remote nodes
nxos_command:
commands:
- show clock
- show int status
- show cdp neigh
- show int desc
- show port-channel summ
- show vpc
- show vpc role
Try with code
---
- name: run multiple commands on remote nodes
register: myshell_output
nxos_command:
commands:
- show clock
- show int status
- show cdp neigh
- show int desc
- show port-channel summ
- show vpc
- show vpc role
- name: Saving data to local file
copy:
content: "{{ myshell_output.stdout|join('\n') }}"
dest: "/tmp/hello.txt"
delegate_to: localhost
It give me an error:
FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'stdout'\n\nThe error appears to be in '/tmp/awx_1869_7__9l_9l/project/roles/bcpcommands/tasks/main.yml': line 3, 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: run multiple commands on remote nodes\n ^ here\n"}
The host normally I limit it at Ansible-Tower LIMIT column.
The ideal output of the file possible to include the hostname and commands that I key in?
Thanks
You probably got the indenting wrong. Try;
---
- hosts: my_host
tasks:
- name: run multiple commands on remote nodes
nxos_command:
commands: "{{ item }}"
loop:
- show clock
- show int status
- show cdp neigh
- show int desc
- show port-channel summ
- show vpc
- show vpc role
register: myshell_output
- debug:
msg: "{{ myshell_output }}"
- name: Saving data to local file and include hostname
copy:
content: "{{ myshell_output.stdout|join('\n') }} hostname: {{ inventory_hostname }}"
dest: "/tmp/hello.txt"
delegate_to: localhost
Edit the hostname.
The debug task must output an 'stdout' message. If that one is not present, then your copy task will fail.