AWS - using an access key, AMI templates, disk snapshots to safely upgrade software
Introduction
Creating an account and access key
Creating a disk snapshot
Upgrading linux software with dpkg
tool
Using AMI templates and restoring a disk snapshot to an EC2 instance
Removing AMI templates and disk snapshots
Introduction
Let’s say we want to upgrade the software on a linux VM on AWS EC2, but first we would like to back up the VM’s boot disk as a snapshot, in case the upgrade causes issues and we want to restore from backup.
We will use the AWS web console to create a user in IAM, and we will use the AWS CLI to take a snapshot of the VM’s disk and restore it, if needed.
Creating an account and access key
In IAM we will create a new user, to which we will assign permissions, and an access key to be used in the AWS CLI.
- Go to
IAM > Users > Create user
Name the usergeorge-aws2-sa-2
or similar. Do not tickProvide user access to AWS console
, as we will use the AWS CLI for commands in the console/terminal only. - In the next screen, choose
Attach policies directly
and tick the policyAmazonEC2FullAccess
, to manage access toEC2
instances and disks. - Scroll at the bottom of the page, choose
Next
, thenCreate user
. - In the user screen, click
Create access key
, chooseCommand line interface
, clickNext
andCreate access key
. - Copy both the
Access key
andSecret access key
. You will be add them to the.aws/credentials
file in your home folder:
[aws-sa-2]
aws_access_key_id = AKIxxxE
aws_secret_access_key = f23xxxe
Creating a disk snapshot
Let’s list the VMs in the eu-west-2
region and their attached disk volumes using aws ec2 describe-instances
; we will use the --profile aws-sa-2
option to select the new AWS CLI profile:
$ aws --profile aws-sa-2 ec2 describe-instances \
--region eu-west-2 \
--query 'Reservations[].Instances[].{InstanceId: InstanceId, State: State.Name, LaunchTime: LaunchTime, Volumes: BlockDeviceMappings[].Ebs.VolumeId}' \
--output table
-----------------------------------------------------------------
| DescribeInstances |
+----------------------+-----------------------------+----------+
| InstanceId | LaunchTime | State |
+----------------------+-----------------------------+----------+
| i-08dc2f13b35f74c25 | 2025-04-05T20:18:47+00:00 | running |
+----------------------+-----------------------------+----------+
|| Volumes ||
|+-------------------------------------------------------------+|
|| vol-047029f1d13f42d7b ||
|+-------------------------------------------------------------+|
To create a snapshot of the disk from the output above, we will use aws ec2 create-snapshot
; we will add the tag WebServerDataBackup
and the current date:
aws ec2 create-snapshot \
--volume-id vol-047029f1d13f42d7b \
--description "Backup of production web server data volume 2025-05-10" \
--region eu-west-2 \
--tag-specifications 'ResourceType=snapshot,Tags=[{Key=Name,Value=WebServerDataBackup},{Key=Date,Value=2025-05-10}]' \
--profile aws-sa-2 # Include if you need a specific profile
The result:
{
"Tags": [
{
"Key": "Name",
"Value": "WebServerDataBackup"
},
{
"Key": "Date",
"Value": "2025-05-10"
}
],
"SnapshotId": "snap-092a608a99f28238f",
"VolumeId": "vol-047029f1d13f42d7b",
"State": "pending",
"StartTime": "2025-05-10T13:24:21.404000+00:00",
"Progress": "",
"OwnerId": "940767832355",
"Description": "Backup of production web server data volume 2025-05-10",
"VolumeSize": 8,
"Encrypted": false
}
We will use aws ec2 describe-snapshots
to list the snapshots in the current AWS account:
aws ec2 describe-snapshots \
--owner-ids self \
--region eu-west-2 \
--query 'Snapshots[*].{ID:SnapshotId,VolumeId:VolumeId,Size:VolumeSize,State:State,StartTime:StartTime,Description:Description}' \
--output table \
--profile aws-sa-2
The output of the command:
--------------------------------------------------------------------------------------------------------------
| DescribeSnapshots |
+------------------------+-------+------------------------------------+------------+-------------------------+
| ID | Size | StartTime | State | VolumeId |
+------------------------+-------+------------------------------------+------------+-------------------------+
| snap-092a608a99f28238f| 8 | 2025-05-10T13:24:21.404000+00:00 | completed | vol-047029f1d13f42d7b |
+------------------------+-------+------------------------------------+------------+-------------------------+
Upgrading linux software with dpkg
tool
Now let’s install a new version of the Hugo static website generator. Let’s get the current version.
$ hugo version
hugo v0.139.3-2f6864387cd31b975914e8373d4bf38bddbd47bc+extended linux/amd64 BuildDate=2024-11-29T15:36:56Z VendorInfo=gohugoio
We can use wget
to download the latest version from Github.
$ wget https://github.com/gohugoio/hugo/releases/download/v0.147.2/hugo_extended_0.147.2_linux-amd64.deb
[..]
Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.109.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 19229722 (18M) [application/octet-stream]
Saving to: ‘hugo_extended_0.147.2_linux-amd64.deb’
hugo_extended_0.147.2_linux-amd64.deb 100%[==========================>] 18.34M 73.6MB/s in 0.2s
2025-05-10 13:33:32 (73.6 MB/s) - ‘hugo_extended_0.147.2_linux-amd64.deb’ saved [19229722/19229722]
We will use the dpkg
Debian package tool to install the new version:
$ sudo dpkg -i hugo_extended_0.147.2_linux-amd64.deb
(Reading database ... 46521 files and directories currently installed.)
Preparing to unpack hugo_extended_0.147.2_linux-amd64.deb ...
Unpacking hugo (0.147.2) over (0.139.3) ...
Setting up hugo (0.147.2) ...
Let’s check, the new hugo
runtime version is installed:
$ hugo version
hugo v0.147.2-c7feb15d10b29a94d7fb57c31e8bcb2e92718fb7+extended linux/amd64 BuildDate=2025-05-06T11:18:55Z VendorInfo=gohugoio
Using AMI templates and restoring a disk snapshot to an EC2 instance
If we want to restore the EC2 VM from the snapshot, we need to create an AMI, a template that contains references to the disk snapshot, network configuration, etc..
We use aws ec2 register-image
to register an AMI image, based on the disk snapshot:
$ aws ec2 register-image \
--profile aws-sa-2 \
--region eu-west-2 \
--name "RestoredAMI" \
--root-device-name /dev/sda1 \
--block-device-mappings "[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"SnapshotId\":\"snap-092a608a99f28238f\"}}]"
The result is the ID of the AMI template:
{
"ImageId": "ami-0d0a76bd8e71c09df"
}
To create a new EC2 instance, we will need more information. First, here is the complete command:
aws ec2 run-instances \
--profile aws-sa-2 \
--region eu-west-2 \
--image-id ami-xxx \
--instance-type t2.micro \
--key-name ssh-keypair-name \
--security-group-ids sg-xx \
--subnet-id subnet-tt
To get the instance type:
$ aws --profile aws-sa-2 ec2 describe-instances \
--region eu-west-2 \
--query 'Reservations[].Instances[].{InstanceId: InstanceId, InstanceType: InstanceType, SubnetId: NetworkInterfaces[0].SubnetId}' \
--output table
---------------------------------------------------------------------
| DescribeInstances |
+----------------------+---------------+----------------------------+
| InstanceId | InstanceType | SubnetId |
+----------------------+---------------+----------------------------+
| i-08dc2f13b35f74c25 | t2.micro | subnet-08b55484cbc415578 |
+----------------------+---------------+----------------------------+
To get the SSH key name, let’s use aws ec2 describe-key-pairs
:
$ aws ec2 describe-key-pairs \
--profile aws-sa-2 \
--region eu-west-2 \
--query "KeyPairs[*].[KeyName, KeyFingerprint]" \
--output table
----------------------------------------------------------------------
| DescribeKeyPairs |
+-------------------+------------------------------------------------+
| my-aws2-keypair1 | yy/xx= |
+-------------------+------------------------------------------------+
To get the security groups attached to an EC2 instance:
$ aws --profile aws-sa-2 ec2 describe-instances \
--region eu-west-2 \
--query 'Reservations[].Instances[].{InstanceId: InstanceId, SecurityGroups: SecurityGroups[].{GroupId: GroupId, GroupName: GroupName}}' \
--output table
-----------------------------------------------
| DescribeInstances |
+---------------------------------------------+
| InstanceId |
+---------------------------------------------+
| i-08dc2f13b35f74c25 |
+---------------------------------------------+
|| SecurityGroups ||
|+-----------------------+-------------------+|
|| GroupId | GroupName ||
|+-----------------------+-------------------+|
|| sg-0744115e5d494da09 | launch-wizard-1 ||
|+-----------------------+-------------------+|
To get the subnet ID:
$ aws --profile aws-sa-2 ec2 describe-instances \
--region eu-west-2 \
--query 'Reservations[].Instances[].{InstanceId: InstanceId, SubnetId: NetworkInterfaces[0].SubnetId}' \
--output table
-----------------------------------------------------
| DescribeInstances |
+----------------------+----------------------------+
| InstanceId | SubnetId |
+----------------------+----------------------------+
| i-08dc2f13b35f74c25 | subnet-08b55484cbc415578 |
+----------------------+----------------------------+
Removing AMI templates and disk snapshots
To deregister the AMI template, if not needed:
$ aws --profile aws-sa-2 ec2 deregister-image \
--image-id ami-0d0a76bd8e71c09df \
--region eu-west-2
To delete the disk snapshot, if not needed:
$ aws --profile aws-sa-2 ec2 delete-snapshot \
--snapshot-id snap-092a608a99f28238f \
--region eu-west-2