Skip to content

[aws-events-targets] Kinesis Stream target with Customer-Managed KMS key causes EventBridge FailedInvocations #10996

@blimmer

Description

@blimmer

When you have a Kinesis stream encrypted by a customer-managed KMS key, aws-events-targets does not give EventBridge permission to encrypt events using the key.

Reproduction Steps

import * as cdk from '@aws-cdk/core';
import * as kinesis from "@aws-cdk/aws-kinesis";
import * as targets from "@aws-cdk/aws-events-targets";
import * as events from '@aws-cdk/aws-events';

export class CdkBugReportsStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const stream = new kinesis.Stream(this, "Stream", {
      encryption: kinesis.StreamEncryption.KMS,
    });
    const target = new targets.KinesisStream(stream);

    new events.Rule(this, "Rule", {
      eventPattern: {
        account: ['123456789'],
      },
      targets: [target],
    });
  }
}

Also available here: https://github.com/blimmer/cdk-bug-reports/compare/bug/kinesis-target-policy?expand=1

What did you expect to happen?

I expected the EventBridge rule to trigger successfully because I used the aws-events-targets package.

What actually happened?

All Invocations were FailedInvocations in Cloudwatch because EventBridge couldn't encrypt the event to PutRecord on the stream.

This is the result of the cdk synth. As you can see, there's StreamEventsRole3ADC0AFD does not have the ability to encrypt using StreamKey238BEC37.

Resources:
  StreamKey238BEC37:
    Type: AWS::KMS::Key
    Properties:
      KeyPolicy:
        Statement:
          - Action:
              - kms:Create*
              - kms:Describe*
              - kms:Enable*
              - kms:List*
              - kms:Put*
              - kms:Update*
              - kms:Revoke*
              - kms:Disable*
              - kms:Get*
              - kms:Delete*
              - kms:ScheduleKeyDeletion
              - kms:CancelKeyDeletion
              - kms:GenerateDataKey
              - kms:TagResource
              - kms:UntagResource
            Effect: Allow
            Principal:
              AWS:
                Fn::Join:
                  - ""
                  - - "arn:"
                    - Ref: AWS::Partition
                    - ":iam::"
                    - Ref: AWS::AccountId
                    - :root
            Resource: "*"
        Version: "2012-10-17"
      Description: Created by CdkBugReportsStack/Stream
    UpdateReplacePolicy: Retain
    DeletionPolicy: Retain
    Metadata:
      aws:cdk:path: CdkBugReportsStack/Stream/Key/Resource
  Stream790BDEE4:
    Type: AWS::Kinesis::Stream
    Properties:
      ShardCount: 1
      RetentionPeriodHours: 24
      StreamEncryption:
        EncryptionType: KMS
        KeyId:
          Fn::GetAtt:
            - StreamKey238BEC37
            - Arn
    Metadata:
      aws:cdk:path: CdkBugReportsStack/Stream/Resource
  StreamEventsRole3ADC0AFD:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: events.amazonaws.com
        Version: "2012-10-17"
    Metadata:
      aws:cdk:path: CdkBugReportsStack/Stream/EventsRole/Resource
  StreamEventsRoleDefaultPolicyC0F247E2:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - kinesis:PutRecord
              - kinesis:PutRecords
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - Stream790BDEE4
                - Arn
        Version: "2012-10-17"
      PolicyName: StreamEventsRoleDefaultPolicyC0F247E2
      Roles:
        - Ref: StreamEventsRole3ADC0AFD
    Metadata:
      aws:cdk:path: CdkBugReportsStack/Stream/EventsRole/DefaultPolicy/Resource
  Rule4C995B7F:
    Type: AWS::Events::Rule
    Properties:
      EventPattern:
        account:
          - "123456789"
      State: ENABLED
      Targets:
        - Arn:
            Fn::GetAtt:
              - Stream790BDEE4
              - Arn
          Id: Target0
          RoleArn:
            Fn::GetAtt:
              - StreamEventsRole3ADC0AFD
              - Arn
    Metadata:
      aws:cdk:path: CdkBugReportsStack/Rule/Resource
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Modules: aws-cdk=1.69.0,@aws-cdk/assets=1.69.0,@aws-cdk/aws-applicationautoscaling=1.69.0,@aws-cdk/aws-autoscaling=1.69.0,@aws-cdk/aws-autoscaling-common=1.69.0,@aws-cdk/aws-autoscaling-hooktargets=1.69.0,@aws-cdk/aws-cloudwatch=1.69.0,@aws-cdk/aws-codeguruprofiler=1.69.0,@aws-cdk/aws-ec2=1.69.0,@aws-cdk/aws-ecr=1.69.0,@aws-cdk/aws-ecr-assets=1.69.0,@aws-cdk/aws-ecs=1.69.0,@aws-cdk/aws-elasticloadbalancingv2=1.69.0,@aws-cdk/aws-events=1.69.0,@aws-cdk/aws-events-targets=1.69.0,@aws-cdk/aws-iam=1.69.0,@aws-cdk/aws-kinesis=1.69.0,@aws-cdk/aws-kms=1.69.0,@aws-cdk/aws-lambda=1.69.0,@aws-cdk/aws-logs=1.69.0,@aws-cdk/aws-s3=1.69.0,@aws-cdk/aws-s3-assets=1.69.0,@aws-cdk/aws-servicediscovery=1.69.0,@aws-cdk/aws-sns=1.69.0,@aws-cdk/aws-sns-subscriptions=1.69.0,@aws-cdk/aws-sqs=1.69.0,@aws-cdk/aws-ssm=1.69.0,@aws-cdk/cloud-assembly-schema=1.69.0,@aws-cdk/core=1.69.0,@aws-cdk/custom-resources=1.69.0,@aws-cdk/cx-api=1.69.0,@aws-cdk/region-info=1.69.0,jsii-runtime=node.js/v12.19.0
    Metadata:
      aws:cdk:path: CdkBugReportsStack/CDKMetadata/Default
    Condition: CDKMetadataAvailable
Conditions:
  CDKMetadataAvailable:
    Fn::Or:
      - Fn::Or:
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-east-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-northeast-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-northeast-2
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-southeast-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-southeast-2
          - Fn::Equals:
              - Ref: AWS::Region
              - ca-central-1
          - Fn::Equals:
              - Ref: AWS::Region
              - cn-north-1
          - Fn::Equals:
              - Ref: AWS::Region
              - cn-northwest-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-central-1
      - Fn::Or:
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-north-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-2
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-3
          - Fn::Equals:
              - Ref: AWS::Region
              - me-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - sa-east-1
          - Fn::Equals:
              - Ref: AWS::Region
              - us-east-1
          - Fn::Equals:
              - Ref: AWS::Region
              - us-east-2
          - Fn::Equals:
              - Ref: AWS::Region
              - us-west-1
          - Fn::Equals:
              - Ref: AWS::Region
              - us-west-2

Environment

  • CLI Version : 1.69.0
  • Framework Version: 1.69.0
  • Node.js Version: 14.8.0
  • OS : macOS
  • Language (Version): all

Other

If you don't explicitly specify encryption e.g.,

const stream = new kinesis.Stream(this, "Stream");

It automatically uses the Customer Master Key, which does not cause FailedInvocations.


This is 🐛 Bug Report

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions