Validating the image build

As well as installing and configuring your image, you might also wish to verify that certain components that are critical, and that you assume to be present, are actually present. This is especially true when you download an image that was created by someone else.

There are many ways to perform this task in Ansible—let's take a simple example. Suppose you have an archival script that makes use of the bzip2 compression utility to compress files. This is just a small tool but if you rely on it for certain purposes, your scripts would break if it was not present. It is also a pertinent example, as the minimal install of CentOS 7 (as we performed earlier) does not actually include it!

How can Ansible solve this problem? There are two approaches we can take. First of all, we know from our earlier background work on Ansible that most modules are idempotentthat is, they are designed to achieve a desired state on the target host and not repeat actions that have already been performed.

Hence, we could have very easily included a role such as this in our configuration playbook:

---
- name: Ensure bzip2 is installed
yum:
name: bzip2
state: present

When this role is run and bzip2 is not installed, it will perform the installation and return the result changed. When it detects that bzip2 is installed, it will return ok and perform no further actions. However, what if we truly want to check for something rather than just perform an action, perhaps as a post-build step? Later in this book, we'll look at more detailed ways of auditing systems, but for now, let's further this example with Ansible.

If you were using shell commands, you would check for the presence of bzip2 in one of two ways, that is, query the RPM database to see whether the bzip2 package is installed or check for the presence of /bin/bzip2 on the filesystem.

  1. Let's look at the latter example in Ansible. The Ansible stat module can be used to verify the existence of a file. Consider the following code, which we'll create in a role called checkbzip2 in the usual manner:
---
- name: Check for the existence of bzip2
stat:
path: /bin/bzip2
register: bzip2result
failed_when: bzip2result.stat.exists == false

- name: Display a message if bzip2 exists
debug:
msg: bzip2 installed.

Here, we are using the stat module to tell us about the /bin/bzip2 file (if it exists). We register the result of the module run in a variable called bzip2result, and then we define a custom failure condition on the task that will cause it to fail (and hence fail the entire the playbook run) if the file does not exist. Note that when a failure condition is encountered, Ansible halts the entire playbook run, forcing you to address the issue before continuing. Obviously, this may or may not be the behavior you desire, but it is easy to vary the failure condition accordingly.

  1. Let's take a look at this in action:

As you can see, the debug statement was never run because of the failure encountered. Hence, we can be absolutely sure when running this role that our image is going to have bzip2 installed—if it doesn't, our playbook will fail.

  1. Once bzip2 is installed, the run looks quite different:

This is quite definitive in its behavior, which is exactly what we would want. Ansible is not just limited to checking for files though—we could also check that our sshd_config file has the PermitRootLogin no line we looked at earlier:

  1. We could do this with a role as follows:
---
- name: Check root login setting in sshd_config
command: grep -e "^PermitRootLogin no" /etc/ssh/sshd_config
register: grepresult
failed_when: grepresult.rc != 0

- name: Display a message if root login is disabled
debug:
msg: root login disabled for SSH
  1. Now, running this when the setting is not in place again yields a failure:

  1. Yet if we put this setting in place, we see the following:

Again, it's very definitive. Note the changed status in the preceding output—this is so because we used the command module, which successfully ran commandhence, it always returns changed. We could alter this behavior with a changed_when clause to this task if we wanted.

In this manner, Ansible playbooks can be put together that not only customize your build but also validate the end result. This is especially useful for testing purposes, and where security is a consideration.

Before completing this chapter, let's take a look, in the next section, at how we pull together all of the disparate roles and pieces of code we have discussed so far to form a cohesive automated solution.

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

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