Introduction
We are now living in the ERA of increased use of Cloud and virtualization. So there is always a question pondering on us about the security in Cloud.
Nowadays it is very important for a Cloud provider to prove their Cloud resources are NOT vulnerable to attacks and Cloud security means a lot to everyone.
Amazon Web Services (AWS) is a pioneer in Cloud and providing multiple methods for securing the resource from vulnerability attacks.
EC2 instances are one of major Cloud product from AWS and widely used AWS resource among the companies around The World.
EC2 has EBS (Elastic Block Storage) disc volume, attached to EC2 instances.
During initial days, the EBS volume encryption was not introduced. But later, AWS improved the security of EBS volume by introducing the feature of Encrypting it using CMK keys.
AWS EC2 root volumes created out of predefined AMIs are not encrypted by default. But as part of disc security we have to encrypt the root volumes too.
EBS Disc volume encryption could be done at 2 different times.
Encrypt EBS - After Creating the EC2 instance
Encrypt EBS - Before Creating the EC2 instances
The script can be used for Encrypt EBS - After Creating the EC2 instance
, where EC2 instance created with un-encrypted root volume and script will be encrypting the root volume of the EC2 instance.
The Script Pre-requisites
AWS CLI needs to be Installed and Configured to run the script.
I) Encrypt EBS - After Creating the EC2 instance
The script takes the EC2 instance_id as input argument. EC2 VM should be having the unencrypted root volume.
Added the validation steps to automatically verify the completion of each step using the do while
loop
Step 1. Stop the running instance
# Get Instance ID and Stop instances
instance_id=$1
echo "Stop instance"
aws ec2 stop-instances --instance-ids $instance_id
while [ "$instance_state" != "stopped" ]
do
instance_state=`aws ec2 describe-instances --instance-ids $instance_id | grep -A 3 "State" | grep -i "Name" | awk -F'\"' '{ print $4 }'`
echo "Waiting to instance state changed to STOPPED"
done
Step 2. Get the un-encrypted volume-id and Create snapshot of the un-encrypted root volume
echo "Get Volume ID not encrypted"
volume=`aws ec2 describe-instances --filters "Name=instance-id,Values=$instance_id" | grep -A 6 "sda1" | grep -i "VolumeID" | awk -F'\"' '{ print $4 }'`
echo $volume
echo "Create snapshot of Volume"
snapshot_id=`aws ec2 create-snapshot --volume-id $volume | grep -i "SnapshotId" | awk -F'\"' '{ print $4 }'`
echo $snapshot_id
while [ "$snapshot1_status" != "completed" ]
do
snapshot1_status=`aws ec2 describe-snapshots --snapshot-ids $snapshot_id | grep -i "State" | awk -F'\"' '{ print $4 }'`
echo "Waiting for Source snapshot creation to be completed"
done
Step 3. Copy the snapshot and encrypt it (this method uses the default CMK key provider by AWS for EBS encryption)
echo "Copy the snapshot and encrypt it"
copied_snapshot=`aws --region us-west-2 ec2 copy-snapshot --source-region us-west-2 --source-snapshot-id $snapshot_id --encrypted | grep -i "SnapshotId" | awk -F'\"' '{ print $4 }'`
echo $copied_snapshot
while [ "$snapshot2_status" != "completed" ]
do
snapshot2_status=`aws ec2 describe-snapshots --snapshot-ids $copied_snapshot | grep -i "State" | awk -F'\"' '{ print $4 }'`
echo "Waiting form copied snapshot creation to be completed"
done
Step 4. Create new volume from the encrypted snapshot
echo "Create new volume from encrypted snapshot"
new_encrypt_volume=`aws ec2 create-volume --size 10 --region us-west-2 --availability-zone us-west-2b --volume-type gp2 --snapshot-id $copied_snapshot | grep -i "VolumeID" | awk -F'\"' '{ print $4 }'`
echo $new_encrypt_volume
while [ "$new_volume_state" != "available" ]
do
new_volume_state=`aws ec2 describe-volumes --volume-ids $new_encrypt_volume | grep -i "State" | awk -F'\"' '{ print $4 }'`
echo "Waiting for new volume creation to be completed"
done
Step 5. Detach existing un-encrypted root volume
echo "Detach un-encrypted volume"
aws ec2 detach-volume --volume-id $volume
while [ "$old_volume_state" != "available" ]
do
old_volume_state=`aws ec2 describe-volumes --volume-ids $volume | grep -i "State" | awk -F'\"' '{ print $4 }'`
echo "Waiting for new volume creation to be completed"
done
Step 6. Attach new encrypted volume created in step 4
echo "Attach newly encrypted volume"
aws ec2 attach-volume --volume-id $new_encrypt_volume --instance-id $instance_id --device /dev/sda1
while [ "$new_volume_state" != "in-use" ]
do
old_volume_state=`aws ec2 describe-volumes --volume-ids $new_encrypt_volume | grep -i "State" | awk -F'\"' '{ print $4 }'`
echo "Waiting for attaching new volume to be completed"
done
Step 7. Start the instance
echo " Start instances"
aws ec2 start-instances --instance-ids $instance_id
II) Encrypt EBS - Before Creating the EC2 instances
Follow the steps below,
Step 1. Stop the running instance
# Stop instances
echo "Stop instance"
aws ec2 stop-instances --instance-ids $instance_id
while [ "$instance_state" != "stopped" ]
do
instance_state=`aws ec2 describe-instances --instance-ids $instance_id | grep -A 3 "State" | grep -i "Name" | awk -F'\"' '{ print $4 }'`
echo "Waiting to instance state changed to STOPPED"
done
Step 2. Get the un-encrypted volume-id and Create snapshot of the un-encrypted root volume
echo "Get Volume ID not encrypted"
volume=`aws ec2 describe-instances --filters "Name=instance-id,Values=$instance_id" | grep -A 6 "sda1" | grep -i "VolumeID" | awk -F'\"' '{ print $4 }'`
echo $volume
echo "Create snapshot of Volume"
snapshot_id=`aws ec2 create-snapshot --volume-id $volume | grep -i "SnapshotId" | awk -F'\"' '{ print $4 }'`
echo $snapshot_id
while [ "$snapshot1_status" != "completed" ]
do
snapshot1_status=`aws ec2 describe-snapshots --snapshot-ids $snapshot_id | grep -i "State" | awk -F'\"' '{ print $4 }'`
echo "Waiting for Source snapshot creation to be completed"
done
Step 3. Copy the snapshot and encrypt it (this method uses the default CMK key provider by AWS for EBS encryption)
echo "Copy the snapshot and encrypt it"
copied_snapshot=`aws --region us-west-2 ec2 copy-snapshot --source-region us-west-2 --source-snapshot-id $snapshot_id --encrypted | grep -i "SnapshotId" | awk -F'\"' '{ print $4 }'`
echo $copied_snapshot
while [ "$snapshot2_status" != "completed" ]
do
snapshot2_status=`aws ec2 describe-snapshots --snapshot-ids $copied_snapshot | grep -i "State" | awk -F'\"' '{ print $4 }'`
echo "Waiting form copied snapshot creation to be completed"
done
Perform the steps below in AWS Console,
Step 4. Create AMI using the encrypted snapshot of root volume
Step 5. Newly created AMI will be available under MyAMI when launching the instance
Step 6. Create EC2 instance using the new AMI
Step 7. We can see the root volume of instance is NOW encrypted by default
Top comments (5)
That's a good approach π
Also, just curious to share what I've come across something interesting earlier which can achieve this task with in a single settings in AWS account.
You can now specify that you want all newly created EBS volumes to be created in encrypted form, with the option to use the default key provided by AWS, or a key that you create.
Please take a look on this :
aws.amazon.com/blogs/aws/new-opt-i...
Yes, Dinesh. Thanks for sharing the doc url. My article mainly focus on encrypting ebs volume of already created ec2 instance.
Thanks Saravanan, Actually I did some test over this doc and also verified that this will also ensure when you "launch a new Instance" its root volume will be encrypted automatically on launch.
Just written Blog post :
Probably this will explain a bit more on this :)
Dinesh I just wanted to clarify that, there are two parts in this article,
So the new option provided by AWS solves the purpose of 2nd part of the article (encrypt volume before creating instance)
Where as the part 1. Encrypt EBS - After Creating the EC2 instance still needs manually encrypting the ec2 instance and my article and script can be used to achieve the same thing in automated way using the script.
Hope this clarifies.
That's correct , Actually mainly I was focusing on Part #2 which focuses upon "Encrypt EBS - Before Creating the EC2 instance" using this feature instead of doing it via a script.
The interesting part is like a scenario when we use Public AMIs , the Snapshot present on S3 in public domain and the OS (root volume) gets created and by default it will be unencrypted and if we use this Account Attributes feature setting for a region, it will definitely save overhead of (stop,copy snapshot,encrypt,AMI,and use that AMI for launch) process which could be done by simply applying Account level region encryption setting without any intervention from a user