This check flags AMIs built on EBS snapshots that aren't encrypted, which means any instance launched from them starts life with unencrypted disks. Re-create the AMI from encrypted snapshots and enable EBS encryption by default so it never happens again.
Amazon Machine Images are the templates your fleet gets cloned from. Every EC2 instance you launch from an AMI inherits its volumes, and those volumes carry whatever encryption posture the underlying snapshots had at build time. If the snapshots baked into an AMI are unencrypted, every instance you spin up from that image will boot with unencrypted disks, often without anyone noticing.
This check, ebs_unencryptedami in the ebs_checks module, inspects the block device mappings of your AMIs and reports any image whose backing EBS snapshots are not encrypted.
What this check detects
An AMI is essentially metadata pointing at one or more EBS snapshots, one per block device. Lensix walks the BlockDeviceMappings of each AMI you own and checks the Encrypted flag on the referenced snapshots. If any device maps to an unencrypted snapshot, the AMI fails the check.
This commonly shows up when:
- An AMI was created from a running instance whose root or data volumes were never encrypted.
- An image was copied or shared from another account without re-encrypting during the copy.
- The image predates your organization enabling EBS encryption by default.
- A custom build pipeline (Packer, EC2 Image Builder) was configured without an encryption step.
Note: Encryption status is fixed at snapshot creation time. You cannot toggle encryption on an existing snapshot or AMI in place. The only way to get an encrypted version is to make an encrypted copy. That detail shapes the entire remediation flow below.
Why it matters
Unencrypted EBS snapshots expose data at rest. The risk isn't abstract, it plays out in a few concrete ways.
Data exposure if a snapshot or AMI is shared
AMIs and snapshots can be shared with other accounts or made public. It happens more often than teams expect, usually by accident when someone is trying to share an image across environments. If the snapshot is unencrypted and gets exposed publicly, anyone can launch an instance from it and read every byte on those volumes: credentials in config files, application secrets, customer data, private keys. Encrypted snapshots can't be shared publicly at all, so encryption acts as a guardrail against this exact mistake.
Compliance failures
Encryption at rest is a baseline requirement in most frameworks. PCI DSS, HIPAA, SOC 2, FedRAMP, and ISO 27001 all expect data at rest to be encrypted. An unencrypted AMI quietly violates that requirement every time it spawns a new instance, and auditors will flag it.
Blast radius through propagation
A single bad AMI doesn't stay a single problem. Auto Scaling groups, launch templates, and CI runners all launch from AMIs repeatedly. One unencrypted golden image can produce hundreds of unencrypted volumes across your account before anyone reviews it.
Warning: Instances already running from an unencrypted AMI keep their unencrypted volumes even after you fix the AMI. Fixing the image stops the bleeding for future launches, but existing volumes need to be re-encrypted separately. Treat the AMI fix and the running-instance fix as two distinct tasks.
How to fix it
The fix is to produce an encrypted version of the AMI. Because encryption is set at copy time, the workflow is: copy the AMI with encryption enabled, validate it, then cut over and retire the old one.
Step 1: Find the offending AMIs
List the AMIs you own and check which snapshots are unencrypted.
aws ec2 describe-images \
--owners self \
--query 'Images[].{ID:ImageId,Name:Name,Snapshots:BlockDeviceMappings[].Ebs.SnapshotId}' \
--output json
Then check the encryption status of a snapshot:
aws ec2 describe-snapshots \
--snapshot-ids snap-0123456789abcdef0 \
--query 'Snapshots[].{ID:SnapshotId,Encrypted:Encrypted}' \
--output table
Step 2: Copy the AMI with encryption enabled
The copy-image call re-encrypts all backing snapshots during the copy. Point it at a KMS key you control.
aws ec2 copy-image \
--source-region us-east-1 \
--source-image-id ami-0123456789abcdef0 \
--name "app-golden-encrypted-2024-06" \
--encrypted \
--kms-key-id arn:aws:kms:us-east-1:111122223333:key/your-key-id \
--region us-east-1
This returns a new ImageId. The copy runs asynchronously, so wait for it to become available:
aws ec2 wait image-available --image-ids ami-0newencryptedimage
Note: If you omit --kms-key-id, AWS uses the default aws/ebs managed key. That satisfies the encryption requirement, but a customer-managed key (CMK) gives you control over key rotation, grants, and cross-account access policies. For shared or regulated workloads, use a CMK.
Step 3: Repoint launch templates and Auto Scaling groups
Update any launch templates referencing the old image. Create a new launch template version:
aws ec2 create-launch-template-version \
--launch-template-id lt-0123456789abcdef0 \
--source-version 1 \
--launch-template-data '{"ImageId":"ami-0newencryptedimage"}'
aws ec2 modify-launch-template \
--launch-template-id lt-0123456789abcdef0 \
--default-version 2
Then trigger an instance refresh on the Auto Scaling group so the fleet rolls to the new image.
Warning: An instance refresh replaces running instances. Set a sensible MinHealthyPercentage and run it during a maintenance window for stateful workloads. For stateless services behind a load balancer, a rolling refresh is usually safe but still warrants monitoring.
Step 4: Deregister the unencrypted AMI
Once nothing references the old image, retire it.
Danger: Deregistering an AMI is irreversible, and you should confirm nothing depends on it first. Check launch templates, Auto Scaling groups, Spot fleet requests, and any IaC state. If you delete the backing snapshots too, that data is gone for good.
aws ec2 deregister-image --image-id ami-0123456789abcdef0
# delete the now-orphaned snapshots
aws ec2 delete-snapshot --snapshot-id snap-0123456789abcdef0
How to prevent it from happening again
Turn on EBS encryption by default
This is the single highest-leverage control. When enabled, every new EBS volume and snapshot in the region is encrypted automatically, including those created during AMI builds. Set it per region, per account.
aws ec2 enable-ebs-encryption-by-default --region us-east-1
# optionally set the default key to a CMK
aws ec2 modify-ebs-default-kms-key-id \
--kms-key-id arn:aws:kms:us-east-1:111122223333:key/your-key-id \
--region us-east-1
Tip: Enforce this org-wide with a Service Control Policy that denies ec2:DisableEbsEncryptionByDefault, so a single account can't quietly turn it off. Combine that with an AWS Config managed rule (ec2-ebs-encryption-by-default) to catch any region where it isn't active.
Bake encryption into your image pipeline
If you build images with Packer, set encryption in the source block:
{
"builders": [{
"type": "amazon-ebs",
"region": "us-east-1",
"encrypt_boot": true,
"kms_key_id": "arn:aws:kms:us-east-1:111122223333:key/your-key-id"
}]
}
With EC2 Image Builder, set the distribution configuration to encrypt the output AMI and specify the KMS key per target region.
Gate it in CI/CD
Add a check to your pipeline that fails the build if a freshly created AMI has unencrypted snapshots, before it ever reaches production:
SNAP_IDS=$(aws ec2 describe-images --image-ids "$AMI_ID" \
--query 'Images[].BlockDeviceMappings[].Ebs.SnapshotId' --output text)
for SNAP in $SNAP_IDS; do
ENCRYPTED=$(aws ec2 describe-snapshots --snapshot-ids "$SNAP" \
--query 'Snapshots[0].Encrypted' --output text)
if [ "$ENCRYPTED" != "True" ]; then
echo "FAIL: snapshot $SNAP in $AMI_ID is not encrypted"
exit 1
fi
done
echo "All snapshots encrypted."
Tip: Lensix runs this check continuously, so you don't have to wire up every account yourself. Use the pipeline gate to block bad builds early and Lensix to catch drift on images that already exist or get shared in from elsewhere.
Best practices
- Default to encryption everywhere. EBS encryption by default removes a whole class of misconfigurations and adds negligible performance overhead.
- Use customer-managed keys for sensitive workloads. CMKs give you key rotation, access policies, and an audit trail in CloudTrail for every decrypt operation.
- Lock down AMI sharing. Audit
LaunchPermissionon your images regularly and never make an AMI public unless it is intentional and contains no sensitive data. - Treat golden images as code. Build them through a versioned, repeatable pipeline rather than snapshotting a hand-tuned instance, so encryption and hardening are guaranteed every time.
- Clean up old AMIs. Stale unencrypted images linger for years. A lifecycle policy that deregisters images past a retention window keeps the surface area small.
- Re-encrypt during cross-account copies. When you receive an AMI from another account, copy it with your own CMK so you control the key and the data is encrypted under your policy.
Encrypting AMIs costs you almost nothing and closes off a quiet but serious data exposure path. Enable encryption by default, build it into your image pipeline, and let continuous checks catch the stragglers.

