in molecule ansible docker amazonlinux ec2 aws ~ read.

Amazon Linux container on molecule

At Claranet, our clients come with their own requirements, even on clouds like AWS. And, due to my previous experience at The Food Assembly I now have the habit to test my code, always. It includes Ansible with its testing framework called Molecule.

For one client, I had to deliver a complete playbook with several roles covering a quite complex setup. It included several systemd services and had to be run on Amazon Linux EC2 instances.

As this distro is loosely based on redhat, afaik, I began to test on CentOS containers with systemd enabled. It was working but I wasn't quite confident as it wasn't the very same OS as Amazon Linux.

Luckily, AWS provides Docker images for this distro. I could then use them and be more confident in my code at one exception: systemd.

Out of box, these images don't include systemd binaries. Moreover, they follow the release cycle of their VM counterpart by being updated regularly. As my client let the updater run on their EC2 instances, I couldn't build a derivate image with systemd.

Fortunately, Molecule helped me achieve having a "rolling" systemd image for tests. Version 2.0 of molecule changed its inner settings and exposed one interesting file : molecule/default/Dockerfile.j2. As its name implies, this file is used by molecule in the create part to build a usable image for testing by inheriting from provided one, in my case amazonlinux:latest and, by modifying this file, I could install systemd on it.

Here is the content of the file:

# Molecule managed

{% if item.registry is defined %}
FROM {{ item.registry.url }}/{{ item.image }}
{% else %}
FROM {{ item.image }}
{% endif %}

{% if item.env is defined %}
{% for var, value in item.env.items() %}
{% if value %}
ENV {{ var }} {{ value }}
{% endif %}
{% endfor %}
{% endif %}

RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates iproute2 && apt-get clean; \
    elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash iproute && dnf clean all; \
    elif [ $(command -v yum) ]; then yum makecache fast && yum install -y **systemd** python sudo yum-plugin-ovl bash iproute && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
    elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \
    elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \
    elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; fi

Then, I had to make sure my container was correctly started using systemd by editing the platform section of file molecule/default/molecule.yml:

platforms:
  - name: amazonlinux-2018
    image: amazonlinux:latest
    command: /usr/lib/systemd/systemd
    tmpfs:
      - /run
      - /tmp
    volumes:
      - /sys/fs/cgroup:/sys/fs/cgroup:ro

And voilà I have a fully usable Amazon Linux docker image with systemd enabled.