calling a custom variable from inventory - ansible

I have a some custom variables in my inventory file. I would like to call them in my playbook, but not sure how to do this.
--------------------------------INV--------------------------------
[testA]
namgw01a
namgw02a
[testB]
namgw01b
namgw02b
[nam:children]
testA
testB
[testA:vars]
file=file_a.conf
[testB:vars]
file=file_b.conf
--------------------------------PLAYBOOK--------------------------------
vars:
- file: "{{ file }}"
- name: "show variable"
debug:
var: file
--------------------------------RESULT--------------------------------
TASK [show variable] **************************************************************************************************************************************
ok: [namgw01b] => {
"file": "VARIABLE IS NOT DEFINED!"
}
ok: [namgw02b] => {
"file": "VARIABLE IS NOT DEFINED!"
}

Related

How to set bool var based on if string or list contains specified value?

Please tell me what I am doing wrong here. I have these Ansible tasks defined in my role:
- meta: end_play
when:
- pp_srv is not defined
- name: Debug pp_srv splitted.
debug:
msg: "pp_srv spilti up is {{ pp_srv.split(',') }}"
- name: Set Monitoring Host
ansible.builtin.set_fact:
cd_mon_host: "{{ groups.monitor.0 }}"
when:
- cd_mon_host is not defined
- name: Debug Show pp_srv
debug:
var: pp_srv
- name: Check Usage - Set is_cd_host to False
ansible.builtin.set_fact:
is_cd_host: False
- name: Check Usage - Set is_cd_host to True
ansible.builtin.set_fact:
is_cd_host: True
when:
- pp_srv | search("diags")
- name: Debug is_cd_host
debug:
msg: "is_cd_host is {{ is_cd_host }}"
- name: Assert if
assert:
that: false
When I run molecule test or run a playbook that using this role I get this output ...
TASK [example.diags : Debug pp_srv splitted.] ******************
ok: [cd-host-01] => {
"msg": "pp_srv spilti up is ['all', 'agger', 'esync', 'apiconf', 'diags']"
}
ok: [cd-host-02] => {
"msg": "pp_srv spilti up is ['apiconf']"
}
ok: [mon-host-01] => {
"msg": "pp_srv spilti up is ['all', 'apiconf', 'diags']"
}
TASK [example.diags : Set Monitoring Host] ******************
ok: [cd-host-01]
ok: [cd-host-02]
ok: [mon-host-01]
TASK [example.diags : Debug Show pp_srv] ***********************
ok: [cd-host-01] => {
"pp_srv": "all,agger,esync,apiconf,diags"
}
ok: [cd-host-02] => {
"pp_srv": "apiconf"
}
ok: [mon-host-01] => {
"pp_srv": "all,apiconf,diags"
}
TASK [example.diags : Check Usage - Set is_cd_host to False] ***
ok: [cd-host-01]
ok: [cd-host-02]
ok: [mon-host-01]
TASK [example.diags : Check Usage - Set is_cd_host to True] ****
ok: [cd-host-01]
ok: [cd-host-02]
ok: [mon-host-01]
TASK [example.diags : Debug is_cd_host] ************************
ok: [cd-host-01] => {
"msg": "is_cd_host is True"
}
ok: [cd-host-02] => {
"msg": "is_cd_host is True"
}
ok: [mon-host-01] => {
"msg": "is_cd_host is True"
}
I had hoped that is_cd_host is False for host cd-host-02 because it does not have the string, diags
in the variable pp_srv.
What did I do wrong?
UPDATE:
Thanks β.εηοιτ.βε
I followed your advice and I my role is working fine now.
I have this now:
- name: Check Usage - Set is_cd_host.
ansible.builtin.set_fact:
is_cd_host: "{{ 'diags' in pp_srv.split(',') }}"

Ansible how to run task only on groups mentioned in playbook and skip other groups even though same host part of other group

