Dockerizing an Ansible Playbook, Part 1
In Part 1 of this two-part series, we will go over the concept of Dockerization. And then, Dockerize an Ansible playbook to run in a Docker container.
Join the DZone community and get the full member experience.
Join For FreeThis is a two-part article series. This is Part 1 of the series, where we will go over the concept of Dockerization. And then, Dockerize an Ansible playbook to run in a Docker container.
In Part 2, we will create a GitLab pipeline to register the Docker image of the Ansible playbook to a Docker registry and deploy it to Kubernetes.
Why Dockerizing?
With the continuously increasing complexity of the business problem domain, building a solution needs a whole lot of dependent libraries and tools with different versions while managing their interdependencies and cross-dependencies. The most challenging area is porting an application to a hosting environment where some of the dependent libraries and packages with specific versions are already installed as part of other applications hosted in the system. The developer now has to deal with conflicting versions while building and running their application without impacting any existing ones.
With Dockerizing, you can pack your application with everything that you need and ship it as a package and run it in an isolated environment called a container. The good part is you have to do it once and run it anywhere consistently.
Some of the other key benefits are
- ROI - Docker dramatically reduces infrastructure costs as it is lightweight and needs only fewer resources to run the same application. It allows multiple applications to run in their own container, sharing the same underlying OS layer
- Developer experience
- Faster deployment as the developer needs to bundle only the libraries and tools that its application needs in a declarative manner. There is no time spent in setting up an infra. Once done, it can be reused again and again.
- Easier debugging as a developer can reproduce the environment easily anywhere with the same exact set of dependencies. This makes promoting to a higher environment, such as UAT and PROD, easy and more reliable
- Better security as less access is needed to work with the code running inside a container.
The key to Dockerization is the Docker engine which interacts with the underlying OS. There is an underlying hardware infrastructure and then the OS on top of it. And then Docker installed on OS. Docker manages libraries and dependencies to run the application.
Docker Engine is available on a variety of Linux platforms. It can also run on Windows 10 through a Docker desktop which creates a Linux virtual machine on top of Windows OS.
What is Ansible Playbook?
Ansible is an automation tool that automates provisioning, configuration management, application deployment, and orchestration of processes. Playbooks are YAML files that define configurations, deployment, and orchestration in Ansible and allow Ansible to perform operations on managed nodes.
Dockerize an Ansible Playbook and Run It in a Docker Container
In this tutorial, we will create a playbook that does the following
- It logs in to localhost and prints OS info. With Dockerizing a playbook, the Docker container will be the localhost
- It connects a remote host through passwordless login and prints OS info
Create an Ansible Playbook
For this tutorial, we will use Windows PowerShell to run all our commands.
Create a working directory named playbooks
and cd
to that directory.
mkdir playbooks
cd playbooks
Create a file named hello.yaml
and copy the below content to it.
- name: This is sample hello program
hosts: localhost
gather_facts: no
tasks:
- name: print os version of the container
shell : "uname -a"
register: osverlocal
- name: display os version
debug:
msg: "Hello loaclhost - {{ osverlocal.stdout }}"
- name: This is sample hello program on ansible server
hosts: common1
remote_user: user1
gather_facts: no
tasks:
- name: print os version of the remote host
shell : "hostname"
register: osverremote
- name: display os version
debug:
msg: "Hello common1 -{{ osverremote.stdout }}"
In this code snippet, we have two sections, one for each host machine: localhost
and remote host defined by the common1
variable. This will be defined in another file called Ansible Inventory File in the next step.
Ansible tasks will be executed on the localhost
using a logged-in user to the container and on the remote host by user1
. We will cover it later in this article.
Create an Inventory File
Create a file named inventory.txt and add the following entry there. Please ensure to replace <fully qualified hostname>
with the remote host machine's FQDN:
[common1]
<fully qualified hostname>
Generate Key Pair and Copy to the Target Machine
For passwordless SSH login to a remote host, we need to use private-public key pair.
On Windows PowerShell, run the following command and follow through prompts to generate a key pair ssh-keygen
.
ssh-keygen
ssh-keygen
This will generate id_rsa
and id_rsa.pub
under<user home directory>/.ssh
folder. id_rsa
file contains the private key, and id_rsa.pub
contains the public key.
- Create
.ssh
folder under /home/user1 if not exists. In this tutorial, I am using "user1" to connect to the remote host. You may use a different user (which must exist in the target machine). - Copy id_rsa.pub to /home/user1/.ssh folder in the target machine.
- Append the content of
id_rsa.pub
file toauthorized_keys
file located under /home/user1/.ssh in the target machine.
Install Docker on Your Local Workstation
Prerequisites
- Docker Desktop for Windows requires WSL2 (Windows System for Linux 2) to be enabled.
NOTE: This step will require a Windows reboot.
To enable WSL2, start the Windows PowerShell as an Administrator. You can do so by typing Windows PowerShell in the Cortona Search bar in the Taskbar, as shown below. Select Run as Administrator option among the three options shown in the pane in the right half. This will bring up the Windows PowerShell terminal window.
- At the Windows PowerShell Terminal prompt, type in the following command:
wsl — install
This single command will do all that is required to enable WSL and install Ubuntu Linux on your Windows laptop.
- Once the installation is done, you will be prompted to reboot.
- Upon reboot, the Ubuntu installation/configuration will continue.
- You will be prompted to set up an account. Type in a username of your choice (your name, for example). You will also be prompted to enter/re-enter the password. Please keep these two handy.
This completes the WSL Setup.
Install Docker Desktop for Windows
NOTE: Installation of Docker Desktop for Windows will require you to log off after the installation. So please save your work before you begin the installation.
Here are the steps for installing Docker Desktop for Windows
Download the Docker Desktop Installer from this web page.
- This will download the Docker Desktop Installer.exe file in the Downloads directory.
- Double Click on this file to begin the installation.
- Accept the defaults in the Dialog box that comes up next. On doing so, the installation will begin.
- Once the installation is completed, you will be prompted to sign out/log off.
- Once you log back in, Docker Desktop for Windows is ready to use.
Build and Run an Ansible Playbook in the Docker Container
Create a Docker File
Create a file named Dockerfile and paste the below content:
FROM python:3.10.8-slim-buster
ARG USERNAME="ansibleuser"
RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
apt-get install -y sshpass git openssh-client openssh-server sudo && \
rm -rf /var/lib/apt/lists/* && \
apt-get clean
RUN echo "root ALL=(ALL) ALL" >> /etc/sudoers
RUN echo "$USERNAME ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers
RUN useradd -ms /bin/bash $USERNAME
RUN mkdir /ansible
COPY ./requirements.txt /ansible/
COPY ./hello.yml /ansible/
COPY ./inventory.txt /ansible/
COPY ./id_rsa.pub /home/$USERNAME/.ssh/id_rsa.pub
RUN sudo /etc/init.d/ssh restart
RUN chown -R $USERNAME:$USERNAME /ansible
RUN chown $USERNAME:$USERNAME -R /home/$USERNAME/.ssh && \
chmod 700 -R /home/$USERNAME/.ssh && \
chmod 640 /home/$USERNAME/.ssh/id_rsa.pub
RUN ssh-keyscan <HOST-NAME> >> /home/$USERNAME/.ssh/known_hosts
RUN pip install -r /ansible/requirements.txt
USER $USERNAME
WORKDIR /ansible
ENTRYPOINT ["tail", "-f", "/ansible/hello.yml"]
me/$USERNAME/.ssh && \
chmod 640 /home/$USERNAME/.ssh/id_rsa.pub
RUN ssh-keyscan <HOST-NAME> >> /home/$USERNAME/.ssh/known_hosts
RUN pip install -r /ansible/requirements.txt
USER $USERNAME
WORKDIR /ansible
ENTRYPOINT ["tail", "-f", "/ansible/hello.yml"]
In this Docker file, we are listing out tools/libraries that are needed to be installed to build and run our Ansible playbook.
We are creating a user named "Ansibleuser" in the container. This user will be used to run Ansible tasks on the localhost machine.
The username defined in remote_user
will be used to log in to the remote host machine. In this tutorial, I am using user1 to log in to the remote host. Please make sure to use the same user that you have copies public key as part of the previous step.
Please replace <HOST_NAME>
in line#22 with the FQDN of the remote host. This will allow the client (in this case, the Docker container) to trust the remote host machine.
Create requirements.txt File
This file contains the libraries that will be installed as part of the pip command provided in the Dockerfile. These libraries are needed to run Ansible runner:
ansible==6.6.0
ansible_runner==2.3.0
Build a Docker Image
Start the Docker desktop that was installed.
This will start a demon process named Docker daemon (Dockerd). It listens to Docker API requests and manages Docker objects such as images, containers, networks, and volumes.
Now open the Windows PowerShell prompt and add “cd” to the playbooks folder (the folder location where you have created all the above files).
Run the following command:
docker build . -t hwa
This will build an image named hwa
. Verify that the image was created by running the below command.
docker image ls
The output will be something as below:
Create a Docker Container
Run the below command to create a container from the image named hwa
:
docker run -d hwa
It will print the container ID something as below:
Verify that the container is running by running the below command:
docker container ls
Please note this ID somewhere to refer to later.
Execute the Ansible Playbook in the Docker Container
Login to the container by running the below command. Please make sure to replace <container-id>
with your container id.
docker container exec -it <container-id> bash
This will let you log into the Docker container giving you a bash shell to interact with.
If you run the ls
command, then you will find all your Ansible-related files below:
Now run the Ansible playbook by running the below command:
ansible-playbook hello.yml -i inventory.txt
This will print the OS version of the Docker container and the remote host by passwordless SSH to the remote host.
Congratulations! You successfully Dockerized your Ansible playbook and executed the playbook in a container.
In Part 2, we will push this to the Docker registry and then deploy it to K8s.
Opinions expressed by DZone contributors are their own.
Comments