Copying AMIs between accounts is difficult, because even if an image is public, the snapshot behind it is private by default. Here we’ll talk about ways of getting around it.
The easy way is to start an instance with the desired image, then create a new image from the instance. We can then copy to another region if we want to.
A more involved approach is to copy the snapshot(s) to our account and then register the image. This does require knowing who the owner of the image is in order for them to share the snapshots with us.
Discovery
We’ll need to describe the image we want to copy to find the snapshot(s) that will need to be shared.
Example API Request
1
2
3
4 https://ec2.us-east-1.amazonaws.com
?Action=DescribeImages
&ImageId.1=ami-12345678
&*AUTHPARAMS*
Console - user@hostname ~ $
1
2
3 aws --region us-east-1 ec2 \
describe-images \
--image-ids "[ \" ami-12345678 \" ]"
Output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 {
"Images" : [
{
"VirtualizationType" : "paravirtual" ,
"Name" : "Example_Image" ,
"Hypervisor" : "xen" ,
"ImageId" : "ami-12345678" ,
"RootDeviceType" : "ebs" ,
"State" : "available" ,
"BlockDeviceMappings" : [
{
"DeviceName" : "/dev/sda" ,
"Ebs" : {
"DeleteOnTermination" : true ,
"SnapshotId" : "snap-23456789" ,
"VolumeSize" : 10 ,
"VolumeType" : "standard" ,
"Encrypted" : false
}
},
{
"DeviceName" : "/dev/sdb" ,
"VirtualName" : "ephemeral0"
},
{
"DeviceName" : "/dev/sdc" ,
"VirtualName" : "ephemeral1"
},
{
"DeviceName" : "/dev/sdd" ,
"VirtualName" : "ephemeral2"
},
{
"DeviceName" : "/dev/sde" ,
"VirtualName" : "ephemeral3"
}
],
"Architecture" : "x86_64" ,
"ImageLocation" : "234567890123/Example_Image" ,
"KernelId" : "aki-b4aa75dd" ,
"OwnerId" : "234567890123" ,
"RootDeviceName" : "/dev/sda" ,
"Public" : true ,
"ImageType" : "machine" ,
"Description" : "Example Description"
}
]
}
Note all the snapshots in BlockDeviceMappings
, just snap-23456789
in this case.
Sharing
Looking at OwnerId
of the image description, we’ll get account 234567890123 to share with us (account 123456789012).
With User
You can have the other account share it with specified users.
Example API Request
1
2
3
4
5 https://ec2.us-east-1.amazonaws.com
?Action=ModifySnapshotAttribute
&SnapshotId=snap-23456789
&CreateVolumePermission.Add.1.UserId=123456789012
&*AUTHPARAMS*
Console - user@hostname ~ $
1
2
3
4
5
6
7
8
9
10 aws --profile "account2" --region us-east-1 ec2 \
modify-snapshot-attribute \
--snapshot-id "snap-23456789" \
--create-volume-permission "{
\" Add \" : [
{
\" UserId \" : \" 123456789012 \"
}
]
}"
With Public
Or the other account can just make the snapshot(s) public.
Example API Request
1
2
3
4
5 https://ec2.us-east-1.amazonaws.com
?Action=ModifySnapshotAttribute
&SnapshotId=snap-23456789
&CreateVolumePermission.Add.1.Group=all
&*AUTHPARAMS*
Console - user@hostname ~ $
1
2
3
4
5
6
7
8
9
10 aws --profile "account2" --region us-east-1 ec2 \
modify-snapshot-attribute \
--snapshot-id "snap-23456789" \
--create-volume-permission "{
\" Add \" : [
{
\" Group \" : \" all \"
}
]
}"
Copy Snapshot
Now we copy the snapshot(s).
Example API Request
1
2
3
4
5
6
7 https://ec2.us-east-1.amazonaws.com
?Action=CopySnapshot
&SourceRegion=us-east-1
&SourceSnapshotId=snap-23456789
&DestinationRegion=us-east-1
&Description=Example&20Description
&*AUTHPARAMS*
Console - user@hostname ~ $
1
2
3
4
5
6 aws --region us-east-1 ec2 \
copy-snapshot \
--source-region "us-east-1" \
--source-snapshot-id "snap-23456789" \
--destination-region "us-east-1" \
--description "Example Description"
Output
1
2
3 {
"SnapshotId" : "snap-abcdef01"
}
Register Image
And register the image once the snapshot(s) are copied.
Example API Request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 https://ec2.us-east-1.amazonaws.com/
?Action=RegisterImage
&Name=Example_Image_Name
&Description=Example%20Image%20Description
&Architecture=x86_64
&KernelId=aki-b4aa75dd
&RootDeviceName=/dev/sda
&BlockDeviceMapping.1.DeviceName=/dev/sda1
&BlockDeviceMapping.1.SnapshotId=snap-abcdef01
&BlockDeviceMapping.2.DeviceName=/dev/sdb
&BlockDeviceMapping.2.VirtualName=ephemeral0
&BlockDeviceMapping.3.DeviceName=/dev/sdc
&BlockDeviceMapping.3.VirtualName=ephemeral1
&BlockDeviceMapping.4.DeviceName=/dev/sdd
&BlockDeviceMapping.4.VirtualName=ephemeral2
&BlockDeviceMapping.5.DeviceName=/dev/sde
&BlockDeviceMapping.5.VirtualName=ephemeral3
&*AUTHPARAMS*
Console - user@hostname ~ $
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 aws --region= us-east-1 ec2 \
register-image \
--name "Example_Image_Name" \
--description "Example Image Description" \
--architecture x86_64 \
--kernel-id aki-b4aa75dd \
--root-device-name "/dev/sda" \
--block-device-mappings "[
{
\" DeviceName \" : \" /dev/sda1 \" ,
\" Ebs \" : {
\" SnapshotId \" : \" snap-abcdef01 \"
}
},
{
\" DeviceName \" : \" /dev/sdb \" ,
\" VirtualName \" : \" ephemeral0 \"
},
{
\" DeviceName \" : \" /dev/sdc \" ,
\" VirtualName \" : \" ephemeral1 \"
},
{
\" DeviceName \" : \" /dev/sdd \" ,
\" VirtualName \" : \" ephemeral2 \"
},
{
\" DeviceName \" : \" /dev/sde \" ,
\" VirtualName \" : \" ephemeral3 \"
}
]"
Output
1
2
3 {
"ImageId" : "ami-a1b2c3d4"
}
Turn Off Sharing
With User
If the other account wants to revoke permission for a single user:
Example API Request
1
2
3
4
5 https://ec2.us-east-1.amazonaws.com
?Action=ModifySnapshotAttribute
&SnapshotId=snap-23456789
&CreateVolumePermission.Remove.1.UserId=123456789012
&*AUTHPARAMS*
Console - user@hostname ~ $
1
2
3
4
5
6
7
8
9
10 aws --profile "account2" --region us-east-1 ec2 \
modify-snapshot-attribute \
--snapshot-id "snap-23456789" \
--create-volume-permission "{
\" Remove \" : [
{
\" UserId \" : \" 123456789012 \"
}
]
}"
With Public
If the snapshot(s) were public and the other account now desires to have them be private again:
Example API Request
1
2
3
4
5 https://ec2.us-east-1.amazonaws.com
?Action=ModifySnapshotAttribute
&SnapshotId=snap-23456789
&CreateVolumePermission.Remove.1.Group=all
&*AUTHPARAMS*
Console - user@hostname ~ $
1
2
3
4
5
6
7
8
9
10 aws --profile "account2" --region us-east-1 ec2 \
modify-snapshot-attribute \
--snapshot-id "snap-23456789" \
--create-volume-permission "{
\" Remove \" : [
{
\" Group \" : \" all \"
}
]
}"