You can share AWS AMIs across multiple accounts in two ways: publicly and privately.

  • Public Sharing: If you’ve created a community AMI that you want to make available to everyone, you can set its visibility to public. This allows anyone to access and use the AMI.

  • Private Sharing: For AMIs containing sensitive or confidential information (such as organization-specific), it’s important to share them privately. This ensures that only authorized AWS accounts can access the AMI.

This page will explain how you can securely share your AMI privately across AWS accounts, along with an automated solution built using Python.

To skip the details and go straight to the automation workflow, jump ahead to the section below.

If your AMI’s snapshot is unencrypted, you can simply share the AMI, and the destination account can access and use it. However, this approach may not be the most secure.

Additionally, many organizations have encryption enabled by default for EBS volumes and snapshots to ensure data security.

If the AMI’s snapshot is encrypted using the default AWS key (aws/ebs), you cannot share it. This is because the default key cannot be shared across accounts.

To share an AMI securely, it must be encrypted using a custom KMS key. Additionally, the destination account must have the necessary permissions to access the custom KMS key in order to use the shared AMI.

Create a Custom KMS Key

Create a custom KMS key and allow the destination account to access it. The JSON policy would look something like this:

{
   "Sid": "Allow external account 111122223333 use of the customer managed key",
   "Effect": "Allow",
   "Principal": {
       "AWS": [
           "arn:aws:iam::111122223333:root"
       ]
   },
   "Action": [
       "kms:Encrypt",
       "kms:Decrypt",
       "kms:ReEncrypt*",
       "kms:GenerateDataKey*",
       "kms:DescribeKey"
   ],
   "Resource": "*"
}

For more details, refer to the AWS documentation 🔗 .

Encrypt AMI Using Custom KMS Key

Once the KMS key is ready, copy the AMI within the same region using the newly created KMS key. You can copy the AMI to any other region where you want it to be available.

However, you cannot directly share an AMI from Region A in the source account to Region B in the destination account. The AMI will be shared only in the same region from where it was originally shared.

Share AMI

To share an AMI, select the AMI and add the destination account’s ID under AMI permissions (private share). You can add multiple AWS accounts, but ensure they all have access to the custom KMS key.

When the AMI is shared, the source account controls the sharing. If the source account deletes the shared AMI or removes the destination account’s permission, the AMI will no longer be available to the destination account, since the destination does not own it.

To own the AMI, launch an instance from the shared AMI in the destination account, then create a new AMI from that instance. This ensures the destination account becomes the owner of the new AMI.

Alternatively, a simpler option is to copy the shared AMI to your own account. By doing so, you become the owner of the AMI, and it will remain available even if the source account revokes access. However, the source account must grant read permissions for the snapshot storage in order for you to copy the AMI.

Workflow of the AMI Sharing Automation

Automation source code is available here 🔗 .

The script requires the proper permissions, role assumptions, and custom KMS key configurations for both the source and destination accounts.

Pre-requisites:

  • Required Access:

    Ensure that both the source and destination AWS accounts have the necessary permissions for the operations to be performed (role assumption, AMI copying, modifying permissions, etc.).

  • Custom KMS Key:

    The script uses a custom KMS key for encryption. You must have a KMS key with appropriate permissions to be used in the AMI copy process. The key’s alias should be set in the ebsKMSKeyForShareAMI variable.

  • Role Assumption:

    Create an IAM role named role/role_sts_cross_account in both the source and destination accounts, allowing the script to assume the role and perform the necessary operations (such as copying the AMI).

Step-by-Step Workflow:

  • In the script, you’ll need to define the AWS account IDs for both the source and destination accounts:

    accountConfig = {
        "AccountA": {"id": "123123123123"},
        "AccountB": {"id": "321321312321"},
    }
    

    Replace AccountA and AccountB with the actual names of your accounts, and update their corresponding AWS account IDs.

  • Set the value for the custom KMS key in the variable ebsKMSKeyForShareAMI. This key will be used for encrypting the copied AMI.

    ebsKMSKeyForShareAMI = "alias/your-custom-kms-key"
    
  • To run the script, pass the following parameters:

    python3.12 main.py -s AccountA -d AccountB -a ami-xxxid -e [email protected]
    -s is the source account name (e.g., AccountA).
    -d is the destination account name (e.g., AccountB).
    -a is the AMI ID to be copied (e.g., ami-xxxid).
    -e is the email address for receiving the notification (e.g., [email protected]).
    
  • The script first assumes the role in the source account (provided in the -s argument) using AWS STS. Ensure that the source account has the correct role role/role_sts_cross_account.

  • The script copies the AMI within the same region (us-east-1 by default). The copied AMI is encrypted using the custom KMS key specified in ebsKMSKeyForShareAMI.

  • The script waits and checks the status of the copied AMI every 10 seconds. Once the AMI’s state is available, the script proceeds to share the AMI.

  • The AMI is shared with the destination account by modifying its permissions. It grants the destination account read permissions for the AMI and its associated snapshots.

  • After sharing the AMI, the script assumes the role in the destination account (provided in the -d argument).

  • The script then copies the shared AMI into the destination account. This ensures the destination account becomes the owner of the AMI.

  • Similar to the earlier step, the script checks the status of the AMI in the destination account every 10 seconds. Once the AMI’s state is available, the script proceeds to clean up.

  • Once the AMI is copied successfully in the destination account, the script deletes the shared AMI and its associated snapshots from the source account.

  • Finally, the script sends an email notification via AWS SES to the provided recipient. The email includes details about the operation, such as:

    • Source Account and Source AMI ID
    • Destination Account and Destination AMI ID
    • KMS Key used for encryption

Key Considerations:

Region Limitation:

Currently, the script only works in the us-east-1 region. If you need it to work in other regions, you can modify the script to support that.

Permissions:

Ensure that both the source and destination accounts have the necessary permissions for the script to perform actions such as assuming roles, modifying AMI permissions, copying AMIs, and deleting snapshots.

Custom KMS Key:

The destination account must have access to the custom KMS key used for encryption. Make sure the key’s policy grants the necessary permissions to the destination account.

Thank you for reading,

-Alon