Installing packages

We have looked at how to install a standalone binary such as docker-compose in the previous sectionbut what if we need to actually install some additional operating system packages that were not installed in our base image? For example, cloud-init is incredibly useful in most cloud environments but was not included in our minimal CentOS 7 install that we performed earlier.

Here, again, Ansible can helpthis time, we will define a role to install the packages we require. We'll reuse the inventory file from the previous section and create a new role called packageinstall in the same manner that we did before: 

  1. Now, the preceding example on copying files would work on all Linux distributions—the only thing you need to be mindful of is where destination files might life. For example, our CentOS 7 VM image will have the chrony configuration file installed in /etc/chrony.conf, whilst an Ubuntu 18.04 LTS server would have it in /etc/chrony/chrony.conf. Apart from this small change to the dest: parameter of the copy module, the code would remain the same.

Unfortunately, it gets a little more complex with package installation.

  1. Let's suppose we want to install cloud-init and docker on our CentOS 7 example image—the role required to do this might look like this:
---
- name: Install the epel-release package
yum:
name: epel-release
state: present

- name: Install cloud-init and docker
yum:
name: "{{ item }}"
state: present
loop:
- cloud-init
- docker
  1. We must install the EPEL repository first, and then we can install the required packages. When we run it, the output should look something like this:

If you are using a different Linux distribution, then you need to vary the package manager accordingly. For example, on distributions that use the apt package manager such as Debian or Ubuntu, the equivalent Ansible role would look like the following block of code:

---
- name: Install cloud-init and docker
apt:
name: "{{ item }}"
state: present
loop:
- cloud-init
- docker.io

Note the change in module from yum to apt, and the different package name used for the Docker container service. Other than that, the playbook is almost identical.

We can improve on this further—this different results in the need to maintain two different roles for two different operating system bases—but what if we could intelligently combine them into one? Fortunately, the facts that Ansible gathers when it first runs can be used to identify the operating system and, as such, run the correct code.

We will repurpose our earlier example code to combine both of these installations into one Ansible role:

  1. The first part of the code is almost identical to the preceding example, except that we have now specified the when clause to ensure it is only run on Debian- or Ubuntu-based Linux distributions:
---
- name: Install cloud-init and docker
apt:
name: "{{ item }}"
state: present
loop:
- cloud-init
- docker.io
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu'
  1. We then add two further tasks that perform the required steps to install Docker on CentOS or Red Hat Enterprise Linux:
- name: Install the epel-release package
yum:
name: epel-release
state: present
when: ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat enterprise Linux'

- name: Install cloud-init and docker
yum:
name: "{{ item }}"
state: present
loop:
- cloud-init
- docker
when: ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat enterprise Linux'

Notice again the when clauses under each task—these specific examples are used to determine whether the tasks should be run depending on the facts that Ansible obtained during the initial part of the run. Hence, if we now run this role on an Ubuntu system, we see the following:

  1. As you can see, the first task related to apt was run, but the two following ones based on yum were skipped because the conditions of the when clause were not met. Now, if we run it on a CentOS 7 target instead, we see this:

The inverse is now true: the apt task was skipped, but the two yum related tasks were run. In this way, it is possible to maintain a single role for installing a common set of package requirements, even when dealing with several different base operating systems. Combining when clauses with Ansible facts is a very powerful way to ensure the correct behavior of a single code base across a variety of systems, and hence if your SOE does extend to both Debian and Red Hat-based systems, you can still maintain code with ease and simplicity. 

Once supplemental packages have been installed, they often must be configured for them to be useful. In the next section, we will explore the use of Ansible in editing configuration files.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset