Ansible variables in template - ansible

template/file.cfg.j2
This template file will contain basic lines that will be shared between three boxes. There will be some differences in the lines that will be unique for each box. This is a value I wish to variable:ize.
set system user nsroot 546426471446579744 -encrypted
The 546... hash should now be in a {{ }} variable, as it will differ between the instances. {{ item.hash}}
I need an approach on how to set it up and structure, do I need include_vars etc.
EDIT: What I have:
vars/vars.yml
servers
ns:
- name: Copy hash
hash: 187f637f107bf7265069ace04bf87fcd8e63923169a2c529a
playbook.yml
tasks:
- name: Variable:ize
template: src=templates/template.j2 dest=/tmp mode=644 owner=root group=wheel
with_items: servers[ansible_hostname]

In your inventory file you'll want to do something like this:
host1 nsroot_hash=12345
host2 nsroot_hash=54321
host3 nsroot_hash=24680
And then your template/file.cfg.j2 will look like this:
set system user nsroot {{ nsroot_hash }} -encrypted
Edit: You want the hash variable to be defined in your inventory file since you want a different value for each host that you're going to run this task against. So your inventory (host_vars) file should look something like this (I assume ns is the name of one of your servers):
ns hash=187f637f107bf7265069ace04bf87fcd8e63923169a2c529a
Then your playbook.yml would simply look something like this:
- hosts: all
tasks:
- name: Variable:ize
template: src=templates/template.j2 dest=/tmp/template.txt mode=644 owner=root group=wheel
Note that you don't need the with_items statement. In the above case, assuming that ns is the name of a host then this will create the file /tmp/template.txt with the templated text in it. (Note that dest is a path to a file, and not just a path to a directory.)
If you want to apply this task to multiple hosts then all you do is edit the inventory file as shown above:
ns hash=187f637f107bf7265069ace04bf87fcd8e63923169a2c529a
aa hash=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bb hash=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
When you run the above playbook.yml file then it will apply the template to all three hosts, ns, aa, and bb, and put the proper hash value in the file on each host.

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 }}"

Ansible alias in separate file

I'm trying to separate my vars from the playbook file.
My vars use an alias to make things easier.
Example of my playbook.yaml:
---
- hosts: localhost
name: playbook name
vars:
login: &login
username: "{{ login.user }}"
password: "{{ login.pass }}"
vars_files:
- creds.yaml
tasks:
- name: using creds
some_module:
some_command: true
<<: *login
How can I move the "vars" section to a file outside the playbook and keep the same template inside "tasks"?
Your way to achieve that is to create a proper inventory and use the inventory variables. ansible inventory docs
Create this schema tree:
hosts (directory)
group_vars (directory)
host_vars (directory)
hosts-groups (directory)
hosts-all (file)
Then either you choose to define your hosts individually in the hosts-all
localhost ansible_ssh_host=x.x.x.x {{ potentially any other needed argument/variable }}
Or You group hosts in groups and define new group in hosts/hosts-groups: Create a file with the desired group name, ex: hosts/hosts-groups/local and inside it define your host-group
[local]
localhost
And then, either in the hosts_var or group_vars (depending on your first step), you create a file either with host name or group name, and inside it, you write your variables. Ex (by group): Create hosts/group_vars/local and inside it write your variables
login: user1
pass: pass1
And then automatically, your play will search the right vars for each hosts according to your inventory structure.

How to substitute values to a conf file using Ansible

I have an ansible playbook that has created a file (/tmp/values.txt) in each server with the following content
1.1.1.1
2.2.2.2
3.3.3.3
4.4.4.4
5.5.5.5
And I have a conf file named etcd.conf in the /tmp/etcd.conf with the following content
and I need to substitute the value of each line from /tmp/values.txt, so /tmp/etcd.conf will look like this:
SELF_IP=1.1.1.1
NODE_1_IP=2.2.2.2
NODE_2_IP=3.3.3.3
NODE_3_IP=4.4.4.4
NODE_4_IP=5.5.5.5
Is there a way I can do this? I used the following lookup method but it only works in the controll server
- name: Create etcd.conf
template:
src: etcd.conf.j2
dest: /tmp/etcd.conf
vars:
my_values: "{{ lookup('file', '/tmp/values.txt').split('\n') }}"
my_vars: [SELF_IP, NODE_1_IP, NODE_2_IP, NODE_3_IP, NODE_4_IP]
my_dict: "{{ dict(my_vars|zip(my_values)) }}"
You can use the slurp: task to grab the content for each machine, or use command: cat /tmp/values.txt and then examine the stdout_lines of its register:-ed variable to achieve that same .split("\n") behavior (I believe you'll still need to use that .split call after | b64decode if you use the slurp approach)
What will likely require some massaging is that you'll need to identify the group (which may very well include all) of inventory hostnames for which that command will produce content, and then grab the hostvar out of them to get all values
Conceptually, similar to [ hostvars[hv].tmp_values.stdout_lines for hv in groups[the_group] ] | join("\n"), but it'll be tedious to write out, so I'd only want to do that if you aren't able to get it to work on your own

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

Resources