In my years at Compoze Labs, I’ve worked on numerous AWS based projects, in a number of highly regulated industries, throughout the years. Whether they fall under PCI, HIPAA, or FISMA, one of the first things we as engineers have had to do is ensure that all data in our systems is encrypted at rest. What does that mean in the AWS world? Ultimately it starts with encrypting all EBS volumes, including the root device attached to EC2 instances.
The way to ensure that all instances start (launch) encrypted by default, is to create an AMI with an encrypted root device. Any EC2 instance, or service requiring an EC2 instance (like EMR), should be created using these AMIs.
My teams over the years have solved this a number of ways, by following the same basic steps.
In order to accomplish this we’ve used a number of approaches including Terraform and even just the AWS console. However, there were problems with these solutions. The AWS console approach is manual and therefore not repeatable while Terraform does not officially support encrypted volume AMIs and requires a workaround.
The approach I’ve found to be the most scalable, repeatable, and maintainable is via Packer, by HashiCorp.
How it works
Packer works by ingesting a configuration file you provide and popping out a machine image with an operating system and various other softwares installed on it. This machine image can then be used as the blueprint to create virtual machines. Packer supports a multitude of image formats, including AWS AMIs.
Hashicorp also supports a docker container for running commands, which I find to be quite convenient for playing around with Packer for the first time. I recommend giving that a try!
Defining the configuration
Packer uses JSON to define its configuration. Let’s take a look at a sample Packer configuration to create a simple Ubuntu AMI
This barebones example is pretty straight forward. You just need to specify the machine type (in this case amazon-ebs) and various metadata like name, description, etc. The other interesting bit to pay attention to is source_ami_filter. This section of the template describes how Packer should find the AMI to use as our base image. In this case it will grab the most recent (most_recent: true) version of the ubuntu-xenial-16.04-amd64-server image. It is worth noting that the seemingly magical number, 099720109477, is the AWS marketplace owner id for Canonical, the group that supports Ubuntu.
Additionally, Packer will need the correct IAM permissions in order to create the AMI. Here is an example policy with the minimum IAM permissions required:
Further details on how you can grant Packer the appropriate permissions can be found here.
Encrypting Root Device
We could use the example template to generate an AMI, but the root volume for any EC2 instance using the AMI would be unencrypted; so how do we extend it to encrypt the root device? We just need to add the following JSON key-value pair:
And here is what out example looks like now:
That’s it! After adding our encrypted flag we can run the Packer build command:
packer build encrypted_ami.json
If our AWS credentials are setup correctly, we should see something similar to the following in the terminal:
Additional Volume Encryption
Encrypting additional volumes is just as easy. Here is an example snippet for specifying an encrypted EBS volume as part of the AMI:
Encryption is an important part of keeping our systems secure in order to protect user data. Cloud providers like AWS give us the tools to build secure systems; while tools like HashiCorp’s Packer work to give us the ability to harness these tools more easily.
Where to go next?
Packer is designed to create an easy workflow for creating machine images. As part of that workflow I encourage you to check out how to introduce testing into that process with tools like Chef’s InSpec. I’ve written a bit on InSpec already as well!
A complete working example of the code snippets from article can be found in this github repository
To chat about your project, shoot us an email at email@example.com. We look forward to hearing from you and talking encryption!
GET IN TOUCH
Speak to a Compoze Labs expert
Compoze Labs Offices
1313 Chestnut Ave., Suite 200, Minneapolis, MN 55403
323 E Wacker Dr.
Chicago, IL 60601
Copyright© Compoze Labs LLC 2021 All Rights Reserved