4.1 Ansible Playbooks - Variables and Loops
In this lab we’ll start to use variables and loops.
Task 1
- In your playbook
webserver.yml
you have two tasks for starting and enabling httpd
and firewalld
. Merge these 2 tasks into one.
Tip
Remember loop:
or with_items:
Solution Task 1
Delete the 2 tasks “start and enable [httpd,firewalld]”. Add a new task with the following content:
1
2
3
4
5
6
7
8
| - name: start and enable services
service:
name: "{{ item }}"
state: started
enabled: yes
loop:
- httpd
- firewalld
|
Tip
Make sure your indentations are correct!
Older versions of Ansible used with_items
instead of loop
Task 2
- In your playbook
webserver.yml
, ensure that that the package firewalld
is installed. Do the installation of httpd
and firewalld
in one task. Do you really need to use a loop? Have a look at the description of Ansible’s dnf
module.
Solution Task 2
1
2
3
4
5
6
7
| tasks:
- name: install httpd and firewalld
dnf:
name:
- httpd
- firewalld
state: installed
|
Task 3
- Write a new playbook
motd.yml
which sets the content of /etc/motd
on all servers to a custom text. Use the variable motd_content
and the copy
module with the option content
containing the variable.
Solution Task 3
Content of motd.yml
:
1
2
3
4
5
6
7
8
9
10
| ---
- hosts: all
become: true
vars:
motd_content: "Thi5 1s some r3ally stR4nge teXT!\n"
tasks:
- name: set content of /etc/motd
copy:
dest: /etc/motd
content: "{{ motd_content }}"
|
1
| ansible-playbook motd.yml
|
Take a look at what your playbook just did:
1
2
3
4
| $ ssh -l ansible <node1-ip>
Last login: Fri Nov 1 14:16:08 2019 from 5-102-146-174.cust.cloudscale.ch
Thi5 1s some r3ally stR4nge teXT! # <-- it worked!
[ansible@node1 ~]$
|
Task 4
- Using the command line, overwrite the content of
motd
by providing the variable motd_content
with a different value. - Modify the content again, but use a
vars.yml
file.
Solution Task 4
1
2
3
4
5
6
| $ ansible-playbook motd.yml --extra-vars motd_content="0th3r_5trang3_TExt"
$ ssh -l ansible <node1-ip>
Last login: Fri Nov 1 14:18:52 2019 from 5-102-146-174.cust.cloudscale.ch
0th3r_5trang3_TExt # <-- it worked
[ansible@node1 ~]$
|
1
2
3
4
| $ cat vars.yml
---
motd_content: "st1ll m0r3 str4ng3 TexT!"
$ ansible-playbook motd.yml --extra-vars @vars.yml
|
Login via SSH again and check if the new text was set.
Task 5
- Set the
motd_content
from Task 4 using group_vars
for node1
and host_vars
for node2
. - Make sure you remove the variable definition in
motd.yml
. Reason being it will have a higher priority. - Limit the run to
node1
and node2
.
Tip
Think about where you have to create the folders for your host and group variablesSolution Task 5
Your motd.yml
should look something like this:
1
2
3
4
5
6
7
8
| ---
- hosts: all
become: true
tasks:
- name: set content of /etc/motd
copy:
dest: /etc/motd
content: "{{ motd_content }}"
|
After creating the new directories and files you should have something similar to this:
1
2
3
4
5
6
| $ cat inventory/group_vars/web.yml
---
motd_content: "This is a webserver\n"
$ cat inventory/host_vars/node2.yml
---
motd_content: "This is node2\n"
|
Run your playbook and check if the text was changed accordingly on the two nodes:
1
2
3
| ansible-playbook motd.yml -l node1,node2
ansible web,node2 -a "cat /etc/motd"
|
Task 6
- Get a feeling for errors: Remove the quotes around the curly brackets and have a look at the output.
Solution Task 6
1
2
3
4
5
6
7
8
| ---
- hosts: all
become: true
tasks:
- name: set content of /etc/motd
copy:
dest: /etc/motd
content: {{ motd_content }} #<-- missing quotes here
|
Task 7 (BONUS!)
- Create a playbook
takemehome.yml
that does the following:- Create a compressed archive containing all the content from your
/home/ansible/techlab/
folder - Don’t include the subfolder
/home/ansible/techlab/awx
with all its content in the archive. - Compress the archive using any supported type of compression.
- Ensure an archive is created even if the source is one single file.
- Send this file via mail to your own email adress. Note that you have to have valid credentials for a smtp server. Put these credentials into a password file
password_file.yml
. - Run the playbook using the smtp password from the file
password_file.yml
- remove the password file
password_file.yml
Warning
It’s NOT secure to put the smtp password unencrypted in a file. We will learn in the labs about ansible-vault how to encrypt sensitive data in a secure way.Solution Task 7
Write your SMTP Password to a file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| $ cat password_file.yml
password: "<my_secret_password>"
Create the playbook:
$ cat takemehome.yml
---
- hosts: localhost
#vars_files: # if the vars file is not provided here, you'll have to use it with
# - password_file.yml # --extra-vars on cmdline as shown below
tasks:
- name: Create archive, excluding awx folder
archive:
path: /home/ansible/techlab/*
dest: /home/ansible/techlab.tar.bz2
exclude_path: /home/ansible/techlab/awx
format: bz2
force_archive: true
- name: Send archive via email
mail:
host: smtp.puzzle.ch
port: 587
username: "tux.puzzler@puzzle.ch"
password: "{{ password }}"
secure: starttls
sender: tux.puzzler@puzzle.ch
to: bill.gates@gmail.com
subject: Techlab stuff
body: Sending my stuff home
attach: /home/ansible/techlab.tar.bz2
no_log: true
|
Run the playbook by using the SMTP password from the file created before. After the playbook was sent, delete the password file.
1
2
3
| ansible-playbook takemehome.yml --extra-vars "@password_file.yml"
ansible-playbook takemehome.yml # if vars file provided in playbook
rm -f password_file.yml
|
All done?