Best practices for building company default constructs
See original GitHub issueHaving built a few production stacks we are seeing patterns in the component parts we use, and want to enforce internal best practices: timeouts / env values / roles etc as well as keep actual stack logic as small/focused as possible. I was discussing this with @eladb on gitter…
I’ve been playing with something like: lib/our-company/lambda.ts
(with a lib/our-company/index.ts
so we can import all constructs with a simple single import):
interface OurCompanyILamdaProps {
assetPath: string, // what are we deploying
environment?: any,
handler?: string,
description?: string,
timeout?: number
}
export class Lambda extends cdk.Construct {
public readonly function: lambda.Function;
constructor(scope: cdk.Construct, id: string, props: OurCompanyILamdaProps) {
super(scope, id);
let env: any = props.environment ? props.environment : {};
// make sure we always have the ENV available to the lambda function.
env.DEPLOY_ENV = process.env.DEPLOY_ENV;
// construct ID needs to be unique
let constructId = id + env.DEPLOY_ENV;
let lam = new lambda.Function(scope, constructId, {
code: lambda.Code.asset(props.assetPath),
handler: props.handler ? props.handler : "index.handler",
runtime: lambda.Runtime.NODEJS_10_X,
environment: props.environment,
description: props.description,
timeout: cdk.Duration.seconds(props.timeout ? props.timeout : 60)
})
// Do stuff..
// if prop.allowAccessSecrets ... create role and assign to lambda
// if prop.addMonitoring ...
// if prop.someThingElse ...
this.function = lam;
}
}
Then assuming stacks/NAME/index.ts
:
import * as OurCompany from '../constructs/';
let lambFunction = new OurCompany.Lambda(this, 'aThing', {
assetPath: __dirname + '/lambda/function_a/',
environment: environment
}).function; // note .function here to get the underlying construct if needed
aDynamoDBTable.grantReadWriteData(lambFunction);
Other sorts of defaults we are thinking of:
- All queues get a DLQ
- Monitoring / alerts
- Permissions to secrets (by creating specific role), but just pass in the secret string
- Backup settings on DynamoDB table
- possibly tagging - though I know you should be able to do that at stack level, last time I tried it hasn’t worked.
Additionally we could build feature factory constructs… ‘swagger file + lambda functions’ = apigateway (I’ve basically used https://gist.github.com/abbottdev/17379763ebc14a5ecbf2a111ffbcdd86 - from https://github.com/awslabs/aws-cdk/issues/1461 - and mundged it to hide the implementation of parsing the swagger file).
Some of this will include differences we want between production and development environments - but the goal being standards and best practices (for our company) over all.
Feedback / thoughts would be most appreciated.
Issue Analytics
- State:
- Created 4 years ago
- Comments:12 (3 by maintainers)
Top GitHub Comments
something i’ve been doing is creating factory functions to initialize constructs with common defaults. makes it easy to override properties as needed.
In my current organization, we use Service Catalog to enforce company defaults and requirements around various aws services. We restrict end users IAM permissions, to be able to primarily operate only via Service Catalog. While we can customize the CDK to enforce those defaults (based on the best practices), is there guidance on how to enforce usage of the customized CDK libs to build and deploy out apps into AWS cloud ?