amazon-web-servicesamazon-s3amazon-iamaws-sdk-nodejs

How do I add a policy statement to a customer managed policy through CDK?


I've created a customer-managed policy Field-Bookish-Dev via the AWS console with the following policy statement:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "s3:ListAllMyBuckets",
            "Resource": "*"
        }
    ]
}

Now I'd like to add an additional policy statement, that allows writing to a bucket, through CDK, so I devised the following:

The following is the code directly related to the above tasks in TypeScript, and using aws-cdk@2.85.0:

import * as cdk from "aws-cdk-lib";
import * as s3 from "aws-cdk-lib/aws-s3";
import * as iam from "aws-cdk-lib/aws-iam";

export class FieldBookBucketStack extends cdk.Stack {
   constructor(scope: Construct, id: string) {  
     const s3Bucket = new s3.Bucket(this, ...);

     // Get customer-managed policy from its ARN.
     const fieldBookBucketPolicyArn = "arn:aws:iam::xxxxxxxxxxxx:policy/Field-Bookish-Dev";
     const fieldBookBucketPolicy = iam.ManagedPolicy.fromManagedPolicyArn(
       this,
      `field-book-bucket-policy-dev`,
       tcuBucketPolicyArn,
     ) as iam.ManagedPolicy;

     // Declare a new policy statement.
     const s3PutObjectPolicy = new iam.PolicyStatement({
       effect: iam.Effect.ALLOW,
       actions: ["s3:PutObject"],
       resources: [s3bucket.bucketArn],
       principals: [new iam.AnyPrincipal()],
     });

     // Add additional permission to existing policy.
     tcuBucketPolicy.addStatements(s3PutObjectPolicy);


     // Additional CDK setup unrelated to policies.
  }
}

When I try to deploy the stack I get the following error:

TypeError: fieldBookBucketPolicy.addStatements is not a function

NOTE: I could probably add the policy statement via the AWS console and call it a day, but I'd like to know if what I'm trying to do is feasible via CDK.


Solution

  • You can't. A CDK app cannot modify resources, such as your Managed Policy, that it doesn't manage. The fromManagedPolicyArn method returns an IManagedPolicy construct. It is a read-only reference, useful for passing your existing Managed Policy's ARN to another construct. The addStatements method does not exist on IManagedPolicy, because that would mean changing an external resource, which the CDK can't do.

    This is a common CDK pattern. Methods like fromFooName return a read-only IFoo interface class, not a writeable Foo construct.