Skip to content

Commit

Permalink
chore: use cdk
Browse files Browse the repository at this point in the history
  • Loading branch information
pseudo-su committed Jul 25, 2021
1 parent ec21327 commit f283ab6
Show file tree
Hide file tree
Showing 12 changed files with 8,589 additions and 15,646 deletions.
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
# dotenv files
/.env*.local

# SST framework
.build
# Build files
/.build
/cdk.out
/.aws-sam

# NodeJS
node_modules/
Expand Down
25 changes: 9 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,15 @@ devstack.restart: devstack.stop devstack.start
.PHONY: devstack.recreate
devstack.recreate: devstack.clean devstack.restart

.PHONY: dev.start
dev.start:
if [ -z "${STAGE}" ]; then echo "STAGE environment variable not set"; exit 1; fi
npx sst start --stage ${STAGE}
.PHONY: dev
dev:
sam-beta-cdk local start-api

.PHONY: dev.stop
dev.stop:
if [ -z "${STAGE}" ]; then echo "STAGE environment variable not set"; exit 1; fi
npx sst remove --stage ${STAGE}
.PHONY: package
package:
npx cdk synth

.PHONY: dev.clean
dev.clean:
rm -rf .build/
.PHONY: deploy.dev
deploy.dev:
npx cdk deploy --app=cdk.out 'Dev/*'

.PHONY: dev.restart
dev.restart: dev.stop dev.start

.PHONY: dev.recreate
dev.recreate: dev.clean dev.restart
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ The [./openapi.yml](./openapi.yml) file contains the [OpenAPI](https://github.co

## Quick start

Install global dependencies

```sh
# Install sam-cli beta
brew tap aws/tap
brew install aws-sam-cli-beta-cdk
```

### Local config files

```sh
Expand Down Expand Up @@ -49,8 +57,8 @@ make devstack.start;
# Run tests (some tests rely on having the DB running)
make test;

# Run the dev server (deploys some remote infra to AWS but executes the functions on your local machine).
make dev.start;
# Run the local dev server.
make dev;
```

At this point you should have a development version of this API project running that you can make API requests to from Postman 🎉.
Expand Down
17 changes: 17 additions & 0 deletions cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"app": "npx ts-node --project cdk/tsconfig.json --prefer-ts-exts cdk/app.ts",
"context": {
"@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true,
"@aws-cdk/core:enableStackNameDuplicates": "true",
"aws-cdk:enableDiffNoFail": "true",
"@aws-cdk/core:stackRelativeExports": "true",
"@aws-cdk/aws-ecr-assets:dockerIgnoreSupport": true,
"@aws-cdk/aws-secretsmanager:parseOwnedSecretName": true,
"@aws-cdk/aws-kms:defaultKeyPolicies": true,
"@aws-cdk/aws-s3:grantWriteWithoutAcl": true,
"@aws-cdk/aws-ecs-patterns:removeDefaultDesiredCount": true,
"@aws-cdk/aws-rds:lowercaseDbIdentifier": true,
"@aws-cdk/aws-efs:defaultEncryptionAtRest": true,
"@aws-cdk/aws-lambda:recognizeVersionProps": true
}
}
176 changes: 176 additions & 0 deletions cdk/api.stack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import { AddRoutesOptions, HttpApi, HttpMethod } from '@aws-cdk/aws-apigatewayv2';
import { HttpLambdaAuthorizer } from "@aws-cdk/aws-apigatewayv2-authorizers";
import { LambdaProxyIntegration, LambdaProxyIntegrationProps } from '@aws-cdk/aws-apigatewayv2-integrations';
import { GoFunction, GoFunctionProps } from '@aws-cdk/aws-lambda-go';
import * as cdk from '@aws-cdk/core';
import { CfnOutput } from '@aws-cdk/core';

type AddOperationOptions = {
name: string;
description?: string;
function: GoFunctionProps;
routes: RouteOptions;
integration?: Omit<LambdaProxyIntegrationProps, 'handler'>;
};

type RouteOptions = Omit<AddRoutesOptions, 'integration'>;
type DefaultRouteOptions = Omit<AddRoutesOptions, 'path' | 'methods'>;

