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.

Remember loop: or with_items:

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 yum module .

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.

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.

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.

Think about where you have to create the folders for your host and group variables

Task 6

  • Get a feeling for errors: Remove the quotes around the curly brackets and have a look at the output.

Solutions

Delete the 2 tasks “start and enable [httpd,firewalld]". Add a new task with the following content:

- name: start and enable services
  service:
    name: "{{ item }}"
    state: started
    enabled: yes
  with_items:
    - httpd
    - firewalld

Make sure your indentations are correct! Older versions of Ansible don’t know the keyword loop yet – use with_items instead.

tasks:
  - name: install httpd and firewalld
    yum:
      name:
        - httpd
        - firewalld
      state: installed

Content of motd.yml:

---
- hosts: all
  become: yes
  vars:
    motd_content: "Thi5 1s some r3ally stR4nge teXT!\n"
  tasks:
   - name: set content of /etc/motd
     copy:
       dest: /etc/motd
       content: "{{ motd_content }}"
$ ansible-playbook motd.yml

Take a look at what your playbook just did:

$ 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 ~]$

$ 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 ~]$
$ 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.

Your motd.yml should look something like this:

---
- hosts: all
  become: yes
  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:

$ 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:

$ ansible-playbook motd.yml -l node1,node2

$ ansible web,node2 -a "cat /etc/motd"

---
- hosts: all
  become: yes
  tasks:
    - name: set content of /etc/motd
      copy:
        dest: /etc/motd
        content: {{ motd_content }} #<-- missing quotes here