Reputation: 237
I'm fairly new to the AWS CDK. I just found out about the aws-cdk/assert module, which is a good reason for me to get more into test-driven development. My main difficulty right now is that I don't entirely understand how to test if all resources of a certain type pass a test. I'm only able to test if there is any resource matching.
Right now I have a combination of expectCDK(stack).to(countResources('AWS::S3::Bucket', 2))
to see if I produce the expected number of buckets, followed by two separate tests to check of they both are private and encrypted.
If I use the following code, it will pass because it simply looks for any resource that has a match (one out of two)
expectCDK(stack).to(haveResource('AWS::S3::Bucket', {
"AccessControl": "Private",
"BucketEncryption": {
"ServerSideEncryptionConfiguration": [
{
"ServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
}
}
]
},
"VersioningConfiguration": {
"Status": "Enabled"
}
}))
Right now it's just two test buckets, but I want to make "least privilege principle" checks for IAM roles later. Given that solutions can have a lot of different roles, I don't want to skip any of them.
Is there a clever way to test if all my buckets are private and encrypted? I wouldn't mind writing testing the synthesized template, but I feel like the expectCDK is a bit closer to the source.
Upvotes: 3
Views: 3979
Reputation: 11
I was able to accomplish this with a little be of complexity:
test("no s3 buckets should be public", () => {
expect(stack).not.toHaveResourceLike("AWS::S3::Bucket", {
PublicAccessBlockConfiguration: ABSENT,
});
expect(stack).not.toHaveResourceLike("AWS::S3::Bucket", {
PublicAccessBlockConfiguration: notMatching(
exactValue({
BlockPublicAcls: true,
BlockPublicPolicy: true,
IgnorePublicAcls: true,
RestrictPublicBuckets: true,
})
),
});
});
test("all s3 buckets should be s3_managed encrypted", () => {
expect(stack).not.toHaveResourceLike("AWS::S3::Bucket", {
BucketEncryption: ABSENT,
});
expect(stack).not.toHaveResourceLike("AWS::S3::Bucket", {
BucketEncryption: notMatching(
exactValue({
ServerSideEncryptionConfiguration: [
{
ServerSideEncryptionByDefault: {
SSEAlgorithm: "AES256",
},
},
],
})
),
});
});
Upvotes: 1
Reputation: 71
This may be late but this may be what you are looking for:
"AccessControl": "Private",
"BucketEncryption": {
"ServerSideEncryptionConfiguration": [
{
"ServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
}
}
]
},
"VersioningConfiguration": {
"Status": "Enabled"
}
}))
Cheers !
Upvotes: 0