Ansible - Unable to run certain JUNOS modules - ansible

I'm trying to run the Ansible modules junos_cli and junos_rollback and I get the following error:
ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path.
The error appears to have been in '/home/quake/network-ansible/roles/junos-rollback/tasks/main.yml': line 2, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
---
- name: I've made a huge mistake
^ here
This is the role in question:
---
- name: I've made a huge mistake
junos_rollback:
host={{ inventory_hostname }}
user=ansible
comment={{ comment }}
confirm={{ confirm }}
rollback={{ rollback }}
logfile={{ playbook_dir }}/library/logs/rollback.log
diffs_file={{ playbook_dir }}/configs/{{ inventory_hostname }}
Here is the Juniper page:
http://junos-ansible-modules.readthedocs.io/en/1.3.1/junos_rollback.html
Their example's syntax is a little odd. host uses a colon while the rest uses = signs. I've tried mixing both and only using one or the other. I keep getting errors.
I also confirmed that my junos-eznc version is higher than 1.2.2 (I have 2.0.1)
I've been able to use junos_cli before, I don't know if a version mismatch happened. On the official Ansible documentation, there is no mention of junos_cli or junos_rollback. Perhaps they're not supported anymore?
http://docs.ansible.com/ansible/list_of_network_modules.html#junos
Thanks,

junos_cli & junos_rollback are part of Galaxy and not core modules. You can find them at
https://galaxy.ansible.com/Juniper/junos/
Is the content posted here has whole content of your playbook? if yes, You need to define other items too in your playbook such as roles, connection, local. For example
refer https://github.com/Juniper/ansible-junos-stdlib#example-playbook
```
---
- name: rollback example
hosts: all
roles:
- Juniper.junos
connection: local
gather_facts: no
tasks:
- name: I've made a huge mistake
junos_rollback:
host = {{inventory_hostname}}
----
----
```

Where have you saved the content of juniper.junos modules?. Can you post the content of your playbook and the output of the tree command to see your file structure? That could help.
I had a similar problem where Ansible was not finding my modules and what I did was to copy the juniper.junos folder to my roles folder and then added a tasks folder within it to execute the main.yaml from there.
Something like this:
/Users/macuared/Ansible_projects/roles/Juniper.junos/tasks
---
- name: "TEST 1 - Gather Facts"
junos_get_facts:
host: "{{ inventory_hostname}}"
user: "uuuuu"
passwd: "yyyyyy"
savedir: "/Users/macuared/Ansible_projects/Ouput/Facts"
ignore_errors: True
register: junos
- name: Checking Device Version
debug: msg="{{ junos.facts.serialnumber }}"
Additionally, I would add "" to the string values in your YAML. Something like this:
---
- name: I've made a huge mistake
junos_rollback:
host="{{ inventory_hostname }}"
user=ansible
comment="{{ comment }}"
confirm={{ confirm }}
rollback={{ rollback }}
logfile="{{ playbook_dir }}/library/logs/rollback.log"
diffs_file="{{ playbook_dir }}/configs/{{ inventory_hostname }}"
Regarding this "I've tried mixing both and only using one or the other. I keep getting errors."
I've used just colon and mine works fine even when in the documentation suggests = signs. See junos_get_facts

Related

"Undefined variable" error on Ansible when run over Windows machines

