Transferring files into the image

It is commonplace, in the experience of the author, to need to inject files into an operating system image to ensure it meets a given set of requirements. These files might be a simple text file, such as an enterprise-standard message of the day, a configuration file for an existing package, or perhaps even a binary file that is not available in a package. Ansible can handle all of these with ease, so let's look at some specific examples. As it is generally good practice to write your Ansible code in roles to support reuse and readability, we will define a role for our example here. In this example, I am making the following assumptions:

  • We have downloaded/built our Linux template as outlined in the previous section of this chapter.
  • We are running this bare template in a virtual machine.
  • The IP address of this virtual machine is 192.168.81.141.
  • The virtual machine has a user account already set up with the following credentials:
    • Username: imagebuild.
    • Password: password.
    • This account is sudo-enabled.

Naturally, we would not distribute a cloud image with a sudo-enabled account that uses a weak password like this, so we are assuming we will use this account during the build phase only and then will remove it during the cleanup phase. Ansible needs to be able to connect to a remote host to perform its magic, but the account it uses can be transient in nature and removed after use:

  1. Under our example, we would create an inventory file that looks like this—yours will undoubtedly be different and customizing it for your image and environment is left as an exercise for you:
[imagesetup]
192.168.81.141

[imagesetup:vars]
ansible_user=imagebuild
ansible_password=password
ansible_sudo_pass=password

This is a very simple example; in many ways, it is the bare minimum needed for this process when we do not have SSH key authentication configured. Often SSH keys are the best way to handle SSH authentication as they offer several benefits, not least that tasks can run without a password prompt.

Although this inventory file is intended to be transient in nature, it is still best practice to use ansible-vault to store passwords and this is recommended here. For the sake of simplicity in this chapter and to reduce the number of steps that you need to complete, we will leave the passwords unencrypted (in cleartext).
  1. Next, we'll create the basic directory structure for our role:
$ mkdir -p roles/filecopyexample/tasks
$ mkdir -p roles/filecopyexample/files
  1. Now, let's create a few sample files to copy across. First of all, create a customized message to append to the message of the day in roles/filecopyexample/files/motd:
------------------------
Enteprise Linux Template
Created with Ansible
------------------------
  1. Let's also create a new configuration file for the chrony service to synchronize time to our corporate time servers in roles/filecopyexample/files/chrony.conf:
pool ntp.example.com iburst maxsources 4

keyfile /etc/chrony/chrony.keys

driftfile /var/lib/chrony/chrony.drift

logdir /var/log/chrony

maxupdateskew 100.0

rtcsync

makestep 1 3

We intend to copy these two files across to the remote server. However, Ansible is not limited to copying files from the Ansible host—it can also download files from a remote server directly to the target host:

  1. Let's suppose your build is going to need docker-composewe could download this from an internal server, or even directly from the internet if your image machine has access to the internet. Suppose we want to install docker-compose 1.18.0 into our images, we can instruct Ansible to download this directly from https://github.com/docker/compose/releases/download/1.18.0/docker-compose-Linux-x86_64.
  2. Now, let's build our role to copy across our two files and download docker-compose into our image—this must be written in roles/filecopyexample/tasks/main.yml. The first part of this role is shown in the following code, and serves to copy across the two configuration files we discussed earlier:
---
- name: Copy new MOTD file, and backup any existing file if it exists
copy:
src: files/motd
dest: /etc/motd
owner: root
group: root
mode: '0644'
backup: yes
- name: Copy across new chrony configuration, and backup any existing file if it exists
copy:
src: files/chrony.conf
dest: /etc/chrony.conf
owner: root
group: root
mode: '0644'
backup: yes

The role then continues, with the task of installing docker-compose on the VM image:

- name: Install docker-compose 1.18.0
get_url:
url: https://github.com/docker/compose/releases/download/1.18.0/docker-compose-Linux-x86_64
dest: /usr/local/bin/docker-compose
mode: 0755
owner: root
group: root

Hence, our role is now complete, though be sure to customize it correctly for your environment. For example, it is likely a newer version of docker-compose might be available and this will mean a change to the url parameter of the preceding get_url module.

The path of the chrony configuration file may vary depending on your operating systemcheck this before running the preceding playbook. The path shown in the example is suitable for a CentOS 7 system like the one we built earlier.
  1. Finally, we will create a file in the top-level directory (where the roles/ directory was created) called site.yml to call and run this role. This should contain the following:
---
- name: Run example roles
hosts: all
become: yes

roles:
- filecopyexample
  1. Finally, let's run our example with the ansible-playbook -i hosts site.yml command and see what happens:

As we can see, the changed statuses tell us that all three of our files were transferred or downloaded successfully, and by way of example, we can see that it is now possible to run docker-compose, which was installed during the playbook run (though this would require Docker to run correctly, which we have not installed as part of this example).

Obviously this example has made a fundamental assumptionthat the chrony package was installed on our example image during the build phase. Although it makes sense to start with a minimal operating system image for the reasons we have discussed previously, there is almost certainly going to be a requirement to install a few supplemental packages on the basic build, and we will explore this in the next section.

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

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