tags: bmocdk

There are two types of KMS keys:

How to “borrow” Cloud Engineering CMKs? For example,

To deploy our own CMK:


kaau@OCLT71159526 ~/myproj/EPRE_NACB_DB_Deployment_and_Support_87735 (epre-nacb-db-deployment-and-support-kms)$ tree .
.
├── build.sh
├── infra
│   ├── bin
│   │   └── infra.ts
│   ├── cdk.json
│   ├── cdk.out
│   ├── config
│   │   └── index.ts
│   ├── controller.json
│   ├── lib
│   │   └── epre-nacb-db-deployment-and-support-kms-stack.ts
│   ├── node_modules
│   ├── package.json
│   └── tsconfig.json
├── readme.md
└── service
 

infra/package.json

[[blue:{]]
[[blue:  "name": "infra",]]
[[blue:  "version": "0.1.0",]]
[[blue:  "bin": {]]
[[blue:    "infra": "bin/infra.js"]]
[[blue:  },]]
[[blue:  "scripts": {]]
[[blue:    "build": "tsc",]]
[[blue:    "watch": "tsc -w",]]
[[blue:    "test": "jest",]]
[[blue:    "cdk": "cdk"]]
[[blue:  },]]
[[blue:  "devDependencies": {]]
[[blue:    "@types/jest": "^26.0.24",]]
[[blue:    "@types/node": "^26.1.1",]]
[[blue:    "aws-cdk-lib": "^2.261.0",]]
[[blue:    "jest": "^26.6.3",]]
[[blue:    "ts-jest": "^26.5.6",]]
[[blue:    "ts-node": "^10.9.2",]]
[[blue:    "typescript": "^6.0.3"]]
[[blue:  },]]
[[blue:  "dependencies": {]]
[[blue:    "@bmo-cdk/common": "^11.0.0",]]
[[blue:    "@bmo-cdk/kms": "^11.0.0",]]
[[blue:    "constructs": "^10.7.0",]]
[[blue:    "source-map-support": "^0.5.21"]]
[[blue:  }]]
[[blue:}]]

infra/tsconfig.json

[[blue:{]]
  [[blue:"compilerOptions": {]]
[[blue:    "target": "ES2023",]]
[[blue:    "module": "commonjs",]]
[[blue:    "lib": ["ES2023"]]]
[[blue:    "skipLibCheck": true,]]
[[blue:    "declaration": true,]]
[[blue:    "strict": true,]]
[[blue:    "noImplicitAny": true,]]
[[blue:    "strictNullChecks": true,]]
[[blue:    "noImplicitThis": true,]]
[[blue:    "alwaysStrict": true,]]
[[blue:    "noUnusedLocals": false,]]
[[blue:    "noUnusedParameters": false,]]
[[blue:    "noImplicitReturns": true,]]
[[blue:    "noFallthroughCasesInSwitch": false,]]
[[blue:    "inlineSourceMap": true,]]
[[blue:    "inlineSources": true,]]
[[blue:    "experimentalDecorators": true,]]
[[blue:    "resolveJsonModule": true,]]
[[blue:    "strictPropertyInitialization": false,]]
[[blue:    "esModuleInterop": true,]]
[[blue:    "types": [ "node"],]]
[[blue:    "typeRoots": []]
[[blue:      "./node_modules/@types"]]
[[blue:    ]]]
[[blue:  },]]
[[blue:  "exclude": []]
[[blue:    "node_modules",]]
[[blue:    "cdk.out"]]
[[blue:  ]]]
[[blue:}]]

infra/controller.json:

