Ansible playbook - environment variables - ansible

I am trying (newbie) to setup a playbook, which will use lookup plugin to fetch secrets from vault (https://github.com/jhaals/ansible-vault), but it will fail on missing environment variables every time. Can anyone help? Thanks for the help.
PS: token is for a test purposes
There is condition in lookup module :
url = os.getenv('VAULT_ADDR')
if not url:
raise AnsibleError('VAULT_ADDR environment variable is missing')
Playbook:
---
- hosts: localhost
vars:
vault1_env:
VAULT_ADDR: https://localhost:8200/
VAULT_TOKEN: my-token-id
VAULT_SKIP_VERIFY: True
tasks:
- shell: echo VAULT_ADDR is $VAULT_ADDR, VAULT_TOKEN is $VAULT_TOKEN, VAULT_SKIP_VERIFY is $VAULT_SKIP_VERIFY
environment: "{{ vault1_env }}"
register: shellout
- debug: var=shellout
- debug: msg="{{ lookup('vault', 'secret/hello', 'value') }}"
output:
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [command] *****************************************************************
changed: [localhost]
TASK [debug] *******************************************************************
ok: [localhost] => {
"shellout": {
"changed": true,
"cmd": "echo VAULT_ADDR is $VAULT_ADDR, VAULT_TOKEN is $VAULT_TOKEN, VAULT_SKIP_VERIFY is $VAULT_SKIP_VERIFY",
"delta": "0:00:00.001268",
"end": "2016-05-17 15:46:34.144735",
"rc": 0,
"start": "2016-05-17 15:46:34.143467",
"stderr": "",
"stdout": "VAULT_ADDR is https://localhost:8200/, VAULT_TOKEN is ab9b16c6-52d9-2051-0802-6f047d929b63, VAULT_SKIP_VERIFY is True",
"stdout_lines": [
"VAULT_ADDR is https://localhost:8200/, VAULT_TOKEN is ab9b16c6-52d9-2051-0802-6f047d929b63, VAULT_SKIP_VERIFY is True"
],
"warnings": []
}
}
TASK [debug] *******************************************************************
fatal: [localhost]: FAILED! => {"failed": true, "msg": "ERROR! VAULT_ADDR environment variable is missing"}
PLAY RECAP *********************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=1

Here you are only setting environmental variables for the shell module, and not for the others. If you want to use variables across multiple modules, or for an entire a host, you should use the environment attribute on all of the modules, or on the host itself, something like this:
---
- hosts: localhost
environment:
VAULT_ADDR: https://localhost:8200/
VAULT_TOKEN: my-token-id
VAULT_SKIP_VERIFY: True

Why don't you make use of the vault feature to encrypt a variable file and then include this file in your playbook.
http://docs.ansible.com/ansible/playbooks_vault.html#running-a-playbook-with-vault

Related

Using Ansible to delete old usernames across entire company network devices

Created below test yml file against test switches to nail down configs, error below. I defined provider in last task with no luck as well
---
- hosts: aus2-mdf-testswitches
gather_facts: no
connection: local
tasks:
- name: OBTAIN LOGIN CREDENTIALS
include_vars: secret.yml
- name: DEFINE PROVIDER
set_fact:
provider:
host: "{{ inventory_hostname }}"
username: "{{ creds['username'] }}"
password: "{{ creds['password'] }}"
auth_pass: "{{ creds['auth_pass'] }}"
- name: Delete users with aggregate
ios_user:
aggregate:
- name: chase
state: absent
Error that was presented. Please keep in mind that I am new with ansible and this problem might be super easy for this group but I appreciate any help. FYI, reading from https://docs.ansible.com/ansible/2.4/ios_user_module.html
[ansible#dc1netansible automation]$ ansible-playbook -i inventories/prod/hosts playbooks/deleteUsername.yml
PLAY [aus2-mdf-testswitches] ********************************************************************************************************************************************
TASK [OBTAIN LOGIN CREDENTIALS] *****************************************************************************************************************************************
ok: [aus2-mdf-testsw1]
ok: [aus2-mdf-testsw2]
TASK [DEFINE PROVIDER] **************************************************************************************************************************************************
ok: [aus2-mdf-testsw1]
ok: [aus2-mdf-testsw2]
TASK [Delete users with aggregate] **************************************************************************************************************************************
fatal: [aus2-mdf-testsw1]: FAILED! => {"changed": false, "msg": "unable to open shell. Please see: https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell"}
fatal: [aus2-mdf-testsw2]: FAILED! => {"changed": false, "msg": "unable to open shell. Please see: https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell"}
to retry, use: --limit #/home/ansible/automation/playbooks/deleteUsername.retry
PLAY RECAP **************************************************************************************************************************************************************
aus2-mdf-testsw1 : ok=2 changed=0 unreachable=0 failed=1
aus2-mdf-testsw2 : ok=2 changed=0 unreachable=0 failed=1
****updated error with new yml config****
---
- hosts: aus2-mdf-testswitches
gather_facts: no
connection: local
tasks:
- name: OBTAIN LOGIN CREDENTIALS
include_vars: secret.yml
- name: DEFINE PROVIDER
set_fact:
provider:
host: "{{ inventory_hostname }}"
username: "{{ creds['username'] }}"
password: "{{ creds['password'] }}"
auth_pass: "{{ creds['auth_pass'] }}"
- name: Delete users with aggregate
ios_user:
users:
- name: chase
authorize: yes
provider: "{{ provider }}"
state: absent
register: result
[ansible#dc1netansible automation]$ ansible-playbook -i inventories/prod/hosts playbooks/deleteUsername.yml
PLAY [aus2-mdf-testswitches] ********************************************************************************************************************************************
TASK [OBTAIN LOGIN CREDENTIALS] *****************************************************************************************************************************************
ok: [aus2-mdf-testsw1]
ok: [aus2-mdf-testsw2]
TASK [DEFINE PROVIDER] **************************************************************************************************************************************************
ok: [aus2-mdf-testsw1]
ok: [aus2-mdf-testsw2]
TASK [Delete users with aggregate] **************************************************************************************************************************************
fatal: [aus2-mdf-testsw1]: FAILED! => {"changed": false, "msg": "unable to open shell. Please see: https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell"}
fatal: [aus2-mdf-testsw2]: FAILED! => {"changed": false, "msg": "unable to open shell. Please see: https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell"}
to retry, use: --limit #/home/ansible/automation/playbooks/deleteUsername.retry
PLAY RECAP **************************************************************************************************************************************************************
aus2-mdf-testsw1 : ok=2 changed=0 unreachable=0 failed=1
aus2-mdf-testsw2 : ok=2 changed=0 unreachable=0 failed=1
Could be my IOS version is too old, as I am using 12x train on a Cisco switch. Ansible mentions this is tested on the 15x train.
****last update****
PLAY [aus2-mdf-testswitches] ********************************************************************************************************************************************
TASK [OBTAIN LOGIN CREDENTIALS] *****************************************************************************************************************************************
ok: [aus2-mdf-testsw1]
ok: [aus2-mdf-testsw2]
TASK [DEFINE PROVIDER] **************************************************************************************************************************************************
ok: [aus2-mdf-testsw1]
ok: [aus2-mdf-testsw2]
TASK [Delete users with aggregate] **************************************************************************************************************************************
fatal: [aus2-mdf-testsw2]: FAILED! => {"changed": false, "msg": "unable to retrieve current config", "stderr": "show running-config | section username\r\n ^\r\n% Invalid input detected at '^' marker.\r\n\r\naus2-mdf-testsw2#", "stderr_lines": ["show running-config | section username", " ^", "% Invalid input detected at '^' marker.", "", "aus2-mdf-testsw2#"]}
fatal: [aus2-mdf-testsw1]: FAILED! => {"changed": false, "msg": "unable to retrieve current config", "stderr": "show running-config | section username\r\n ^\r\n% Invalid input detected at '^' marker.\r\n\r\naus2-mdf-testsw1#", "stderr_lines": ["show running-config | section username", " ^", "% Invalid input detected at '^' marker.", "", "aus2-mdf-testsw1#"]}
to retry, use: --limit #/home/ansible/automation/playbooks/deleteUsername.retry
Configs listed here do not work on the IOS I have on my Cisco switch.

Read name of directory created using ansible's tempfile module

I wrote a simple ansible script to create a temporary directory and want to save the name of this directory into a variable. My .yml file is:
- hosts: " {{ lookup('env', 'HOSTNAME') }} "
tasks:
- name : Create staging directory
tempfile:
state: directory
suffix: staging
path: "{{ lookup('env', 'HOME') }}"
become: true
register: output
- name: print stdout
debug: msg="{{ output }}"
The output from running the above prints a dict
$ ansible-playbook -i hosts tempfile.yml
PLAY [localhost] ******************************************************************************************
TASK [Gathering Facts] ************************************************************************************
ok: [localhost]
TASK [Create staging directory] ***************************************************************************
changed: [localhost]
TASK [print stdout] ***************************************************************************************
ok: [localhost] => {
"msg": {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0700",
"owner": "root",
"path": "/home/xxxx/ansible.Fb7rbKstaging",
"size": 4096,
"state": "directory",
"uid": 0
}
}
PLAY RECAP ************************************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0
How do I get access to some_dict['localhost']['msg']['path']? I looked up the hostvars variable and do see my temporary directory in it, but can't figure out how to get access to it.
Check the Registered variables section in the docs to get more details, from your example register: output you could access the path by using something like this:
- name: print stdout
debug:
msg: "{{ output.path }}"

Ansible task variable output not displaying

Below is my simple playbook
name: "test"
hosts: webservers
tasks:
- name: Echo my_env_var
shell: "echo $MY_ENV_VARIABLE"
environment:
MY_ENV_VARIABLE: whatever_value
- name: Echo my_env_var again
shell: "echo $MY_ENV_VARIABLE"
register: stdd
- debug: msg={{stdd.stdout_lines}}
My output is always msg:"" or msg: []. Why am i not able to see the value of variable
I took your example and changed it from debug msg to debug var. I also simplified it by only running the task once, and found the error in the process. The environment argument is specific to a task. You aren't including it in your second shell task.
Here's the example I used.
echo.yml
- hosts: localhost
tasks:
- name: Echo my_env_var
shell: "echo $MY_ENV_VARIABLE"
environment:
MY_ENV_VARIABLE: whatever_value
register: stdd
- debug: var=stdd
execution
$ ansible-playbook -c local -i "localhost," echo.yml
PLAY [localhost] **************************************************************
GATHERING FACTS ***************************************************************
ok: [localhost]
TASK: [Echo my_env_var] *******************************************************
changed: [localhost]
TASK: [debug var=stdd] ********************************************************
ok: [localhost] => {
"var": {
"stdd": {
"changed": true,
"cmd": "echo $MY_ENV_VARIABLE",
"delta": "0:00:00.005332",
"end": "2016-07-25 19:42:54.320667",
"invocation": {
"module_args": "echo $MY_ENV_VARIABLE",
"module_complex_args": {},
"module_name": "shell"
},
"rc": 0,
"start": "2016-07-25 19:42:54.315335",
"stderr": "",
"stdout": "whatever_value",
"stdout_lines": [
"whatever_value"
],
"warnings": []
}
}
}
PLAY RECAP ********************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0

Register Ansible variable property

Using Ansible I'm having a problem registering a variable the way I want. Using the implementation below I will always have to call .stdout on the variable - is there a way I can do better?
My playbook:
Note the unwanted use of .stdout - I just want to be able to use the variable directly without calling a propery...?
---
- name: prepare for new deployment
hosts: all
user: ser85
tasks:
- name: init deploy dir
shell: echo ansible-deploy-$(date +%Y%m%d-%H%M%S-%N)
# http://docs.ansible.com/ansible/playbooks_variables.html
register: deploy_dir
- debug: var=deploy_dir
- debug: var=deploy_dir.stdout
- name: init scripts dir
shell: echo {{ deploy_dir.stdout }}/scripts
register: scripts_dir
- debug: var=scripts_dir.stdout
The output when I execute the playbook:
TASK [init deploy dir] *********************************************************
changed: [123.123.123.123]
TASK [debug] *******************************************************************
ok: [123.123.123.123] => {
"deploy_dir": {
"changed": true,
"cmd": "echo ansible-deploy-$(date +%Y%m%d-%H%M%S-%N)",
"delta": "0:00:00.002898",
"end": "2016-05-27 10:53:38.122217",
"rc": 0,
"start": "2016-05-27 10:53:38.119319",
"stderr": "",
"stdout": "ansible-deploy-20160527-105338-121888719",
"stdout_lines": [
"ansible-deploy-20160527-105338-121888719"
],
"warnings": []
}
}
TASK [debug] *******************************************************************
ok: [123.123.123.123] => {
"deploy_dir.stdout": "ansible-deploy-20160527-105338-121888719"
}
TASK [init scripts dir] ********************************************************
changed: [123.123.123.123]
TASK [debug] *******************************************************************
ok: [123.123.123.123] => {
"scripts_dir.stdout": "ansible-deploy-20160527-105338-121888719/scripts"
}
Any help or insights appreciated - thank you :)
If I understood it right you want to assign deploy_dir.stdout to a variable that you can use without stdout key. It can be done with set_fact module:
tasks:
- name: init deploy dir
shell: echo ansible-deploy-$(date +%Y%m%d-%H%M%S-%N)
# http://docs.ansible.com/ansible/playbooks_variables.html
register: deploy_dir
- set_fact: my_deploy_dir="{{ deploy_dir.stdout }}"
- debug: var=my_deploy_dir

ansible: how to associate two remote hosts with eachother, and share hostvars between them

Background information:
I need to dynamically set a variable on a set of hosts (web1) and then check the same on a different set of hosts. Once they match, I can perform further actions.
Code
My hosts file looks like this:
[web1]
web1.ttv.mydomain.com
[web1:vars]
primary_count=0
[web2]
web2.ttv.mydomain.com
[web2:vars]
secondary_count=0
[web]
web1
web2
And this is the playbook:
- hosts: web1
tasks:
- name: query primary servers
shell: psql -U widget widget -c 'SELECT COUNT(*) FROM test' -t
register: result
- set_fact: primary_count={{result.stdout}}
- hosts: web
tasks:
- name: retrieve variable from previous play
shell: echo hello
- debug: var=primary_count
This playbook produces the following results:
TASK [setup] *******************************************************************
ok: [web1.ttv.mydomain.com]
TASK [query primary servers] ****************************************************
changed: [web1.ttv.mydomain.com]
TASK [debug] *******************************************************************
ok: [web1.ttv.mydomain.com] => {
"primary_count": 0
}
TASK [set_fact] ****************************************************************
ok: [web1.ttv.mydomain.com]
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [web1.ttv.mydomain.com]
ok: [web2.ttv.mydomain.com]
TASK [retrieve variable from previous play] ************************************
changed: [web1.ttv.mydomain.com]
changed: [web2.ttv.mydomain.com]
TASK [debug] *******************************************************************
ok: [web2.ttv.mydomain.com] => {
"primary_count": "VARIABLE IS NOT DEFINED!"
}
ok: [web1.ttv.mydomain.com] => {
"primary_count": " 2"
}
Problem
Now I need a way to do the following in the second play:
run the same select statement on web2.ttv.mydomain.com
save the value to secondary_count variable
check if secondary_count matches the value of the "primary_count" on web1.mydomain.com. (Notice how right now, since I'm looping through more than just the web1 servers in play 2, I get an error about the "primary_count" not being defined on web2 servers.)
when the values match then restart various services on secondary
Questions:
How do I evaluate the "primary_count" variable on the web1 host with the matching web2 host name on? In the future my hosts file will look like this:
[web1]
web1.ttv.mydomain.com
web1.ttx.mydomain.com
[web2]
web2.ttv.mydomain.com
web2.ttx.mydomain.com
[web]
web1
web2
So I need to write some sort of an eval statement that does this:
(pseudocode)
while looping through ***ALL*** web servers
if primary_count on web1.ttv.mydomain.com matches secondary_count on web2.ttx.mydomain.com then
restart service x on web2.ttx.mydomain.com
else
wait a few seconds and repeat
end
end loop
I think the solution lies with my hosts / inventory file. Somehow I need this playbook to run on all web1 servers and all web2 servers... but I also need a way to associate web1.ttv with just web2.ttv and web1.ttx with just web2.ttx and so on.
I'm just learning ansible as I go along, so if this approach is entirely wrong, please let me know!
Thanks.
EDIT 1
On doing some research about group_vars, it looks like group_vars doesn't really help me because I still have the same problem. While looping through all web servers (play 2), the variables I set on web1 servers in play 1 are not visible from web2 servers.
EDIT 2:
- hosts: web1
tasks:
- name: query primary servers
shell: psql -U widget widget -c 'SELECT COUNT(*) FROM widget' -t
register: result
- local_action: shell echo {{ result.stdout }} > varacrossplay.txt
That fails on the local_action line with this error:
fatal: [web1.ttv.mydomain.com -> localhost]: FAILED! => {"changed": true, "cmd": "echo 2 > varacrossplay.txt", "delta": "0:00:00.001641", "end":
": "echo 2 > varacrossplay.txt", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true}, "mod
1: cannot create varacrossplay.txt: Permission denied", "stdout": "", "stdout_lines": [], "warnings": []}
Try with this example playbook:
[jenkins#batman ansible]$ cat testplaybook.yml
- hosts: web1
tasks:
- name: query primary servers
shell: echo "TEST"
register: result
- local_action: shell echo {{ result.stdout }} > varacrossplay.txt
- hosts: web
tasks:
- local_action: shell cat varacrossplay.txt
register: result
- set_fact: other_fact="{{ result.stdout }}"
- debug: var=other_fact
With my servers all works fine xD
[jenkins#batman ansible]$ ansible-playbook -i inventory testplaybook.yml
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [10.0.0.100]
TASK [query primary servers] ***************************************************
changed: [10.0.0.100]
TASK [command] *****************************************************************
changed: [10.0.0.100 -> localhost]
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [10.0.0.2]
ok: [10.0.0.1]
TASK [command] *****************************************************************
changed: [10.0.0.1 -> localhost]
changed: [10.0.0.2 -> localhost]
TASK [set_fact] ****************************************************************
ok: [10.0.0.1]
ok: [10.0.0.2]
TASK [debug] *******************************************************************
ok: [10.0.0.2] => {
"other_fact": "TEST"
}
ok: [10.0.0.1] => {
"other_fact": "TEST"
}
PLAY RECAP *********************************************************************
10.0.0.100 : ok=3 changed=2 unreachable=0 failed=0
10.0.0.1 : ok=4 changed=1 unreachable=0 failed=0
10.0.0.2 : ok=4 changed=1 unreachable=0 failed=0

Resources