AWS Enable Volume Encryption - Security Rule
More Info:
Ensure that all your Amazon Elastic Block Store (EBS) volumes are encrypted in order to meet security and compliance requirements. With encryption enabled, your EBS volumes can hold sensitive, confidential, and critical data. The data encryption and decryption process is handled transparently and does not require any additional action from you, your server instance, or your application.
Risk Level
Medium
Address
Security
Compliance Standards
CBP, HIPAA, ISO27001, AWSWAF, SOC2, GDPR, NISTCSF, PCIDSS
Remediation
How to enable EBS volume encryption for EC2 instances
Using AWS Console
- Open the AWS Management Console and navigate to the EC2 dashboard.
- Select the EC2 instance for which you want to enable EBS volume encryption. (In the Cloudanix Console, navigate to "Misconfig" page and look for Affected Assets for "Enable Volume Encryption" Policy.)
- Stop the instance by selecting it and clicking on the "Instance State" dropdown menu and selecting "Stop".
- Once the instance is stopped, select the instance and click on the "Actions" dropdown menu and select "Create Image". This will create an Amazon Machine Image (AMI) of the instance.
- Once the AMI is created, select it and click on the "Launch" button.
- In the "Step 1: Choose an Instance Type" section, select the instance type that you want to launch.
- In the "Step 2: Configure Instance Details" section, configure the instance details as per your requirements.
- In the "Step 3: Add Storage" section, select the "Encrypt this volume" checkbox for each EBS volume that you want to encrypt.
- In the "Step 4: Add Tags" section, add any tags that you want to apply to the instance.
- In the "Step 5: Configure Security Group" section, configure the security group as per your requirements.
- In the "Step 6: Review Instance Launch" section, review the instance details and click on the "Launch" button.
- In the "Select an existing key pair or create a new key pair" dialog box, select an existing key pair or create a new key pair.
- Once the instance is launched, start the instance by selecting it and clicking on the "Instance State" dropdown menu and selecting "Start".
- Once the instance is running, you can verify that the EBS volumes are encrypted by selecting the instance and clicking on the "Description" tab. In the "Block devices" section, you will see that the EBS volumes are encrypted.
Triage and Remediation
- Remediation
Remediation
Using Console
Below are step‑by‑step instructions using the AWS Management Console to ensure EC2 volumes are encrypted. There are two parts:
- Enable default EBS encryption for all new volumes
- Encrypt existing unencrypted volumes
1. Enable default EBS volume encryption (for all new volumes)
- Sign in to the AWS Management Console and go to EC2.
- In the left navigation pane, under Elastic Block Store, choose Settings (or EBS encryption depending on console version).
- Click Manage (or Edit).
- Check Enable encryption by default.
- (Optional) In AWS KMS key, choose a customer‑managed KMS key, or leave the default
aws/ebs. - Click Save changes.
All new EBS volumes and snapshots created in this Region are now encrypted.
2. Encrypt an existing unencrypted EBS volume
You cannot turn encryption on directly for an existing volume; you must migrate data to a new encrypted volume.
2.1 Identify the unencrypted volume
- In the EC2 console, in the left pane choose Volumes.
- Add the Encrypted column (gear icon ▸ check Encrypted).
- Find volumes where Encrypted = False that you want to remediate.
2.2 Create a snapshot of the unencrypted volume
- Select the unencrypted volume.
- Click Actions ▸ Create snapshot.
- Enter a Description (e.g.,
snapshot-before-encryption-vol-<id>). - Click Create snapshot.
- Go to Snapshots and wait until the snapshot’s Status is
completed.
2.3 Copy the snapshot and enable encryption
- In Snapshots, select the snapshot you just created.
- Click Actions ▸ Copy snapshot.
- Keep the same Region (or choose another if needed).
- Under Encryption, check Encrypt this snapshot.
- Choose the KMS key (default
aws/ebsor your CMK). - Click Copy snapshot.
- Wait until the copied snapshot’s Status is
completed.
2.4 Create an encrypted volume from the encrypted snapshot
- In Snapshots, select the encrypted snapshot (the copy).
- Click Actions ▸ Create volume.
- Choose:
- Availability Zone: must match the AZ of the original volume’s attached instance (e.g.,
us-east-1a). - Volume type and Size: match the original volume (or larger).
- Availability Zone: must match the AZ of the original volume’s attached instance (e.g.,
- Ensure Encrypted is
Yesand the correct KMS key is selected. - Click Create volume.
- Wait until the new volume’s State is
available.
2.5 Detach the old volume and attach the new encrypted volume
To avoid data loss, perform this during a maintenance window and back up first.
-
In EC2 ▸ Instances, select the instance using the original unencrypted volume.
-
Stop application services that write to the disk, then stop the instance:
- Instance state ▸ Stop instance and confirm.
-
After the instance is
stopped, go to Volumes. -
Select the old unencrypted volume.
-
Click Actions ▸ Detach volume and confirm.
-
Note its Device name (e.g.,
/dev/xvda,/dev/sdf) for the next step. -
Select the new encrypted volume.
-
Click Actions ▸ Attach volume.
-
Choose the Instance and specify the Device name to match the old one.
-
Click Attach volume.
2.6 Start the instance and validate
- Go back to Instances, select the instance.
- Click Instance state ▸ Start instance.
- Once running, log into the instance and validate:
- Volumes and file systems mount correctly.
- Applications run as expected.
- In Volumes, confirm the attached volume shows Encrypted = True.
2.7 (Optional) Clean up old unencrypted resources
After you’ve confirmed everything works and backups are in place:
- In Volumes, select the old unencrypted volume.
- Click Actions ▸ Delete volume and confirm.
- In Snapshots, delete the original unencrypted snapshot if no longer needed.
You can repeat steps 2.1–2.7 for each unencrypted EBS volume you need to remediate.
Using CLI
Below are the key ways to remediate “Enable Volume Encryption” for AWS EC2 using the AWS CLI.
1. Enable Default EBS Encryption (Global Setting)
This ensures all new EBS volumes and snapshots created in this region are encrypted by default.
1.1. Check current default encryption status
aws ec2 get-ebs-encryption-by-default
Look for "EbsEncryptionByDefault": false or true.
1.2. Enable default EBS encryption
aws ec2 enable-ebs-encryption-by-default
(Optionally specify a custom KMS key)
aws ec2 modify-ebs-default-kms-key-id \
--kms-key-id arn:aws:kms:<region>:<account-id>:key/<key-id>
2. Encrypt an Existing Unencrypted EBS Volume
Existing volumes cannot be encrypted in-place; you must:
- Create an encrypted snapshot from it,
- Create a new encrypted volume from that snapshot,
- Stop the instance, swap volumes, and start the instance.
Assume:
- Region:
us-east-1 - Instance ID:
i-0123456789abcdef0 - Old volume ID:
vol-0123456789abcdef0 - Device name:
/dev/xvda(root volume example)
2.1. Create a snapshot of the existing unencrypted volume
aws ec2 create-snapshot \
--region us-east-1 \
--volume-id vol-0123456789abcdef0 \
--description "Snapshot before encryption"
Note the SnapshotId returned, e.g. snap-0123456789abcdef0.
Wait for snapshot completion:
aws ec2 describe-snapshots \
--region us-east-1 \
--snapshot-ids snap-0123456789abcdef0 \
--query "Snapshots[0].State"
Continue when state is completed.
2.2. Create an encrypted copy of the snapshot
aws ec2 copy-snapshot \
--region us-east-1 \
--source-region us-east-1 \
--source-snapshot-id snap-0123456789abcdef0 \
--encrypted \
--description "Encrypted copy of snapshot"
Optionally specify a KMS key:
aws ec2 copy-snapshot \
--region us-east-1 \
--source-region us-east-1 \
--source-snapshot-id snap-0123456789abcdef0 \
--encrypted \
--kms-key-id arn:aws:kms:us-east-1:<account-id>:key/<key-id> \
--description "Encrypted copy of snapshot"
Note the new SnapshotId (e.g. snap-0encrypted123456789), and wait until it’s completed as above.
2.3. Create a new encrypted volume from the encrypted snapshot
Get the Availability Zone of the current volume:
aws ec2 describe-volumes \
--region us-east-1 \
--volume-ids vol-0123456789abcdef0 \
--query "Volumes[0].AvailabilityZone" \
--output text
Assume it returns us-east-1a.
Create the encrypted volume:
aws ec2 create-volume \
--region us-east-1 \
--availability-zone us-east-1a \
--snapshot-id snap-0encrypted123456789 \
--volume-type gp3
Note the new VolumeId (e.g. vol-0encrypted123456789) and wait until state is available:
aws ec2 describe-volumes \
--region us-east-1 \
--volume-ids vol-0encrypted123456789 \
--query "Volumes[0].State"
2.4. Stop the instance
aws ec2 stop-instances \
--region us-east-1 \
--instance-ids i-0123456789abcdef0
Wait until it’s stopped:
aws ec2 wait instance-stopped \
--region us-east-1 \
--instance-ids i-0123456789abcdef0
2.5. Detach the old (unencrypted) volume
aws ec2 detach-volume \
--region us-east-1 \
--volume-id vol-0123456789abcdef0
Wait for it to become available.
2.6. Attach the new encrypted volume
Attach using the same device name as before (e.g. /dev/xvda):
aws ec2 attach-volume \
--region us-east-1 \
--volume-id vol-0encrypted123456789 \
--instance-id i-0123456789abcdef0 \
--device /dev/xvda
2.7. Start the instance
aws ec2 start-instances \
--region us-east-1 \
--instance-ids i-0123456789abcdef0
3. Verify the Volume Is Encrypted
aws ec2 describe-volumes \
--region us-east-1 \
--volume-ids vol-0encrypted123456789 \
--query "Volumes[0].{Encrypted:Encrypted,KmsKeyId:KmsKeyId}"
You should see "Encrypted": true.
If you share:
- region,
- instance ID,
- which volume(s) (root vs data), I can tailor exact command sequences for each.
Using Python
Below are concrete remediation steps and a Python (boto3) example to enable EBS volume encryption for EC2 in AWS.
1. Prerequisites
-
Install and configure AWS CLI or set environment variables so boto3 can authenticate:
pip install boto3aws configure # or set AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_REGION -
Make sure your IAM principal has:
ec2:DescribeVolumesec2:ModifyVolumeec2:DescribeInstancesec2:EnableEbsEncryptionByDefault(if you also want to turn on default encryption)- Permissions to use the chosen KMS key (
kms:Encrypt,kms:Decrypt, etc.).
2. One-time: Enable EBS encryption by default (recommended)
This makes all new EBS volumes encrypted automatically.
import boto3
region = "us-east-1"
ec2 = boto3.client("ec2", region_name=region)
response = ec2.enable_ebs_encryption_by_default()
print("EBS encryption by default enabled:", response["EbsEncryptionByDefault"])
3. Encrypt existing unencrypted EBS volumes in-place
AWS now supports converting an unencrypted EBS volume to encrypted using modify_volume.
High-level steps
- List all volumes (optionally filter by instance, tags, region).
- For each volume:
- Skip if
EncryptedisTrue. - Call
ModifyVolumewithEncrypted=Trueand optionalKmsKeyId. - Poll
DescribeVolumesModificationsuntil the modification state iscompletedoroptimizing.
- Skip if
Important notes
- This operation is online: the instance can remain running.
- Performance may be slightly impacted while the volume is being optimized.
- Choose a CMK if your security policy requires customer-managed keys; otherwise, AWS-managed key is fine.
4. Example Python script (boto3)
This example:
- Targets a specific region.
- Optionally targets a specific instance by ID (or all volumes in the region).
- Encrypts all unencrypted volumes with the default EBS KMS key (or a specific CMK if provided).
import time
import boto3
REGION = "us-east-1"
INSTANCE_ID = None # set to an EC2 instance ID like "i-0123456789abcdef0" or leave as None for all volumes in the region
KMS_KEY_ID = None # e.g. "arn:aws:kms:us-east-1:123456789012:key/abcd-..." or leave None to use AWS-managed key
ec2 = boto3.client("ec2", region_name=REGION)
def get_target_volumes(instance_id=None):
filters = []
if instance_id:
filters.append({"Name": "attachment.instance-id", "Values": [instance_id]})
paginator = ec2.get_paginator("describe_volumes")
volumes = []
for page in paginator.paginate(Filters=filters):
for vol in page["Volumes"]:
if not vol["Encrypted"]:
volumes.append(vol)
return volumes
def encrypt_volume(volume_id, kms_key_id=None):
params = {
"VolumeId": volume_id,
"Encrypted": True,
}
if kms_key_id:
params["KmsKeyId"] = kms_key_id
print(f"Starting encryption for volume {volume_id} ...")
ec2.modify_volume(**params)
def wait_for_encryption(volume_id, timeout=3600, poll_interval=15):
"""Wait until volume modification is completed or optimizing."""
start = time.time()
while True:
resp = ec2.describe_volumes_modifications(VolumeIds=[volume_id])
mods = resp.get("VolumesModifications", [])
if not mods:
print(f"No modification record for volume {volume_id}, assuming done.")
return
mod = mods[0]
state = mod["ModificationState"]
progress = mod.get("Progress", 0)
print(f"Volume {volume_id} state={state}, progress={progress}%")
if state in ("completed", "optimizing"):
print(f"Encryption finished/optimizing for volume {volume_id}.")
return
if time.time() - start > timeout:
raise TimeoutError(f"Timeout waiting for volume {volume_id} encryption")
time.sleep(poll_interval)
def main():
# 1. Enable EBS encryption by default for new volumes (optional but recommended)
try:
resp = ec2.enable_ebs_encryption_by_default()
print("EBS encryption by default:", resp["EbsEncryptionByDefault"])
except ec2.exceptions.ClientError as e:
print("Could not enable EBS encryption by default (check perms):", e)
# 2. Find all unencrypted volumes (optionally only for one instance)
vols = get_target_volumes(INSTANCE_ID)
if not vols:
print("No unencrypted volumes found.")
return
print(f"Found {len(vols)} unencrypted volumes.")
for v in vols:
vol_id = v["VolumeId"]
print(f"Processing volume {vol_id} (size={v['Size']}GiB, type={v['VolumeType']})")
# 3. Start encryption
try:
encrypt_volume(vol_id, KMS_KEY_ID)
except ec2.exceptions.ClientError as e:
print(f"Failed to start encryption for {vol_id}: {e}")
continue
# 4. Wait until encryption is done/optimizing
try:
wait_for_encryption(vol_id)
except Exception as e:
print(f"Error waiting for encryption of {vol_id}: {e}")
if __name__ == "__main__":
main()
5. What to adjust for your environment
- Set
REGIONto your AWS region. - Set
INSTANCE_IDif you only want to remediate a single instance. - Set
KMS_KEY_IDto a CMK if required by policy. - Optionally narrow scopes using tags via
Filtersindescribe_volumes.
This is sufficient to remediate the “Enable Volume Encryption” finding for EC2 EBS volumes using Python on AWS.
Using Terraform
# Encrypt all new EBS volumes in this account/region by default
resource "aws_ebs_encryption_by_default" "default" {
enabled = true
}
# (Optional) Use a specific KMS key instead of aws/ebs
# Replace KMS_KEY_ARN with your KMS key ARN (e.g. arn:aws:kms:us-east-1:123456789012:key/abc-...)
resource "aws_ebs_default_kms_key" "default" {
key_arn = "KMS_KEY_ARN"
}
# Example: encrypted standalone EBS volume
# NOTE: Turning on `encrypted` for an existing, unmanaged-by-Terraform volume
# requires creating a new encrypted volume and migrating data; Terraform can’t
# flip encryption in-place.
resource "aws_ebs_volume" "encrypted_data" {
availability_zone = "AVAILABILITY_ZONE" # e.g. us-east-1a
size = 100
encrypted = true
kms_key_id = aws_ebs_default_kms_key.default.key_arn # or omit to use aws/ebs
tags = {
Name = "ENCRYPTED_VOLUME_NAME"
}
}
# Example: encrypt the root volume of a new EC2 instance via a launch template
resource "aws_launch_template" "encrypted" {
name_prefix = "ENCRYPTED_LT_NAME_PREFIX"
image_id = "AMI_ID"
instance_type = "t3.micro"
block_device_mappings {
device_name = "/dev/xvda"
ebs {
volume_size = 20
encrypted = true
kms_key_id = aws_ebs_default_kms_key.default.key_arn
volume_type = "gp3"
}
}
}
Enabling aws_ebs_encryption_by_default is in-place; adding encrypted = true (and optionally kms_key_id) on aws_ebs_volume or launch templates causes new encrypted volumes to be created instead of unencrypted ones. For already-existing unencrypted volumes, Terraform must create new encrypted volumes and you must handle cutover; encryption cannot be toggled in-place.
After remediation, terraform plan should show:
aws_ebs_encryption_by_default.defaultcreated withenabled = true.- (Optional)
aws_ebs_default_kms_key.defaultcreated with your KMS key ARN. - Any
aws_ebs_volumeor launch template changes addingencrypted = true(andkms_key_id), with volume resources marked for replacement where applicable.