[[blue:{]]
  [[blue:"stacks": "null"]]
[[blue:[[}]]

infra/config/index.ts

import { configurationHelperFactory } from '@bmo-cdk/common'
import { PurposeCode } from '@bmo-cdk/common/lib/configurationHelper/CommonConfigurationHelperTypes'

export const createBmoCdkHelper = configurationHelperFactory({
    appCatId: '87735',
    projectName: 'TREONACB', // Alphanumeric only, the project name (e.g., CENG)
    serviceName: 'NACBDBDeploymentandSupport', // Alphanumeric and hyphens only
    serviceDescription: 'ERRE NACB DB Development and Support',
    purposeCode: PurposeCode.DATA_AND_ANALYTICS, // Purpose code of the multi account. Use PurposeCode.NONE for old account.
    costCenter: 'H9395',
    supportTeam: 'RUN_EPRE_NACB_DBA_Deploy_Support'
})

infra/bin/infra.ts

import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { createBmoCdkHelper } from '../config';
import { EpreNacbDbDevelopAndSupportKmsStack } from '../lib/epre-nacb-db-deployment-and-support-kms-stack';

const app = new cdk.App();
const helper = createBmoCdkHelper(app)
const env = {
  account: helper.deployment.accountId,
  region: helper.deployment.region
}
const stage = process.env.Stage;
var isAccountStage = (stage == "sbx" || stage == "dev") ? true : false;

if (isAccountStage) {
  const rdsMonitoringKMSStack = new EpreNacbDbDevelopAndSupportKmsStack(app, "epre-nacb-db-development-and-support-kms-stack", { env })
}

infra/lib/epre-nacb-db-deployment-and-support-kms-stack.ts:

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { createBmoCdkHelper } from '../config';
import { BMOKMSConstruct } from '@bmo-cdk/kms';

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

    const helper = createBmoCdkHelper(this);
    const accountId = helper.deployment.accountId;
    const region = helper.deployment.region;

    const myKms = new BMOKMSConstruct(this, 'epre-nacb-db-development-and-support-kms-key', {
      alias: 'epre-nacb-db-development-and-support-kms-key',
      keyType: 'application',
      applicationKeyAppCatIdForTagBasedAccess: helper.tags.AppCatID,
      description: 'EPRE NACB DB Development and Support KMS key',
      enabled: true,
      keyUsage: 'ENCRYPT_DECRYPT',
      pendingWindowInDaysForDeletion: 7,
      keyPolicy: {
        "Version": "2012-10-17",
        "Id": "EPRE NACB DB Development and Support KMS IAM access roles",
        "Statement": [
          {
            "Sid": "EnableRootAndNacbDbServicesL2SupportTeamPermissions",
            "Effect": "Allow",
            "Principal": {
              "AWS": [
                `arn:aws:iam::${accountId}:root`,
                `arn:aws:iam::${accountId}:role/aws-reserved/sso.amazonaws.com/ca-central-1/AWSReservedSSO_AWS-NACB-DBServices-L2Support_f580d021a6d473fe`
              ]
            },
            "Action": "kms:*",
            "Resource": "*"
          },
          {
            "Sid": "AllowAwsServiceUsageViaServiceCondition",
            "Effect": "Allow",
            "Principal": {
              "Service": [
                "s3.amazonaws.com",
                "lambda.amazonaws.com",
                "sns.amazonaws.com",
                "sqs.amazonaws.com",
                "ec2.amazonaws.com",
                "rds.amazonaws.com",
                "redshift.amazonaws.com",
                "redshift-serverless.amazonaws.com"
              ]
            },
            "Action": [
              "kms:Encrypt",
              "kms:Decrypt",
              "kms:ReEncrypt*",
              "kms:GenerateDataKey*",
              "kms:DescribeKey"
            ],
            "Resource": "*",
            "Condition": {
              "StringEquals": {
                "kms:CallerAccount": accountId
              },
              "StringLike": {
                "kms:ViaService": [
                  `s3.${region}.amazonaws.com`,
                  `lambda.${region}.amazonaws.com`,
                  `sns.${region}.amazonaws.com`,
                  `sqs.${region}.amazonaws.com`,
                  `ec2.${region}.amazonaws.com`,
                  `rds.${region}.amazonaws.com`,
                  `redshift.${region}.amazonaws.com`,
                  `redshift-serverless.${region}.amazonaws.com`
                ]
              }
            }
          },
          {
            "Sid": "AllowCloudWatchLogsUsage",
            "Effect": "Allow",
            "Principal": {
              "Service": `logs.${region}.amazonaws.com`
            },
            "Action": [
              "kms:Encrypt",
              "kms:Decrypt",
              "kms:ReEncrypt*",
              "kms:GenerateDataKey*",
              "kms:DescribeKey"
            ],
            "Resource": "*",
            "Condition": {
              "StringEquals": {
                "kms:CallerAccount": accountId
              }
            }
          }
        ]
      },
      multiRegion: true,
      wizScanAccess: true,
      tags: {
        AppCatID: helper.tags.AppCatID,
        Cost_Center: helper.tags.Cost_Center,
        Description: helper.tags.Description,
        Environment: helper.tags.Environment,
        ServiceName: helper.tags.ServiceName,
        Stage: helper.tags.Stage,
        'Support-Team': helper.tags['Support-Team']
      }
    });

    new cdk.CfnOutput(this, 'EpreNacbDbDevelopmentAndSupportKmsKeyArn', {
      value: myKms.kmsKey.attrArn,
      description: 'EPRE NACB DB Development and Support KMS key ARN',
      exportName: 'epre-nacb-db-development-and-support-kms-key-arn'
    });
  }
}