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
JavaScript
"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=