Ansible managing inclusions

When working with complex or long playbooks, administrators can use separate files to divide tasks and lists of variables into smaller pieces for easier management. There are multiple ways to include task files and variables in a playbook.

• Tasks can be included in a playbook from an external file by using the include directive.

• The include_vars module can include variables defined in either JSON or YAML files, overriding host variables and playbook variables already defined.

Using multiple, external files for tasks and variables is a convenient way to build the main playbook in a modular way, and facilitates reuse of Ansible elements across multiple playbooks.

Including tasks

The include directive allows administrators to have a task file inserted at a particular point in a playbook. A task file is simply a file that contains a flat list of tasks ( environment.yml):

An include directive with variables could be used in a playbook, like this:

Important
Tasks included in a playbook are evaluated based on their order in the playbook. For example, a playbook may have a task to start a service provided by a software package, and a second task included from an external file that installs that software package. The external task must be included in the playbook before the task to start the package’s service is declared in the playbook.

For complex projects, roles provide a powerful way to organize included task files and playbooks.

 

Including variables
Just as tasks can be included in playbooks, variables can be externally defined and included in playbooks. There are many ways in which this can be done. Some of the ways to set variables include:
• Inventory variables defined in the inventory file or in external files in host_vars and group_vars directories
• Facts and registered variables
• Playbook variables defined in the playbook file with vars or in an external file through vars_files

The following YAML file, variables.yml, contains two variables
that define the packages to install:

To import these two variables in a playbook, the include_vars module can be used:

Important
When deciding where to define variables, try to keep things simple.
In most cases, it is not necessary to use include_vars, host_vars and
group_vars files, playbook vars_files directives, inlined variables in playbook and inventory files, and command-line overrides all at the same time. In fact, that much complexity could make it hard to easily maintain your Ansible project.

 

Example 1.

Define the paths.yml variables file and create a dictionary that sets some system paths. Specify the fileserver base path  with the  ansible_fqdn variable and dbpath base path  with the ansible_fqdn variable.

Create the fileservers.yml playbook and include the paths.yml variables file. The fileserver will be created using the variable defined previously in the paths.yml variables file.

Run the fileservers.yml playbook and examine the output.

The output shows the directory structure that has been created by Ansible, which matches the path that has been set by the paths.fileserver variable.

Create the dbservers.yml playbook. Include the variable file and use the paths.dbpath variable to create the directory structure.

Run the dbservers.yml playbook and examine the output.

Create another variable file, package.yml, and define the name of the package to install.

Create a task file, called install_package.yml, and create a basic task that installs a package.

Create the playbook.yml playbook. Define it for the hosts in the fileservers group. Include both variable files as well as the task file.

Run the playbook and watch the output.

Note the httpd package has been installed from a task, whereas the name of the package to install is defined in the variables file.

Update the playbook.yml playbook to override the name of the package to install. Append a vars block to the include statement and define a dictionary to override the name of the package to install.

Run the playbook and watch the output as Ansible installs the tomcat package.

 

Example 2.

In the vars directory, create the variables.yml variables file. The file defines the firewall_pkg variable in YAML format. The file should read as follows:

In the tasks directory, create the environment.yml task file. Define the two tasks that install and start the web server; use the package variable for the package name, service for the service name, and svc_state for the service state.

Create and edit the main playbook, named playbook.yml. The playbook imports the tasks as well as the variables; and it installs the firewalld service and configures it.  Start by adding the webserver host group. Define a rule variable with a value of http.

Define the first task, which uses the include_vars module to import extra variables in the playbook. The variables are used by other tasks in the playbook. Include the variables.yml variable file created previously.

Define the second task which uses the include module to include the base
environment.yml playbook. Because the three defined variables are used in the base playbook, but are not defined, include a vars block. Set three variables in the vars section: package set as httpd, service set as httpd, and svc_state set as started.

Create three more tasks: one that installs the firewalld package, one that starts the firewalld service, and one that adds a rule for the HTTP service. Use the variables that were defined previously.

Create a task that installs the firewalld package using the firewall_pkg variable. Create a task that starts the firewalld service. Create a task that adds a firewall rule for the HTTP service using the rule variable.

Finally, add a task that creates the index.html file for the web server using the copy module. Create the file with the Ansible ansible_fqdn fact, which returns the fully qualified domain name. Also include a time stamp in the file using an Ansible fact.

The main playbook.yml playbook appear as follows:

Run the playbook using the ansible-playbook command. Watch the output as Ansible starts by including the environment.yml playbook and running its tasks, then keeps executing the tasks defined in the main playbook.

Use curl to ensure the web server is reachable from workstation. Because the
index.html has been created, the output should appear as follows:

 

Example 2.

Create a facts file in INI format called custom.fact. Create a section called packages and define two facts: one called db_package, with a value of mariadb-server, and one called web_package, with a value of httpd. Create a section called services with two facts: one called db_service, with a value of mariadb, and one called web_service, with a value of httpd.
Define a playbook, called setup_facts.yml, that will install the facts on serverb.

Create the fact file custom.fact. The file should appear as follows:

From the project directory, create the setup_facts.yml playbook to install the facts on the managed host, serverb.lab.example.com. Use the file and copy modules to install the custom facts. The playbook should appear as follows:

Run the playbook to install the custom facts and verify the facts are available as Ansible facts.

Ensure the newly created facts can be retrieved.

Create a directory for variables, called vars. Define a YAML variable file, called main.yml, in that directory that defines a new variable, called web_root, with a value of /var/www/html.

Create the variables directory, vars, inside the project directory.

Create the variables file vars/main.yml. The file should contain the following content:

From the project directory, lab-managing-vars, create a directory for tasks, called tasks. Define a task file in the subdirectory, called main.yml, that instructs Ansible to install both the web server package and the database package using facts Ansible gathered from serverb.lab.example.com. When they are installed, start the two services.

Create the tasks directory inside the project directory.

Create the tasks file, tasks/main.yml. The tasks should install both the database and the web server, and start the services httpd and mariadb. Use the custom Ansible facts for the name of the services to manage. The file should appear as follows:

Create the main playbook playbook.yml in the top-level directory for this lab. The playbook should be in the following order: target the lamp hosts groups and define a new variable, firewall with a value of firewalld.
Create the following tasks:
• A task that includes the variable file main.yml.
• A task that includes the tasks defined in the tasks file.
• A task for installing the latest version of the firewall package.
• A task for for starting the firewall service.
• A task for opening TCP port 80 permanently.
• A task that uses the copy module to create the index.html page in the directory the variable defines.
The index.html should appear as follows:

Both the host name and the IP address should use Ansible facts.

When complete, the tree should appear as follows:

The main playbook should appear as follows:

Explanation:

First task includes the variables file located under vars/main.yml. Second task imports the tasks file located under tasks/main.yml. Next tasks that install the firewall, start the service, open port 80, and reload the service. Finally, create the task that uses the copy module to create a custom main page, index.html. Use the variable web_root, defined in the variables file, for the home directory of the web server.

Run the playbook playbook.yml created in the previous step.

From workstation, use curl to ensure the web server is reachable.

Also use an ad hoc command to connect to serverb as the devops user and ensure the mariadb service is running.