Starting with a base AMI

by Sebastien Mirolo on Wed, 19 May 2021

Before you start any DevOps workflow, you will need to pick an OS distribution (and image) to base the servers on.

CentOS was a good choice for many years

  • it was tested and stable
  • Security was well managed
  • it could be deployed on virtual machines on a developper laptop as well as at a Cloud provider.
  • Many paying software are compatible with CentOS and packaged as .rpm

Unfortunately the acquisition of RedHat by IBM in 2019 whrecked havoc on CentOS land, sending many organizations scrambling to adjust their infrastructure roadmaps.

Amazon Linux 2 is largely based on Redhat. As far as I can tell there are no ISO disk you could install on a local laptop but it will do for now.

Finding the latest Amazon Linux 2 AMI

First we need to find the ID of the latest Amazon Linux 2 AMI available.

Terminal
$ aws ec2 describe-images \
    --owners amazon \
    --filters "Name=name,Values=amzn2-ami-hvm-2.0.????????.?-x86_64-gp2" "Name=state,Values=available" \
    --query "reverse(sort_by(Images, &CreationDate))[:1]"
[
    {
        "CreationDate": "2021-04-29T10:13:59.000Z",
        "ImageId": "ami-0cf6f5c8a62fa5da6",
        "Description": "Amazon Linux 2 AMI 2.0.20210427.0 x86_64 HVM gp2",
        ...
    }
]

Starting an EC2 instance

We start an EC2 instance using the AMI we previously identified.

Terminal
$ aws ec2 run-instances --instance-type t3.small --key-name *keyname* \
    --image-id ami-0cf6f5c8a62fa5da6

Enabling SELinux

Surprisingly enough, SELinux has been disabled by default. It is creating some trouble as now we need to enable SELinux on the instance. Unfortunately most of the guides seem rather old. Amazon Linux 2 comes with Grub2.

Terminal
$ diff /etc/selinux/config
-SELINUX=disabled
+SELINUX=enforcing

$ diff /etc/default/grub
-GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 nvme_core.io_timeout=4294967295 rd.emergency=poweroff rd.shell=0"
+GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 nvme_core.io_timeout=4294967295 rd.emergency=poweroff rd.shell=0 selinux=1 security=selinux"

With the changes required in hand, we can run the following commands to mechanically do the updates.

Terminal
$ sudo yum install selinux-policy selinux-policy-targeted policycoreutils-python
$ sudo sed -i 's/SELINUX=\(\w\w*\)/SELINUX=enforcing/g' /etc/selinux/config
$ sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="\(.*\)"/GRUB_CMDLINE_LINUX_DEFAULT="\1 selinux=1 security=selinux"/' /etc/default/grub
$ sudo /usr/sbin/grub2-mkconfig -o /boot/grub2/grub.cfg
$ sudo touch /.autorelabel
$ sudo reboot

We wait for the instance to reboot, reconnect to it and check SELinux is enforcing.

Terminal
$ getenforce
Enforcing

Creating an AMI

Since enabling SELinux requires to reboot the machine, we will create a new base image to start the deployment scripts from.

Terminal
$ aws ec2 stop-instances --instance-id i-*****
$ aws ec2 create-image --instance-id i-***** --name AmazonLinux2SELinuxBase
{
    "ImageId": "ami-*****"
}

More to read

If you are looking for more AWS related posts, you might be interested to read PostgreSQL, encrypted EBS volume and Key Management Service or Resizing an EBS disk.

More technical posts are also available on the DjaoDjin blog, as well as business lessons we learned running a SaaS application hosting platform.

by Sebastien Mirolo on Wed, 19 May 2021


Receive news about DjaoDjin in your inbox.

Bring fully-featured SaaS products to production faster.

Follow us on