HowTo: Create an EBS backed Amazon EC2 AMI
To create an EBS backed AMI, you need a volume snapshot and you need to register the image. You can use the command CreateImage which will do both steps for you, or you can do it yourself with the CreateSnapshot and RegisterImage commands.
If running this from the command line, you will need to install the AWS CLI or ec2-api-tools.
CreateImage
CreateImage is basically snapshotting an entire instance. CreateImage will create an AMI that is just like the instance that is being imaged: it will have the same Kernel ID; Ramdisk ID; mounted devices (and if those devices are EBS devices, they will be snapshot along with the boot device); behavior for deleting volumes on shutdown; behavior for instance initiated shutdown.
Example API Request
1
2
3
4
5
6
https://ec2.us-east-1.amazonaws.com/
?Action=CreateImage
&InstanceId=i-12345678
&Name=Example_Image_Name
&Description=Example%20Image%20Description
&*AUTHPARAMS*
Using AWS CLI:
Console - user@hostname ~ $
1
2
3
4
5
aws --region=us-east-1 ec2 \
create-image \
--instance-id "i-12345678" \
--name "Example_Image_Name" \
--description "Example Image Description"
Using ec2-api-tools:
Console - user@hostname ~ $
1
2
3
4
5
ec2-create-image \
--region us-east-1 \
i-12345678 \
--name "Example_Image_Name" \
--description "Example Image Description"
CreateSnapshot / RegisterImage
Normally with EBS backed instances you would run CreateImage as it will create the snapshot and register it in a single command. However, if you want to have the default settings of the new image be different than that of the instance you are imaging, you will have to run the commands separately. If you want to create an image from a volume that you did not boot from, for example, as we did when bootstrapping the Gentoo Linux image, you will have to run the commands separately.
CreateSnapshot
Example API Request
1
2
3
4
5
https://ec2.us-east-1.amazonaws.com/
?Action=CreateSnapshot
&VolumeId=vol-12345678
&Description=Example%20Snapshot%20Description
&*AUTHPARAMS*
Using AWS CLI:
Console - user@hostname ~ $
1
2
3
4
aws --region=us-east-1 ec2 \
create-snapshot \
--volume-id "vol-12345678" \
--description "Example Snapshot Description"
Using ec2-api-tools:
Console - user@hostname ~ $
1
2
3
4
ec2-create-snapshot \
--region us-east-1 \
vol-12345678 \
--description "Example Snapshot Description"
RegisterImage
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 Image Description
&Architecture=x86_64
&KernelId=aki-88aa75e1
&RootDeviceName=/dev/sda1
&BlockDeviceMapping.1.DeviceName=/dev/sda1
&BlockDeviceMapping.1.SnapshotId=snap-12345678
&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*
Using AWS CLI:
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-88aa75e1 \
--root-device-name "/dev/sda1" \
--block-device-mappings "[
{
\"DeviceName\": \"/dev/sda1\",
\"Ebs\": {
\"SnapshotId\": \"snap-12345678\"
}
},
{
\"DeviceName\": \"/dev/sdb\",
\"VirtualName\": \"ephemeral0\"
},
{
\"DeviceName\": \"/dev/sdc\",
\"VirtualName\": \"ephemeral1\"
},
{
\"DeviceName\": \"/dev/sdd\",
\"VirtualName\": \"ephemeral2\"
},
{
\"DeviceName\": \"/dev/sde\",
\"VirtualName\": \"ephemeral3\"
}
]"
Using ec2-api-tools:
Console - user@hostname ~ $
1
2
3
4
5
6
7
8
9
10
11
12
ec2-register \
--region us-east-1 \
--name "Example_Image_Name" \
--description "Example Image Description" \
--architecture x86_64 \
--kernel aki-88aa75e1 \
--root-device-name /dev/sda1 \
--block-device-mapping "/dev/sda1=snap-12345678" \
--block-device-mapping "/dev/sdb=ephemeral0" \
--block-device-mapping "/dev/sdc=ephemeral1" \
--block-device-mapping "/dev/sdd=ephemeral2" \
--block-device-mapping "/dev/sde=ephemeral3"
Using DescribeVolumes to find the volume ID to snapshot
CreateSnapshot requires the Volume ID to snapshot; the easiest way to get this Volume ID when all you have is the Instance ID is to use the DescribeVolumes action with the attachment.instance-id and attachment.device filters.
Example API Request
1
2
3
4
5
6
7
https://ec2.us-east-1.amazonaws.com/
?Action=DescribeVolumes
&Filter.1.Name=attachment.instance-id
&Filter.1.Value.1=i-12345678
&Filter.2.Name=attachement.device
&Filter.2.Value.1=/dev/sda1
&*AUTHPARAMS*
Using AWS CLI:
Console - user@hostname ~ $
1
2
3
4
5
6
7
8
9
10
11
12
13
14
aws --region=us-east-1 ec2 \
describe-volumes \
--filters "[
{
\"Name\": \"attachment.instance-id\",
\"Values\": [\"i-12345678\"]
},
{
\"Name\": \"attachment.device\",
\"Values\": [\"/dev/sda1\"]
}
]" \
| \
jq -r ".Volumes[0].VolumeId"
Using ec2-api-tools:
Console - user@hostname ~ $
1
2
3
4
5
6
ec2-describe-volumes \
--region us-east-1 \
--filter attachment.instance-id=i-12345678 \
--filter attachment.device=/dev/sda1 \
| grep "^VOLUME" \
| awk '{ print $2 }'