如何使用CDK同时添加SNS Topic默认策略与自定义策略?
问题:在AWS CDK中创建SNS Topic时,如何同时保留默认访问策略并添加自定义策略?
我通过CDK创建了一个SNS Topic,并附加了自定义策略语句:
const snsTopic = new Topic(this, 'SnsTopic'); const snsTopicPolicyStatement = new PolicyStatement({ effect: Effect.ALLOW, actions: ['SNS:Publish'], principals: [ new ArnPrincipal('arn:xxx'), new ArnPrincipal('arn:xxx'), ], resources: ['SNS_TOPIC_ARN'], }); snsTopicPolicyStatement.sid = 'publishStatementId'; snsTopic.addToResourcePolicy(snsTopicPolicyStatement);
但此时该主题仅拥有这条自定义策略;而如果仅创建Topic不附加任何自定义策略,它会自动生成如下默认访问策略:
{ "Version": "2008-10-17", "Id": "__default_policy_ID", "Statement": [ { "Sid": "__default_statement_ID", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": [ "SNS:GetTopicAttributes", "SNS:SetTopicAttributes", "SNS:AddPermission", "SNS:RemovePermission", "SNS:DeleteTopic", "SNS:Subscribe", "SNS:ListSubscriptionsByTopic", "SNS:Publish" ], "Resource": "arn:xxx", "Condition": { "StringEquals": { "AWS:SourceOwner": "xxx" } } } ] }
请问如何同时为该SNS Topic添加默认访问策略与自定义策略?
解决方案
AWS CDK中,当调用addToResourcePolicy添加自定义策略语句时,默认的资源策略不会自动保留,因此需要手动构建默认策略的语句并添加到Topic中,再追加自定义策略。
具体实现代码
import { Topic, PolicyStatement, Effect, ArnPrincipal, AnyPrincipal } from 'aws-cdk-lib/aws-sns'; import { Stack } from 'aws-cdk-lib'; import { Construct } from 'constructs'; export class SnsTopicStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); const snsTopic = new Topic(this, 'SnsTopic'); const topicArn = snsTopic.topicArn; const accountId = this.account; // 构建与默认策略一致的语句 const defaultPolicyStmt = new PolicyStatement({ effect: Effect.ALLOW, actions: [ 'SNS:GetTopicAttributes', 'SNS:SetTopicAttributes', 'SNS:AddPermission', 'SNS:RemovePermission', 'SNS:DeleteTopic', 'SNS:Subscribe', 'SNS:ListSubscriptionsByTopic', 'SNS:Publish' ], principals: [new AnyPrincipal()], // 对应原默认策略的"AWS": "*" resources: [topicArn], conditions: { StringEquals: { 'AWS:SourceOwner': accountId } } }); defaultPolicyStmt.sid = '__default_statement_ID'; // 添加默认策略语句 snsTopic.addToResourcePolicy(defaultPolicyStmt); // 添加自定义发布策略 const customPublishStmt = new PolicyStatement({ effect: Effect.ALLOW, actions: ['SNS:Publish'], principals: [ new ArnPrincipal('arn:xxx'), new ArnPrincipal('arn:xxx'), ], resources: [topicArn], }); customPublishStmt.sid = 'publishStatementId'; snsTopic.addToResourcePolicy(customPublishStmt); } }
说明
- 手动构建默认策略的
PolicyStatement,完全匹配自动生成的默认策略内容,包括权限动作、主体范围、条件限制等。 - 先将默认策略语句添加到Topic的资源策略中,再添加自定义的策略语句。
- 最终生成的SNS Topic资源策略会同时包含默认语句和自定义语句,既保留了账号内主体对Topic的完整管理权限,又允许指定的外部主体执行发布操作。
内容的提问来源于stack exchange,提问作者Liumx31
相关产品推荐
相关产品推荐

