import an variable file to another in ansible - ansible

I am new to ansible.
I have 2 variable files one is global and another is environment specific.
Here is the global one in global/group_var/all.yaml folder:
rel:
deployment:
webui:
dockerName: "rel"
dockerTag: "Dev_{{ travis.build_number }}"
And the specific one is in develop/group_var/all.yaml folder
docker:
registery: "xxxx"
is there any way I can import global/group_var/all.yaml to develop/group_var/all.yaml
import global/group_var/all.yaml
docker:
registery: "xxxx"
so develop/group_var/all.yaml becomes:
rel:
deployment:
webui:
dockerName: "rel"
docker:
registery: "xxxx"
dockerTag: "Dev_1111"
Thanks

It's possible to read the global variables into a dictionary. For example
$ cat develop/group_var/all.yaml
global: "{{ lookup('file', 'global/group_var/all.yaml')|from_yaml }}"
docker:
registery: "xxxx"
the playbook
- hosts: localhost
tasks:
- include_vars: develop/group_var/all.yaml
- debug:
var: global
- debug:
var: docker
gives
"global": {
"rel": {
"deployment": {
"webui": {
"dockerName": "rel"
}
}
}
}
"docker": {
"registery": "xxxx"
}

Related

Ansible play is not able to take variable

C:\CYGWIN64\ETC\ANSIBLE\ANSIBLE-ACI-CONFIG
├───environments
│ ├───houston
│ └───munich
├───group_vars
├───plays
├───plugins
│ └───filter
│ └───__pycache__
└───roles
├───aci-fabric-onboarding
│ └───tasks
variable file:
oob_nodes:
- { node_id: "101", obb_address: "10.10.10.10", obb_cidr: "27" , obb_gateway: "10.10.10.1" }
- { node_id: "102", obb_address: "10.10.10.11", obb_cidr: "27" , obb_gateway: "10.10.10.1" }
- { node_id: "201", obb_address: "10.10.10.12", obb_cidr: "27" , obb_gateway: "10.10.10.1" }
play
========
- name: Setup ACI Fabric
hosts: "{{ target }}"
gather_facts: no
any_errors_fatal: true
tasks:
- include_vars:
file: "{{ ACI_SSoT_path }}/fabricsetup.yml"
- include_vars:
file: "{{ ACI_SSoT_path }}/oob.yml"
# Intent Statement
- include_role:
name: aci-fabric-onboarding
roles
==============
# Adding OBB address
- name: Add OBB address
delegate_to: localhost
aci_rest:
host: "{{ aci_ip }}"
username: ansible
private_key: ansible.key
certificate_name: ansible
use_ssl: yes
validate_certs: false
path: /api/node/mo/uni/tn-mgmt/mgmtp-default/oob-default/rsooBStNode-[topology/pod-1/node-"{{item.node_id}}"].json
method: post
content:
{
"mgmtRsOoBStNode":{
"attributes":{
"tDn":"topology/pod-1/node-101",
"addr":"25.96.131.61/27",
"gw":"25.96.131.33",
"status":"created"
},
"children":[
]
}
}
with_items: "{{ oob_nodes }}"
error:
TASK [aci-fabric-onboarding : Add OBB address] *****************************************************************************************************************************************************
task path: /etc/ansible/Ansible-Aci-config/roles/aci-fabric-onboarding/tasks/apply-oob-config.yml:4
fatal: [25.96.131.30]: FAILED! => {
"msg": "The task includes an option with an undefined variable. The error was: 'item' is undefined\n\nThe error appears to be in '/etc/ansible/Ansible-Aci-config/roles/aci-fabric-onboarding/tasks/apply-oob-config.yml': line 4, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n# Adding OBB address\n- name: Add OBB address\n ^ here\n"
}
That looks like an indention error to me. You have with_items with the same indention as aci_rest:
# Adding OBB address
- name: Add OBB address
delegate_to: localhost
aci_rest:
host: "{{ aci_ip }}"
username: ansible
private_key: ansible.key
certificate_name: ansible
use_ssl: yes
validate_certs: false
path: /api/node/mo/uni/tn-mgmt/mgmtp-default/oob-default/rsooBStNode-[topology/pod-1/node-"{{ item.node_id }}"].json
method: post
content:
{
"mgmtRsOoBStNode":{
"attributes":{
"tDn":"topology/pod-1/node-101",
"addr":"25.96.131.61/27",
"gw":"25.96.131.33",
"status":"created"
},
"children":[
]
}
}
with_items: "{{ oob_nodes }}"
Have a look at the documentation as well.

