Rachelle Janssen
Rachelle Janssen

Reputation: 237

How do I check if all resources in my CDK stack have certain properties?

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

Answers (2)

Edwards
Edwards

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

Omar Kacimi
Omar Kacimi

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

Related Questions