Skip to content

Commit

Permalink
feat(sns): enable passing PolicyDocument to TopicPolicy (#10559)
Browse files Browse the repository at this point in the history
Adds optional `policyDocument` prop to `TopicPolicyProps` to allow passing existing policy documents.

fixes #7934

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
ap00rv committed Mar 17, 2021
1 parent e5297b1 commit 0d9c300
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 0 deletions.
40 changes: 40 additions & 0 deletions packages/@aws-cdk/aws-sns/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,43 @@ codeCommitRepository.onCommit(new targets.SnsTopic(myTopic));

This will result in adding a target to the event rule and will also modify the
topic resource policy to allow CloudWatch events to publish to the topic.

## Topic Policy

A topic policy is automatically created when `addToResourcePolicy` is called, if
one doesn't already exist. Using `addToResourcePolicy` is the simplest way to
add policies, but a `TopicPolicy` can also be created manually.

```ts
const topic = new sns.Topic(stack, 'Topic');
const topicPolicy = new sns.TopicPolicy(stack, 'TopicPolicy', {
topics: [topic],
});

topicPolicy.document.addStatements(new iam.PolicyStatement({
actions: ["sns:Subscribe"],
principals: [new iam.AnyPrincipal()],
resources: [topic.topicArn],
}));
```

A policy document can also be passed on `TopicPolicy` construction

```ts
const topic = new sns.Topic(stack, 'Topic');
const policyDocument = new iam.PolicyDocument({
assignSids: true,
statements: [
new iam.PolicyStatement({
actions: ["sns:Subscribe"],
principals: [new iam.AnyPrincipal()],
resources: [topic.topicArn]
}),
],
});

const topicPolicy = new sns.TopicPolicy(this, 'Policy', {
topics: [topic],
policyDocument,
});
```
8 changes: 8 additions & 0 deletions packages/@aws-cdk/aws-sns/lib/policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ export interface TopicPolicyProps {
* The set of topics this policy applies to.
*/
readonly topics: ITopic[];
/**
* IAM policy document to apply to topic(s).
* @default empty policy document
*/
readonly policyDocument?: PolicyDocument;

}

/**
Expand All @@ -32,6 +38,8 @@ export class TopicPolicy extends Resource {
constructor(scope: Construct, id: string, props: TopicPolicyProps) {
super(scope, id);

this.document = props.policyDocument ?? this.document;

new CfnTopicPolicy(this, 'Resource', {
policyDocument: this.document,
topics: props.topics.map(t => t.topicArn),
Expand Down
91 changes: 91 additions & 0 deletions packages/@aws-cdk/aws-sns/test/test.sns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,97 @@ export = {
test.done();
},

'TopicPolicy passed document'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const topic = new sns.Topic(stack, 'MyTopic');
const ps = new iam.PolicyStatement({
actions: ['service:statement0'],
principals: [new iam.ArnPrincipal('arn')],
});

// WHEN
new sns.TopicPolicy(stack, 'topicpolicy', { topics: [topic], policyDocument: new iam.PolicyDocument({ assignSids: true, statements: [ps] }) });

// THEN
expect(stack).toMatch({
'Resources': {
'MyTopic86869434': {
'Type': 'AWS::SNS::Topic',
},
'topicpolicyF8CF12FD': {
'Type': 'AWS::SNS::TopicPolicy',
'Properties': {
'PolicyDocument': {
'Statement': [
{
'Action': 'service:statement0',
'Effect': 'Allow',
'Principal': { 'AWS': 'arn' },
'Sid': '0',
},
],
'Version': '2012-10-17',
},
'Topics': [
{
'Ref': 'MyTopic86869434',
},
],
},
},
},
});

test.done();
},

'Add statements to policy'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const topic = new sns.Topic(stack, 'MyTopic');

// WHEN
const topicPolicy = new sns.TopicPolicy(stack, 'TopicPolicy', {
topics: [topic],
});
topicPolicy.document.addStatements(new iam.PolicyStatement({
actions: ['service:statement0'],
principals: [new iam.ArnPrincipal('arn')],
}));

// THEN
expect(stack).toMatch({
'Resources': {
'MyTopic86869434': {
'Type': 'AWS::SNS::Topic',
},
'TopicPolicyA24B096F': {
'Type': 'AWS::SNS::TopicPolicy',
'Properties': {
'PolicyDocument': {
'Statement': [
{
'Action': 'service:statement0',
'Effect': 'Allow',
'Principal': { 'AWS': 'arn' },
'Sid': '0',
},
],
'Version': '2012-10-17',
},
'Topics': [
{
'Ref': 'MyTopic86869434',
},
],
},
},
},
});
test.done();
},

'topic resource policy includes unique SIDs'(test: Test) {
const stack = new cdk.Stack();

Expand Down

0 comments on commit 0d9c300

Please sign in to comment.