Skip to content

Commit

Permalink
Merge pull request #211 from ap2020/feature/reorganize-resources
Browse files Browse the repository at this point in the history
  • Loading branch information
pizzacat83 committed Mar 21, 2021
2 parents c04886f + 08f0e11 commit 8d72e0d
Show file tree
Hide file tree
Showing 13 changed files with 916 additions and 443 deletions.
2 changes: 1 addition & 1 deletion aws/package.json
Expand Up @@ -37,7 +37,7 @@
"ifdef-loader": "^2.1.5",
"jest": "^26.6.2",
"js-yaml": "^3.14.0",
"serverless": "^2.12.0",
"serverless": "^2.30.3",
"serverless-dynamodb-local": "^0.2.39",
"serverless-offline": "^6.8.0",
"serverless-offline-sns": "^0.68.0",
Expand Down
13 changes: 9 additions & 4 deletions aws/serverless.yml
@@ -1,6 +1,7 @@
service: ap2020bot

frameworkVersion: '2'
variablesResolutionMode: 20210219

plugins:
- serverless-webpack
Expand All @@ -10,7 +11,10 @@ plugins:

custom:
stage: '${opt:stage, "local"}'
accountId: ${file(serverless/lib/sts.js):accountId}
resourcePrefix: ap2020bot-${self:custom.stage}-
iam:
lambdaRole: ap2020bot-${self:custom.stage}-${self:provider.region}-lambdaRole
webpack:
webpackConfig: ./webpack.config.js
packager: yarn
Expand All @@ -23,6 +27,7 @@ custom:
watch-portal: ${self:custom.resourcePrefix}watch-portal
sns:
topicName:
error: ${self:custom.resourcePrefix}error
slack-events: ${self:custom.resourcePrefix}slack-events
# config for dynamodb-local
dynamodb:
Expand All @@ -34,7 +39,7 @@ custom:
migrate: true
serverless-offline-sns:
port: 3001 # a free port for the sns server to run on
accountId: ${ssm:/ap2020bot/aws/account-id} # TODO: use fake accountId
accountId: ${ssm:/ap2020bot/${self:custom.stage}/aws/account-id} # TODO: use fake accountId

provider:
name: aws
Expand Down Expand Up @@ -67,7 +72,6 @@ provider:
Action:
- "sns:Publish"
Resource: "arn:aws:sns:${self:provider.region}:*:${self:custom.sns.topicName.slack-events}"
rolePermissionsBoundary: arn:aws:iam::${ssm:/ap2020bot/aws/account-id}:policy/ap2020botLambdaBoundary
deploymentBucket:
blockPublicAccess: true
httpApi:
Expand Down Expand Up @@ -110,12 +114,13 @@ functions:
- channel_unarchive

resources:
- '${file(serverless/error-alarms.js):${self:custom.stage}}'
- '${file(serverless/resources/error-alarms.js):cfn}'
- '${file(serverless/resources/iam/deploy.yml)}'
- Resources:
ErrorTopic:
Type: AWS::SNS::Topic
Properties:
TopicName: ap2020bot-${self:custom.stage}-error
TopicName: ${self:custom.sns.topicName.error}
DisplayName: ap2020bot errors
WatchPortalDynamoDbTable:
Type: 'AWS::DynamoDB::Table'
Expand Down
51 changes: 0 additions & 51 deletions aws/serverless/error-alarms.js

This file was deleted.

8 changes: 8 additions & 0 deletions aws/serverless/lib/dynamodb.js
@@ -0,0 +1,8 @@
const tables = async ({ resolveConfigurationProperty }) => await resolveConfigurationProperty(['custom', 'dynamodbConfig', 'tableName']);
module.exports.tables = tables;

const fullnames = async (sls) => Object.values(await tables(sls));
module.exports.fullnames = fullnames;

const arns = async (sls) => (await fullnames(sls)).map(table => `arn:aws:dynamodb:\${self:provider.region}:\${self:custom.accountId}:table/${table}`);
module.exports.arns = arns;
24 changes: 24 additions & 0 deletions aws/serverless/lib/functions.js
@@ -0,0 +1,24 @@
const calcFullname = func => `ap2020bot-\${self:custom.stage}-${func}`;
module.exports.calcFullname = calcFullname;

