包详细信息

@alma-cdk/project

alma-cdk6kApache-2.01.0.9

Opinionated CDK Project “Framework”

aws, aws-cdk, awscdk, cdk

自述文件

Alma CDK Project

Stability: Stable Versioning: SemVer 2.0.0 release Quality Gate Status Coverage

[!Tip] Migrating from v0 to v1? 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:

  1. Shared account (shared):

    default-multi

  2. Multi-account (dev+prod)– RECOMMENDED:

    default-multi


  1. Multi-account (dev+preprod+prod):

    default-multi


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:

  1. Choose your Account Strategy

  2. Initialize a new Project instead of cdk.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: 'mad.scientists@acme.example.com',
       },
    
       // 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',
           },
         },
       }),
     })
    
  3. 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
         });
       }
     }
    
  4. Define a new environmental which extends EnvironmentWrapper and initialize all your environmental SmartStack 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 | mad.scientists@acme.example.com |

  5. 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.