How to create an IAM policy with multiple statements using CDK?

Viewed 6857

I am trying to explore if there is a better way. I just define the IAM policy using policy generator and then use the following --

const policyDocument = {
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "FirstStatement",
      "Effect": "Allow",
      "Action": ["iam:ChangePassword"],
      "Resource": "*"
    },
    {
      "Sid": "SecondStatement",
      "Effect": "Allow",
      "Action": [
        "s3:List*",
        "s3:Get*"
      ],
      "Resource": [
        "arn:aws:s3:::confidential-data",
        "arn:aws:s3:::confidential-data/*"
      ],
      "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
    }
  ]
};

Then following needs to defined --

const customPolicyDocument = iam.PolicyDocument.fromJson(policyDocument);

const newManagedPolicy = new ManagedPolicy(stack, 'MyNewManagedPolicy', {
  document: customPolicyDocument
});
const newPolicy = new Policy(stack, 'MyNewPolicy', {
  document: customPolicyDocument
});

Finally, I create a role and attach the policy -

const TestBucketRole = new iam.Role(this, 'TestBucketRole', {
        assumedBy: new iam.ArnPrincipal('arn:aws:iam::123456789012:user/user1'),
        roleName: "test-role-cdk"
    }) 
 
   TestBucketRole.attachInlinePolicy(newPolicy);

Is there a better way of doing this ?

1 Answers

you can use CDK constructs to iam.PolicyDocument and iam.PolicyStatement to achieve the same thing:

import * as iam from "@aws-cdk/aws-iam";

let policy = new iam.PolicyDocument({
  statements: [
    new iam.PolicyStatement({
      effect: iam.Effect.ALLOW,
      actions: ["iam:ChangePassword"],
      resources: ["*"],
    }),
    new iam.PolicyStatement({
      effect: iam.Effect.ALLOW,
      actions: ["iam:ChangePassword"],
      resources: ["*"],
    }),
    new iam.PolicyStatement({
      effect: iam.Effect.ALLOW,
      actions: ["s3:List*", "s3:Get*"],
      resources: [
        "arn:aws:s3:::confidential-data",
        "arn:aws:s3:::confidential-data/*",
      ],
      conditions: {
        Bool: { "aws:MultiFactorAuthPresent": "true" },
      },
    }),
  ],
});

what I like about using CDK constructs instead of JSON is the TypeScript property/type checking and autocomplete.

but in the end, they are interchangeable!

Related