Ansible with cisco devices - ansible

I try to test my audit activity on cisco device by the following task;
tasks:
- name: 1.1.1 Enable 'aaa new-model' (Scored)
ios_command:
commands: show running-config | incl aaa new-model
register: output1
- name: 1.1.1 Check results
delegate_to: localhost
lineinfile:
path: /tmp/Summary.txt
line: "1.1.1|Fail"
when: output1.stdout is 'no aaa new-model'
- name: 1.1.1 Check results
delegate_to: localhost
lineinfile:
path: /tmp/Summary.txt
line: "1.1.1|Pass"
when: output1.stdout is not 'no aaa new-model'
This activity will run ios command and register values after that I will check for condition and paste the result to my localhost(linux)
but I got this errors;
FAILED! => {"msg": "The conditional check 'output1.stdout is 'no aaa new-model'' failed. The error was: template error while templating string: expected token 'name', got 'string'. String: {% if output1.stdout is 'no aaa new-model' %} True {% else %} False {% endif %}\n\nThe error appears to be in '/etc/ansible/Cisco/1.1.yaml': line 15, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n register: output1\n - name: 1.1.1 Check results\n ^ here\n"}
Can anyone tell me what happens?
PS. My ansible version is 2.9.3

The result you stored in the "output1" variable is contained in 'output1.stdout[0]'.
'output1.stdout' is a list, and 'output1.stdout[0] is the string you are after.

Related

azure-network_interface says variable is undefined

