Ansible -- Part Two

Posted on Mon 17 December 2018 in linux

In the second part of the ansible series some more of the advanced playbook features are discussed. For the installation and basic setup see the first part of the series.

Variables

Playbooks can make use of variables to allow a more flexible design. The variables can be defined in the vars section of a playbook. For example:

---
- hosts: all
  become: true
  vars:
     package: apache2
  tasks:
     - name: Install Package
       apt: name={{ package }} state=latest

Ansible uses jinja2 to render templates. As a result, the defined variables can be accessed by curly brackets {{ .. }}, as in the example using the package variable to set the package name that should be installed.

Variables can also be defined as list, as done in the following example:

---
- hosts: all
  become: true
  vars:
     packages: ["apache2", "apache2-doc", "apache2-utils"]
  tasks:
     - name: Install Package
       apt: name={{ item }} state=latest
       with_items: packages

Arrays are assigned via the with_items key and can then be accessed using the item keyword.

Tags

To group one or multiple tasks within a playbook, the tags keyword can be assigned to the corresponding tasks, e.g.:

- name: make sure apache2 is installed
  apt: name=apache2 state=installed
  tags: apache2

This enables the use of certain sub-functionalities of a playbook by using the --tags apache2 argument when starting the playbook.

Conditions

Moreover, the when keyword can be provided to start a task when a certain condition is fulfilled. For example, to reboot the remote system when it runs Debian as operating system do:

tasks:
  - name: Shut down Debian system
    command: /sbin/shutdown -t now
    when: ansible_os_family == "Debian"

Templates

The use of jinja2 in ansible also allows to utilization of templates for other files. For example, an apache2 site configuration file (mysite.j2) could be rendered by a template:

<VirtualHost *:{{ http_port }}>
    ServerAdmin webmaster@localhost
    DocumentRoot {{ doc_root }}

    <Directory {{ doc_root }}>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

In the ansible playbook the template can be rendered as follows:

  vars:
    http_port: 80
    doc_root: /var/www/mysite

...

  - name: Create mysite apache2 configuration file
    template: src=mysite.j2 dest=/etc/apache2/sites-available/mysite.conf

The defined variables will be replaced with the specified arguments, when the template is rendered.

Handlers

Apart from tasks, handlers can be defined, which will only be executed when triggered using the notification keyword. Handlers are often used together with services, e.g., when a certain configuration file is changed the service will be restarted. For example, after rendering the mysite configuration template, the apache2 service has to be restarted:

handlers:
    - name: restart apache2
      service: name=apache2 state=restarted

...

- name: Create mysite apache2 configuration file
  template: src=mysite.j2 dest=/etc/apache2/sites-available/mysite.conf
  notify: restart apache2

Complex Example

A more complex example that makes use of the presented functionalities is shown in the following:

---
- hosts: webservers
  become: true
  vars:
    http_port: 80
    doc_root: /var/www/mysite
  tasks:
    - name: Update apt
      apt: update_cache=yes

    - name: Install apache2
      apt: name=apache2 state=latest

    - name: Create document root
      file: path={{ doc_root }} state=directory owner=www-data group=www-data

    - name: Create index.html file
      copy: src=index.html dest={{ doc_root }}/index.html owner=www-data group=www-data mode=0644

    - name: Render apache2 configuration file
      template: src=mysite.j2 dest=/etc/apache2/sites-available/mysite.conf

    - name: Enabling new apache2 configuration file
      command: a2ensite mysite.conf
      notify: restart apache2

  handlers:
    - name: restart apache2
      service: name=apache2 state=restarted