Ansible: How can I Include variable file with conditional statement - ansible

I have three sets of servers. Depending on the hostname, I want the client to grab the correct file. I tested the playbook on a server with the word "batch" but it picks up both files group_vars/perl and group_vars/batch
pre_tasks:
- include_vars: group_vars/web
when: "'web' in ansible_hostname"
- include_vars: group_vars/batch
when: "'web' not in ansible_hostname"
- include_vars: group_vars/perl
when: "'web' not in ansible_hostname" or "'batch' not in ansible_hostname"

Ansible will handle group_vars for you. For any hosts in the group web, the vars at group_vars/web (or group_vars/web.yml) will be automatically included. See Splitting Out Host and Group Specific Data in the Ansible docs.
To answer your question about conditional variable includes, the examples you gave are the correct syntax. Here's another example, not using group_vars:
- include_vars: vars/{{ ansible_distribution}}_packages.yml
when: install_extra_packages is defined and
install_extra_packages != ''
Note that include_vars accepts expressions, so you can use variables to determine the vars files to pull in dynamically.

Related

Include a vars.yml file inside group_vars/all.yml

I want to include variables from a file (say vars.yml) and use it inside group_vars/all.yml.
How this can be achieved?
tried (in all.yml):
include_vars:
file: ../inventories/dev/cluster-0/group_vars/vars.yml
name: x
ansible_user: "{{ x.username }}"
include_vars is an ansible task, and can only appear in a playbook or task list. A variable file can only contain variables; there's no "include"-style mechanism.
Depending on what exactly you're trying to do, you can turn all.yml into a directory (group_vars/all/) and then place multiple files in that directory:
group_vars/all/file1.yaml
group_vars/all/file2.yaml

How to pass an additional inventory file (dynamic inventory script) in molecule?

In my playbook I use var group[inventory_group]. And I need to use my dynamic inventory script. In the documentation I found:
Like above, it is possible to pass an additional inventory file (or
even dynamic inventory script), using the hosts key. Ansible will
automatically merge this inventory with the one generated by molecule.
This can be useful if you want to define extra hosts that are not
managed by Molecule.
But I didn't find any examples.
So, how do I "pass an additional inventory file (or even dynamic inventory script), using the hosts key" ?
Perhaps you could execute the dynamic inventory script in create or prepare steps in the molecule scenario, and then use the add_host module to add the hosts to the in memory inventory?
So something like:
- command:
cmd: /path/to/your_dynamic_inventory_scri.pt
delegate_to: localhost
register: dynamic_inventory
- add_host:
name: "{{ item }}"
loop: "{{ dynamic_inventory.stdout_lines }}"

How to read a specific line from the file and register it as a variable and pass it to another role in ansible

I am creating a azure image using ansible roles, below is the sample of my play book:
- hosts: localhost
gather_facts: yes
roles:
- azure_vmcreator
- hosts: azure_vms
gather_facts: no
roles:
- vm_software
- download_Artifact
- hosts: localhost
gather_facts: yes
roles:
- azure_imagecreator
The idea is to download a f.exe file in download_Artifact role and install it in the vm, on installation f.exe will create a product.id file. I want to read the second line of that file and register it as a variable say image_prefix, so that i can use image_prefix variable in azure_imagecreator role and create a image adding it in the prefix.
I am new to ansible can any one help me out with this ?
Accessing variables set on another host in a playbook isn't very straightforward. The general workflow would look like this:
In download_Artifact use the set_fact module to save the line in question as a host_var. ( set_fact always stores variables as host vars).
You can use with_file to get the contents of a file into a variable and then use jinja to get the second line of the file:
- name: Print Second line of a File
debug:
msg: "{{ item.split("\n")[1] }}"
with_file:
- "/filepath"
What the jinja2 snippet does, is splitting the file on newlines, converting it to an array of the lines, and then accessing the second line (Array indices start with 0).
Instead of printing the contents, you would need to use the set_fact module to save that string into a variable.
Then, In your third playbook, pass the hostvar you've set as an argument to the role. Use can use hostvars.<hostname>.<varname> to access the hostvars of another host.
If you don't know the hostname beforehand, you can use ansibles special variable groups to get the name during playbook execution. The call would then look somewhat like this (haven't tested this though and assuming your role accepts a variable called image_prefix):
- hosts: localhost
gather_facts: yes
roles:
- name: azure_imagecreator
azure_imagecreator:
image_prefix: hostvars[groups.azure_vms[0]].image_prefix

How to use variables between different roles in ansible

my playbook structure looks like:
- hosts: all
name: all
roles:
- roles1
- roles2
In tasks of roles1, I define such a variable
---
# tasks for roles1
- name: Get the zookeeper image tag # rel3.0
run_once: true
shell: echo '{{item.split(":")[-1]}}' # Here can get the string rel3.0 normally
with_items: "{{ret.stdout.split('\n')}}"
when: "'zookeeper' in item"
register: zk_tag
ret.stdout:
Loaded image: test/old/kafka:latest
Loaded image: test/new/mysql:v5.7
Loaded image: test/old/zookeeper:rel3.0
In tasks of roles2, I want to use the zk_tag variable
- name: Test if the variable zk_tag can be used in roles2
debug: var={{ zk_tag.stdout }}
Error :
The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'stdout'
I think I encountered the following 2 problems:
When registering a variable with register, when condition is added, this variable cannot be used in all groups. How to solve this problem? How to make this variable available to all groups?
is my title, How to use variables between different roles in ansible?
You're most likely starting a new playbook for a new host. Meaning all previous collected vars are lost.
What you can do is pass a var to another host with the add_host module.
- name: Pass variable from this play to the other host in the same play
add_host:
name: hostname2
var_in_play_2: "{{ var_in_play_1 }}"
--- EDIT ---
It's a bit unclear. Why do you use the when statement in the first place if you want every host in the play for it to be available?
You might want to use the group_vars/all.yml file to place vars in.
Also, using add_host should be the way to go as how I read it. Can you post your playbook, and the outcome of your playbook on a site, e.g. pastebin?
If there is any chance the var is not defined because of a when condition, you should use a default value to force the var to be defined when using it. While you are at it, use the debug module for your tests rather than echoing something in a shell
- name: Debug my var
debug:
msg: "{{ docker_exists | default(false) }}"

How to set extra variables for Ansible Tower job template from the file?

I'm looking for Ansible Tower equivalent approach of loading extra variables from file. Just like from cli with ...--extra-vars "#somefile.yml" parameters. Can this be done in Ansible Tower?
From the Tower you have several options:
Under Job Templates use the Extra Variables option. This is the --extra-vars equivalent to the cli (Take into account that Tower is not cli and you cannot pass a file but you can copy/paste your file there)
Use Surveys
Load the Var file from your playbook directly and make it "flexible" with a variable to be sent from a Survey like:
- name: Load a variable file based on Survey, or a default if not found.
include_vars: "{{ item }}"
with_first_found:
- "{{ firts_option }}.yaml"
- "{{ second_option }}.yaml"
- default.yaml

Resources