This is a very simple Ansible playbook I run from AWX to get information about hosts, and it works as intended on Linux machines:
---
- name: Get some info
debug:
msg: "{{ ansible_hostname }} {{ ansible_default_ipv4.address }} {{ ansible_distribution }}"
However, when run over Windows machines, it returns this error:
fatal: [MYWINHOST1]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'ansible_default_ipv4' is undefined\n\nThe error appears to be in '/tmp/bwrap_21138_4q41r57e/awx_21138_is8pox6p/project/roles/windows/tasks/getsomeinfo.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: Get some info\n ^ here\n"}
How do I access and print the same Ansible facts values from a Windows machine?
From the documentation:
ansible_facts
This key should contain a dictionary which will be appended to the facts assigned to the host. These will be directly accessible and don’t require using a registered variable.
Source: https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#ansible-facts
So, if printing hostvars[inventory_hostname] shows you a variable ansible_facts.ip_addresses then you can access it via ansible_ip_addresses — if that node only have one IP address assigned, see below if this is not the case:
- debug:
msg: >-
{{ ansible_hostname }}
{{ ansible_ip_addresses }}
{{ ansible_distribution }}
Mind that there is a bug that has been reported to the Ansible tracker about Windows machine having multiple IP addresses, and that it does not seems to be as trivial of a consensus as though what really is the default IP address:
There's really not a great solution to this issue- the concept of a "default IP address" means different things to different people, and the Linux fact is wrong as much as it's right. Usually this comes down to locating an address on a particular subnet, which we have to filters to assist with given the list of IP addresses... Given the lack of clarity on this, I'm going to close this issue.
Source: nitzmahone's comment on the issue https://github.com/ansible/ansible/issues/17014
So, to clear things up, the fact gathering in Windows and Linux are not implementing the same variable, you sure can work around this, implementing an inline-if:
- debug:
msg: >-
{{ ansible_hostname }}
{{
ansible_ip_addresses
if ansible_os_family == "Windows"
else ansible_default_ipv4.address
}}
{#
Mind that you still have to implement your own logic
of what is the "default" IP if you have more
than one IP address on that Windows machine, as linked above
#}
{{ ansible_distribution }}
The first thing I would do is using the new notation (removing any possibility to have failures due to misinterpretation):
---
- name: Gather Info
hosts: all
gather_facts: yes
tasks:
- name: Get some info
debug:
msg: "{{ ansible_hostname }} {{ ansible_default_ipv4['address'] }} {{ ansible_distribution }}"
Unless you're using caching mechanisms like redis/memcache, sometimes it takes some time to get results and probably is more efficient to get minimum facts.
To address the issue, I can't assist too much but if there's a bug closed in the windows module only developers could help here, as either Ansible team address this somehow or you might need to develop a small module for your needs.
UPDATE #1:
For what I can see if you gather a subset, you miss some information that you require ...
If you activate the gather_facts it doesn't fail with The error was: 'ansible_default_ipv4' is undefined.
UPDATE #2:
In regards to your error message, looks like something copied didn't was properly aligned.
In regards to how to get access to the variables:
pre_tasks:
- name: Collect only minimum facts.
ansible.builtin.setup:
gather_subset: "!all"
register: facts
When I register the collection, I use: facts.ansible_facts.ansible_domain to get the domain. maybe that give you enough insight about how to get the variables you need.

Ansible pre-check before run playbook

Is it possible to add a condition before to run a playbook which check if there is a title, a description, the environment and the versions on the playbook ?
For example my test.yml playbook:
---
#Apache servers
#Linux
#Ubuntu
#version 2.1.1
#Testing for secure the webserver
task:
xxxxxx
xxxxxx
And I would like to check if all the comment before are present before to run this task !
I tried to test this solution :
name: run Apachetest playbook
include: test.yml
when: "{{ lookup('file', 'test.yml').split('\n')[1] == '#Apache servers' }}"
But still not working...
BS
Comments are, well, comments. They do not impact the execution and are just ignored. So there is no way, and actually no real reason, to check if comments are present or not. You would need to implement that yourself.
To check playbooks, roles, etc. there is ansible-lint which will verify the syntax and some best practices (e.g. if you use a command or shell for something there is a module for) but this does not verify comments (again, checking for comments does not make sense from a execution perspective, as they are ignored).
You want some information to be present in your playbook, that is what I understand. If I was you, I would either create a git hook, that verifies if the information is present before letting you push that code to your repository or establish a proper review-process, where the reviewer only accepts a merge/pull request, if the information is present.
Otherwise, here is the code, that will do what you are trying to do:
---
#Apache server
- hosts: all
tasks:
- name: set fact
set_fact:
pb: "{{ lookup('file', 'test.yml').split('\n')[1] }}"
- name: check if we found it
debug:
msg: 'found'
when: "'#Apache server' in pb"
You could use the apache role for apache installed like that
---
- hosts: apache
sudo: yes
tasks:
- name: install apache2
apt: name=apache2 update_cache=yes state=latest
have a look here how-to-install-apache-on-ansible

Usage of variable and role in openstack-ansible

I am a newbie to Ansible and I started to study deploying Openstack with Ansible recently.
Here is the git of openstack-ansible:
https://github.com/openstack/openstack-ansible
From the tutorial:
https://docs.openstack.org/project-deploy-guide/openstack-ansible/newton/run-playbooks.html
there is one command running playbook:
openstack-ansible setup-hosts.yml
I read this playbook, it includes another playbook at line 16:
include: openstack-hosts-setup.yml
Then I read the included openstack-hosts-setup.yml and following is the snippet from it:
- name: Basic host setup
hosts: "{{ openstack_host_group|default('hosts') }}"
gather_facts: "{{ gather_facts | default(True) }}"
max_fail_percentage: 20
user: root
pre_tasks:
- name: Check for a supported Operating System
assert:
that:
- (ansible_distribution == 'Ubuntu' and ansible_distribution_release == 'xenial') or
(ansible_os_family == 'RedHat' and ansible_distribution_major_version == '7')
msg: "The only supported platforms for this release are Ubuntu 16.04 LTS (Xenial) and CentOS 7 (WIP)"
roles:
- role: "openstack_hosts"
tags:
- openstack-hosts
I was confused about roles here
roles:
- role: "openstack_hosts"
As far as I know, there should be directory structure when using roles like:
roles/
openstack_hosts/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
However, I can't find this structure in this openstack-ansible project.
So I have no idea where is the role(openstack_hosts) in this playbook.
When running this playbook , an error occurred just expected:
ERROR! the role 'openstack_hosts' was not found in /opt/openstack-ansible/playbooks/roles:/root/ansible/roles:/opt/openstack-ansible/playbooks
Also, I was wondering where the variablescome from:
hosts: "{{ openstack_host_group|default('hosts') }}"
I thought the variable will be found from the directory vars or defaults
under roles directory.
Since there is no such directory, I have no idea where this variable comes from.
Could any tell me where should I find the variable openstack_host_group
and explain how the role is used here?
Or did I miss something or I was wrong with some concepts about Ansible?
Thanks!!
By the way, this is the first time I ask question.
If the question is not clear enough or something not proper, please let me know :). Thanks again.
I guess you didn't complete bootstrap-ansible.sh from this guide. So you don't have required roles installed.
As for openstack_host_group, it seems that it is optional variable, so you can override default host pattern (which is hosts) if you want with extra variable (like -e openstack_host_group=my_other_group).

