Conditional role inclusion fails in Ansible - ansible

I want to run an Ansible role conditionally, i.e. only when some binary does NOT exist (which for me implies absence of some particular app installation).
Something like the pattern used here.
Using the following code in my playbook:
- hosts: my_host
tasks:
- name: check app existence
command: /opt/my_app/somebinary
register: myapp_exists
ignore_errors: yes
roles:
- { role: myconditional_role, when: myapp_exists|failed }
- another_role_to_be_included_either_way
Here is the output:
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [my_host ]
TASK [ myconditional_role : create temporary installation directory] ***********************
fatal: [my_host]: FAILED! => {"failed": true, "msg": "ERROR! The conditional check 'myapp_exists|failed' failed. The error was: ERROR! |failed expects a dictionary"}
Why is the conditional check failing?
Using ansible 2.0.0.2 on Ubuntu 16.04.01
btw: "create temporary installation directory" is the name of the first main task of the conditionally included role.

Tasks are executed after roles, so myapp_exists is undefined.
Use pre_tasks instead.
Also keep in mind that when is not actually a conditional role, it just attaches this when statement to every task in your role.

Related

How do I share variables/facts between Molecule Playbooks?

I'm trying to share a variable between my converge step and my cleanup step of my Molecule. Since both playbooks are being run on the same host, I figure I can use facts to cache the variable as a fact.
In converge.yml:
- name: Cache some variable
set_fact:
cacheable: yes
my_fact: "howdy, world"
In cleanup.yml:
- debug:
msg: "{{ my_fact }}"
and in my top-level ansible.cfg I specify:
[defaults]
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/facts_cache
fact_caching_timeout = 7200
I first run molecule converge and then I run molecule cleanup I'm getting the error: (reformatted)
TASK [debug] *******************************************************************
fatal: [cluster-toolchain]: FAILED! => {"msg": "The task includes an option
with an undefined variable. The error was: 'my_fact' is undefined
The error appears to be in '{REDACTED}/cleanup.yml': line 5, column 7, but may be
elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:\n\n tasks:\n - debug:\n ^ here\n"}
I've got some guesses, like maybe Molecule doesn't see my top level ansible.cfg or something.
Anyway, I was hoping for some help here. Maybe there is a better way to share the variable in Molecule world.
Molecule is a tool to test Ansible roles. It is not targeted to execute Ansible playbooks. Usual command is ansible-playbook.
Molecule cannot not read your ansible.cfg with fact caching settings. If you want to make your commands working, add settings in molecule.yml:
provisioner:
name: ansible
config_options:
defaults:
gathering: smart
fact_caching: jsonfile
fact_caching_connection: /tmp/facts_cache
fact_caching_timeout: 7200
Then molecule converge followed by molecule cleanup gives:
PLAY [Cleanup] ************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
ok: [vagrant-instance] => {
"msg": "howdy, world"
}

Problem when invoking Ansible from Jenkins

When i Invoking Ansible through Jenkins i have added the below script in my Playbook
- name: HELLO WORLD PLAY
hosts: webserver
become: yes
become_method: sudo
tasks:
- debug:
msg: "HELLO......."
- shell: echo "HELLO WORLD"
I am getting below error when i build job
TASK [setup] *******************************************************************
fatal: [10.142.0.13]: UNREACHABLE! =>
{
"changed": false,
"msg": "ERROR! SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue",
"unreachable": true
}
when I run this playbook through CLI it is running successfully
but I am not able to run through Jenkins as (i have already done the set up by pasting private key in Jenkins)

ansible win_user, create is fine, but replaying playbook fails

I am able to create a user on a windows server as part of a playbook, but when the playbook is re-run, the create task fails.
I'm trying to work out if I am missing something.
playbook:
---
# vim: set filetype=ansible ff=unix ts=2 sw=2 ai expandtab :
#
# Playbook to configure the environment
- hosts: createuser
tasks:
- name: create user
run_once: true
win_user:
name: gary
password: 'B0bP4ssw0rd123!^'
password_never_expires: true
account_disabled: no
account_locked: no
password_expired: no
state: present
groups:
- Administrators
- Users
if I run the playbook when the user does not exist, the create works fine.
When I re-run, I get:
PLAY [createuser] *******************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************************************************************************************************************
ok: [dsy-demo-mssql02]
TASK [create user] ******************************************************************************************************************************************************************************************************************
fatal: [dsy-demo-mssql02]: FAILED! => {"changed": false, "failed": true, "msg": "Exception calling \"ValidateCredentials\" with \"2\" argument(s): \"The network path was not found.\r\n\""}
I have verified that I can logon to the server using the created user credentials.
Anyone seen this before, or understand what can be happening?
It looks to me like it might be the
run_once: true
is only telling the task to run once. For the ansible documentation on that delegation you can go here https://docs.ansible.com/ansible/playbooks_delegation.html#run-once

Invoke another 'play' based on output of another play - Ansible

I am trying to use Ansible to check if SELinux is enabled (set to Enforcing), and if not, enable it. The play to enable SELinux must be invoked only if SELinux is disabled.
The playbook looks like so:
- hosts: all
# root should execute this.
remote_user: root
become: yes
tasks:
# Check if SELinux is enabled.
- name: check if selinux is enabled
tags: selinuxCheck
register: selinuxCheckOut
command: getenforce
- debug: var=selinuxCheckOut.stdout_lines
- name: enable selinux if not enabled already
tags: enableSELinux
selinux: policy=targeted state=enforcing
when: selinuxCheckOut.stdout_lines == "Enforcing"
- debug: var=enableSELinuxOut.stdout_lines
When I run this, the task enableSELinux fails with the reason, "Conditional check failed". The output is:
TASK [debug] *******************************************************************
task path: /root/ansible/playbooks/selinuxConfig.yml:24
ok: [localhost] => {
"selinuxCheckOut.stdout_lines": [
"Enforcing"
]
}
TASK [enable selinux if not enabled already] ***********************************
task path: /root/ansible/playbooks/selinuxConfig.yml:26
skipping: [localhost] => {"changed": false, "skip_reason": "Conditional check failed", "skipped": true}
My questions:
1. Is this the correct way to get a play to execute depending on the output from another play?
2. How do I get this to work?
Your playbook is correct. But stdout_lines is a list. You have to compare the first element in that list. Try this:
when: selinuxCheckOut.stdout_lines[0] == "Enforcing"

Ansible etcd lookup plugin issue

I've etcd running on the Ansible control machine (local). I can get and put the values as shown below but Ansible wouldn't get values, any thoughts?
I can also get the value using curl
I got this simple playbook
#!/usr/bin/env ansible-playbook
---
- name: simple ansible playbook ping
hosts: all
gather_facts: false
tasks:
- name: look up value in etcd
debug: msg="{{ lookup('etcd', 'weather') }}"
And running this playbook wouldn't fetch values from etcd
TASK: [look up value in etcd] *************************************************
ok: [app1.test.com] => {
"msg": ""
}
ok: [app2.test.com] => {
"msg": ""
}
Currently (31.05.2016) Ansible etcd lookup plugin support only calls to v1 API and not compatible with newer etcd instances that publish v2 API endpoint.
Here is the issue.
You can use my quickly patched etcd2.py lookup plugin.
Place it into lookup_plugins subdirectory near you playbook (or into Ansible global lookup_plugins path).
Use lookup('etcd2', 'weather') in your playbook.

Resources