Automating EBS Default Encryption Across Your Organization
A practical guide to implementing organization-wide EBS encryption using CloudFormation StackSets
The Challenge
Organizations with multiple AWS accounts need consistent EBS encryption policies to protect data at rest and satisfy compliance requirements. Manual enablement of EBS default encryption across hundreds of accounts and regions becomes impractical and creates security gaps. Organizations need automated deployment that enables EBS default encryption organization-wide without ongoing maintenance overhead.
This best practice is supported by CIS AWS Foundations Benchmark v3.0.0 EC2.7 control, which requires that EBS default encryption should be enabled.
Manual vs Automated EBS Default Encryption
Manual EBS encryption configuration creates compliance gaps and operational overhead compared to automated organization-wide deployment:
Manual Configuration Problems:
- Scale management across hundreds of accounts and multiple regions
- Inconsistent encryption settings between accounts
- New accounts may lack EBS default encryption enabled
Automated Benefits:
- Organization-wide consistency across all accounts and regions
- Automatic application to new accounts without manual intervention
- Ensures all new EBS volumes are encrypted by default
Implementation Approach
CloudFormation StackSets provide scalable deployment using Lambda-backed custom resources to call the EC2 Account Management API. AWS CloudFormation lacks native support for account-level EBS default encryption configuration, making custom resources the standard implementation approach. The solution deploys consistently across all accounts and regions, automatically applying to new accounts when configured with automatic deployment.
CloudFormation Template
AWSTemplateFormatVersion: '2010-09-09' Parameters: DefaultKMSKeyId: Type: String Default: 'alias/aws/ebs' Description: 'Default KMS key for EBS encryption (use alias/aws/ebs for AWS managed key)' Resources: EBSDefaultEncryption: Type: AWS::CloudFormation::CustomResource Properties: ServiceToken: !GetAtt EBSEncryptionFunction.Arn DefaultKMSKeyId: !Ref DefaultKMSKeyId EBSEncryptionFunction: Type: AWS::Lambda::Function Properties: Runtime: python3.12 Handler: index.handler Role: !GetAtt LambdaExecutionRole.Arn Code: ZipFile: | import boto3 import cfnresponse def handler(event, context): try: # Get all regions ec2_client = boto3.client('ec2') regions = [region['RegionName'] for region in ec2_client.describe_regions()['Regions']] if event['RequestType'] == 'Create' or event['RequestType'] == 'Update': for region in regions: try: regional_ec2 = boto3.client('ec2', region_name=region) # Enable EBS default encryption regional_ec2.enable_ebs_encryption_by_default() # Set default KMS key (only after encryption is enabled) kms_key_id = event['ResourceProperties']['DefaultKMSKeyId'] if kms_key_id: regional_ec2.modify_ebs_default_kms_key_id(KmsKeyId=kms_key_id) except Exception as e: print(f"Error in region {region}: {str(e)}") # Continue with other regions cfnresponse.send(event, context, cfnresponse.SUCCESS, {}) except Exception as e: print(f"Error: {str(e)}") cfnresponse.send(event, context, cfnresponse.FAILED, {}) LambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Policies: - PolicyName: EBSEncryptionManagement PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - ec2:EnableEbsEncryptionByDefault - ec2:GetEbsEncryptionByDefault - ec2:ModifyEbsDefaultKmsKeyId - ec2:GetEbsDefaultKmsKeyId - ec2:DescribeRegions Resource: '*' Outputs: EBSEncryptionStatus: Description: 'EBS default encryption configuration completed' Value: 'Enabled across all regions' Export: Name: !Sub '${AWS::StackName}-EBSEncryptionStatus'
Deployment Strategy
Deploy using CloudFormation StackSets from the management account or delegated administrator. Target the entire organization and enable automatic deployment for new accounts.
# Create StackSet with auto-deployment enabled aws cloudformation create-stack-set \ --stack-set-name ebs-default-encryption-stackset \ --template-body file://ebs-default-encryption.yaml \ --capabilities CAPABILITY_IAM \ --auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false \ --parameters ParameterKey=DefaultKMSKeyId,ParameterValue=alias/aws/ebs # Deploy to entire organization aws cloudformation create-stack-instances \ --stack-set-name ebs-default-encryption-stackset \ --deployment-targets OrganizationalUnitIds=r-1234567890abcdef \ --regions us-east-1 \ --operation-preferences MaxConcurrentPercentage=100
Deployment Targets:
r-1234567890abcdef- Organization root ID (targets entire organization)ou-1234567890abcdef- Organizational unit ID (targets specific OU)
Auto-Deployment: New accounts added to the organization automatically receive EBS default encryption configuration without manual intervention.
Operations and Maintenance
EBS default encryption is persistent and requires no ongoing maintenance once enabled. The setting applies automatically to all new EBS volumes and snapshots created in each region, providing comprehensive coverage without per-resource configuration.
AWS Security Hub provides built-in detective controls to monitor accounts without proper EBS default encryption through CIS compliance checks.
Testing and Validation
Validate the EBS default encryption deployment:
Check Encryption Status:
# Verify EBS default encryption is enabled aws ec2 get-ebs-encryption-by-default --region us-east-1 # Check default KMS key configuration aws ec2 get-ebs-default-kms-key-id --region us-east-1
Test Volume Creation:
# Create new EBS volume (should be automatically encrypted) aws ec2 create-volume \ --size 10 \ --availability-zone us-east-1a # Verify volume is encrypted aws ec2 describe-volumes --volume-ids vol-1234567890abcdef
Expected Results:
- EBS default encryption should show as enabled
- Default KMS key should be configured
- New volumes should be automatically encrypted without explicit encryption parameter
Limitations and Considerations
This implementation enables EBS default encryption but has specific operational considerations:
Scope and Coverage:
- ✅ Applies to all new EBS volumes and snapshots
- ✅ Works across all current and previous generation instance types
- ⚠️ Does not affect existing unencrypted volumes
Regional Considerations:
- EBS default encryption is region-specific
- Lambda function enables encryption in all available regions
- New regions require stack update or manual enablement
Cost Implications:
- No additional charges for EBS encryption
- KMS key usage charges apply for customer-managed keys
- AWS managed keys (alias/aws/ebs) have no additional charges
Next Steps
While this implementation satisfies CIS EC2.7 compliance requirements, organizations should consider encrypting existing unencrypted EBS volumes and implementing monitoring for encryption compliance across their infrastructure.
This implementation supports security best practices and satisfies CIS AWS Foundations Benchmark v3.0.0 EC2.7 control requirements.
- Language
- English
Relevant content
AWS OFFICIALUpdated 3 years ago