Right, so you’ve built the perfect EC2 instance. It’s a pristine snowflake of configuration, a work of art with all your apps, dependencies, and security settings dialed in. You’ve turned it into an AMI. Now you need to get this digital masterpiece over to your buddy’s AWS account, or maybe to a separate production account. This is where things get… interesting. AWS gives you the tools, but it also gives you enough rope to accidentally build a very secure, very inaccessible gibberish machine if you’re not careful. Let’s do this right.

Sharing an AMI isn’t like emailing a PDF. You’re not sending a file; you’re granting permission for another AWS account to see and launch a copy of a snapshot that already exists in your account. This is a crucial distinction. The AMI itself is just metadata—a recipe that points to one or more EBS snapshots (the actual data) and a kernel ID. When you share, you’re sharing access to that recipe and the underlying ingredients.

The Basic Incantation: modify-image-attribute

The primary tool for this job is the modify-image-attribute CLI command. The web console has a nice “Share” button, but we’re command-line wizards here, and you need to know how to script this. The command is straightforward, but it has a classic AWS CLI quirk: it expects a JSON file for the --attribute parameter. Because of course it does.

First, find the AMI ID you want to share. Let’s say it’s ami-1234567890abcdef0. You want to share it with account 111122223333.

Create a simple JSON file, let’s call it share_ami.json:

{
  "OperationType": "add",
  "UserIds": ["111122223333"]
}

Now, run the magic spell:

aws ec2 modify-image-attribute \
    --image-id ami-1234567890abcdef0 \
    --attribute launchPermission \
    --cli-input-json file://share_ami.json

Poof. Account 111122223333 can now see this AMI in their console when they filter by “Private images” and can launch instances from it. But wait, did you hear that? That was the sound of a potential pitfall. You’ve only shared the AMI metadata. If your AMI is backed by EBS volumes (which it almost certainly is), you must also share every single underlying snapshot. Forgetting this step is the number one reason for the dreaded “you are not authorized to use this image” error on the other side.

Sharing the Underlying Snapshots

This is the part everyone forgets until they get the angry text from their colleague. You have to do this separately for each snapshot. Find the snapshot IDs associated with your AMI. You can describe the AMI to get them:

aws ec2 describe-images --image-ids ami-1234567890abcdef0 --query "Images[].BlockDeviceMappings[].Ebs.SnapshotId" --output text

Let’s say it returns snap-aaaabbbbccccdddd. Now, share that snapshot using its own similar, but frustratingly different, command. This one uses --user-ids directly instead of a JSON file. Consistency is overrated, apparently.

aws ec2 modify-snapshot-attribute \
    --snapshot-id snap-aaaabbbbccccdddd \
    --attribute createVolumePermission \
    --operation-type add \
    --user-ids 111122223333

Now the target account can truly use the AMI. They’ll find it in their EC2 Console under Images > AMIs, and they can launch it just like any other. The first launch will take a bit longer as it creates a copy of the volume(s) in their account—your original snapshots stay safe and sound in yours.

The “Why”: It’s All About Permissions

Why this two-step process? Because AWS treats these as separate resources with separate permission systems. An AMI is an EC2 service resource. A snapshot is an EBS service resource. The EC2 service needs to check if you’re allowed to use the AMI, and then the underlying EBS calls need to check if you’re allowed to access the snapshot data to create a volume from it. If either check fails, the whole operation fails. This design, while annoying, is actually quite logical from a security perspective. It gives you granular control. You could, for instance, share a snapshot with a data scientist for analysis without giving them the full AMI launch permissions.

Best Practices and Gotchas

  1. Cross-Region is a Different Beast: This whole process only works within the same AWS region. To get an AMI to another region, you must copy it there first (aws ec2 copy-image), which creates a completely new AMI and set of snapshots in the destination region, and then share it from there. This costs money for snapshot storage and data transfer.

  2. Public AMIs are Forever: There’s a --user-ids all option to make an AMI public. Think twice, then think again. Once an AMI is public, you cannot make it private again. You can only deregister it. Any copies of the snapshots made by others are out of your control. This is AWS’s way of preventing you from pulling the rug out from under anyone who came to rely on your public image.

  3. Clean Up Permissions: To remove access, simply run the same modify-image-attribute and modify-snapshot-attribute commands but use "OperationType": "remove". Always clean up what you don’t need.

  4. Encryption Throws a Wrench: If your source snapshot is encrypted with a custom KMS key (not the default aws/ebs one), sharing gets more complex. The target account must also have permission to use the KMS key you used to encrypt the snapshot. This typically involves updating the key’s policy, which is a whole other can of security worms. Often, it’s easier to copy the AMI to the target account, which will re-encrypt it with a key they own, if you don’t need to maintain the original encryption.