Skip to content

iam: need a well-supported way to depend on added permissions #7236

@blimmer

Description

@blimmer

I'm manually creating an IAM role for my Kinesis Data Stream -> Kinesis Data Firehose infrastructure. However, when I use either role.addToPolicy or stream.grantRead(myRole), it doesn't wait for generated policies to be attached to the created role.

Reproduction Steps

import * as cdk from "@aws-cdk/core";
import * as kinesis from "@aws-cdk/aws-kinesis";
import * as kinesisfirehose from "@aws-cdk/aws-kinesisfirehose";
import * as iam from "@aws-cdk/aws-iam";
import * as s3 from "@aws-cdk/aws-s3";

export class MyStack extends cdk.Stack {
  readonly dataStream: kinesis.Stream;
  readonly s3Bucket: s3.Bucket;
  readonly s3DeliveryStream: kinesisfirehose.CfnDeliveryStream;

  private constructName: string;

  constructor(scope: cdk.Construct, id: string, props: cdk.StackProps) {
    super(scope, id, props);
    this.constructName = "ExampleStack";

    this.dataStream = this.createDataStream();
    this.s3Bucket = this.createS3Bucket();
    this.s3DeliveryStream = this.createDeliveryStream(this.s3Bucket, this.dataStream);
  }

  private createDataStream(): kinesis.Stream {
    return new kinesis.Stream(this, `${this.constructName}DataStream`, {
      shardCount: 1,
    });
  }

  private createS3Bucket(): s3.Bucket {
    return new s3.Bucket(this, `${this.constructName}Bucket`, {
      bucketName: "my-example-bucket-fjdklsajklfdsa123124",
      blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
    });
  }

  private createDeliveryStream(bucket: s3.Bucket, dataStream: kinesis.Stream): kinesisfirehose.CfnDeliveryStream {
    const deliveryStreamRole = new iam.Role(this, `${this.constructName}DeliveryStreamRole`, {
      assumedBy: new iam.ServicePrincipal("firehose.amazonaws.com"),
    });
    dataStream.grantRead(deliveryStreamRole);

    deliveryStreamRole.addToPolicy(
      new iam.PolicyStatement({
        resources: [bucket.bucketArn, `${bucket.bucketArn}/*`],
        actions: [
          "s3:AbortMultipartUpload",
          "s3:GetBucketLocation",
          "s3:GetObject",
          "s3:ListBucket",
          "s3:ListBucketMultipartUploads",
          "s3:PutObject",
        ],
      }),
    );

    const deliveryStream = new kinesisfirehose.CfnDeliveryStream(this, `${this.constructName}DeliveryStream`, {
      deliveryStreamName: `${this.constructName}-delivery-stream`,
      deliveryStreamType: "KinesisStreamAsSource",
      kinesisStreamSourceConfiguration: {
        kinesisStreamArn: dataStream.streamArn,
        roleArn: deliveryStreamRole.roleArn,
      },
      s3DestinationConfiguration: {
        bucketArn: bucket.bucketArn,
        bufferingHints: {
          intervalInSeconds: 300,
          sizeInMBs: 2,
        },
        compressionFormat: "GZIP",
        roleArn: deliveryStreamRole.roleArn,
      },
    });
    // I tried to do this to make it wait for the policies, but it doesn't seem to
    // work.
    deliveryStream.addDependsOn(deliveryStreamRole.node.defaultChild as iam.CfnRole);
    return deliveryStream;
  }
}

Error Log

cdk deploy 'EventBusTestCDKIssue101F1437'
This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:

