aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.56k stars 3.87k forks source link

L2 SNS Topic: Setting enforceSSL prop to true does not create AWS::SNS::TopicPolicy #31558

Open jaychung-aws opened 1 week ago

jaychung-aws commented 1 week ago

Describe the bug

CDK Version used: 2.147.2

Steps to Reproduce:

  1. Create a L2 SNS Topic construct with enforceSSL prop set to true.
    
    import * as cdk from 'aws-cdk-lib';
    import * as sns from 'aws-cdk-lib/aws-sns';

const stack = new cdk.Stack();

const topic = new sns.Topic(stack, 'MySNSTopic', { topicName: 'my-sns-topic', enforceSSL: true, });

3. cdk synth.
4. Inspect the synthesized CloudFormation template.
5. Check if CDK generated an `AWS::SNS::TopicPolicy` with a statement that denies any sns::Publish if aws:SecureTransport is false, as follows:

{ "Action": "sns:Publish", "Condition": { "Bool": { "aws:SecureTransport": "false" } }, "Effect": "Deny", "Principal": "*", "Resource": { "Ref": "SnsTopicStdAllProps5206973F" }, "Sid": "AllowPublishThroughSSLOnly" }

6. CDK does not create the expected `AWS::SNS::TopicPolicy`. However, if you haven a policy statement being added as follows to the Topic via `.addToResourcePolicy(..)`:

import as cdk from 'aws-cdk-lib'; import as sns from 'aws-cdk-lib/aws-sns';

const stack = new cdk.Stack();

const topic = new sns.Topic(stack, 'MySNSTopic', { topicName: 'my-sns-topic', enforceSSL: true, }); topic.addToResourcePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW, principals: [ new iam.ServicePrincipal('sns.amazonaws.com'), ], actions: [ 'SNS:Publish', ], resources: [ '*', ], }));

then CDK correctly creates an `AWS::SNS::TopicPolicy` and appends the above statement to it:

"SnsTopicStdAllPropsPolicy76A2A260": { "Type": "AWS::SNS::TopicPolicy", "Properties": { "PolicyDocument": { "Statement": [ { "Action": "SNS:Publish", "Effect": "Allow", "Principal": { "Service": "sns.amazonaws.com" }, "Resource": "", "Sid": "0" }, { "Action": "sns:Publish", "Condition": { "Bool": { "aws:SecureTransport": "false" } }, "Effect": "Deny", "Principal": "", "Resource": { "Ref": "SnsTopicStdAllProps5206973F" }, "Sid": "AllowPublishThroughSSLOnly" } ], "Version": "2012-10-17" }, "Topics": [ { "Ref": "SnsTopicStdAllProps5206973F" } ] }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete", "Metadata": { "aws:cdk:path": "TestedConstructStacks-SNSTopicStdAllProperties-stack/SnsTopicStdAllProps/Policy/Resource" } }


### Regression Issue

- [ ] Select this option if this issue appears to be a regression.

### Last Known Working CDK Version

_No response_

### Expected Behavior

When a user synthesizes a CDK stack containing L2 SNS Topic with `enforceSSL` set to true, then CDK should output a CloudFormation stack that contains an `AWS::SNS::TopicPolicy` with a statement that "Adds a statement to enforce encryption of data in transit when publishing to the topic" as defined in the CDK documentation.

### Current Behavior

When a user synthesizes a CDK stack containing L2 SNS Topic with `enforceSSL` set to true, CDK does not output a CloudFormation stack that contains an `AWS::SNS::TopicPolicy` with a statement that "Adds a statement to enforce encryption of data in transit when publishing to the topic" as defined in the CDK documentation.

CDK however handles this correctly when there is a policy being added to the Topic via `.addToResourcePolicy()`. In this case, a `AWS::SNS::TopicPolicy` is included in the synthesized CloudFormation template where the statement that blocks sns::Publish from sources that do not use SSL.

### Reproduction Steps

aws-cdk-lib Version used:
2.147.2

Steps to Reproduce:

1. Create a L2 SNS Topic construct with `enforceSSL` prop set to true.

import as cdk from 'aws-cdk-lib'; import as sns from 'aws-cdk-lib/aws-sns';

const stack = new cdk.Stack();

const topic = new sns.Topic(stack, 'MySNSTopic', { topicName: 'my-sns-topic', enforceSSL: true, });

3. cdk synth.
4. Inspect the synthesized CloudFormation template.
5. Check if CDK generated an `AWS::SNS::TopicPolicy` with a statement that denies any sns::Publish if aws:SecureTransport is false, as follows:

{ "Action": "sns:Publish", "Condition": { "Bool": { "aws:SecureTransport": "false" } }, "Effect": "Deny", "Principal": "*", "Resource": { "Ref": "SnsTopicStdAllProps5206973F" }, "Sid": "AllowPublishThroughSSLOnly" }

6. CDK does not create the expected `AWS::SNS::TopicPolicy`. However, if you haven a policy statement being added as follows to the Topic via `.addToResourcePolicy(..)`:

import as cdk from 'aws-cdk-lib'; import as sns from 'aws-cdk-lib/aws-sns';

const stack = new cdk.Stack();

const topic = new sns.Topic(stack, 'MySNSTopic', { topicName: 'my-sns-topic', enforceSSL: true, }); topic.addToResourcePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW, principals: [ new iam.ServicePrincipal('sns.amazonaws.com'), ], actions: [ 'SNS:Publish', ], resources: [ '*', ], }));

then CDK correctly creates an `AWS::SNS::TopicPolicy` and appends the above statement to it:

"SnsTopicStdAllPropsPolicy76A2A260": { "Type": "AWS::SNS::TopicPolicy", "Properties": { "PolicyDocument": { "Statement": [ { "Action": "SNS:Publish", "Effect": "Allow", "Principal": { "Service": "sns.amazonaws.com" }, "Resource": "", "Sid": "0" }, { "Action": "sns:Publish", "Condition": { "Bool": { "aws:SecureTransport": "false" } }, "Effect": "Deny", "Principal": "", "Resource": { "Ref": "SnsTopicStdAllProps5206973F" }, "Sid": "AllowPublishThroughSSLOnly" } ], "Version": "2012-10-17" }, "Topics": [ { "Ref": "SnsTopicStdAllProps5206973F" } ] }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete", "Metadata": { "aws:cdk:path": "TestedConstructStacks-SNSTopicStdAllProperties-stack/SnsTopicStdAllProps/Policy/Resource" } }



### Possible Solution

_No response_

### Additional Information/Context

_No response_

### CDK CLI Version

2.156.0

### Framework Version

_No response_

### Node.js Version

18.20.2

### OS

MacOS Sonoma 14.6.1

### Language

TypeScript

### Language Version

_No response_

### Other information

_No response_
ashishdhingra commented 6 days ago

Reproducible using customer provided code. Simply using the below code doesn't create AWS::SNS::TopicPolicy at all (AWS CDK version 2.160.0 (build 7a8ae02)):

import * as cdk from 'aws-cdk-lib';
import * as sns from 'aws-cdk-lib/aws-sns';

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

    const topic = new sns.Topic(this, 'MySNSTopic', {
      topicName: 'my-sns-topic',
      enforceSSL: true,
    });
  }
}

PR https://github.com/aws/aws-cdk/pull/31569 contributed by community addresses the issue.