Role duplication and execution, passing multiple variable structure for arguments that can have multiple entries

I am trying come up with a way to pass multiple variables to the same field in a role but not having any luck getting it to work using the Role duplication and execution method I've been using. As an example I want an SLB Server to have multiple ports assigned to it using the port_number variable. I'm new to Ansible so making some rookie mistakes like the code below (port_number: "80", port_number: "8080" returns duplicate entry so only uses the first) but I have tried just about every syntax I have found examples for and nothing is working right. The end result is basically having test3 with both of the port_number: entries assigned to it but at this point I'm not even sure it's possible doing it this way or if I have to run a separate module after the fact to add the entries. Any help is greatly appreciated. Thanks.
---
- name: Deploy A10 config
connection: local
hosts: all
roles:
- role: server
vars:
name: "test1"
fqdn_name: "test1.test.domain.net"
health_check: "TCP-8080-HALFOPEN"
port_number: "80"
- { role: server, vars: { name: "test2", fqdn_name: "test2.test.domain.net", port_number: "8080" }}
- { role: server, vars: { name: "test3", fqdn_name: "test3.test.domain.net", port_number: "80", port_number: "8080" }}
---
- name: Test server create
a10_slb_server:
a10_host: "10.1.1.1"
a10_username: "admin"
a10_password: "admin"
a10_port: "443"
a10_protocol: "https"
state: present
name: "{{ name }}"
fqdn_name: "{{ fqdn_name }}"
port_list:
- port_number: "{{ port_number }}"
In your code vars is dictionary. The keys in a dictionary must be unique.
vars:
name: "test1"
fqdn_name: "test1.test.domain.net"
health_check: "TCP-8080-HALFOPEN"
port_number: "80"
YAML resolves the duplication of the keys simply by overriding the value. This expression
vars: { name: "test3", fqdn_name: "test3.test.domain.net", port_number: "80", port_number: "8080" }
would give
"vars": {
"fqdn_name": "test3.test.domain.net",
"name": "test3",
"port_number": "8080"
}
In your code port_list is list. It's a list of dictionaries. This seems to be the proper way to declare multiple port numbers.
port_list:
- port_number: "80"
- port_number: "8080"
In serialized format
port_list: [{port_number: "80"}, {port_number: "8080"}]
But, in your code role: server it's not clear how these variables are used in the role. It is necessary to review the role to learn how to submit the data.
For example:
- role: server
vars:
name: "test1"
fqdn_name: "test1.test.domain.net"
health_check: "TCP-8080-HALFOPEN"
port_number1: "80"
port_number2: "8080"
--
- name: Test server create
a10_slb_server:
a10_host: "10.1.1.1"
a10_username: "admin"
a10_password: "admin"
a10_port: "443"
a10_protocol: "https"
state: present
name: "{{ name }}"
fqdn_name: "{{ fqdn_name }}"
port_list:
- port_number: "{{ port_number1 }}"
- port_number: "{{ port_number2 }}"

How to generate json files in the same task with templates in Ansible