I have a role that is common for both mongo replicas and arbiters and hosts groups separately for each replica and arbiter because the role should support the arbiter on the same host & different host.
hosts:
[replicas]
127.0.0.1
127.0.0.2
[arbiter]
127.0.0.2
the task inside role:
- name: Run only on replicas
debug msg=" Only on replica"
when: '"replicas" in group_names'
- name: Run only on the arbiter
debug: msg="Only on the arbiter"
when: '"arbiter" in group_names'
playbook:
- hosts: replicas
roles:
- role: "common"
- role: "replica"
- hosts: arbiter
roles:
- role: "common"
- role: "arbiter'
Expected output while running on replicas:
TASK [debug] *********************************************************************************************************************************************
ok: [127.0.0.1] => {
"msg": " Only on replica"
}
ok: [127.0.0.2] => {
"msg": " Only on replica"
}
TASK [debug(arbiter)] *********************************************************************************************************************************************
skipping: [127.0.0.1]
skipping: [127.0.0.2]
But is not skipping on arbiter task as expected as the same host is part of replicas group. Below is the actual output.
Actual output:
TASK [debug] *********************************************************************************************************************************************
ok: [127.0.0.1] => {
"msg": " Only on replica"
}
ok: [127.0.0.2] => {
"msg": " Only on replica"
}
TASK [debug(arbiter)] *********************************************************************************************************************************************
skipping: [127.0.0.1]
ok: [127.0.0.2] => {
"msg": " Only on replica"
}
How to run on a specific group that playbook delegated?
hello you can use this method:
Playbook:
- hosts: replicas
roles:
- { role: common, vars: { group: "replicas" } }
- { role: replica, vars: { group: "replicas" } }
- hosts: arbiter
roles:
- { role: common, vars: { group: "arbiter" } }
- { role: arbiter, vars: { group: "arbiter" } }
and inside your role:
- name: Run only on replicas
debug msg=" Only on replica"
when: group == "replicas"
- name: Run only on the arbiter
debug: msg="Only on the arbiter"
when: group == "arbiter"
I hope that can help you to resolve your issue.

Ansible: How to pass the condition when variable is undefined

I tried to combine the below dictionaries to one but struggling to pass the condition when one of the variable is not defined.
ok: [vm1.nodekite.com]] => {
"containeruplist": {
"service": "service-test-app",
"platform-service": "service-dev-app"
}
}
ok: [vm1.nodekite.com] => {
"containerexitedlist": {
"nginx": "www-service"
}
}
Here is my code.
- set_fact:
final_list: "{{ final_list|default({}) | combine( {item.key:item.value} ) }}"
with_dict:
- "{{ containeruplist }}"
- "{{ containerexitedlist }}"
when: (containeruplist is defined) or (containerexitedlist is defined)
Here is the output
ok: [vm1.nodekite.com] => {
"final_list": {
"service": "service-test-app",
"platform-service": "service-dev-app"
"nginx": "www-service"
}
}
but how to pass all the 3 conditionals when one of the variable is not defined.
containeruplist is populated or containerexitedlist is undefined
containeruplist is undefined or containerexitedlist is populated
containeruplist is populated or containerexitedlist is populated
I tried with when: (containeruplist is defined) or (containerexitedlist is defined) which still throws {"msg": "'containerexitedlist' is undefined"}

Using url module with jinja2 templates

