AWS EC2 - EBS Volume Encryption
Tags: aws, ec2, security, showdev
Published: 2020-07-08 07:38:08

## 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](https://github.com/chefgs/aws_cli_scripts/blob/master/ec2_ebs_encrypt.sh) 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](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) and [Configured](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html) 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

###Bibliography
[AWS EBS Encryption](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#how-ebs-encryption-works)