const calcArnFromFullName = func => `arn:aws:lambda:\${self:provider.region}:\${self:custom.accountId}:function:${func}`;
module.exports.calcArnFromFullName = calcArnFromFullName;

const calcArnFromShortName = func => calcArnFromFullName(calcFullname(func));
module.exports.calcArnFromShortName = calcArnFromShortName;

const functions = async ({ resolveConfigurationProperty }) => {
return await resolveConfigurationProperty(['functions']);
}

const shortnames = async (sls) => Object.keys(await functions(sls));
module.exports.shortnames = shortnames;

const fullnames = async (sls) => (await shortnames(sls)).map(func => calcFullname(func));
module.exports.fullnames = fullnames;

const arns = async (sls) => (await fullnames(sls)).map(func => calcArnFromFullName(func));
module.exports.arns = arns;

const logGroupArns = async (sls) => (await fullnames(sls)).map(func => `arn:aws:logs:\${self:provider.region}:\${self:custom.accountId}:log-group:/aws/lambda/${func}:*`);
module.exports.logGroupArns = logGroupArns;
8 changes: 8 additions & 0 deletions aws/serverless/lib/sns.js
@@ -0,0 +1,8 @@
const topics = async ({ resolveConfigurationProperty }) => await resolveConfigurationProperty(['custom', 'sns', 'topicName']);
module.exports.topics = topics;

const fullnames = async (sls) => Object.values(await topics(sls));
module.exports.fullnames = fullnames;

const arns = async (sls) => (await fullnames(sls)).map(topic => `arn:aws:sns:\${self:provider.region}:\${self:custom.accountId}:${topic}`);
module.exports.arns = arns;
File renamed without changes.
4 changes: 4 additions & 0 deletions aws/serverless/lib/sts.js
@@ -0,0 +1,4 @@
const { STS } = require('aws-sdk');
const sts = new STS();

module.exports.accountId = async () => (await sts.getCallerIdentity().promise()).Account;
50 changes: 50 additions & 0 deletions aws/serverless/resources/error-alarms.js
@@ -0,0 +1,50 @@
const {pascalCase} = require('change-case');

const { shortnames: getFuncShortnames, calcFullname } = require('../lib/functions');

const calcAlarmName = (funcShortname) => `ap2020bot-\${self:custom.stage}-error-${funcShortname}`;

const createAlarm = (func) => ([
`${pascalCase(func)}ErrorAlarm`,
{
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmName": calcAlarmName(func),
"Namespace": "AWS/Lambda",
"Dimensions": [
{
"Name": "FunctionName",
"Value": calcFullname(func),
}
],
"MetricName": "Errors",
"ComparisonOperator": "GreaterThanOrEqualToThreshold",
"Period": 60,
"EvaluationPeriods": 1,
"Statistic": "Maximum",
"Threshold": 1,
"AlarmActions": [
{
"Ref": "ErrorTopic"
}
]
}
},
]);

const names = async (sls) => {
const functions = await getFuncShortnames(sls);
return functions.map(func => calcAlarmName(func));
};
module.exports.names = names;

const arns = async (sls) => (await names(sls)).map(alarm => `arn:aws:cloudwatch:\${self:provider.region}:\${self:custom.accountId}:alarm:${alarm}`);
module.exports.arns = arns;

const cfn = async (sls) => {
const functions = await getFuncShortnames(sls);
return {
"Resources": Object.fromEntries(functions.map(func => createAlarm(func))),
};
};
module.exports.cfn = cfn;
7 changes: 7 additions & 0 deletions aws/serverless/resources/iam/admin.yml
@@ -0,0 +1,7 @@
Resources:
Ap2020BotAdminGroup:
Type: AWS::IAM::Group
Properties:
GroupName: 'ap2020bot-admin-${self:custom.stage}'
ManagedPolicyArns:
- Ref: Ap2020DeployAdminAssumablePolicy

0 comments on commit 8d72e0d

Please sign in to comment.