Ansible role_path undefined error

I have a task file that looks like this:
- name: Drop schemas
mysql_db: state=import name=mysql target={{ role_path }}/files/schemas/drop-imdb-perf.sql login_user={{ MYSQL_ROOT_USER }} login_password={{ MYSQL_ROOT_PWD }} login_host={{ inventory_hostname }}
I'm invoking it from a playbook that looks like this:
- name: Drop mySQL data
gather_facts: no
hosts: imdb
connection: local
tags:
- mysql-data-drop
tasks:
- include: ../roles/mysql/tasks/drop-perf.yml
I'm using Ansible version 1.9.4 so I'm thinking role_path should be a valid variable.
But when I run the playbook, I get this output:
TASK: [Drop schemas] **************************************************
fatal: [imdb] => One or more undefined variables: 'role_path' is undefined
I can't figure out why role_path is undefined. According to the ansible docs, it seems like for versions 1.8 and above it should be populated with the directory of the role in question, but I'm clearly mistaken about something or other.
I don't see you using any roles. Without looking into the Ansible code it seems obvious that role_path is defined within a role. Including a file of a role does not make it run in context of a role though.
If your include is by intend, role_path won't be defined. You could try to set it yourself together with the include like so:
tasks:
- include: ../roles/mysql/tasks/drop-perf.yml
role_path: ../roles/mysql
That might work or not, since role_path still is a magic variable and therefore might not be manually changed.
If you actually meant to include the role, then you need to define your playbook like this:
- name: Drop mySQL data
gather_facts: no
hosts: imdb
connection: local
tags:
- mysql-data-drop
roles:
- role: ../roles/mysql
But my guess is, you're trying to only run a single tasks file of that role and not the whole role. But what you're trying to do there seem to be against best practice. My recommendation would be to move the tag mysql-data-drop into the tasks of the file drop-perf.yml, because that's what tags are for: to trigger a limited set of tasks of roles or playbooks.

How do I use ansible to create IAM users as shown in the documentation?

Setup
I want to use Ansible to configure my IAM users, groups and permissions but I am having trouble even getting off the ground. I installed the development fork of Ansible (2.1.0) and attempted to run the simple play shown in the example in the docs.
site.yml
# Basic user creation example
tasks:
- name: Create two new IAM users with API keys
iam:
iam_type: user
name: "{{ item }}"
state: present
password: "{{ temp_pass }}"
access_key_state: create
with_items:
- jcleese
- mpython
I ran the play with the following command:
$ ansible-playbook site.yml
And received the following error:
Error
ERROR! playbooks must be a list of plays
The error appears to have been in '~/aws_kingdom/site.yml': line 2, column 1, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
# Basic user creation example
tasks:
^ here
I am going to plead ignorance on a lack of understanding of the anatomy of a playbook especially one that should effectively have no hosts since it only applies to creating users in the AWS IAM service.
References
http://docs.ansible.com/ansible/iam_module.html
You still need to tell Ansible what hosts it needs to run on, just that it needs to run locally.
So instead your site.yml file should look like:
- hosts: 127.0.0.1
connection: local
tasks:
# Basic user creation example
- name: Create two new IAM users with API keys
iam:
iam_type: user
name: "{{ item }}"
state: present
password: "{{ temp_pass }}"
access_key_state: create
with_items:
- jcleese
- mpython
I encountered the:
ERROR! playbooks must be a list of plays
error myself and after double checking everything couldn't find the error.
By accident I found that when I removed any trailing whitespace and/or newlines from my playbook.yml that it fixed the issue.
It's weird because I tried validating my YAML with a linter before encountering this fix so I can't understand why it worked.
Admittedly, I don't have much experience with YAML so there might be some rule that I don't understand that I'm missing.

Resources