I know how to process jinja2 templates files and let them create files. I also know how to POST to webservices using the url module.
For now I use some code like this, which successfully posts hardcoded JSON to my remote service:
tasks:
- name: GSA app definition
uri:
url: "http://localhost:8764/api/apps?relatedObjects=false"
method: POST
force_basic_auth: yes
user: "{{ admin_name }}"
password: "{{ admin_pass }}"
body_format: json
body: "{\"name\":\"My new app\", \"description\":\"A really great new app\" }"
follow_redirects: all
status_code: 200
timeout: 15
register: app_gsa_cfg
But the JSON is static, how can I process a jinja2 template and POST its content ? I would prefer not having to create temporary files on disk and POST them, what I am looking for is a direct connection or perhaps an approach that puts the template processing result into a string.
For starters a jinja2 template could look like this, later I will add variables too:
{#
This file creates the basic GSA app in Fusion. See https://doc.lucidworks.com/fusion-server/4.2/reference-guides/api/apps-api.html#create-a-new-app for details
#}
{
"name": "GSA",
"description": "Contains all configuration specific to the migrated GSA legacy searches"
}
(I know that this has little advantage over a static json included into the playbook. But is is easier to edit and offers me the opportunity to have (jinja style) comments in Json, which is normally not possible)
In my case, what I do is the following:
I have an API, so I do the following:
- name: Change API Status
uri:
url: "{{ enpoint }}/v1/requests/{{ whatever }}"
method: PATCH
user: "{{ tokenid }}"
password: x
headers:
X-4me-Account: "myaccount"
body: '{ "status":"{{ reqstatus }}" }'
body_format: json
status_code:
- 201
- 200
force_basic_auth: true
validate_certs: false
return_content: true
Then your reqstatus var will change.
Even you can add your whole text as yaml, import into a variable and convert with filters {{ some_variable | to_json }}
Note: Have a look to the formatting without escaping quotes. That will help.
It makes no sense creating a file with jinja2 if you are not going to copy it remotely. Ansible supports jinja natively but its strength is the possibility to have plugins for better maintainability. There is no difference between template (or win_template) modules unless (as said) you copy the file somewhere. Look this example:
---
- name: Adhoc Jinja
hosts: localhost
connection: local
gather_facts: false
vars:
mytemplate:
- name: "GSA"
description: "Contains all configuration specific to the migrated GSA legacy searches"
- name: "Another Name"
description: "Contains Another Var"
tasks:
- name: Read Vars Loop
debug:
msg: "{{ item | to_json }}"
with_items: "{{ mytemplate }}"
- name: Include Vars
include_vars: adhocjinja2.yml
- name: Read Vars Loop
debug:
msg: "{{ item | to_json }}"
with_items: "{{ mytemplate }}"
And adhocjinja2.yml:
mytemplate:
- name: "GSA2"
description: "Contains all configuration specific to the migrated GSA legacy searches"
- name: "Another Name 2"
description: "Contains Another Var"
The output is:
TASK [Read Vars Loop] **************************************************************************************
ok: [localhost] => (item={'name': 'GSA', 'description': 'Contains all configuration specific to the migrated GSA legacy searches'}) => {
"msg": "{\"name\": \"GSA\", \"description\": \"Contains all configuration specific to the migrated GSA legacy searches\"}"
}
ok: [localhost] => (item={'name': 'Another Name', 'description': 'Contains Another Var'}) => {
"msg": "{\"name\": \"Another Name\", \"description\": \"Contains Another Var\"}"
}
TASK [Include Vars] ****************************************************************************************
ok: [localhost]
TASK [Read Vars Loop] **************************************************************************************
ok: [localhost] => (item={'name': 'GSA2', 'description': 'Contains all configuration specific to the migrated GSA legacy searches'}) => {
"msg": "{\"name\": \"GSA2\", \"description\": \"Contains all configuration specific to the migrated GSA legacy searches\"}"
}
ok: [localhost] => (item={'name': 'Another Name 2', 'description': 'Contains Another Var'}) => {
"msg": "{\"name\": \"Another Name 2\", \"description\": \"Contains Another Var\"}"
}
You can manage your variables as you want and create your json on the fly as Ansible has jinja and json it its heart.

Creating Ansible role for services addition to nagiosXI

I am trying to add a service to the NagiosXI with the below CURL command.
curl -k -XPOST "https://16.231.22.60/nagiosxi/api/v1/config/service?apikey=qfOQpKFORCNo7HPunDUsSjW7f2rNNmrdVv3kvYpmQcNdSS2grV2jeXKsgbv3QgfL&pretty=1" -d "host_name=***{{ item }}***&***service_description=Service status for: sshd***&use=xiwizard_ncpa_service&check_command=check_xi_ncpa\! -t 5nidNag -P 5693 -M services -q service=sshd,status=running&check_interval=5&retry_interval=1"
In the above command only hostname and service description description changes. I am calling hostname with Item module. and adding service description manually. if i need to add 50 services i neeed to write this command for 50 times.
i am planning to write it by ansible roles. can someone help me out with this.
You can do something like:
---
- name: Nagios Config
gather_facts: False
hosts: localhost
vars:
servers:
- 10.100.10.5
- 10.100.10.6
- 10.100.10.7
services:
- ssh
- https
- smtp
tasks:
- name: Add Nagios services
debug:
msg: "curl -host {{item.0}} with service {{ item.1 }}"
with_nested:
- "{{ servers }}"
- "{{ services }}"
Getting the following output:
TASK [Add Nagios services] ********************************************************************************************************
ok: [localhost] => (item=None) => {
"msg": "curl -host 10.100.10.5 with service ssh"
}
ok: [localhost] => (item=None) => {
"msg": "curl -host 10.100.10.5 with service https"
}
ok: [localhost] => (item=None) => {
"msg": "curl -host 10.100.10.5 with service smtp"
}
ok: [localhost] => (item=None) => {
"msg": "curl -host 10.100.10.6 with service ssh"
}
ok: [localhost] => (item=None) => {
"msg": "curl -host 10.100.10.6 with service https"
}
ok: [localhost] => (item=None) => {
"msg": "curl -host 10.100.10.6 with service smtp"
}
ok: [localhost] => (item=None) => {
"msg": "curl -host 10.100.10.7 with service ssh"
}
ok: [localhost] => (item=None) => {
"msg": "curl -host 10.100.10.7 with service https"
}
ok: [localhost] => (item=None) => {
"msg": "curl -host 10.100.10.7 with service smtp"
}
Try the uri module if it doesn't fit your requirements, go for the shell one. I have reflected the debug one just to answer the question.

Resources