We switched to ansible 2.10
Before it was azure_rm_networkinterface_facts (working) now is azure_rm_networkinterface_info
- name: "Get facts for network interface by it's name"
azure_rm_networkinterface_facts:
resource_group: "{{ target_resourcegroup }}"
name: "{{ target_nic_name }}"
- name: "Define private IP address"
set_fact:
private_ip_address: "{{ ansible_facts | json_query(query) }}"
vars:
query: "azure_networkinterfaces[0].properties.ipConfigurations[0].properties.privateIPAddress"
when: azure_networkinterfaces|length > 0
Error I get is:
4 TASK [azure_preconditions : Define private IP address] *************************
00:01:38.844 [0;31mfatal: [40.118.86.58]: FAILED! => {"msg": "The conditional check 'azure_networkinterfaces|length > 0' failed. The error was: error while evaluating conditional (azure_networkinterfaces|length > 0): 'azure_networkinterfaces' is undefined\n\nThe error appears to be in '/var/lib/jenkins/workspace/PA-28544-ansible-version-upgrade/roles/azure_preconditions/tasks/main.yml': line 143, 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: \"Define private IP address\"\n ^ here\n"}[0m
00:01:38.844
azure_networkinterfaces seems to be a return value of azure_rm_networkinterface_facts so it's normal that it doesn't exist...
I'd write a playbook like this:
- name: "Get facts for network interface by it's name"
azure_rm_networkinterface_facts:
resource_group: "{{ target_resourcegroup }}"
name: "{{ target_nic_name }}"
register: output
I suggest you debug the output variable to check your return values. I don't know the version of Azure you are using and a lot of changes can exist depending on it.
- name: "Display return value"
debug:
msg: "{{ output }}"
You could play with output.azure_networkinterfaces or output.networkinterfaces
Following the last documentation, its seems azure_rm_networkinterface_fact is deprecated, replaced by azure_rm_networkinterface_info
azure_rm_networkinterface_info

How to use a combination of variable and a string in ansible when condition?

I want to search for a combination of a string and a file in a particular command output and if both exists then skip the task
Here my data_dir variable value is /data/dbdata/test
- name: Extracting existing selinux context
shell: "semanage fcontext -l -C|grep -i {{data_dir|dirname}}"
register: selin_context
- name: Setting Selinux context for data and log dir
command: "semanage fcontext -a -t {{item.name}} {{item.dirpath|dirname}}(/.*)?"
with_items:
- { name: 'postgresql_db' , dirpath: "{{data_dir}}" }
when: "'postgresql_db' and {{data_dir}} not in selin_context.stdout'
If i try above then getting below error
[WARNING]: conditional statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: 'postgresql_db' and
{{data_dir}} not in selin_context.stdout
fatal: [pgdbsql-02]: FAILED! => {
"msg": "The conditional check ''postgresql_db' and {{data_dir|dirname}} not in selin_context.stdout' failed. The error was: template error while templating string: unexpected '/'. String: {% if 'postgresql_db' and /data/dbdata not in selin_context.stdout %} True {% else %} False {% endif %}\n\nThe error appears to be in '/home/ec2-user/ansible/pgdb/roles/pgdb/tasks/main.yml': line 56, 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: Setting Selinux context for data and log dir\n ^ here\n"
Please guide me how to handle this?

using inventory_hostname as part of a dictionary lookup

I would like to use inventory_hostname as part of a dictionary lookup to configure servers that use the same template, but with different variables
/etc/ansible/hosts
[nodes]
node1 ansible_host=192.168.0.2
roles/role/defaults/main.yml
node1:
if1: eth1
ip1: 1.1.1.1/11
node2:
if1: eth4
ip1: 4.4.4.4/44
roles/role/tasks/main.yml
- name: test
debug:
msg: "{{ [inventory_hostname].[if1] }} end test "
expected this to display eth1 on the console but got the error
fatal: [node1]: FAILED! => {
"msg": "The task includes an option with an undefined variable. The error was: 'if1' is undefined\n\nThe error appears to have been in '/root/ansible/roles/role/tasks/main.yml': line 6, 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: test\n ^ here\n"
}
What you are looking for is vars:
- name: test
debug:
msg: "{{ vars[ansible_hostname]['if1'] }} end test"

Ansible Print IOS output on string match

I'm trying to use Ansible to hit a bunch (100+) Cisco Catalyst switches and check if they have a certain line card installed. Via SSH, this can be done with the "sh mod" command. I want to parse the output of that command in a playbook and then show the output of the command if a certain string matches. Right now with the playbook below I get the following error:
fatal: [redacted-hostname]: FAILED! => {"failed": true, "msg": "The
conditional check 'showmod | search(\"4548\")' failed. The error was:
Unexpected templating type error occurred on ({% if showmod |
search(\"4548\") %} True {% else %} False {% endif %}): expected
string or buffer\n\nThe error appears to have been in
'/etc/ansible/playbooks/linecard-4548.yaml': line 22, 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 - debug:
\"msg='4548 Card Found'\"\n ^ here\n"}
Current playbook code:
---
- hosts: redacted-hostname
gather_facts: yes
connection: local
tasks:
- name: SYS | Define provider
set_fact:
provider:
host: "{{ inventory_hostname }}"
username: redacted-user
password: redacted-password
- name: IOS | Get Module List
ios_command:
provider: "{{ provider }}"
commands:
- sh mod | inc 4548
register: showmod
- debug: "msg='4548 Card Found'"
when: showmod.stdout | search("/4548/")
I've tried the when in the debug with and without the .stdout to no avail. I've done some research and the error I'm getting usually occurs when, in my case, showmod is undefined but it definitely is. If I replace the debug with the following snippet, the playbook runs fine but of course it'll print the output for every switch which isn't what I want.
- name: IOS | Show Output
debug:
var: showmod
Any suggestions?
ios_command returns stdout as list and stdout_lines as list of lists (whereas command module return stdout as string and stdout_lines as list).
So in your case, you may want to try:
- debug: "msg='4548 Card Found'"
when: showmod.stdout | join(" ") | search("/4548/")

Ansible: do not run shell command if a file exists

I would like to do the following in an Ansible playbook:
- name: "Generate variant html report"
shell: "<my command>"
with_items: "{{ variants | default([]) }}"
when: ({{ folderReports }}/{{ item }}).exists == False
Inside the when, I need a way to create the file path, and determine if it exists or not. I tried to use the "(" ")" to surround my first expression, but it doesn't seem to be working:
2016-10-13 16:22:48,130 p=94292 u=sautomation | fatal: [localhost]: FAILED! => {"failed": true, "msg": "The conditional check '({{ folderReports }}/{{ item }}).exists == True' failed. The error was: template error while templating string: unexpected '/'. String: {% if (/opt/diff-test1.diff).exists == True %} True {% else %} False {% endif %}\n\nThe error appears to have been in '/opt/ansible/roles/stats/tasks/main.yml': line 45, 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: \"Generate report\"\n ^ here\n"}
To prevent a task from executing if a specified file already exists, use creates parameter of the shell module:
- name: "Generate variant html report"
shell: "<my command>"
args:
creates: "{{ folderReports }}/{{ item }}"
with_items: "{{ variants | default([]) }}"
You get an error because .exists, in your conditional, checks if a variable (fact) exist, not a file on the target node.

Resources