I need to get JMX metrics from the Hazelcast product. I have created a Logstash process that connects to the JMX port. This process has to read a json where is the information of the hostname, port, cluster, environment, etc of Hazelcast JMX. I need to deploy on the Logstash machines the json file for each Hazelcast machine / port. In this case there are three Hazelcast machines and a total of 6 processes with different ports.
Example data:
Hazelcast Hostnames: hazelcast01, hazelcast02, hazelcast03
Hazelcast Ports: 6661, 6662, 6663, 6664, 6665
Logstash Hostnames: logstash01, logstash02, logstash03
Dictionary of Hazelcast information in Ansible:
logstash_hazelcast_jmx:
- hazelcast_pre:
name: hazelcast_pre
port: 15554
cluster: PRE
- hazelcast_dev:
name: hazelcast_dev
port: 15555
cluster: DEV
Example of task in Ansible:
- name: Deploy HAZELCAST JMX config
template:
src: "hazelcast_jmx.json.j2"
dest: "{{ logstash_directory_jmx_hazelcast }}/hazelcast_jmx_{{ item }}_{{ item.value.cluster }}.json"
owner: "{{ logstash_system_user }}"
group: "{{ logstash_system_group }}"
mode: 0640
with_dict:
- "{{ groups['HAZELCAST'] }}"
- logstash_hazelcast_jmx
The final result should be as follows:
/opt/logstash/jmx/hazelcast/hazelcast_jmx_hazelcast01_DEV.json
/opt/logstash/jmx/hazelcast/hazelcast_jmx_hazelcast01_PRE.json
/opt/logstash/jmx/hazelcast/hazelcast_jmx_hazelcast02_DEV.json
...
Here is an example of the json content:
{
"host" : "{{ hostname of groups['HAZELCAST' }}",
"port" : {{ item.value.port }},
"alias" : "{{ hostname of groups['HAZELCAST' }}_{{ item.value.cluster }}",
"queries" : [
{
"object_name" : "com.hazelcast:instance=_hz_{{ item.value.cluster }},type=XXX,name=YYY",
"attributes" : [ "size", "localHits" ],
"object_alias" : "Hazelcast_map"
} ,{
"object_name" : "com.hazelcast:instance=_hz_{{ item.value.cluster }},type=IMap,name=user",
"attributes" : [ "size", "localHits" ],
"object_alias" : "Hazelcast_map"
}
]
}
I think the problem I have is that the with_dict option does not allow using a listing of inventory hosts and a dictionary.
How can I get this generation of json files for each machine / port?
If you run your playbook against logstash hosts, you can use with_nested:
---
- hosts: logstash_hosts
tasks:
- name: Deploy HAZELCAST JMX config
template:
src: "hazelcast_jmx.json.j2"
dest: "{{ logstash_directory_jmx_hazelcast }}/hazelcast_jmx_{{ helper_host }}_{{ helper_cluster }}.json"
owner: "{{ logstash_system_user }}"
group: "{{ logstash_system_group }}"
mode: 0640
with_nested:
- "{{ groups['HAZELCAST'] }}"
- "{{ logstash_hazelcast_jmx }}"
vars:
helper_host: "{{ item.0 }}"
helper_cluster: "{{ item.1.cluster }}"
helper_port: "{{ item.1.port }}"
I also used helper variables with more meaningful names. You should also modify your template with either helper vars or item.0, item.1 – where item.0 is a host from HAZELCAST group, and item.1 is an item from logstash_hazelcast_jmx list.

variable does not recognized by ansible while calling role with variable

top_level_main.yml
roles:
- { role: deploy_nds }
roles/deploy_nds/vars/main.yml
artifact_url: urlsomething
roles/deploy_nds/meta/main.yml
dependencies:
- {role: download_artifact, url: artifact_url }
roles/download_artifactory/tasks/main.yml
- name: download artifact from jfrog
get_url:
url: "{{ url }}"
dest: /var/tmp
I tried using variable name as "{{ artifact_url }}" but still it does not work as expect. Can someone please help?
I have explicitly included vars file of perticular role in playbook then it worked.
vars_files:
- roles/deploy_nds/vars/main.yml
roles:
- { role: deploy_nds }

Is it possible to import roles into an ansible playbook?

I have a bunch of playbooks where a big percentage of roles are common to all servers. So I'd like to do something like:
---
- hosts: nfs2pre2
sudo: true
gather_facts: no
roles:
- include: initial_setup.yml
- { role: role10, tags: ['role10' ] }
- { role: role11, tags: ['role11' ] }
The initial_setup.yml would be something like:
- { role: role1, tags: ['role1' ] }
- { role: role2, tags: ['role2' ] }
Is it possible?
That's not possible as far as I know, but there is a simple workaround. You can create a role which will only have dependencies on other roles. To follow your example, you can create a role initial_setup, by creating a directory roles/initial_setup and in it create a directory meta with a file main.yml:
# roles/initial_setup/meta/main.yml
---
dependencies:
- { role: 'role1', tags: 'role1' }
- { role: 'role2', tags: 'role2' }
Now you can use initial_setup as any regular role:
- hosts: nfs2pre2
sudo: true
gather_facts: no
roles:
- { role: initial_setup, tags: ['initial_setup' ] }
- { role: role10, tags: ['role10' ] }
- { role: role11, tags: ['role11' ] }

Resources