Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(sns): use ICfnTopic wherever possible #28298

Merged
merged 3 commits into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-appconfig-alpha/lib/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ export class SnsDestination implements IEventDestination {
public readonly type: SourceType;
public readonly policyDocument?: iam.PolicyDocument;

constructor(topic: sns.ITopic) {
this.extensionUri = topic.topicArn;
constructor(topic: sns.ICfnTopic) {
this.extensionUri = topic.attrTopicArn;
this.type = SourceType.SNS;
const policy = new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ export class SnsTopicAction implements iot.IAction {
* @param topic The Amazon SNS topic to publish data on. Must not be a FIFO topic.
* @param props Properties to configure the action.
*/
constructor(topic: sns.ITopic, props: SnsTopicActionProps = {}) {
if (topic.fifo) {
constructor(topic: sns.ICfnTopic, props: SnsTopicActionProps = {}) {
this.topic = sns.Topic.fromCfnTopic(topic);

if (this.topic.fifo) {
throw Error('IoT Rule actions cannot be used with FIFO SNS Topics, please pass a non-FIFO Topic instead');
}

this.topic = topic;
this.role = props.role;
this.messageFormat = props.messageFormat;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import { sameEnvDimension } from './util';
*/
export class SnsPublish extends ScheduleTargetBase implements IScheduleTarget {
constructor(
private readonly topic: sns.ITopic,
private readonly topic: sns.ICfnTopic,
private readonly props: ScheduleTargetBaseProps = {},
) {
super(props, topic.topicArn);
super(props, topic.attrTopicArn);
}

protected addTargetActionToRole(schedule: ISchedule, role: IRole): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import * as sns from '../../aws-sns';
* Use an SNS topic as a hook target
*/
export class TopicHook implements autoscaling.ILifecycleHookTarget {
constructor(private readonly topic: sns.ITopic) {
private readonly _topic: sns.ITopic;

constructor(topic: sns.ICfnTopic) {
this._topic = sns.Topic.fromCfnTopic(topic);
}

/**
Expand All @@ -18,10 +21,10 @@ export class TopicHook implements autoscaling.ILifecycleHookTarget {
*/
public bind(_scope: Construct, options: autoscaling.BindHookTargetOptions): autoscaling.LifecycleHookTargetConfig {
const role = createRole(_scope, options.role);
this.topic.grantPublish(role);
this._topic.grantPublish(role);

return {
notificationTargetArn: this.topic.topicArn,
notificationTargetArn: this._topic.attrTopicArn,
createdRole: role,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1746,7 +1746,7 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
}

return this.notifications.map(notification => ({
topicArn: notification.topic.topicArn,
topicArn: notification.topic.attrTopicArn,
notificationTypes: notification.scalingEvents ? notification.scalingEvents._types : ScalingEvents.ALL._types,
}));
}
Expand Down Expand Up @@ -1874,7 +1874,7 @@ export interface NotificationConfiguration {
/**
* SNS topic to send notifications about fleet scaling events
*/
readonly topic: sns.ITopic;
readonly topic: sns.ICfnTopic;

/**
* Which fleet scaling events triggers a notification
Expand Down
7 changes: 4 additions & 3 deletions packages/aws-cdk-lib/aws-backup/lib/vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export interface BackupVaultProps {
*
* @default - no notifications
*/
readonly notificationTopic?: sns.ITopic
readonly notificationTopic?: sns.ICfnTopic;

/**
* The vault events to send.
Expand Down Expand Up @@ -276,11 +276,12 @@ export class BackupVault extends BackupVaultBase {

let notifications: CfnBackupVault.NotificationObjectTypeProperty | undefined;
if (props.notificationTopic) {
const notificationTopic = sns.Topic.fromCfnTopic(props.notificationTopic);
notifications = {
backupVaultEvents: props.notificationEvents || Object.values(BackupVaultEvents),
snsTopicArn: props.notificationTopic.topicArn,
snsTopicArn: notificationTopic.attrTopicArn,
};
props.notificationTopic.grantPublish(new iam.ServicePrincipal('backup.amazonaws.com'));
notificationTopic.grantPublish(new iam.ServicePrincipal('backup.amazonaws.com'));
}

this.accessPolicy = props.accessPolicy ?? new iam.PolicyDocument();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export interface SlackChannelConfigurationProps {
*
* @default None
*/
readonly notificationTopics?: sns.ITopic[];
readonly notificationTopics?: sns.ICfnTopic[];

/**
* Specifies the logging level for this configuration.
Expand Down Expand Up @@ -290,7 +290,7 @@ export class SlackChannelConfiguration extends SlackChannelConfigurationBase {

this.grantPrincipal = this.role;

this.notificationTopics = props.notificationTopics ?? [];
this.notificationTopics = props.notificationTopics?.forEach((topic) => sns.Topic.fromCfnTopic(topic)) ?? [];

const configuration = new CfnSlackChannelConfiguration(this, 'Resource', {
configurationName: props.slackChannelConfigurationName,
Expand Down Expand Up @@ -322,8 +322,8 @@ export class SlackChannelConfiguration extends SlackChannelConfigurationBase {
* Adds a SNS topic that deliver notifications to AWS Chatbot.
* @param notificationTopic
*/
public addNotificationTopic(notificationTopic: sns.ITopic): void {
this.notificationTopics.push(notificationTopic);
public addNotificationTopic(notificationTopic: sns.ICfnTopic): void {
this.notificationTopics.push(sns.Topic.fromCfnTopic(notificationTopic));
}
}

4 changes: 2 additions & 2 deletions packages/aws-cdk-lib/aws-cloudformation/lib/nested-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export interface NestedStackProps {
*
* @default - notifications are not sent for this stack.
*/
readonly notifications?: sns.ITopic[];
readonly notifications?: sns.ICfnTopic[];
}

/**
Expand All @@ -68,7 +68,7 @@ export class NestedStack extends core.NestedStack {
super(scope, id, {
parameters: props.parameters,
timeout: props.timeout,
notificationArns: props.notifications?.map(n => n.topicArn),
notificationArns: props.notifications?.map(n => n.attrTopicArn),
});
}
}
4 changes: 2 additions & 2 deletions packages/aws-cdk-lib/aws-cloudtrail/lib/cloudtrail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export interface TrailProps {
*
* @default - No notifications.
*/
readonly snsTopic?: sns.ITopic;
readonly snsTopic?: sns.ICfnTopic;

/**
* The name of the trail. We recommend customers do not set an explicit name.
Expand Down Expand Up @@ -261,7 +261,7 @@ export class Trail extends Resource {
},
}));

this.topic = props.snsTopic;
this.topic = props.snsTopic ? sns.Topic.fromCfnTopic(props.snsTopic) : undefined;
if (this.topic) {
this.topic.grantPublish(cloudTrailPrincipal);
}
Expand Down
7 changes: 5 additions & 2 deletions packages/aws-cdk-lib/aws-cloudwatch-actions/lib/sns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ import * as sns from '../../aws-sns';
* Use an SNS topic as an alarm action
*/
export class SnsAction implements cloudwatch.IAlarmAction {
constructor(private readonly topic: sns.ITopic) {
private readonly _topic: sns.ITopic;

constructor(topic: sns.ICfnTopic) {
this._topic = sns.Topic.fromCfnTopic(topic);
}

/**
* Returns an alarm action configuration to use an SNS topic as an alarm action
*/
public bind(_scope: Construct, _alarm: cloudwatch.IAlarm): cloudwatch.AlarmActionConfig {
return { alarmActionArn: this.topic.topicArn };
return { alarmActionArn: this._topic.attrTopicArn };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface ManualApprovalActionProps extends codepipeline.CommonAwsActionP
/**
* Optional SNS topic to send notifications to when an approval is pending.
*/
readonly notificationTopic?: sns.ITopic;
readonly notificationTopic?: sns.ICfnTopic;

/**
* A list of email addresses to subscribe to notifications when this Action is pending approval.
Expand Down Expand Up @@ -90,7 +90,7 @@ export class ManualApprovalAction extends Action {

protected bound(scope: Construct, stage: codepipeline.IStage, options: codepipeline.ActionBindOptions): codepipeline.ActionConfig {
if (this.props.notificationTopic) {
this._notificationTopic = this.props.notificationTopic;
this._notificationTopic = sns.Topic.fromCfnTopic(this.props.notificationTopic);
} else if ((this.props.notifyEmails || []).length > 0) {
this._notificationTopic = new sns.Topic(scope, 'TopicResource');
}
Expand Down
4 changes: 2 additions & 2 deletions packages/aws-cdk-lib/aws-config/lib/managed-rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export interface CloudFormationStackNotificationCheckProps extends RuleProps {
*
* @default - No topics.
*/
readonly topics?: sns.ITopic[];
readonly topics?: sns.ICfnTopic[];
}

/**
Expand All @@ -123,7 +123,7 @@ export class CloudFormationStackNotificationCheck extends ManagedRule {
...props,
identifier: ManagedRuleIdentifiers.CLOUDFORMATION_STACK_NOTIFICATION_CHECK,
inputParameters: props.topics && props.topics.reduce(
(params, topic, idx) => ({ ...params, [`snsTopic${idx + 1}`]: topic.topicArn }),
(params, topic, idx) => ({ ...params, [`snsTopic${idx + 1}`]: topic.attrTopicArn }),
{},
),
ruleScope: RuleScope.fromResources([ResourceType.CLOUDFORMATION_STACK]),
Expand Down
9 changes: 6 additions & 3 deletions packages/aws-cdk-lib/aws-lambda-destinations/lib/sns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,21 @@ import * as sns from '../../aws-sns';
* Use a SNS topic as a Lambda destination
*/
export class SnsDestination implements lambda.IDestination {
constructor(private readonly topic: sns.ITopic) {
private readonly _topic: sns.ITopic;

constructor(topic: sns.ICfnTopic) {
this._topic = sns.Topic.fromCfnTopic(topic);
}

/**
* Returns a destination configuration
*/
public bind(_scope: Construct, fn: lambda.IFunction, _options?: lambda.DestinationOptions): lambda.DestinationConfig {
// deduplicated automatically
this.topic.grantPublish(fn);
this._topic.grantPublish(fn);

return {
destination: this.topic.topicArn,
destination: this._topic.attrTopicArn,
};
}
}
9 changes: 6 additions & 3 deletions packages/aws-cdk-lib/aws-lambda-event-sources/lib/sns-dlq.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ import * as sns from '../../aws-sns';
* An SNS dead letter queue destination configuration for a Lambda event source
*/
export class SnsDlq implements IEventSourceDlq {
constructor(private readonly topic: sns.ITopic) {
private readonly _topic: sns.ITopic;

constructor(topic: sns.ICfnTopic) {
this._topic = sns.Topic.fromCfnTopic(topic);
}

/**
* Returns a destination configuration for the DLQ
*/
public bind(_target: IEventSourceMapping, targetHandler: IFunction): DlqDestinationConfig {
this.topic.grantPublish(targetHandler);
this._topic.grantPublish(targetHandler);

return {
destination: this.topic.topicArn,
destination: this._topic.attrTopicArn,
};
}
}
18 changes: 9 additions & 9 deletions packages/aws-cdk-lib/aws-lambda/lib/function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ export interface FunctionOptions extends EventInvokeConfigOptions {
*
* @default - no SNS topic
*/
readonly deadLetterTopic?: sns.ITopic;
readonly deadLetterTopic?: sns.ICfnTopic;

/**
* Enable AWS X-Ray Tracing for Lambda Function.
Expand Down Expand Up @@ -875,13 +875,13 @@ export class Function extends FunctionBase {
this.addEnvironment(key, value);
}

// DLQ can be either sns.ITopic or sqs.IQueue
// DLQ can be either sns.ICfnTopic or sqs.IQueue
const dlqTopicOrQueue = this.buildDeadLetterQueue(props);
if (dlqTopicOrQueue !== undefined) {
if (this.isQueue(dlqTopicOrQueue)) {
this.deadLetterQueue = dlqTopicOrQueue;
} else {
this.deadLetterTopic = dlqTopicOrQueue;
this.deadLetterTopic = sns.Topic.fromCfnTopic(dlqTopicOrQueue);
}
}

Expand Down Expand Up @@ -1467,11 +1467,11 @@ Environment variables can be marked for removal when used in Lambda@Edge by sett
return props.snapStart._render();
}

private isQueue(deadLetterQueue: sqs.IQueue | sns.ITopic): deadLetterQueue is sqs.IQueue {
private isQueue(deadLetterQueue: sqs.IQueue | sns.ICfnTopic): deadLetterQueue is sqs.IQueue {
return (<sqs.IQueue>deadLetterQueue).queueArn !== undefined;
}

private buildDeadLetterQueue(props: FunctionProps): sqs.IQueue | sns.ITopic | undefined {
private buildDeadLetterQueue(props: FunctionProps): sqs.IQueue | sns.ICfnTopic | undefined {
if (!props.deadLetterQueue && !props.deadLetterQueueEnabled && !props.deadLetterTopic) {
return undefined;
}
Expand All @@ -1484,10 +1484,10 @@ Environment variables can be marked for removal when used in Lambda@Edge by sett

let deadLetterQueue: sqs.IQueue | sns.ITopic;
if (props.deadLetterTopic) {
deadLetterQueue = props.deadLetterTopic;
deadLetterQueue = sns.Topic.fromCfnTopic(props.deadLetterTopic);
this.addToRolePolicy(new iam.PolicyStatement({
actions: ['sns:Publish'],
resources: [deadLetterQueue.topicArn],
resources: [deadLetterQueue.attrTopicArn],
}));
} else {
deadLetterQueue = props.deadLetterQueue ?
Expand All @@ -1504,10 +1504,10 @@ Environment variables can be marked for removal when used in Lambda@Edge by sett
return deadLetterQueue;
}

private buildDeadLetterConfig(deadLetterQueue?: sqs.IQueue | sns.ITopic) {
private buildDeadLetterConfig(deadLetterQueue?: sqs.IQueue | sns.ICfnTopic) {
if (deadLetterQueue) {
return {
targetArn: this.isQueue(deadLetterQueue) ? deadLetterQueue.queueArn : deadLetterQueue.topicArn,
targetArn: this.isQueue(deadLetterQueue) ? deadLetterQueue.queueArn : deadLetterQueue.attrTopicArn,
};
} else {
return undefined;
Expand Down
13 changes: 8 additions & 5 deletions packages/aws-cdk-lib/aws-s3-notifications/lib/sns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,26 @@ import * as sns from '../../aws-sns';
* Use an SNS topic as a bucket notification destination
*/
export class SnsDestination implements s3.IBucketNotificationDestination {
constructor(private readonly topic: sns.ITopic) {
private readonly _topic: sns.ITopic;

constructor(topic: sns.ICfnTopic) {
this._topic = sns.Topic.fromCfnTopic(topic);
}

public bind(_scope: Construct, bucket: s3.ICfnBucket): s3.BucketNotificationDestinationConfig {
this.topic.addToResourcePolicy(new iam.PolicyStatement({
this._topic.addToResourcePolicy(new iam.PolicyStatement({
principals: [new iam.ServicePrincipal('s3.amazonaws.com')],
actions: ['sns:Publish'],
resources: [this.topic.topicArn],
resources: [this._topic.attrTopicArn],
conditions: {
ArnLike: { 'aws:SourceArn': bucket.attrArn },
},
}));

return {
arn: this.topic.topicArn,
arn: this._topic.attrTopicArn,
type: s3.BucketNotificationDestinationType.TOPIC,
dependencies: [this.topic], // make sure the topic policy resource is created before the notification config
dependencies: [this._topic], // make sure the topic policy resource is created before the notification config
};
}
}
4 changes: 2 additions & 2 deletions packages/aws-cdk-lib/aws-ses-actions/lib/bounce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export interface BounceProps {
*
* @default no notification
*/
readonly topic?: sns.ITopic;
readonly topic?: sns.ICfnTopic;
}

/**
Expand All @@ -100,7 +100,7 @@ export class Bounce implements ses.IReceiptRuleAction {
sender: this.props.sender,
smtpReplyCode: this.props.template.props.smtpReplyCode,
message: this.props.template.props.message,
topicArn: this.props.topic?.topicArn,
topicArn: this.props.topic?.attrTopicArn,
statusCode: this.props.template.props.statusCode,
},
};
Expand Down
Loading