IAM Statement Changes
┌───┬────────────────────────┬────────┬────────────────────────┬─────────────────────────┬───────────┐
│   │ Resource               │ Effect │ Action                 │ Principal               │ Condition │
├───┼────────────────────────┼────────┼────────────────────────┼─────────────────────────┼───────────┤
│ + │ ${TestCDKIssue/Example │ Allow  │ s3:AbortMultipartUploa │ AWS:${TestCDKIssue/Exam │           │
│   │ StackBucket.Arn}       │        │ d                      │ pleStackDeliveryStreamR │           │
│   │ ${TestCDKIssue/Example │        │ s3:GetBucketLocation   │ ole}                    │           │
│   │ StackBucket.Arn}/*     │        │ s3:GetObject           │                         │           │
│   │                        │        │ s3:ListBucket          │                         │           │
│   │                        │        │ s3:ListBucketMultipart │                         │           │
│   │                        │        │ Uploads                │                         │           │
│   │                        │        │ s3:PutObject           │                         │           │
├───┼────────────────────────┼────────┼────────────────────────┼─────────────────────────┼───────────┤
│ + │ ${TestCDKIssue/Example │ Allow  │ kinesis:DescribeStream │ AWS:${TestCDKIssue/Exam │           │
│   │ StackDataStream.Arn}   │        │ kinesis:GetRecords     │ pleStackDeliveryStreamR │           │
│   │                        │        │ kinesis:GetShardIterat │ ole}                    │           │
│   │                        │        │ or                     │                         │           │
├───┼────────────────────────┼────────┼────────────────────────┼─────────────────────────┼───────────┤
│ + │ ${TestCDKIssue/Example │ Allow  │ sts:AssumeRole         │ Service:firehose.amazon │           │
│   │ StackDeliveryStreamRol │        │                        │ aws.com                 │           │
│   │ e.Arn}                 │        │                        │                         │           │
└───┴────────────────────────┴────────┴────────────────────────┴─────────────────────────┴───────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)

Do you wish to deploy these changes (y/n)? y
EventBusTestCDKIssue101F1437: deploying...
EventBusTestCDKIssue101F1437: creating CloudFormation changeset...
 0/7 | 11:37:19 AM | CREATE_IN_PROGRESS   | AWS::Kinesis::Stream                 | EventBus/TestCDKIssue/ExampleStackDataStream (ExampleStackDataStream6000A15C)
 0/7 | 11:37:19 AM | CREATE_IN_PROGRESS   | AWS::CDK::Metadata                   | CDKMetadata
 0/7 | 11:37:19 AM | CREATE_IN_PROGRESS   | AWS::S3::Bucket                      | EventBus/TestCDKIssue/ExampleStackBucket (ExampleStackBucket87307B5D)
 0/7 | 11:37:19 AM | CREATE_IN_PROGRESS   | AWS::IAM::Role                       | EventBus/TestCDKIssue/ExampleStackDeliveryStreamRole (ExampleStackDeliveryStreamRole99360ADD)
 0/7 | 11:37:19 AM | CREATE_IN_PROGRESS   | AWS::Kinesis::Stream                 | EventBus/TestCDKIssue/ExampleStackDataStream (ExampleStackDataStream6000A15C) Resource creation Initiated
 0/7 | 11:37:20 AM | CREATE_IN_PROGRESS   | AWS::IAM::Role                       | EventBus/TestCDKIssue/ExampleStackDeliveryStreamRole (ExampleStackDeliveryStreamRole99360ADD) Resource creation Initiated
 0/7 | 11:37:21 AM | CREATE_IN_PROGRESS   | AWS::S3::Bucket                      | EventBus/TestCDKIssue/ExampleStackBucket (ExampleStackBucket87307B5D) Resource creation Initiated
 0/7 | 11:37:21 AM | CREATE_IN_PROGRESS   | AWS::CDK::Metadata                   | CDKMetadata Resource creation Initiated
 1/7 | 11:37:21 AM | CREATE_COMPLETE      | AWS::CDK::Metadata                   | CDKMetadata
 2/7 | 11:37:35 AM | CREATE_COMPLETE      | AWS::IAM::Role                       | EventBus/TestCDKIssue/ExampleStackDeliveryStreamRole (ExampleStackDeliveryStreamRole99360ADD)
 3/7 | 11:37:42 AM | CREATE_COMPLETE      | AWS::S3::Bucket                      | EventBus/TestCDKIssue/ExampleStackBucket (ExampleStackBucket87307B5D)
3/7 Currently in progress: ExampleStackDataStream6000A15C
 4/7 | 11:38:20 AM | CREATE_COMPLETE      | AWS::Kinesis::Stream                 | EventBus/TestCDKIssue/ExampleStackDataStream (ExampleStackDataStream6000A15C)
 4/7 | 11:38:22 AM | CREATE_IN_PROGRESS   | AWS::IAM::Policy                     | EventBus/TestCDKIssue/ExampleStackDeliveryStreamRole/DefaultPolicy (ExampleStackDeliveryStreamRoleDefaultPolicy9AA6D67D)
 4/7 | 11:38:22 AM | CREATE_IN_PROGRESS   | AWS::KinesisFirehose::DeliveryStream | EventBus/TestCDKIssue/ExampleStackDeliveryStream (ExampleStackDeliveryStream)
 5/7 | 11:38:23 AM | CREATE_FAILED        | AWS::KinesisFirehose::DeliveryStream | EventBus/TestCDKIssue/ExampleStackDeliveryStream (ExampleStackDeliveryStream) Role arn:aws:iam::<MYACCOUNTNUMBER>:role/EventBusTestCDKIssue101F1-ExampleStackDeliveryStre-QQQLVXOG8HIC is not authorized to perform: kinesis:DescribeStream on resource arn:aws:kinesis:us-west-2:<MYACCOUNTNUMBER>:stream/EventBusTestCDKIssue101F1437-ExampleStackDataStream6000A15C-1XGB6GV60GFKN. (Service: AmazonKinesisFirehose; Status Code: 400; Error Code: InvalidArgumentException; Request ID: da4a0ca8-b564-7949-8d4c-b06783a4b8f2)
	EventBusS3DeliveryStack.createDeliveryStream (/Users/blimmer/code/cdk-example/src/stacks/event-bus-s3-delivery.ts:56:28)
	\_ new EventBusS3DeliveryStack (/Users/blimmer/code/cdk-example/src/stacks/event-bus-s3-delivery.ts:20:34)
	\_ EventBusStack.createS3DeliveryStream (/Users/blimmer/code/cdk-example/src/stacks/event-bus.ts:111:5)
	\_ new EventBusStack (/Users/blimmer/code/cdk-example/src/stacks/event-bus.ts:51:10)
	\_ Object.<anonymous> (/Users/blimmer/code/cdk-example/src/index.ts:16:22)
	\_ Module._compile (internal/modules/cjs/loader.js:1158:30)
	\_ Module.m._compile (/Users/blimmer/code/cdk-example/node_modules/ts-node/src/index.ts:836:23)
	\_ Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
	\_ Object.require.extensions.<computed> [as .ts] (/Users/blimmer/code/cdk-example/node_modules/ts-node/src/index.ts:839:12)
	\_ Module.load (internal/modules/cjs/loader.js:1002:32)
	\_ Function.Module._load (internal/modules/cjs/loader.js:901:14)
	\_ Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
	\_ main (/Users/blimmer/code/cdk-example/node_modules/ts-node/src/bin.ts:226:14)
	\_ Object.<anonymous> (/Users/blimmer/code/cdk-example/node_modules/ts-node/src/bin.ts:485:3)
	\_ Module._compile (internal/modules/cjs/loader.js:1158:30)
	\_ Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
	\_ Module.load (internal/modules/cjs/loader.js:1002:32)
	\_ Function.Module._load (internal/modules/cjs/loader.js:901:14)
	\_ Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
	\_ /Users/blimmer/.nvm/versions/node/v12.16.1/lib/node_modules/npm/node_modules/libnpx/index.js:268:14
 5/7 | 11:38:23 AM | CREATE_IN_PROGRESS   | AWS::IAM::Policy                     | EventBus/TestCDKIssue/ExampleStackDeliveryStreamRole/DefaultPolicy (ExampleStackDeliveryStreamRoleDefaultPolicy9AA6D67D) Resource creation Initiated
 6/7 | 11:38:23 AM | CREATE_FAILED        | AWS::IAM::Policy                     | EventBus/TestCDKIssue/ExampleStackDeliveryStreamRole/DefaultPolicy (ExampleStackDeliveryStreamRoleDefaultPolicy9AA6D67D) Resource creation cancelled
	new Policy (/Users/blimmer/code/cdk-example/node_modules/@aws-cdk/aws-iam/lib/policy.ts:114:22)
	\_ Role.addToPolicy (/Users/blimmer/code/cdk-example/node_modules/@aws-cdk/aws-iam/lib/role.ts:353:28)
	\_ Function.addToPrincipal (/Users/blimmer/code/cdk-example/node_modules/@aws-cdk/aws-iam/lib/grant.ts:147:61)
	\_ Stream.grant (/Users/blimmer/code/cdk-example/node_modules/@aws-cdk/aws-kinesis/lib/stream.ts:168:22)
	\_ Stream.grantRead (/Users/blimmer/code/cdk-example/node_modules/@aws-cdk/aws-kinesis/lib/stream.ts:118:22)
	\_ EventBusS3DeliveryStack.createDeliveryStream (/Users/blimmer/code/cdk-example/src/stacks/event-bus-s3-delivery.ts:40:16)
	\_ new EventBusS3DeliveryStack (/Users/blimmer/code/cdk-example/src/stacks/event-bus-s3-delivery.ts:20:34)
	\_ EventBusStack.createS3DeliveryStream (/Users/blimmer/code/cdk-example/src/stacks/event-bus.ts:111:5)
	\_ new EventBusStack (/Users/blimmer/code/cdk-example/src/stacks/event-bus.ts:51:10)
	\_ Object.<anonymous> (/Users/blimmer/code/cdk-example/src/index.ts:16:22)
	\_ Module._compile (internal/modules/cjs/loader.js:1158:30)
	\_ Module.m._compile (/Users/blimmer/code/cdk-example/node_modules/ts-node/src/index.ts:836:23)
	\_ Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
	\_ Object.require.extensions.<computed> [as .ts] (/Users/blimmer/code/cdk-example/node_modules/ts-node/src/index.ts:839:12)
	\_ Module.load (internal/modules/cjs/loader.js:1002:32)
	\_ Function.Module._load (internal/modules/cjs/loader.js:901:14)
	\_ Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
	\_ main (/Users/blimmer/code/cdk-example/node_modules/ts-node/src/bin.ts:226:14)
	\_ Object.<anonymous> (/Users/blimmer/code/cdk-example/node_modules/ts-node/src/bin.ts:485:3)
	\_ Module._compile (internal/modules/cjs/loader.js:1158:30)
	\_ Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
	\_ Module.load (internal/modules/cjs/loader.js:1002:32)
	\_ Function.Module._load (internal/modules/cjs/loader.js:901:14)
	\_ Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
	\_ /Users/blimmer/.nvm/versions/node/v12.16.1/lib/node_modules/npm/node_modules/libnpx/index.js:268:14
 6/7 | 11:38:24 AM | ROLLBACK_IN_PROGRESS | AWS::CloudFormation::Stack           | EventBusTestCDKIssue101F1437 The following resource(s) failed to create: [ExampleStackDeliveryStream, ExampleStackDeliveryStreamRoleDefaultPolicy9AA6D67D]. . Rollback requested by user.

Environment

  • CLI Version : 1.31.0
  • Framework Version: 1.31.0
  • OS : MacOS
  • Language : English

Other

If I look at the console during the creation of this stack, I can see that the Role is created, but it has no policies attached. The way I've worked around this is by creating the role separately during a cdk deploy, then create the stream. Then, everything works.


This is 🐛 Bug Report

Metadata

Metadata

Assignees

Labels

@aws-cdk/aws-iamRelated to AWS Identity and Access Management@aws-cdk/aws-kinesisRelated to Amazon Kinesiseffort/mediumMedium work item – several days of effortfeature-requestA feature should be added or improved.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions