@alma-cdk/project
v1.0.9
Published
Opinionated CDK Project “Framework”
Downloads
4,201
Maintainers
Readme
[!Tip] Migrating from
v0
tov1
? See Migration Guide.
Opinionated CDK “framework” with constructs & utilities for:
deploying multiple environments to multiple accounts (with many-to-many relationship)
managing account configuration through standardized props (no more random config files)
querying account and/or environment specific information within your CDK code
enabling dynamic & short-lived “feature-environments”
enabling well-defined tagging
providing structure & common conventions to CDK projects
choosing the target account & environment by passing in runtime context:
npx cdk deploy -c account=dev -c environment=feature/abc-123
... which means you don't need to define all the possible environments ahead of time!
Account Strategies
Depending on the use case, you may choose a configuration between 1-3 AWS accounts with the following environments:
Shared account (
shared
):Multi-account (
dev
+prod
)– RECOMMENDED:
Multi-account (
dev
+preprod
+prod
):
Getting Started
Steps required to define a environmental project resources; At first, it might seem complex but once you get into the habbit of defining your projects this way it starts to make sense:
Choose your Account Strategy
Initialize a new
Project
instead ofcdk.App
:// bin/app.ts import { Project, AccountStrategy } from '@alma-cdk/project'; const project = new Project({ // Basic info, you could also read these from package.json if you want name: 'my-cool-project', author: { organization: 'Acme Corp', name: 'Mad Scientists', email: '[email protected]', }, // If not set, defaults to one of: $CDK_DEFAULT_REGION, $AWS_REGION or us-east-1 defaultRegion: 'eu-west-1', // Configures the project to use 2 AWS accounts (recommended) accounts: AccountStrategy.two({ dev: { id: '111111111111', config: { // whatever you want here as [string]: any baseDomain: 'example.net', }, }, prod: { id: '222222222222', config: { // whatever you want here as [string]: any baseDomain: 'example.com', }, }, }), })
Define a stack which
extends SmartStack
with resources:// lib/my-stack.ts import { Construct } from 'constructs'; import { StackProps, RemovalPolicy } from 'aws-cdk-lib'; import { SmartStack, Name, UrlName, PathName, EC } from '@alma-cdk/project'; export class MyStack extends SmartStack { constructor(scope: Construct, id: string, props: StackProps) { super(scope, id, props); new dynamodb.Table(this, 'Table', { removalPolicy: EC.isStable(this) ? RemovalPolicy.RETAIN : RemovalPolicy.DESTROY, tableName: Name.it(this, 'MyTable'), partitionKey: { type: dynamodb.AttributeType.STRING, name: 'pk', }, // StagingMyTable }); new events.EventBus(this, 'EventBus', { eventBusName: Name.withProject(this, 'MyEventBus'), // MyCoolProjectStagingMyEventBus }); new s3.Bucket(this, 'Bucket', { removalPolicy: EC.isStable(this) ? RemovalPolicy.RETAIN : RemovalPolicy.DESTROY, autoDeleteObjects: EC.isStable(this) ? false : true, bucketName: UrlName.globally(this, 'MyBucket'), // acme-corp-my-cool-project-feature-foo-bar-my-bucket }); new ssm.StringParameter(this, 'Parameter', { stringValue: 'Foo', tier: ssm.ParameterTier.ADVANCED, parameterName: PathName.withProject(this, 'MyNamespace/MyParameter'), // /MyCoolProject/Staging/MyNamespace/MyParameter }); } }
Define a new environmental which
extends EnvironmentWrapper
and initialize all your environmentalSmartStack
stacks within:// lib/environment.ts import { Construct } from 'constructs'; import { EnvironmentWrapper } from '@alma-cdk/project'; import { MyStack } from './my-stack'; export class Environment extends EnvironmentWrapper { constructor(scope: Construct) { super(scope); new MyStack(this, 'MyStack', { description: 'This is required' }); } }
Resulting Stack properties (given
environment=staging
):| Property | Example value | | :---------------------- | :--------------------------------------------------- | |
stackName
|"MyCoolProject-Environment-Staging-MyExampleStack"
| |terminationProtection
|true
| |env.account
|"111111111111"
| |env.region
|"eu-west-1"
|Resulting Tags for the Stack and its resources (given
environment=staging
):| Property | Example value | | :---------------------- | :-------------------------------- | |
Account
|dev
| |Environment
|staging
| |Project
|my-cool-project
| |Author
|Mad Scientists
| |Organization
|Acme Corp
| |Contact
|[email protected]
|Finally initialize the environment with the
Project
scope:// bin/app.ts import { Project, Accounts } from '@alma-cdk/project'; import { Environment } from '../lib/environment'; const project = new Project({/* removed for brevity, see step 1 */}) new Environment(project);
Documentation
See detailed documentation for specific classes & methods at constructs.dev.
Generally speaking you would be most interested in the following:
- Project
- AccountStrategy
- SmartStack
- AccountWrapper & EnvironmentWrapper
- AccountContext (AC)
- EnvironmentContext (EC)
- Name / UrlName / PathName
Migration Guide
Migrating from v0
to v1
? See Migration Guide.
Roadmap
For now, see Issue #36.