UNPKG

daily-spend-to-slack

Version:

A construct that deploys a CloudWatch cronjob that will trigger a Lambda that will fetch the yesterday usage of AWS and send it to a SNS as a spoofed ECR CloudWatch event that can be parsed by AWS Chatbot and send to Slack.

72 lines 9.21 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.DailySpendToSlack = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const chatbot = require("aws-cdk-lib/aws-chatbot"); const aws_events_1 = require("aws-cdk-lib/aws-events"); const aws_events_targets_1 = require("aws-cdk-lib/aws-events-targets"); const aws_iam_1 = require("aws-cdk-lib/aws-iam"); const aws_lambda_1 = require("aws-cdk-lib/aws-lambda"); const sns = require("aws-cdk-lib/aws-sns"); const constructs_1 = require("constructs"); /** * @stability stable */ class DailySpendToSlack extends constructs_1.Construct { /** * @stability stable */ constructor(scope, id, props) { var _b; super(scope, id); this.props = props; // Everything here should be created in the console. It is not possible automatically // as a link is needed with Slack which require some oAuth shenanigans. const slackChannel = new chatbot.SlackChannelConfiguration(this, 'DailySpendReportChannel', { slackChannelConfigurationName: `DailySpendreportchannel-${this.props.slackChannelName}`, slackWorkspaceId: this.props.slackWorkspaceId, slackChannelId: this.props.slackChannelId, }); // Creating the SNS topic where we will send our spoofed message to const snsTopic = new sns.Topic(this, 'DailySpendReportSnsTopic'); slackChannel.addNotificationTopic(snsTopic); // Create Lambda function const handler = new aws_lambda_1.Function(this, 'DailySpendReportLambda', { handler: 'run.handler', code: aws_lambda_1.Code.fromAsset('functions'), runtime: aws_lambda_1.Runtime.PYTHON_3_9, architecture: aws_lambda_1.Architecture.ARM_64, description: 'Lambda that will publish daily amount to SNS topic that is coupled with AWS Chatbot', environment: { SNS_TOPIC_ARN: snsTopic.topicArn, ACCOUNT_NICKNAME: this.props.accountName, }, }); // Set task role and permissions const snsPermissions = new aws_iam_1.PolicyStatement({ actions: [ 'sns:Publish', ], resources: [snsTopic.topicArn], }); const costExplorerPermissions = new aws_iam_1.PolicyStatement({ actions: [ 'ce:GetCostAndUsage', ], resources: ['*'], }); (_b = handler.role) === null || _b === void 0 ? void 0 : _b.attachInlinePolicy(new aws_iam_1.Policy(this, 'sns-and-cost-explorer-permissions', { statements: [snsPermissions, costExplorerPermissions], })); // Run this script according to schedule. const rule = new aws_events_1.Rule(this, 'ScheduleBudgetNotification', { schedule: this.props.schedule, }); rule.addTarget(new aws_events_targets_1.LambdaFunction(handler)); } } exports.DailySpendToSlack = DailySpendToSlack; _a = JSII_RTTI_SYMBOL_1; DailySpendToSlack[_a] = { fqn: "daily-spend-to-slack.DailySpendToSlack", version: "0.0.3" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxtREFBbUQ7QUFDbkQsdURBQXdEO0FBQ3hELHVFQUFnRTtBQUNoRSxpREFBOEQ7QUFDOUQsdURBQStFO0FBQy9FLDJDQUEyQztBQUMzQywyQ0FBdUM7Ozs7QUFXdkMsTUFBYSxpQkFBa0IsU0FBUSxzQkFBUzs7OztJQUc5QyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQTZCOztRQUNyRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBRW5CLHFGQUFxRjtRQUNyRix1RUFBdUU7UUFFdkUsTUFBTSxZQUFZLEdBQUcsSUFBSSxPQUFPLENBQUMseUJBQXlCLENBQUMsSUFBSSxFQUFFLHlCQUF5QixFQUFFO1lBQzFGLDZCQUE2QixFQUFFLDJCQUEyQixJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUFFO1lBQ3ZGLGdCQUFnQixFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCO1lBQzdDLGNBQWMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWM7U0FDMUMsQ0FBQyxDQUFDO1FBRUgsbUVBQW1FO1FBRW5FLE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsMEJBQTBCLENBQUMsQ0FBQztRQUNqRSxZQUFZLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFNUMseUJBQXlCO1FBRXpCLE1BQU0sT0FBTyxHQUFHLElBQUkscUJBQVEsQ0FBQyxJQUFJLEVBQUUsd0JBQXdCLEVBQUU7WUFDM0QsT0FBTyxFQUFFLGFBQWE7WUFDdEIsSUFBSSxFQUFFLGlCQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQztZQUNqQyxPQUFPLEVBQUUsb0JBQU8sQ0FBQyxVQUFVO1lBQzNCLFlBQVksRUFBRSx5QkFBWSxDQUFDLE1BQU07WUFDakMsV0FBVyxFQUFFLHFGQUFxRjtZQUNsRyxXQUFXLEVBQUU7Z0JBQ1gsYUFBYSxFQUFFLFFBQVEsQ0FBQyxRQUFRO2dCQUNoQyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVc7YUFDekM7U0FDRixDQUFDLENBQUM7UUFFSCxnQ0FBZ0M7UUFFaEMsTUFBTSxjQUFjLEdBQUcsSUFBSSx5QkFBZSxDQUFDO1lBQ3pDLE9BQU8sRUFBRTtnQkFDUCxhQUFhO2FBQ2Q7WUFDRCxTQUFTLEVBQUUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO1NBQy9CLENBQUMsQ0FBQztRQUVILE1BQU0sdUJBQXVCLEdBQUcsSUFBSSx5QkFBZSxDQUFDO1lBQ2xELE9BQU8sRUFBRTtnQkFDUCxvQkFBb0I7YUFDckI7WUFDRCxTQUFTLEVBQUUsQ0FBQyxHQUFHLENBQUM7U0FDakIsQ0FBQyxDQUFDO1FBRUgsTUFBQSxPQUFPLENBQUMsSUFBSSwwQ0FBRSxrQkFBa0IsQ0FDOUIsSUFBSSxnQkFBTSxDQUFDLElBQUksRUFBRSxtQ0FBbUMsRUFBRTtZQUNwRCxVQUFVLEVBQUUsQ0FBQyxjQUFjLEVBQUUsdUJBQXVCLENBQUM7U0FDdEQsQ0FBQyxFQUNGO1FBRUYseUNBQXlDO1FBRXpDLE1BQU0sSUFBSSxHQUFHLElBQUksaUJBQUksQ0FBQyxJQUFJLEVBQUUsNEJBQTRCLEVBQUU7WUFDeEQsUUFBUSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUTtTQUM5QixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksbUNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBRTlDLENBQUM7O0FBbEVILDhDQW1FQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNoYXRib3QgZnJvbSAnYXdzLWNkay1saWIvYXdzLWNoYXRib3QnO1xuaW1wb3J0IHsgUnVsZSwgU2NoZWR1bGUgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZXZlbnRzJztcbmltcG9ydCB7IExhbWJkYUZ1bmN0aW9uIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWV2ZW50cy10YXJnZXRzJztcbmltcG9ydCB7IFBvbGljeVN0YXRlbWVudCwgUG9saWN5IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQgeyBDb2RlLCBGdW5jdGlvbiwgUnVudGltZSwgQXJjaGl0ZWN0dXJlIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgKiBhcyBzbnMgZnJvbSAnYXdzLWNkay1saWIvYXdzLXNucyc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcblxuXG5leHBvcnQgaW50ZXJmYWNlIERhaWx5U3BlbmRUb1NsYWNrUHJvcHMge1xuICByZWFkb25seSBzY2hlZHVsZTogU2NoZWR1bGU7XG4gIHJlYWRvbmx5IHNsYWNrV29ya3NwYWNlSWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgc2xhY2tDaGFubmVsSWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgc2xhY2tDaGFubmVsTmFtZTogc3RyaW5nO1xuICByZWFkb25seSBhY2NvdW50TmFtZTogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgRGFpbHlTcGVuZFRvU2xhY2sgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBwcml2YXRlIHByb3BzOiBEYWlseVNwZW5kVG9TbGFja1Byb3BzO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBEYWlseVNwZW5kVG9TbGFja1Byb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIHRoaXMucHJvcHMgPSBwcm9wcztcblxuICAgIC8vIEV2ZXJ5dGhpbmcgaGVyZSBzaG91bGQgYmUgY3JlYXRlZCBpbiB0aGUgY29uc29sZS4gSXQgaXMgbm90IHBvc3NpYmxlIGF1dG9tYXRpY2FsbHlcbiAgICAvLyBhcyBhIGxpbmsgaXMgbmVlZGVkIHdpdGggU2xhY2sgd2hpY2ggcmVxdWlyZSBzb21lIG9BdXRoIHNoZW5hbmlnYW5zLlxuXG4gICAgY29uc3Qgc2xhY2tDaGFubmVsID0gbmV3IGNoYXRib3QuU2xhY2tDaGFubmVsQ29uZmlndXJhdGlvbih0aGlzLCAnRGFpbHlTcGVuZFJlcG9ydENoYW5uZWwnLCB7XG4gICAgICBzbGFja0NoYW5uZWxDb25maWd1cmF0aW9uTmFtZTogYERhaWx5U3BlbmRyZXBvcnRjaGFubmVsLSR7dGhpcy5wcm9wcy5zbGFja0NoYW5uZWxOYW1lfWAsXG4gICAgICBzbGFja1dvcmtzcGFjZUlkOiB0aGlzLnByb3BzLnNsYWNrV29ya3NwYWNlSWQsXG4gICAgICBzbGFja0NoYW5uZWxJZDogdGhpcy5wcm9wcy5zbGFja0NoYW5uZWxJZCxcbiAgICB9KTtcblxuICAgIC8vIENyZWF0aW5nIHRoZSBTTlMgdG9waWMgd2hlcmUgd2Ugd2lsbCBzZW5kIG91ciBzcG9vZmVkIG1lc3NhZ2UgdG9cblxuICAgIGNvbnN0IHNuc1RvcGljID0gbmV3IHNucy5Ub3BpYyh0aGlzLCAnRGFpbHlTcGVuZFJlcG9ydFNuc1RvcGljJyk7XG4gICAgc2xhY2tDaGFubmVsLmFkZE5vdGlmaWNhdGlvblRvcGljKHNuc1RvcGljKTtcblxuICAgIC8vIENyZWF0ZSBMYW1iZGEgZnVuY3Rpb25cblxuICAgIGNvbnN0IGhhbmRsZXIgPSBuZXcgRnVuY3Rpb24odGhpcywgJ0RhaWx5U3BlbmRSZXBvcnRMYW1iZGEnLCB7XG4gICAgICBoYW5kbGVyOiAncnVuLmhhbmRsZXInLFxuICAgICAgY29kZTogQ29kZS5mcm9tQXNzZXQoJ2Z1bmN0aW9ucycpLFxuICAgICAgcnVudGltZTogUnVudGltZS5QWVRIT05fM185LFxuICAgICAgYXJjaGl0ZWN0dXJlOiBBcmNoaXRlY3R1cmUuQVJNXzY0LFxuICAgICAgZGVzY3JpcHRpb246ICdMYW1iZGEgdGhhdCB3aWxsIHB1Ymxpc2ggZGFpbHkgYW1vdW50IHRvIFNOUyB0b3BpYyB0aGF0IGlzIGNvdXBsZWQgd2l0aCBBV1MgQ2hhdGJvdCcsXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBTTlNfVE9QSUNfQVJOOiBzbnNUb3BpYy50b3BpY0FybixcbiAgICAgICAgQUNDT1VOVF9OSUNLTkFNRTogdGhpcy5wcm9wcy5hY2NvdW50TmFtZSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyBTZXQgdGFzayByb2xlIGFuZCBwZXJtaXNzaW9uc1xuXG4gICAgY29uc3Qgc25zUGVybWlzc2lvbnMgPSBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgJ3NuczpQdWJsaXNoJyxcbiAgICAgIF0sXG4gICAgICByZXNvdXJjZXM6IFtzbnNUb3BpYy50b3BpY0Fybl0sXG4gICAgfSk7XG5cbiAgICBjb25zdCBjb3N0RXhwbG9yZXJQZXJtaXNzaW9ucyA9IG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgYWN0aW9uczogW1xuICAgICAgICAnY2U6R2V0Q29zdEFuZFVzYWdlJyxcbiAgICAgIF0sXG4gICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgIH0pO1xuXG4gICAgaGFuZGxlci5yb2xlPy5hdHRhY2hJbmxpbmVQb2xpY3koXG4gICAgICBuZXcgUG9saWN5KHRoaXMsICdzbnMtYW5kLWNvc3QtZXhwbG9yZXItcGVybWlzc2lvbnMnLCB7XG4gICAgICAgIHN0YXRlbWVudHM6IFtzbnNQZXJtaXNzaW9ucywgY29zdEV4cGxvcmVyUGVybWlzc2lvbnNdLFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIC8vIFJ1biB0aGlzIHNjcmlwdCBhY2NvcmRpbmcgdG8gc2NoZWR1bGUuXG5cbiAgICBjb25zdCBydWxlID0gbmV3IFJ1bGUodGhpcywgJ1NjaGVkdWxlQnVkZ2V0Tm90aWZpY2F0aW9uJywge1xuICAgICAgc2NoZWR1bGU6IHRoaXMucHJvcHMuc2NoZWR1bGUsXG4gICAgfSk7XG5cbiAgICBydWxlLmFkZFRhcmdldChuZXcgTGFtYmRhRnVuY3Rpb24oaGFuZGxlcikpO1xuXG4gIH1cbn0iXX0=