caccl-deploy
Version:
A cli tool for managing ECS/Fargate app deployments
95 lines (78 loc) • 2.62 kB
text/typescript
import path from 'path';
import {
aws_sns as sns,
aws_iam as iam,
aws_lambda as lambda,
aws_cloudwatch_actions as actions,
aws_sns_subscriptions as subscriptions,
CfnOutput,
Stack,
} from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { CacclDocDb, CacclRdsDb } from './db';
import { CacclLoadBalancer } from './lb';
import { CacclService } from './service';
export interface CacclNotificationsProps {
email?: string | string[];
slack?: string;
service: CacclService;
loadBalancer: CacclLoadBalancer;
db?: CacclDocDb | CacclRdsDb;
}
export class CacclNotifications extends Construct {
topic: sns.Topic;
subscriptions: sns.Subscription[];
constructor(scope: Construct, id: string, props: CacclNotificationsProps) {
super(scope, id);
const email = typeof props.email === 'string' ? [props.email] : props.email;
const { slack, service, loadBalancer, db } = props;
this.topic = new sns.Topic(this, 'NotificationTopic', {
displayName: `${Stack.of(this).stackName}-notifications`,
});
this.topic.grantPublish({
grantPrincipal: new iam.ServicePrincipal('cloudwatch.amazonaws.com'),
});
if (email) {
email.forEach((emailAddr, idx) => {
new sns.Subscription(this, `email-subscription-${idx}`, {
topic: this.topic,
protocol: sns.SubscriptionProtocol.EMAIL,
endpoint: emailAddr,
});
});
}
if (slack !== undefined) {
const slackFunction = new lambda.Function(this, 'SlackFunction', {
functionName: `${Stack.of(this).stackName}-slack-notify`,
runtime: lambda.Runtime.PYTHON_3_8,
handler: 'notify.handler',
code: lambda.Code.fromAsset(
path.join(__dirname, '..', 'assets/slack_notify'),
),
environment: {
SLACK_WEBHOOK_URL: slack,
},
});
this.topic.addSubscription(
new subscriptions.LambdaSubscription(slackFunction),
);
}
loadBalancer.alarms.forEach((alarm) => {
alarm.addAlarmAction(new actions.SnsAction(this.topic));
});
service.alarms.forEach((alarm) => {
alarm.addAlarmAction(new actions.SnsAction(this.topic));
});
db?.alarms.forEach((alarm) => {
alarm.addAlarmAction(new actions.SnsAction(this.topic));
});
new CfnOutput(this, 'TopicName', {
exportName: `${Stack.of(this).stackName}-sns-topic-name`,
value: this.topic.topicName,
});
new CfnOutput(this, 'TopicArn', {
exportName: `${Stack.of(this).stackName}-sns-topic-arn`,
value: this.topic.topicArn,
});
}
}