export class Api extends cdk.Construct {
api: HttpApi;
defaultFunctionProps?: GoFunctionProps;
defaultRouteOptions?: DefaultRouteOptions;

constructor(scope: cdk.Construct, id: string) {
super(scope, id);

this.api = new HttpApi(this, "ApiGateway");

new CfnOutput(this, 'ApiGatewayUrl', {
value: this.api.url!,
});
}

setDefaultFunctionProps(props: GoFunctionProps) {
this.defaultFunctionProps = props;
}

setDefaultRouteOptions(options: DefaultRouteOptions) {
this.defaultRouteOptions = options;
}

addOperation(opts: AddOperationOptions) {
const { name } = opts;
const functionProps = {
...this.defaultFunctionProps,
...(opts.function || {}),
bundling: {
...(this.defaultFunctionProps?.bundling || {}),
...(opts.function.bundling || {}),
environment: {
...(this.defaultFunctionProps?.bundling?.environment || {}),
...(opts.function.bundling?.environment || {}),
},
},
};

const lambdaFunction = new GoFunction(this, `${name}Function`, functionProps);

const routes = this.api.addRoutes({
...(this.defaultRouteOptions || {}),
...opts.routes,
integration: new LambdaProxyIntegration({
handler: lambdaFunction,
...opts.integration,
}),
});

new CfnOutput(this, `${name}FunctionName`, {
value: lambdaFunction.functionName,
description: `${name} function name`,
});

new CfnOutput(this, `${name}ApiPath`, {
value: routes[0].path!,
description: `${name} API path`,
});

return {
lambdaFunction,
routes,
};
}
}

export class ApiStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, properties?: cdk.StackProps) {
super(scope, id, properties);

const authorizer = new HttpLambdaAuthorizer({
authorizerName: "UserAuthorizer",
handler: new GoFunction(this, `UserAuthorizerFunction`, {
entry: "lambda/authorizer"
}),
});

const api = new Api(this, "Api");

api.addOperation({
name: 'runDatabaseMigrations',
description: 'Run database migrations',
routes: {
path: '/commands/runDatabaseMigrations',
methods: [HttpMethod.POST],
authorizer,
},
function: {
entry: 'lambda/commands/runDatabaseMigrations',
},
});

api.addOperation({
name: 'searchLeagues',
description: 'Search leagues',
routes: {
path: '/admin/leagues',
methods: [HttpMethod.GET],
authorizer,
},
function: {
entry: 'lambda/queries/leagues/search',
},
});

api.addOperation({
name: 'getLeagueById',
description: 'Get league by ID',
routes: {
path: '/admin/league/{leagueId}',
methods: [HttpMethod.GET],
authorizer: authorizer,
},
function: {
entry: 'lambda/queries/leagues/search',
},
});

api.addOperation({
name: 'createLeague',
description: 'Create league',
routes: {
path: '/commands/createLeague',
methods: [HttpMethod.POST],
authorizer: authorizer,
},
function: {
entry: 'lambda/commands/createLeague',
},
});

api.addOperation({
name: 'deleteLeague',
description: 'Delete league',
routes: {
path: '/commands/deleteLeague',
methods: [HttpMethod.POST],
authorizer: authorizer,
},
function: {
entry: 'lambda/commands/deleteLeague',
},
});

api.addOperation({
name: 'updateLeague',
description: 'Update league',
routes: {
path: '/commands/udpateLeague',
methods: [HttpMethod.POST],
authorizer: authorizer,
},
function: {
entry: 'lambda/commands/updateLeague',
},
});
}
}
31 changes: 31 additions & 0 deletions cdk/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env node

import "source-map-support/register";
import * as cdk from "@aws-cdk/core";
import { ApiStack } from "./api.stack";

type GolangServerlessCDKTemplateProperties = {
account: string;
};

class GolangServerlessCDKTemplate extends cdk.Construct {
constructor(
scope: cdk.Construct,
id: string,
properties: GolangServerlessCDKTemplateProperties
) {
super(scope, id);
new ApiStack(this, `GolangServerlessCDKTemplate`, {
env: {
account: properties.account,
region: "ap-southeast-2",
},
});
}
}

const app = new cdk.App();

new GolangServerlessCDKTemplate(app, "Dev", {
account: "067289113644",
});
30 changes: 30 additions & 0 deletions cdk/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"compilerOptions": {
"target": "ES2018",
"module": "commonjs",
"lib": [
"es2018"
],
"declaration": true,
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noImplicitThis": true,
"alwaysStrict": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": false,
"inlineSourceMap": true,
"inlineSources": true,
"experimentalDecorators": true,
"strictPropertyInitialization": false,
"typeRoots": [
"../node_modules/@types"
]
},
"exclude": [
"../node_modules",
"../cdk.out"
]
}
63 changes: 0 additions & 63 deletions lib/ApiStack.js

This file was deleted.

Loading

0 comments on commit f283ab6

Please sign in to comment.