AWS has this "automatic encryption" setting that I'd like to turn on for my account: https://aws.amazon.com/premiumsupport/knowledge-center/ebs-automatic-encryption/.
I've spent a while poking around, and I cannot figure out how to enable that setting with CDK. Is it possible?
Possibly relevant links from my research:
I also was not able to find a way to do this with the EC2 CDK construct, I was however able to solve this using the AwsCustomResource construct to make the SDK call to enable-ebs-encryption-by-default. I will also note that in my case I wanted to use a KMS key that was customer managed, so this required an additional SDK call/custom resource to modify-ebs-default-kms-key-id otherwise the first call will just ensure that the EBS volumes are encrypted with the default AWS managed EBS KMS key. Be aware though that if you use a customer managed KMS key as the default key and then you will also need to modify the key policy so the CDK stack itself can use it (you also need to ensure your EC2 instances have an IAM policy that allows use of the key as well. Below is a snippet of code for how I solved this in Typescript, however you can use this same approach in your language of choice.
TL;DR if you can't find a way to implement what you want via a standard CDK construct you can always use a custom resource to make virtually any AWS SDK/API call.
// first modify the EBS default KMS key
const modifyEbsDefaultKmsKeyId: cr.AwsCustomResource = new cr.AwsCustomResource(
this,
'modifyEbsDefaultKmsKeyId', {
onUpdate: { // will also be called for a CREATE event
service: 'EC2',
action: 'modifyEbsDefaultKmsKeyId',
parameters: {
'KmsKeyId': 'your-key-id-here'
},
physicalResourceId: cr.PhysicalResourceId.of(`modifyEbsDefaultKmsKeyId`),
},
policy: cr.AwsCustomResourcePolicy.fromSdkCalls({
resources: cr.AwsCustomResourcePolicy.ANY_RESOURCE,
}
),
}
);
// then enable EBS encryption by default
const enableEbsEncryptionByDefault: cr.AwsCustomResource = new cr.AwsCustomResource(
this,
'enableEbsEncryptionByDefault', {
onUpdate: { // will also be called for a CREATE event
service: 'EC2',
action: 'enableEbsEncryptionByDefault',
physicalResourceId: cr.PhysicalResourceId.of('enableEbsEncryptionByDefault'),
},
policy: cr.AwsCustomResourcePolicy.fromSdkCalls({
resources: cr.AwsCustomResourcePolicy.ANY_RESOURCE,
}
),
}
);
// KMS key and key policy required for the code above (I created this in my KMS stack and pass the key into my consuming stack)
this.emrKmsKey = this.createKmsKey(emrKmsKeyName)
// added below to enable key to be used as default ebs key
this.emrKmsKey.addToResourcePolicy(new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
principals: [
new iam.StarPrincipal()
],
actions: [
'kms:Encrypt',
'kms:Decrypt',
'kms:ReEncrypt*',
'kms:GenerateDataKey*',
'kms:CreateGrant',
'kms:DescribeKey',
],
resources: [
'*'
],
conditions: {
'StringEquals': {
'kms:CallerAccount': `${awsAccount}`,
'kms:ViaService': `ec2.${region}.amazonaws.com`
}
}
}
)
)