DEV Community

loading...

AWS EC2 - EBS Volume Encryption

Saravanan G
Cloud DevOps and Infra as Code
Originally published at github.com ・Updated on ・4 min read

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.

  1. Encrypt EBS - After Creating the EC2 instance

  2. 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Step 7. Start the instance

echo " Start instances"
aws ec2 start-instances --instance-ids $instance_id
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

Bibliography

AWS EBS Encryption

Discussion (5)

Collapse
dineshrathee12 profile image
Dinesh Rathee • Edited

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...

Collapse
chefgs profile image
Saravanan G Author • Edited

Yes, Dinesh. Thanks for sharing the doc url. My article mainly focus on encrypting ebs volume of already created ec2 instance.

Collapse
dineshrathee12 profile image
Dinesh Rathee • Edited

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 :

  • Blog Post
  • Probably this will explain a bit more on this :)

    Thread Thread
    chefgs profile image
    Saravanan G Author • Edited

    Dinesh I just wanted to clarify that, there are two parts in this article,

    1. Encrypt EBS - After Creating the EC2 instance
    2. Encrypt EBS - Before Creating the EC2 instance..

    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.

    Thread Thread
    dineshrathee12 profile image
    Dinesh Rathee

    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