Packer: EBS encrypt on launch from unencrypted AMI

Created on 15 Sep 2019  ยท  7Comments  ยท  Source: hashicorp/packer

It's now (since early 2018) possible to launch an EC2 instance with an encrypted boot volume, even when the source AMI is unencrypted.

For example, if your source AMI is the public Ubuntu AMI, and you want to create your own as encrypted.

However, in this scenario, packer is still launching an instance with an unencrypted root volume, then creating an AMI, and then separately doing a copy AMI to the encrypted one.

This last copy step can take 5-10 minutes, and is now redundant given you can launch the instance already encrypted.

So, if I specify encrypt_boot, can packer launch the instance as encrypted?

Thanks!

buildeamazon enhancement question

Most helpful comment

I sat down to implement this and found that it's already part of the current implementation.

According to the Amazon docs, you tell Amazon whether to encrypt on launch using block device mappings. And luckily, we already allow you to configure the block device mappings however you want.

All you need to add to your config is:

            "launch_block_device_mappings": [{
                "device_name": "/dev/sda1",
                "encrypted": true
            }]

/dev/sda1 is the device name reserved for the root volume, so all we're saying here is to encrypt the root volume.

The above will encrypt using your default kms key, but you can also use a custom key by adding another field:

            "launch_block_device_mappings": [{
                "device_name": "/dev/sda1",
                "encrypted": true
                "kms_key_id": "1a2b3c4d-5e6f-1a2b-3c4d-5e6f1a2b3c4d"
            }]

Fully functional example (minus the bogus key):

{
    "builders": [
        {
            "ami_name": "packer-whee",
            "force_deregister": true,
            "instance_type": "t2.micro",
            "source_ami_filter": {
                    "filters": {
                        "virtualization-type": "hvm",
                        "name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*",
                        "root-device-type": "ebs"
                    },
                    "owners": ["099720109477"],
                    "most_recent": true
            },
            "ssh_username": "ubuntu",
            "type": "amazon-ebs",
            "launch_block_device_mappings": [{
                "device_name": "/dev/sda1",
                "encrypted": true,
                "kms_key_id": "1a2b3c4d-5e6f-1a2b-3c4d-5e6f1a2b3c4d"
            }]
        }
    ],
  "provisioners": [
    {
        "type": "shell",
        "inline": "echo heeeey"
    },
    {
        "type": "breakpoint"
    }
  ]
}

This isn't super well documented by us. I'm not seeing the kms_key_id portion documented on our page at all...it should be here, and a guide would probably be useful.

I'll leave this issue open until I fix up the docs.

All 7 comments

Id say more importantly than the time taken by the copy, is organizations with requirements for al volumes to be encrypted.

At our organization we cannot run any unencrypted volumes, even if they are only shortlived during a packer build.

I sat down to implement this and found that it's already part of the current implementation.

According to the Amazon docs, you tell Amazon whether to encrypt on launch using block device mappings. And luckily, we already allow you to configure the block device mappings however you want.

All you need to add to your config is:

            "launch_block_device_mappings": [{
                "device_name": "/dev/sda1",
                "encrypted": true
            }]

/dev/sda1 is the device name reserved for the root volume, so all we're saying here is to encrypt the root volume.

The above will encrypt using your default kms key, but you can also use a custom key by adding another field:

            "launch_block_device_mappings": [{
                "device_name": "/dev/sda1",
                "encrypted": true
                "kms_key_id": "1a2b3c4d-5e6f-1a2b-3c4d-5e6f1a2b3c4d"
            }]

Fully functional example (minus the bogus key):

{
    "builders": [
        {
            "ami_name": "packer-whee",
            "force_deregister": true,
            "instance_type": "t2.micro",
            "source_ami_filter": {
                    "filters": {
                        "virtualization-type": "hvm",
                        "name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*",
                        "root-device-type": "ebs"
                    },
                    "owners": ["099720109477"],
                    "most_recent": true
            },
            "ssh_username": "ubuntu",
            "type": "amazon-ebs",
            "launch_block_device_mappings": [{
                "device_name": "/dev/sda1",
                "encrypted": true,
                "kms_key_id": "1a2b3c4d-5e6f-1a2b-3c4d-5e6f1a2b3c4d"
            }]
        }
    ],
  "provisioners": [
    {
        "type": "shell",
        "inline": "echo heeeey"
    },
    {
        "type": "breakpoint"
    }
  ]
}

This isn't super well documented by us. I'm not seeing the kms_key_id portion documented on our page at all...it should be here, and a guide would probably be useful.

I'll leave this issue open until I fix up the docs.

oh interesting, I did not know that any field could be passed into block device mappings. I actually had a thought of maybe this was possible, but I couldnt easily find the object the api accepted so i never took a shot at putting the options in. Thank you for adding this to docs!

Yeah, I just checked and our config's block device mapping object provides all the fields you can configure in the EbsBlockDevice object and the BlockDeviceMapping object in the AWS api.

@SwampDragons Thanks for looking into this! I gave this a try, and although this results in having an encrypted source instance, it still does a completely unnecessary copy AMI at the end.

I had to take out the 'encrypt_boot' true setting as well, which is a bit counter intuitive. Perhaps packer could do a check that if the bake instance has the exact same key as the destination, to skip the copy step? Or is the encrypt_boot setting ready to be deprecated, as people should simply use the block configurations?

This saves a solid 5 mins in my AMI build job.. thanks!

We can update the docs for encrypt_boot to explain that this will copy your ami and encrypt it with the given key, and that if you want to have the disk encrypted the same as it already is then you don't need to set it.

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mwhooker picture mwhooker  ยท  3Comments

mushon4 picture mushon4  ยท  3Comments

s4mur4i picture s4mur4i  ยท  3Comments

shantanugadgil picture shantanugadgil  ยท  3Comments

sourav82 picture sourav82  ยท  3Comments