Overcome AWS Copy AMI boundaries – share encrypted AMIs with Packer – follow up

By Nikolay Bunev, Cloud Consultant at HeleCloud


Back in March, we wrote a detailed explanation on how to overcome AWS Copy AMI boundaries by utilizing Hashicorp’s Packer. The solution outlined is still valid and working great – if you have it implemented, there is no need to revise it.

However, back in May AWS have changed their APIs and now it’s possible to actually share an encrypted AMI with another account without copying and re-encrypting the AMI. They also wrote a nice blog-post on their own to accompany the availability of a single step sharing, which is worth reading if you are going to use the AWS Console to AWS CLI to achieve that goal. But if you are a fan of automation as we at HeleCloud are, in the next lines we will explain how to update the solution from our previous post in order to achieve the same.

The Prerequisites

Before we do so, let’s get back to the AWS announcement and see what the requirements are for sharing AMIs encrypted with customer-managed KMS keys (CMKs) with another account. In essence, you need:

  • To grant explicit launch permissions to the respective account number on the receiving account (the IAM role used by code build should have ModifyImageAttribute)

To grant access to the receiving account in the CMKs resource policy with which you have encrypted the AMI (example policy below)

"Sid": "Allow use of the ami key",
"Effect": "Allow",
"Principal": {
"AWS": [
"Action": [
"Resource": [

The Solution

The new functionality simplifies the encrypted AMI sharing process and we can now:

  • remove the “Distribute AMI” stage from our previous CI/CD and replace it with a simple sharing
  • have a single packer build instead of a two-phase build (one un-encrypted plus one encrypted).

The new simplified diagram looks like:

The Code

Let’s see what we need to change in the code in order to use the new sharing option.

  • ami_regions (array of strings) – A list of regions to copy the AMI to. Tags and attributes are copied along with the AMI. AMI copying takes time depending on the size of the AMI, but will generally take many minutes.
  • ami_users (string) – A list of account IDs that have access to launch the resulting AMI(s). By default, no additional users other than the user creating the AMI has permissions to launch it.

To sum it up, we still utilize the ami_regions EBS Packer Builder configuration option, but we need to add the ami_users as well, in order to share the image with the accounts with which we want to do so.
As pointed out before, most of the configuration options are dynamically inherited in Packer as input variables from CodeBuild:
"variables": {
"keep_input_artifact": "true",
"vpc": "{{env `vpc_id`}}",
"subnet": "{{env `subnet_id`}}",
"aws_region": "{{env `AWS_REGION`}}",
"os_type": "{{env `os_type`}}",
"app_type": "{{env `app_type`}}",
"ami_name": "{{env `ami_name`}}",
"kms_key": "{{env `kms_key`}}",
"ami_id": "{{env `ami_id`}}",
"account_ids": "{{env `account_ids`}}"
"builders": [{
"type": "amazon-ebs",
"region": "{{user `aws_region`}}",
"source_ami": "{{user `ami_id`}}",
"ami_block_device_mappings": [
"delete_on_termination": "true",
"device_name": "/dev/sda1"
"instance_type": "t2.medium",
"user_data_file": "windows/bootstrap_win.txt",
"communicator": "winrm",
"winrm_username": "administrator",
"ami_name": "{{user `ami_name`}}",
"encrypt_boot": "true",
"kms_key_id": "{{user `kms_key`}}",
"ami_users": {{ "user `account_ids`" }},
"ami_regions": [ "eu-west-1", "eu-west-2" ],
"region_kms_key_ids": {
"eu-west-1": "KMS_KEY_IN_EU_WEST_1",
"eu-west-2": "KMS_KEY_IN_EU_WEST_2",
"tags": {
"Name": "{{user `ami_name`}}",
"ami_base_id": "{{.SourceAMI}}",
"ami_base_name": "{{.SourceAMIName}}",
"ami_description": "{{user `os_type`}} {{user `app_type`}}",
"associate_public_ip_address": "false",
"vpc_id": "{{user `vpc`}}",
"subnet_id": "{{user `subnet`}}"


The encrypted AMI built in the originating account will be shared with all accounts listed as input to the ami_users and the AMI will be visible under “Private Images” in each region supplied to ami_regions, with one caveat (any tags that you may have on the originating AMI are not available, however, the AMI Name is still present, as visible on the screenshot below)


Final Thoughts

As already pointed out, our old solution is still a valid approach, especially if you want to have a separate AMI copy in each account encrypted with its own key. However, managing all those copies in different regions and accounts, even automated could become cumbersome.
This revised option will allow you to keep a single copy in the originating account while you are still able to use encrypted AMIs across your AWS account estate.
Please get in touch if we can help with AWS solution designs or any other aspect of the AWS platform.