> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Enable Volume Encryption

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

1. Open the AWS Management Console and navigate to the EC2 dashboard.
2. 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.)
3. Stop the instance by selecting it and clicking on the "Instance State" dropdown menu and selecting "Stop".
4. 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.
5. Once the AMI is created, select it and click on the "Launch" button.
6. In the "Step 1: Choose an Instance Type" section, select the instance type that you want to launch.
7. In the "Step 2: Configure Instance Details" section, configure the instance details as per your requirements.
8. In the "Step 3: Add Storage" section, select the "Encrypt this volume" checkbox for each EBS volume that you want to encrypt.
9. In the "Step 4: Add Tags" section, add any tags that you want to apply to the instance.
10. In the "Step 5: Configure Security Group" section, configure the security group as per your requirements.
11. In the "Step 6: Review Instance Launch" section, review the instance details and click on the "Launch" button.
12. 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.
13. Once the instance is launched, start the instance by selecting it and clicking on the "Instance State" dropdown menu and selecting "Start".
14. 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

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        Below are step‑by‑step instructions using the AWS Management Console to ensure EC2 volumes are encrypted. There are two parts:

        1. Enable **default EBS encryption** for all new volumes
        2. Encrypt **existing unencrypted volumes**

        ***

        ## 1. Enable default EBS volume encryption (for all new volumes)

        1. Sign in to the AWS Management Console and go to **EC2**.
        2. In the left navigation pane, under **Elastic Block Store**, choose **Settings** (or **EBS encryption** depending on console version).
        3. Click **Manage** (or **Edit**).
        4. Check **Enable encryption by default**.
        5. (Optional) In **AWS KMS key**, choose a customer‑managed KMS key, or leave the default `aws/ebs`.
        6. 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

        1. In the **EC2** console, in the left pane choose **Volumes**.
        2. Add the **Encrypted** column (gear icon ▸ check **Encrypted**).
        3. Find volumes where **Encrypted = False** that you want to remediate.

        ***

        ### 2.2 Create a snapshot of the unencrypted volume

        1. Select the unencrypted volume.
        2. Click **Actions ▸ Create snapshot**.
        3. Enter a **Description** (e.g., `snapshot-before-encryption-vol-<id>`).
        4. Click **Create snapshot**.
        5. Go to **Snapshots** and wait until the snapshot’s **Status** is `completed`.

        ***

        ### 2.3 Copy the snapshot and enable encryption

        1. In **Snapshots**, select the snapshot you just created.
        2. Click **Actions ▸ Copy snapshot**.
        3. Keep the same **Region** (or choose another if needed).
        4. Under **Encryption**, check **Encrypt this snapshot**.
        5. Choose the **KMS key** (default `aws/ebs` or your CMK).
        6. Click **Copy snapshot**.
        7. Wait until the **copied** snapshot’s **Status** is `completed`.

        ***

        ### 2.4 Create an encrypted volume from the encrypted snapshot

        1. In **Snapshots**, select the **encrypted** snapshot (the copy).
        2. Click **Actions ▸ Create volume**.
        3. 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).
        4. Ensure **Encrypted** is `Yes` and the correct **KMS key** is selected.
        5. Click **Create volume**.
        6. 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.

        1. In **EC2 ▸ Instances**, select the instance using the original unencrypted volume.

        2. Stop application services that write to the disk, then **stop the instance**:
           * **Instance state ▸ Stop instance** and confirm.

        3. After the instance is `stopped`, go to **Volumes**.

        4. Select the **old unencrypted** volume.

        5. Click **Actions ▸ Detach volume** and confirm.

        6. Note its **Device name** (e.g., `/dev/xvda`, `/dev/sdf`) for the next step.

        7. Select the **new encrypted** volume.

        8. Click **Actions ▸ Attach volume**.

        9. Choose the **Instance** and specify the **Device name** to match the old one.

        10. Click **Attach volume**.

        ***

        ### 2.6 Start the instance and validate

        1. Go back to **Instances**, select the instance.
        2. Click **Instance state ▸ Start instance**.
        3. Once running, log into the instance and validate:
           * Volumes and file systems mount correctly.
           * Applications run as expected.
        4. 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:

        1. In **Volumes**, select the **old unencrypted** volume.
        2. Click **Actions ▸ Delete volume** and confirm.
        3. 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.
      </Accordion>

      <Accordion title="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

        ```bash theme={null}
        aws ec2 get-ebs-encryption-by-default
        ```

        Look for `"EbsEncryptionByDefault": false` or `true`.

        ### 1.2. Enable default EBS encryption

        ```bash theme={null}
        aws ec2 enable-ebs-encryption-by-default
        ```

        (Optionally specify a custom KMS key)

        ```bash theme={null}
        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:

        1. Create an encrypted snapshot from it,
        2. Create a new encrypted volume from that snapshot,
        3. 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

        ```bash theme={null}
        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:

        ```bash theme={null}
        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

        ```bash theme={null}
        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:

        ```bash theme={null}
        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:

        ```bash theme={null}
        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:

        ```bash theme={null}
        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`:

        ```bash theme={null}
        aws ec2 describe-volumes \
          --region us-east-1 \
          --volume-ids vol-0encrypted123456789 \
          --query "Volumes[0].State"
        ```

        ### 2.4. Stop the instance

        ```bash theme={null}
        aws ec2 stop-instances \
          --region us-east-1 \
          --instance-ids i-0123456789abcdef0
        ```

        Wait until it’s stopped:

        ```bash theme={null}
        aws ec2 wait instance-stopped \
          --region us-east-1 \
          --instance-ids i-0123456789abcdef0
        ```

        ### 2.5. Detach the old (unencrypted) volume

        ```bash theme={null}
        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`):

        ```bash theme={null}
        aws ec2 attach-volume \
          --region us-east-1 \
          --volume-id vol-0encrypted123456789 \
          --instance-id i-0123456789abcdef0 \
          --device /dev/xvda
        ```

        ### 2.7. Start the instance

        ```bash theme={null}
        aws ec2 start-instances \
          --region us-east-1 \
          --instance-ids i-0123456789abcdef0
        ```

        ***

        ## 3. Verify the Volume Is Encrypted

        ```bash theme={null}
        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.
      </Accordion>

      <Accordion title="Using Python">
        Below are concrete remediation steps and a Python (boto3) example to enable EBS volume encryption for EC2 in AWS.

        ***

        ## 1. Prerequisites

        1. Install and configure AWS CLI or set environment variables so boto3 can authenticate:
           ```bash theme={null}
           pip install boto3
           aws configure  # or set AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_REGION
           ```

        2. Make sure your IAM principal has:
           * `ec2:DescribeVolumes`
           * `ec2:ModifyVolume`
           * `ec2:DescribeInstances`
           * `ec2: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.

        ```python theme={null}
        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

        1. List all volumes (optionally filter by instance, tags, region).
        2. For each volume:
           * Skip if `Encrypted` is `True`.
           * Call `ModifyVolume` with `Encrypted=True` and optional `KmsKeyId`.
           * Poll `DescribeVolumesModifications` until the modification state is `completed` or `optimizing`.

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

        ```python theme={null}
        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 `REGION` to your AWS region.
        * Set `INSTANCE_ID` if you only want to remediate a single instance.
        * Set `KMS_KEY_ID` to a CMK if required by policy.
        * Optionally narrow scopes using tags via `Filters` in `describe_volumes`.

        This is sufficient to remediate the “Enable Volume Encryption” finding for EC2 EBS volumes using Python on AWS.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # 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.default` created with `enabled = true`.
        * (Optional) `aws_ebs_default_kms_key.default` created with your KMS key ARN.
        * Any `aws_ebs_volume` or launch template changes adding `encrypted = true` (and `kms_key_id`), with volume resources marked for replacement where applicable.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* \[[https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html)]
