From 3ba852e078626c52464e651a9dafbbaeb62dc700 Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Wed, 31 Jan 2024 13:21:30 +1100 Subject: [PATCH 01/21] Update orcabus-pipeline-stack.ts --- lib/pipeline/orcabus-pipeline-stack.ts | 95 ++++++++------------------ 1 file changed, 29 insertions(+), 66 deletions(-) diff --git a/lib/pipeline/orcabus-pipeline-stack.ts b/lib/pipeline/orcabus-pipeline-stack.ts index ff4f1cb8d..7b77d5b35 100644 --- a/lib/pipeline/orcabus-pipeline-stack.ts +++ b/lib/pipeline/orcabus-pipeline-stack.ts @@ -6,7 +6,6 @@ import * as codebuild from 'aws-cdk-lib/aws-codebuild'; import { OrcaBusStatelessConfig, OrcaBusStatelessStack } from '../workload/orcabus-stateless-stack'; import { OrcaBusStatefulConfig, OrcaBusStatefulStack } from '../workload/orcabus-stateful-stack'; import { getEnvironmentConfig } from '../../config/constants'; -import { PolicyStatement } from 'aws-cdk-lib/aws-iam'; export class PipelineStack extends cdk.Stack { constructor(scope: Construct, id: string, props: cdk.StackProps) { @@ -14,38 +13,37 @@ export class PipelineStack extends cdk.Stack { // A connection where the pipeline get its source code const codeStarArn = ssm.StringParameter.valueForStringParameter(this, 'codestar_github_arn'); - const sourceFile = pipelines.CodePipelineSource.connection('umccr/orcabus', 'main', { - connectionArn: codeStarArn, + const sourceFile = pipelines.CodePipelineSource.connection( + 'umccr/orcabus', + 'feature/base-cdk-deployment', + { + connectionArn: codeStarArn, + } + ); + + const orcabusUnitTest = new pipelines.CodeBuildStep('UnitTest', { + commands: ['yarn install --forzen-lockfile', 'make suite'], + input: sourceFile, + primaryOutputDirectory: '.', }); const synthAction = new pipelines.CodeBuildStep('Synth', { - input: sourceFile, - commands: ['yarn install --frozen-lockfile', 'yarn cdk synth -v'], + commands: ['yarn install --frozen-lockfile', 'yarn run cdk synth -v'], + input: orcabusUnitTest, primaryOutputDirectory: 'cdk.out', - rolePolicyStatements: [ - new PolicyStatement({ - actions: ['sts:AssumeRole'], - resources: ['*'], - conditions: { - StringEquals: { - 'iam:ResourceTag/aws-cdk:bootstrap-role': 'lookup', - }, - }, - }), - ], }); - synthAction.addStepDependency(new OrcaBusTestStep('OrcaBusUnitTest', { source: sourceFile })); const pipeline = new pipelines.CodePipeline(this, 'Pipeline', { synth: synthAction, selfMutation: true, crossAccountKeys: true, + dockerEnabledForSynth: true, codeBuildDefaults: { buildEnvironment: { - buildImage: codebuild.LinuxBuildImage.STANDARD_6_0, + computeType: codebuild.ComputeType.SMALL, + buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0, }, }, - dockerEnabledForSelfMutation: true, }); /** @@ -59,17 +57,17 @@ export class PipelineStack extends cdk.Stack { }) ); - /** - * Deployment to Gamma (Staging) account - */ - const gammaConfig = getEnvironmentConfig('gamma'); - if (!gammaConfig) throw new Error(`No 'Gamma' account configuration`); - pipeline.addStage( - new OrcaBusDeploymentStage(this, 'GammaDeployment', gammaConfig.stackProps, { - account: gammaConfig.accountId, - }), - { pre: [new pipelines.ManualApprovalStep('PromoteToGamma')] } - ); + // /** + // * Deployment to Gamma (Staging) account + // */ + // const gammaConfig = getEnvironmentConfig('gamma'); + // if (!gammaConfig) throw new Error(`No 'Gamma' account configuration`); + // pipeline.addStage( + // new OrcaBusDeploymentStage(this, 'GammaDeployment', gammaConfig.stackProps, { + // account: gammaConfig.accountId, + // }), + // { pre: [new pipelines.ManualApprovalStep('PromoteToGamma')] } + // ); /** * Deployment to Prod account (DISABLED) @@ -98,41 +96,6 @@ class OrcaBusDeploymentStage extends cdk.Stage { super(scope, environmentName, { env: { account: env?.account, region: 'ap-southeast-2' } }); new OrcaBusStatefulStack(this, 'OrcaBusStatefulStack', stackProps.orcaBusStatefulConfig); - new OrcaBusStatelessStack(this, 'OrcaBusStatelessStack', stackProps.orcaBusStatelessConfig); - } -} - -interface OrcaBusTestStepProps { - source: pipelines.CodePipelineSource; -} -class OrcaBusTestStep extends pipelines.CodeBuildStep { - constructor(id: string, props: OrcaBusTestStepProps) { - const stepProps: pipelines.CodeBuildStepProps = { - input: props.source, - commands: [], - partialBuildSpec: codebuild.BuildSpec.fromObject({ - env: { - shell: 'bash', - }, - phases: { - install: { - commands: [ - 'wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-py310_23.3.1-0-Linux-x86_64.sh', - 'bash Miniconda3-py310_23.3.1-0-Linux-x86_64.sh -b', - 'export PATH=/root/miniconda3/bin:$PATH', - 'conda init bash', - 'source activate', - 'conda create -q -n orcabus python=3.10', - 'conda run -n orcabus yarn install', - ], - }, - build: { - commands: ['conda run -n orcabus make test'], - }, - }, - version: '0.2', - }), - }; - super(id, stepProps); + // new OrcaBusStatelessStack(this, 'OrcaBusStatelessStack', stackProps.orcaBusStatelessConfig); } } From 73944b4b784f27f166652fbedb0770d7f71d568f Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Wed, 31 Jan 2024 15:14:34 +1100 Subject: [PATCH 02/21] Update orcabus-pipeline-stack.ts --- lib/pipeline/orcabus-pipeline-stack.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pipeline/orcabus-pipeline-stack.ts b/lib/pipeline/orcabus-pipeline-stack.ts index 7b77d5b35..bff01bc8c 100644 --- a/lib/pipeline/orcabus-pipeline-stack.ts +++ b/lib/pipeline/orcabus-pipeline-stack.ts @@ -15,14 +15,14 @@ export class PipelineStack extends cdk.Stack { const codeStarArn = ssm.StringParameter.valueForStringParameter(this, 'codestar_github_arn'); const sourceFile = pipelines.CodePipelineSource.connection( 'umccr/orcabus', - 'feature/base-cdk-deployment', + 'feature/base-cdk-codepipeline', { connectionArn: codeStarArn, } ); const orcabusUnitTest = new pipelines.CodeBuildStep('UnitTest', { - commands: ['yarn install --forzen-lockfile', 'make suite'], + commands: ['yarn install --frozen-lockfile', 'make suite'], input: sourceFile, primaryOutputDirectory: '.', }); From 72086ee0aac6fde9597bacf08bb2d064c01fc2aa Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Wed, 31 Jan 2024 17:11:40 +1100 Subject: [PATCH 03/21] wait for healthy db --- lib/workload/stateless/metadata_manager/Makefile | 2 +- lib/workload/stateless/sequence_run_manager/Makefile | 2 +- shared/mock-db.yml | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/workload/stateless/metadata_manager/Makefile b/lib/workload/stateless/metadata_manager/Makefile index 610a97626..e9113e7cd 100644 --- a/lib/workload/stateless/metadata_manager/Makefile +++ b/lib/workload/stateless/metadata_manager/Makefile @@ -39,7 +39,7 @@ build: edgetypes # Testing # full test pipeline -test: install docker-edgedb edgetypes suite +test: install docker-edgedb edgetypes suite down suite: @yarn test diff --git a/lib/workload/stateless/sequence_run_manager/Makefile b/lib/workload/stateless/sequence_run_manager/Makefile index edb763ba4..33b2065ac 100644 --- a/lib/workload/stateless/sequence_run_manager/Makefile +++ b/lib/workload/stateless/sequence_run_manager/Makefile @@ -23,7 +23,7 @@ suite: @python manage.py test up: - @docker compose up -d + @docker compose up --wait -d down: @docker compose down diff --git a/shared/mock-db.yml b/shared/mock-db.yml index 041c52878..3045ed58f 100644 --- a/shared/mock-db.yml +++ b/shared/mock-db.yml @@ -15,3 +15,9 @@ services: - POSTGRES_PASSWORD=orcabus ports: - "5432:5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready", "-d", "orcabus"] + interval: 10s + timeout: 60s + retries: 5 + start_period: 90s From da4f4fc1679a7828b5e1eb0baecfd2c076a128c5 Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Wed, 31 Jan 2024 18:41:47 +1100 Subject: [PATCH 04/21] Update orcabus-pipeline-stack.ts --- lib/pipeline/orcabus-pipeline-stack.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/pipeline/orcabus-pipeline-stack.ts b/lib/pipeline/orcabus-pipeline-stack.ts index bff01bc8c..80aa35646 100644 --- a/lib/pipeline/orcabus-pipeline-stack.ts +++ b/lib/pipeline/orcabus-pipeline-stack.ts @@ -25,6 +25,15 @@ export class PipelineStack extends cdk.Stack { commands: ['yarn install --frozen-lockfile', 'make suite'], input: sourceFile, primaryOutputDirectory: '.', + buildEnvironment: { + computeType: codebuild.ComputeType.LARGE, + buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0, + environmentVariables: { + NODE_OPTIONS: { + value: '--max-old-space-size=8192', + }, + }, + }, }); const synthAction = new pipelines.CodeBuildStep('Synth', { @@ -38,9 +47,10 @@ export class PipelineStack extends cdk.Stack { selfMutation: true, crossAccountKeys: true, dockerEnabledForSynth: true, + dockerEnabledForSelfMutation: true, codeBuildDefaults: { buildEnvironment: { - computeType: codebuild.ComputeType.SMALL, + computeType: codebuild.ComputeType.LARGE, buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0, }, }, From 000bdb71c49f7286bc97399df6bab1d8743d0ebe Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Thu, 1 Feb 2024 09:47:05 +1100 Subject: [PATCH 05/21] Update orcabus-pipeline-stack.ts --- lib/pipeline/orcabus-pipeline-stack.ts | 33 +++++++++++++------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/lib/pipeline/orcabus-pipeline-stack.ts b/lib/pipeline/orcabus-pipeline-stack.ts index 80aa35646..ecedf4b87 100644 --- a/lib/pipeline/orcabus-pipeline-stack.ts +++ b/lib/pipeline/orcabus-pipeline-stack.ts @@ -3,6 +3,7 @@ import * as cdk from 'aws-cdk-lib'; import * as ssm from 'aws-cdk-lib/aws-ssm'; import * as pipelines from 'aws-cdk-lib/pipelines'; import * as codebuild from 'aws-cdk-lib/aws-codebuild'; +import * as iam from 'aws-cdk-lib/aws-iam'; import { OrcaBusStatelessConfig, OrcaBusStatelessStack } from '../workload/orcabus-stateless-stack'; import { OrcaBusStatefulConfig, OrcaBusStatefulStack } from '../workload/orcabus-stateful-stack'; import { getEnvironmentConfig } from '../../config/constants'; @@ -21,25 +22,17 @@ export class PipelineStack extends cdk.Stack { } ); - const orcabusUnitTest = new pipelines.CodeBuildStep('UnitTest', { - commands: ['yarn install --frozen-lockfile', 'make suite'], - input: sourceFile, - primaryOutputDirectory: '.', - buildEnvironment: { - computeType: codebuild.ComputeType.LARGE, - buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0, - environmentVariables: { - NODE_OPTIONS: { - value: '--max-old-space-size=8192', - }, - }, - }, - }); - const synthAction = new pipelines.CodeBuildStep('Synth', { - commands: ['yarn install --frozen-lockfile', 'yarn run cdk synth -v'], - input: orcabusUnitTest, + commands: ['yarn install --frozen-lockfile', 'make suite', 'yarn run cdk synth'], + input: sourceFile, primaryOutputDirectory: 'cdk.out', + rolePolicyStatements: [ + new iam.PolicyStatement({ + effect: iam.Effect.ALLOW, + actions: ['sts:AssumeRole'], + resources: ['*'], + }), + ], }); const pipeline = new pipelines.CodePipeline(this, 'Pipeline', { @@ -50,8 +43,14 @@ export class PipelineStack extends cdk.Stack { dockerEnabledForSelfMutation: true, codeBuildDefaults: { buildEnvironment: { + privileged: true, computeType: codebuild.ComputeType.LARGE, buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0, + environmentVariables: { + NODE_OPTIONS: { + value: '--max-old-space-size=8192', + }, + }, }, }, }); From 27a136ae9872dc9784f836d75f84c6bba0ca615e Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Thu, 1 Feb 2024 10:20:09 +1100 Subject: [PATCH 06/21] remove reserved keyword --- config/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/constants.ts b/config/constants.ts index e78f69e1d..2d6784b83 100644 --- a/config/constants.ts +++ b/config/constants.ts @@ -24,7 +24,7 @@ const orcaBusStatefulConfig = { defaultDatabaseName: 'orcabus', version: AuroraPostgresEngineVersion.VER_15_4, parameterGroupName: 'default.aurora-postgresql15', - username: 'admin', + username: 'postgres', dbPort: 5432, masterSecretName: rdsMasterSecretName, monitoring: { From 955f1ffc140b0151321b348eaf0077259469d68e Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Thu, 1 Feb 2024 11:25:11 +1100 Subject: [PATCH 07/21] Update orcabus-pipeline-stack.ts --- lib/pipeline/orcabus-pipeline-stack.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/pipeline/orcabus-pipeline-stack.ts b/lib/pipeline/orcabus-pipeline-stack.ts index ecedf4b87..00c2d0f33 100644 --- a/lib/pipeline/orcabus-pipeline-stack.ts +++ b/lib/pipeline/orcabus-pipeline-stack.ts @@ -43,7 +43,6 @@ export class PipelineStack extends cdk.Stack { dockerEnabledForSelfMutation: true, codeBuildDefaults: { buildEnvironment: { - privileged: true, computeType: codebuild.ComputeType.LARGE, buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0, environmentVariables: { @@ -104,7 +103,7 @@ class OrcaBusDeploymentStage extends cdk.Stage { ) { super(scope, environmentName, { env: { account: env?.account, region: 'ap-southeast-2' } }); - new OrcaBusStatefulStack(this, 'OrcaBusStatefulStack', stackProps.orcaBusStatefulConfig); - // new OrcaBusStatelessStack(this, 'OrcaBusStatelessStack', stackProps.orcaBusStatelessConfig); + // new OrcaBusStatefulStack(this, 'OrcaBusStatefulStack', stackProps.orcaBusStatefulConfig); + new OrcaBusStatelessStack(this, 'OrcaBusStatelessStack', stackProps.orcaBusStatelessConfig); } } From e5c77b2abddd92a0d6339f142fcba643b6b78d19 Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Thu, 1 Feb 2024 17:44:02 +1100 Subject: [PATCH 08/21] test cdk diff check --- bin/orcabus.ts | 4 +- bin/pipeline.ts | 4 +- cdk.json | 2 +- ...ts => orcabus-stateless-pipeline-stack.ts} | 52 ++++++++++++++++--- package.json | 1 - 5 files changed, 49 insertions(+), 14 deletions(-) rename lib/pipeline/{orcabus-pipeline-stack.ts => orcabus-stateless-pipeline-stack.ts} (65%) diff --git a/bin/orcabus.ts b/bin/orcabus.ts index 1c04b7315..56afb7ebc 100644 --- a/bin/orcabus.ts +++ b/bin/orcabus.ts @@ -15,8 +15,8 @@ import { getEnvironmentConfig } from '../config/constants'; const app = new cdk.App(); const props: cdk.StackProps = { env: { - account: process.env.CDK_DEFAULT_ACCOUNT, - region: process.env.CDK_DEFAULT_REGION, + account: process.env.CDK_DEPLOY_ACCOUNT || process.env.CDK_DEFAULT_ACCOUNT, + region: process.env.CDK_DEPLOY_REGION || process.env.CDK_DEFAULT_REGION, }, tags: { 'umccr-org:Stack': 'OrcaBusSandboxApp', diff --git a/bin/pipeline.ts b/bin/pipeline.ts index 336546fe5..009f58c97 100644 --- a/bin/pipeline.ts +++ b/bin/pipeline.ts @@ -2,14 +2,14 @@ import 'source-map-support/register'; import * as cdk from 'aws-cdk-lib'; -import { PipelineStack } from '../lib/pipeline/orcabus-pipeline-stack'; +import { StatelessPipelineStack } from '../lib/pipeline/orcabus-stateless-pipeline-stack'; const AWS_TOOLCHAIN_ACCOUNT = '383856791668'; // Bastion const AWS_TOOLCHAIN_REGION = 'ap-southeast-2'; const app = new cdk.App(); -new PipelineStack(app, `OrcaBusPipeline`, { +new StatelessPipelineStack(app, `OrcaBusPipeline`, { env: { account: AWS_TOOLCHAIN_ACCOUNT, region: AWS_TOOLCHAIN_REGION, diff --git a/cdk.json b/cdk.json index 87f0bb642..faf5362ca 100644 --- a/cdk.json +++ b/cdk.json @@ -1,5 +1,5 @@ { - "app": "npx ts-node --prefer-ts-exts bin/pipeline.ts", + "app": "yarn run ts-node --prefer-ts-exts bin/orcabus.ts", "watch": { "include": [ "**" diff --git a/lib/pipeline/orcabus-pipeline-stack.ts b/lib/pipeline/orcabus-stateless-pipeline-stack.ts similarity index 65% rename from lib/pipeline/orcabus-pipeline-stack.ts rename to lib/pipeline/orcabus-stateless-pipeline-stack.ts index 00c2d0f33..c94a8e231 100644 --- a/lib/pipeline/orcabus-pipeline-stack.ts +++ b/lib/pipeline/orcabus-stateless-pipeline-stack.ts @@ -5,10 +5,10 @@ import * as pipelines from 'aws-cdk-lib/pipelines'; import * as codebuild from 'aws-cdk-lib/aws-codebuild'; import * as iam from 'aws-cdk-lib/aws-iam'; import { OrcaBusStatelessConfig, OrcaBusStatelessStack } from '../workload/orcabus-stateless-stack'; -import { OrcaBusStatefulConfig, OrcaBusStatefulStack } from '../workload/orcabus-stateful-stack'; +import { OrcaBusStatefulConfig } from '../workload/orcabus-stateful-stack'; import { getEnvironmentConfig } from '../../config/constants'; -export class PipelineStack extends cdk.Stack { +export class StatelessPipelineStack extends cdk.Stack { constructor(scope: Construct, id: string, props: cdk.StackProps) { super(scope, id, props); @@ -60,9 +60,34 @@ export class PipelineStack extends cdk.Stack { const betaConfig = getEnvironmentConfig('beta'); if (!betaConfig) throw new Error(`No 'Beta' account configuration`); pipeline.addStage( - new OrcaBusDeploymentStage(this, 'BetaDeployment', betaConfig.stackProps, { + new OrcaBusStatelessDeploymentStage(this, 'BetaDeployment', betaConfig.stackProps, { account: betaConfig.accountId, - }) + }), + { + pre: [ + // need to make sure state*ful* stack matches with the current asset + new pipelines.CodeBuildStep('BetaStatefulDiffCheck', { + commands: [ + 'yarn install --frozen-lockfile', + "yarn run cdk diff -a 'yarn run ts-node --prefer-ts-exts bin/orcabus.ts' --fail OrcaBusStatefulStack", + ], + rolePolicyStatements: [ + new iam.PolicyStatement({ + effect: iam.Effect.ALLOW, + actions: ['sts:AssumeRole'], + resources: ['*'], + }), + ], + buildEnvironment: { + environmentVariables: { + CDK_DEPLOY_ACCOUNT: { + value: betaConfig.accountId, + }, + }, + }, + }), + ], + } ); // /** @@ -71,10 +96,22 @@ export class PipelineStack extends cdk.Stack { // const gammaConfig = getEnvironmentConfig('gamma'); // if (!gammaConfig) throw new Error(`No 'Gamma' account configuration`); // pipeline.addStage( - // new OrcaBusDeploymentStage(this, 'GammaDeployment', gammaConfig.stackProps, { + // new OrcaBusStatelessDeploymentStage(this, 'GammaDeployment', gammaConfig.stackProps, { // account: gammaConfig.accountId, // }), - // { pre: [new pipelines.ManualApprovalStep('PromoteToGamma')] } + // { + // pre: [ + // // need to make sure stateful stack matches + // // new pipelines.CodeBuildStep('StatefulDiffCheck', { + // // commands: [ + // // 'yarn install --frozen-lockfile', + // // 'yarn run cdk diff OrcaBusPipeline/GammaDeployment/OrcaBusStatelessStack --fail', + // // ], + // // }), + // // approval to gamma release + // new pipelines.ManualApprovalStep('PromoteToGamma'), + // ], + // } // ); /** @@ -91,7 +128,7 @@ export class PipelineStack extends cdk.Stack { } } -class OrcaBusDeploymentStage extends cdk.Stage { +class OrcaBusStatelessDeploymentStage extends cdk.Stage { constructor( scope: Construct, environmentName: string, @@ -103,7 +140,6 @@ class OrcaBusDeploymentStage extends cdk.Stage { ) { super(scope, environmentName, { env: { account: env?.account, region: 'ap-southeast-2' } }); - // new OrcaBusStatefulStack(this, 'OrcaBusStatefulStack', stackProps.orcaBusStatefulConfig); new OrcaBusStatelessStack(this, 'OrcaBusStatelessStack', stackProps.orcaBusStatelessConfig); } } diff --git a/package.json b/package.json index 75ef53e31..7d58addf6 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,6 @@ "bin": "bin/pipeline.js", "scripts": { "test": "tsc && jest", - "cdk": "cdk", "orcabus": "cdk --app 'npx ts-node --prefer-ts-exts bin/orcabus.ts'", "build": "cdk synth -q", "watch": "tsc -w", From 4a9193007beabfa6d78e1e4e9d13583c7d1f748d Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Thu, 1 Feb 2024 18:16:29 +1100 Subject: [PATCH 09/21] Update cdk.json --- cdk.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdk.json b/cdk.json index faf5362ca..ff46b3996 100644 --- a/cdk.json +++ b/cdk.json @@ -1,5 +1,5 @@ { - "app": "yarn run ts-node --prefer-ts-exts bin/orcabus.ts", + "app": "yarn run ts-node --prefer-ts-exts bin/pipeline.ts", "watch": { "include": [ "**" From 24f17498874c918b57dbc2adf8ede192568285bd Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Fri, 2 Feb 2024 12:19:16 +1100 Subject: [PATCH 10/21] seperate stateless and ful stack --- bin/stateful-pipeline.ts | 21 ++++ bin/{pipeline.ts => stateless-pipeline.ts} | 4 +- cdk.json | 2 +- .../orcabus-stateful-pipeline-stack.ts | 109 ++++++++++++++++++ .../orcabus-stateless-pipeline-stack.ts | 93 +++++---------- package.json | 6 +- 6 files changed, 168 insertions(+), 67 deletions(-) create mode 100644 bin/stateful-pipeline.ts rename bin/{pipeline.ts => stateless-pipeline.ts} (80%) create mode 100644 lib/pipeline/orcabus-stateful-pipeline-stack.ts diff --git a/bin/stateful-pipeline.ts b/bin/stateful-pipeline.ts new file mode 100644 index 000000000..338f3166f --- /dev/null +++ b/bin/stateful-pipeline.ts @@ -0,0 +1,21 @@ +#!/usr/bin/env node +import 'source-map-support/register'; + +import * as cdk from 'aws-cdk-lib'; +import { StatefulPipelineStack } from '../lib/pipeline/orcabus-stateful-pipeline-stack'; + +const AWS_TOOLCHAIN_ACCOUNT = '383856791668'; // Bastion +const AWS_TOOLCHAIN_REGION = 'ap-southeast-2'; + +const app = new cdk.App(); + +new StatefulPipelineStack(app, `OrcaBusStatefulPipeline`, { + env: { + account: AWS_TOOLCHAIN_ACCOUNT, + region: AWS_TOOLCHAIN_REGION, + }, + tags: { + 'umccr-org:Stack': 'OrcaBusStatefulPipelineApp', + 'umccr-org:Product': 'OrcaBus', + }, +}); diff --git a/bin/pipeline.ts b/bin/stateless-pipeline.ts similarity index 80% rename from bin/pipeline.ts rename to bin/stateless-pipeline.ts index 009f58c97..8bed2c1b4 100644 --- a/bin/pipeline.ts +++ b/bin/stateless-pipeline.ts @@ -9,13 +9,13 @@ const AWS_TOOLCHAIN_REGION = 'ap-southeast-2'; const app = new cdk.App(); -new StatelessPipelineStack(app, `OrcaBusPipeline`, { +new StatelessPipelineStack(app, `OrcaBusStatelessPipeline`, { env: { account: AWS_TOOLCHAIN_ACCOUNT, region: AWS_TOOLCHAIN_REGION, }, tags: { - 'umccr-org:Stack': 'OrcaBusPipelineApp', + 'umccr-org:Stack': 'OrcaBusStatelessPipeline', 'umccr-org:Product': 'OrcaBus', }, }); diff --git a/cdk.json b/cdk.json index ff46b3996..faf5362ca 100644 --- a/cdk.json +++ b/cdk.json @@ -1,5 +1,5 @@ { - "app": "yarn run ts-node --prefer-ts-exts bin/pipeline.ts", + "app": "yarn run ts-node --prefer-ts-exts bin/orcabus.ts", "watch": { "include": [ "**" diff --git a/lib/pipeline/orcabus-stateful-pipeline-stack.ts b/lib/pipeline/orcabus-stateful-pipeline-stack.ts new file mode 100644 index 000000000..16d815885 --- /dev/null +++ b/lib/pipeline/orcabus-stateful-pipeline-stack.ts @@ -0,0 +1,109 @@ +import { Construct } from 'constructs'; +import * as cdk from 'aws-cdk-lib'; +import * as ssm from 'aws-cdk-lib/aws-ssm'; +import * as pipelines from 'aws-cdk-lib/pipelines'; +import * as codebuild from 'aws-cdk-lib/aws-codebuild'; +import * as iam from 'aws-cdk-lib/aws-iam'; +import { OrcaBusStatefulConfig, OrcaBusStatefulStack } from '../workload/orcabus-stateful-stack'; +import { getEnvironmentConfig } from '../../config/constants'; + +export class StatefulPipelineStack extends cdk.Stack { + constructor(scope: Construct, id: string, props: cdk.StackProps) { + super(scope, id, props); + + // A connection where the pipeline get its source code + const codeStarArn = ssm.StringParameter.valueForStringParameter(this, 'codestar_github_arn'); + const sourceFile = pipelines.CodePipelineSource.connection( + 'umccr/orcabus', + 'feature/base-cdk-codepipeline', + { + connectionArn: codeStarArn, + } + ); + + const synthAction = new pipelines.CodeBuildStep('Synth', { + commands: [ + 'yarn install --frozen-lockfile', + 'make test', + 'yarn run cdk-stateful-pipeline synth', + ], + input: sourceFile, + primaryOutputDirectory: 'cdk.out', + rolePolicyStatements: [ + new iam.PolicyStatement({ + effect: iam.Effect.ALLOW, + actions: ['sts:AssumeRole'], + resources: ['*'], + }), + ], + }); + + const pipeline = new pipelines.CodePipeline(this, 'Pipeline', { + synth: synthAction, + selfMutation: true, + crossAccountKeys: true, + dockerEnabledForSynth: true, + dockerEnabledForSelfMutation: true, + codeBuildDefaults: { + buildEnvironment: { + computeType: codebuild.ComputeType.LARGE, + buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0, + environmentVariables: { + NODE_OPTIONS: { + value: '--max-old-space-size=8192', + }, + }, + }, + }, + }); + + /** + * Deployment to Beta (Dev) account + */ + const betaConfig = getEnvironmentConfig('beta'); + if (!betaConfig) throw new Error(`No 'Beta' account configuration`); + pipeline.addStage( + new OrcaBusStatefulDeploymentStage(this, 'BetaDeployment', betaConfig.stackProps, { + account: betaConfig.accountId, + }) + ); + + /** + * Deployment to Gamma (Staging) account + */ + const gammaConfig = getEnvironmentConfig('gamma'); + if (!gammaConfig) throw new Error(`No 'Gamma' account configuration`); + pipeline.addStage( + new OrcaBusStatefulDeploymentStage(this, 'GammaDeployment', gammaConfig.stackProps, { + account: gammaConfig.accountId, + }) + ); + + /** + * Deployment to Prod account (DISABLED) + */ + const prodConfig = getEnvironmentConfig('prod'); + if (!prodConfig) throw new Error(`No 'Prod' account configuration`); + pipeline.addStage( + new OrcaBusStatefulDeploymentStage(this, 'prodDeployment', prodConfig.stackProps, { + account: gammaConfig?.accountId, + }), + { pre: [new pipelines.ManualApprovalStep('PromoteToProd')] } + ); + } +} + +class OrcaBusStatefulDeploymentStage extends cdk.Stage { + constructor( + scope: Construct, + environmentName: string, + stackProps: { + orcaBusStatefulConfig: OrcaBusStatefulConfig; + }, + env?: cdk.Environment + ) { + super(scope, environmentName, { env: { account: env?.account, region: 'ap-southeast-2' } }); + + new OrcaBusStatefulStack(this, 'OrcaBusStatefulStack', stackProps.orcaBusStatefulConfig); + } +} diff --git a/lib/pipeline/orcabus-stateless-pipeline-stack.ts b/lib/pipeline/orcabus-stateless-pipeline-stack.ts index c94a8e231..040275c26 100644 --- a/lib/pipeline/orcabus-stateless-pipeline-stack.ts +++ b/lib/pipeline/orcabus-stateless-pipeline-stack.ts @@ -5,7 +5,6 @@ import * as pipelines from 'aws-cdk-lib/pipelines'; import * as codebuild from 'aws-cdk-lib/aws-codebuild'; import * as iam from 'aws-cdk-lib/aws-iam'; import { OrcaBusStatelessConfig, OrcaBusStatelessStack } from '../workload/orcabus-stateless-stack'; -import { OrcaBusStatefulConfig } from '../workload/orcabus-stateful-stack'; import { getEnvironmentConfig } from '../../config/constants'; export class StatelessPipelineStack extends cdk.Stack { @@ -23,7 +22,11 @@ export class StatelessPipelineStack extends cdk.Stack { ); const synthAction = new pipelines.CodeBuildStep('Synth', { - commands: ['yarn install --frozen-lockfile', 'make suite', 'yarn run cdk synth'], + commands: [ + 'yarn install --frozen-lockfile', + 'make suite', + 'yarn run yarn run cdk-stateless-pipeline synth synth', + ], input: sourceFile, primaryOutputDirectory: 'cdk.out', rolePolicyStatements: [ @@ -60,71 +63,38 @@ export class StatelessPipelineStack extends cdk.Stack { const betaConfig = getEnvironmentConfig('beta'); if (!betaConfig) throw new Error(`No 'Beta' account configuration`); pipeline.addStage( - new OrcaBusStatelessDeploymentStage(this, 'BetaDeployment', betaConfig.stackProps, { + new OrcaBusStatelessDeploymentStage(this, 'BetaStatelessDeployment', betaConfig.stackProps, { account: betaConfig.accountId, - }), - { - pre: [ - // need to make sure state*ful* stack matches with the current asset - new pipelines.CodeBuildStep('BetaStatefulDiffCheck', { - commands: [ - 'yarn install --frozen-lockfile', - "yarn run cdk diff -a 'yarn run ts-node --prefer-ts-exts bin/orcabus.ts' --fail OrcaBusStatefulStack", - ], - rolePolicyStatements: [ - new iam.PolicyStatement({ - effect: iam.Effect.ALLOW, - actions: ['sts:AssumeRole'], - resources: ['*'], - }), - ], - buildEnvironment: { - environmentVariables: { - CDK_DEPLOY_ACCOUNT: { - value: betaConfig.accountId, - }, - }, - }, - }), - ], - } + }) ); - // /** - // * Deployment to Gamma (Staging) account - // */ - // const gammaConfig = getEnvironmentConfig('gamma'); - // if (!gammaConfig) throw new Error(`No 'Gamma' account configuration`); - // pipeline.addStage( - // new OrcaBusStatelessDeploymentStage(this, 'GammaDeployment', gammaConfig.stackProps, { - // account: gammaConfig.accountId, - // }), - // { - // pre: [ - // // need to make sure stateful stack matches - // // new pipelines.CodeBuildStep('StatefulDiffCheck', { - // // commands: [ - // // 'yarn install --frozen-lockfile', - // // 'yarn run cdk diff OrcaBusPipeline/GammaDeployment/OrcaBusStatelessStack --fail', - // // ], - // // }), - // // approval to gamma release - // new pipelines.ManualApprovalStep('PromoteToGamma'), - // ], - // } - // ); + /** + * Deployment to Gamma (Staging) account + */ + const gammaConfig = getEnvironmentConfig('gamma'); + if (!gammaConfig) throw new Error(`No 'Gamma' account configuration`); + pipeline.addStage( + new OrcaBusStatelessDeploymentStage( + this, + 'GammaStatelessDeployment', + gammaConfig.stackProps, + { + account: gammaConfig.accountId, + } + ) + ); /** - * Deployment to Prod account (DISABLED) + * Deployment to Prod account */ - // const prodConfig = getEnvironmentConfig('prod'); - // if (!prodConfig) throw new Error(`No 'Prod' account configuration`); - // pipeline.addStage( - // new OrcaBusDeploymentStage(this, 'prodDeployment', prodConfig.stackProps, { - // account: gammaConfig?.accountId, - // }), - // { pre: [new pipelines.ManualApprovalStep('PromoteToProd')] } - // ); + const prodConfig = getEnvironmentConfig('prod'); + if (!prodConfig) throw new Error(`No 'Prod' account configuration`); + pipeline.addStage( + new OrcaBusStatelessDeploymentStage(this, 'ProdStatelessDeployment', prodConfig.stackProps, { + account: gammaConfig?.accountId, + }), + { pre: [new pipelines.ManualApprovalStep('PromoteToProd')] } + ); } } @@ -133,7 +103,6 @@ class OrcaBusStatelessDeploymentStage extends cdk.Stage { scope: Construct, environmentName: string, stackProps: { - orcaBusStatefulConfig: OrcaBusStatefulConfig; orcaBusStatelessConfig: OrcaBusStatelessConfig; }, env?: cdk.Environment diff --git a/package.json b/package.json index 7d58addf6..66c4b1f68 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,6 @@ "bin": "bin/pipeline.js", "scripts": { "test": "tsc && jest", - "orcabus": "cdk --app 'npx ts-node --prefer-ts-exts bin/orcabus.ts'", "build": "cdk synth -q", "watch": "tsc -w", "clean": "tsc --build --clean", @@ -20,7 +19,10 @@ "lint": "eslint .", "lint-fix": "eslint --fix .", "prettier": "prettier --check .", - "prettier-fix": "prettier --write ." + "prettier-fix": "prettier --write .", + "cdk-stateless-pipeline": "cdk --app 'yarn run -B ts-node --prefer-ts-exts bin/stateless-pipeline.ts'", + "cdk-stateful-pipeline": "cdk --app 'yarn run -B ts-node --prefer-ts-exts bin/stateful-pipeline.ts'", + "cdk-orcabus": "cdk --app 'yarn run -B ts-node --prefer-ts-exts bin/orcabus.ts'" }, "dependencies": { "@aws-cdk/aws-apigatewayv2-alpha": "^2.110.0-alpha.0", From e78660d537ee2ae4931d3ac38df39fe752c2ab02 Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Fri, 2 Feb 2024 15:32:16 +1100 Subject: [PATCH 11/21] add cdk-nag check --- config/constants.ts | 5 +- lib/workload/stateful/database/component.ts | 5 +- package.json | 1 + test/cdkNag/pipeline.test.ts | 87 +++++++++++++++++++ test/cdkNag/stateful-deployment.test.ts | 50 +++++++++++ test/cdkNag/stateless-deployment.test.ts | 46 ++++++++++ .../stateful/databaseConstruct.test.ts | 0 .../stateful/eventbusConstruct.test.ts | 0 .../stateful/schemaRegistryConstruct.test.ts | 0 .../stateful/securityGroupConstruct.test.ts | 0 yarn.lock | 11 +++ 11 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 test/cdkNag/pipeline.test.ts create mode 100644 test/cdkNag/stateful-deployment.test.ts create mode 100644 test/cdkNag/stateless-deployment.test.ts rename test/{workload => construct}/stateful/databaseConstruct.test.ts (100%) rename test/{workload => construct}/stateful/eventbusConstruct.test.ts (100%) rename test/{workload => construct}/stateful/schemaRegistryConstruct.test.ts (100%) rename test/{workload => construct}/stateful/securityGroupConstruct.test.ts (100%) diff --git a/config/constants.ts b/config/constants.ts index 2d6784b83..294254d2d 100644 --- a/config/constants.ts +++ b/config/constants.ts @@ -1,7 +1,7 @@ import { OrcaBusStatefulConfig } from '../lib/workload/orcabus-stateful-stack'; import { AuroraPostgresEngineVersion } from 'aws-cdk-lib/aws-rds'; import { OrcaBusStatelessConfig } from '../lib/workload/orcabus-stateless-stack'; -import { Duration, aws_lambda } from 'aws-cdk-lib'; +import { Duration, aws_lambda, RemovalPolicy } from 'aws-cdk-lib'; const regName = 'OrcaBusSchemaRegistry'; const eventBusName = 'OrcaBusMain'; @@ -94,6 +94,7 @@ export const getEnvironmentConfig = ( maxACU: 1, enhancedMonitoringInterval: Duration.seconds(60), enablePerformanceInsights: true, + removalPolicy: RemovalPolicy.DESTROY, }, securityGroupProps: { ...orcaBusStatefulConfig.securityGroupProps, @@ -123,6 +124,7 @@ export const getEnvironmentConfig = ( maxACU: 1, enhancedMonitoringInterval: Duration.seconds(60), enablePerformanceInsights: true, + removalPolicy: RemovalPolicy.DESTROY, }, securityGroupProps: { ...orcaBusStatefulConfig.securityGroupProps, @@ -150,6 +152,7 @@ export const getEnvironmentConfig = ( numberOfInstance: 1, minACU: 0.5, maxACU: 1, + removalPolicy: RemovalPolicy.RETAIN, }, securityGroupProps: { ...orcaBusStatefulConfig.securityGroupProps, diff --git a/lib/workload/stateful/database/component.ts b/lib/workload/stateful/database/component.ts index 423b62c4f..d214cc9b7 100644 --- a/lib/workload/stateful/database/component.ts +++ b/lib/workload/stateful/database/component.ts @@ -36,6 +36,7 @@ export type DatabaseProps = MonitoringProps & { minACU: number; maxACU: number; dbPort: number; + removalPolicy: RemovalPolicy; allowedInboundSG?: ec2.SecurityGroup; }; @@ -78,7 +79,9 @@ export class DatabaseConstruct extends Construct { props.parameterGroupName ), port: props.dbPort, - removalPolicy: RemovalPolicy.DESTROY, + storageEncrypted: true, + iamAuthentication: true, + removalPolicy: props.removalPolicy, securityGroups: [this.dbSecurityGroup], serverlessV2MaxCapacity: props.maxACU, serverlessV2MinCapacity: props.minACU, diff --git a/package.json b/package.json index 66c4b1f68..ee2759b45 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@aws-cdk/aws-apigatewayv2-integrations-alpha": "^2.110.0-alpha.0", "@aws-cdk/aws-lambda-python-alpha": "2.110.0-alpha.0", "aws-cdk-lib": "^2.110.0", + "cdk-nag": "^2.28.27", "constructs": "^10.2.69", "dotenv": "^16.3.1", "rust.aws-cdk-lambda": "^1.2.1", diff --git a/test/cdkNag/pipeline.test.ts b/test/cdkNag/pipeline.test.ts new file mode 100644 index 000000000..1d6cc71f1 --- /dev/null +++ b/test/cdkNag/pipeline.test.ts @@ -0,0 +1,87 @@ +import { App, Aspects } from 'aws-cdk-lib'; +import { Annotations, Match } from 'aws-cdk-lib/assertions'; +import { SynthesisMessage } from 'aws-cdk-lib/cx-api'; +import { AwsSolutionsChecks, NagSuppressions } from 'cdk-nag'; +import { StatelessPipelineStack } from '../../lib/pipeline/orcabus-stateless-pipeline-stack'; +import { StatefulPipelineStack } from '../../lib/pipeline/orcabus-stateful-pipeline-stack'; + +function synthesisMessageToString(sm: SynthesisMessage): string { + return `${sm.entry.data} [${sm.id}]`; +} + +// Stateless Stack +describe('cdk-nag-stateless-pipeline', () => { + let stack: StatelessPipelineStack; + let app: App; + + beforeEach(() => { + app = new App({}); + stack = new StatelessPipelineStack(app, 'TestStack', { + env: { + account: '123456789', + region: 'ap-southeast-2', + }, + }); + Aspects.of(stack).add(new AwsSolutionsChecks()); + + NagSuppressions.addStackSuppressions(stack, [ + { id: 'AwsSolutions-IAM4', reason: 'Allow CDK Pipeline' }, + { id: 'AwsSolutions-IAM5', reason: 'Allow CDK Pipeline' }, + { id: 'AwsSolutions-S1', reason: 'Allow CDK Pipeline' }, + { id: 'AwsSolutions-KMS5', reason: 'Allow CDK Pipeline' }, + { id: 'AwsSolutions-CB3', reason: 'Allow CDK Pipeline' }, + ]); + }); + + test('cdk-nag AwsSolutions Pack errors', () => { + const errors = Annotations.fromStack(stack) + .findError('*', Match.stringLikeRegexp('AwsSolutions-.*')) + .map(synthesisMessageToString); + expect(errors).toHaveLength(0); + }); + + test('cdk-nag AwsSolutions Pack warnings', () => { + const warnings = Annotations.fromStack(stack) + .findWarning('*', Match.stringLikeRegexp('AwsSolutions-.*')) + .map(synthesisMessageToString); + expect(warnings).toHaveLength(0); + }); +}); + +describe('cdk-nag-stateful-pipeline', () => { + let stack: StatefulPipelineStack; + let app: App; + + beforeEach(() => { + app = new App({}); + stack = new StatefulPipelineStack(app, 'TestStack', { + env: { + account: '123456789', + region: 'ap-southeast-2', + }, + }); + Aspects.of(stack).add(new AwsSolutionsChecks()); + + NagSuppressions.addStackSuppressions(stack, [ + { id: 'AwsSolutions-IAM4', reason: 'Allow CDK Pipeline' }, + { id: 'AwsSolutions-IAM5', reason: 'Allow CDK Pipeline' }, + { id: 'AwsSolutions-S1', reason: 'Allow CDK Pipeline' }, + { id: 'AwsSolutions-KMS5', reason: 'Allow CDK Pipeline' }, + { id: 'AwsSolutions-CB3', reason: 'Allow CDK Pipeline' }, + ]); + }); + + test('cdk-nag AwsSolutions Pack errors', () => { + const errors = Annotations.fromStack(stack) + .findError('*', Match.stringLikeRegexp('AwsSolutions-.*')) + .map(synthesisMessageToString); + expect(errors).toHaveLength(0); + }); + + test('cdk-nag AwsSolutions Pack warnings', () => { + const warnings = Annotations.fromStack(stack) + .findWarning('*', Match.stringLikeRegexp('AwsSolutions-.*')) + .map(synthesisMessageToString); + expect(warnings).toHaveLength(0); + }); +}); diff --git a/test/cdkNag/stateful-deployment.test.ts b/test/cdkNag/stateful-deployment.test.ts new file mode 100644 index 000000000..4bf8947b8 --- /dev/null +++ b/test/cdkNag/stateful-deployment.test.ts @@ -0,0 +1,50 @@ +import { App, Aspects } from 'aws-cdk-lib'; +import { Annotations, Match } from 'aws-cdk-lib/assertions'; +import { SynthesisMessage } from 'aws-cdk-lib/cx-api'; +import { AwsSolutionsChecks, NagSuppressions } from 'cdk-nag'; +import { OrcaBusStatefulStack } from '../../lib/workload/orcabus-stateful-stack'; +import { getEnvironmentConfig } from '../../config/constants'; + +function synthesisMessageToString(sm: SynthesisMessage): string { + return `${sm.entry.data} [${sm.id}]`; +} +// Picking prod environment to test as it contain the sensitive data +const config = getEnvironmentConfig('prod')!; + +describe('cdk-nag-stateful-stack', () => { + let stack: OrcaBusStatefulStack; + let app: App; + + beforeAll(() => { + app = new App({ context: {} }); + stack = new OrcaBusStatefulStack(app, 'TestStack', { + env: { + account: '12345678', + region: 'ap-southeast-2', + }, + ...config.stackProps.orcaBusStatefulConfig, + }); + Aspects.of(stack).add(new AwsSolutionsChecks()); + + // Suppress CDK-NAG for secret rotation + NagSuppressions.addResourceSuppressionsByPath( + stack, + `/${stack.stackName}/OrcaBusDatabaseConstruct/OrcaBusDatabaseConstructDbSecret/Resource`, + [{ id: 'AwsSolutions-SMG4', reason: 'Dont require secret rotation' }] + ); + }); + + test('cdk-nag AwsSolutions Pack errors', () => { + const errors = Annotations.fromStack(stack) + .findError('*', Match.stringLikeRegexp('AwsSolutions-.*')) + .map(synthesisMessageToString); + expect(errors).toHaveLength(0); + }); + + test('cdk-nag AwsSolutions Pack warnings', () => { + const warnings = Annotations.fromStack(stack) + .findWarning('*', Match.stringLikeRegexp('AwsSolutions-.*')) + .map(synthesisMessageToString); + expect(warnings).toHaveLength(0); + }); +}); diff --git a/test/cdkNag/stateless-deployment.test.ts b/test/cdkNag/stateless-deployment.test.ts new file mode 100644 index 000000000..5f222c846 --- /dev/null +++ b/test/cdkNag/stateless-deployment.test.ts @@ -0,0 +1,46 @@ +import { App, Aspects } from 'aws-cdk-lib'; +import { Annotations, Match } from 'aws-cdk-lib/assertions'; +import { SynthesisMessage } from 'aws-cdk-lib/cx-api'; +import { AwsSolutionsChecks } from 'cdk-nag'; +import { OrcaBusStatelessStack } from '../../lib/workload/orcabus-stateless-stack'; +import { getEnvironmentConfig } from '../../config/constants'; + +function synthesisMessageToString(sm: SynthesisMessage): string { + return `${sm.entry.data} [${sm.id}]`; +} +// Picking prod environment to test as it contain the sensitive data +const config = getEnvironmentConfig('prod')!; + +describe('cdk-nag-stateless-stack', () => { + let stack: OrcaBusStatelessStack; + let app: App; + + beforeAll(() => { + app = new App({}); + stack = new OrcaBusStatelessStack(app, 'TestStack', { + env: { + account: '12345678', + region: 'ap-southeast-2', + }, + ...config.stackProps.orcaBusStatelessConfig, + }); + Aspects.of(stack).add(new AwsSolutionsChecks()); + + // Suppressions (if any) + // ... + }); + + test('cdk-nag AwsSolutions Pack errors', () => { + const errors = Annotations.fromStack(stack) + .findError('*', Match.stringLikeRegexp('AwsSolutions-.*')) + .map(synthesisMessageToString); + expect(errors).toHaveLength(0); + }); + + test('cdk-nag AwsSolutions Pack warnings', () => { + const warnings = Annotations.fromStack(stack) + .findWarning('*', Match.stringLikeRegexp('AwsSolutions-.*')) + .map(synthesisMessageToString); + expect(warnings).toHaveLength(0); + }); +}); diff --git a/test/workload/stateful/databaseConstruct.test.ts b/test/construct/stateful/databaseConstruct.test.ts similarity index 100% rename from test/workload/stateful/databaseConstruct.test.ts rename to test/construct/stateful/databaseConstruct.test.ts diff --git a/test/workload/stateful/eventbusConstruct.test.ts b/test/construct/stateful/eventbusConstruct.test.ts similarity index 100% rename from test/workload/stateful/eventbusConstruct.test.ts rename to test/construct/stateful/eventbusConstruct.test.ts diff --git a/test/workload/stateful/schemaRegistryConstruct.test.ts b/test/construct/stateful/schemaRegistryConstruct.test.ts similarity index 100% rename from test/workload/stateful/schemaRegistryConstruct.test.ts rename to test/construct/stateful/schemaRegistryConstruct.test.ts diff --git a/test/workload/stateful/securityGroupConstruct.test.ts b/test/construct/stateful/securityGroupConstruct.test.ts similarity index 100% rename from test/workload/stateful/securityGroupConstruct.test.ts rename to test/construct/stateful/securityGroupConstruct.test.ts diff --git a/yarn.lock b/yarn.lock index 63b031c86..6b02032a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1726,6 +1726,16 @@ __metadata: languageName: node linkType: hard +"cdk-nag@npm:^2.28.27": + version: 2.28.27 + resolution: "cdk-nag@npm:2.28.27" + peerDependencies: + aws-cdk-lib: ^2.116.0 + constructs: ^10.0.5 + checksum: 208a704f021ebf695bee215d29b51fb5b0a49128371d56a2f35052fbbb61393f9fcb28baac2a0899ba10bf9857e8f079f8ba1dc5d1e86fea0664f9e722d3ea24 + languageName: node + linkType: hard + "chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -3957,6 +3967,7 @@ __metadata: "@typescript-eslint/parser": ^6.19.1 aws-cdk: 2.110.0 aws-cdk-lib: ^2.110.0 + cdk-nag: ^2.28.27 constructs: ^10.2.69 dotenv: ^16.3.1 eslint: ^8.44.0 From 9656b5b14b19f8dfc8080291ea05b7208c3fce9b Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Fri, 2 Feb 2024 16:19:07 +1100 Subject: [PATCH 12/21] CodeBuildReport --- .gitignore | 1 + jest.config.js | 9 ++++ .../orcabus-stateless-pipeline-stack.ts | 30 +++++++++++- package.json | 1 + .../stateful/databaseConstruct.test.ts | 4 +- .../stateful/eventbusConstruct.test.ts | 4 +- .../stateful/schemaRegistryConstruct.test.ts | 4 +- .../stateful/securityGroupConstruct.test.ts | 4 +- .../stateful-deployment.test.ts | 0 test/stateful/stateful-pipeline.test.ts | 47 +++++++++++++++++++ .../stateless-deployment.test.ts | 0 .../stateless-pipeline.test.ts} | 39 --------------- yarn.lock | 31 +++++++++++- 13 files changed, 125 insertions(+), 49 deletions(-) rename test/{construct => }/stateful/databaseConstruct.test.ts (92%) rename test/{construct => }/stateful/eventbusConstruct.test.ts (79%) rename test/{construct => }/stateful/schemaRegistryConstruct.test.ts (79%) rename test/{construct => }/stateful/securityGroupConstruct.test.ts (84%) rename test/{cdkNag => stateful}/stateful-deployment.test.ts (100%) create mode 100644 test/stateful/stateful-pipeline.test.ts rename test/{cdkNag => stateless}/stateless-deployment.test.ts (100%) rename test/{cdkNag/pipeline.test.ts => stateless/stateless-pipeline.test.ts} (55%) diff --git a/.gitignore b/.gitignore index 3798768dd..f91e2d7d5 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,4 @@ cdk.context.json data/ Brewfile.lock.json +*.xml diff --git a/jest.config.js b/jest.config.js index 44ead8540..1dd85861e 100644 --- a/jest.config.js +++ b/jest.config.js @@ -5,4 +5,13 @@ module.exports = { transform: { '^.+\\.tsx?$': 'ts-jest', }, + reporters: [ + 'default', + [ + 'jest-junit', + { + outputDirectory: './target', + }, + ], + ], }; diff --git a/lib/pipeline/orcabus-stateless-pipeline-stack.ts b/lib/pipeline/orcabus-stateless-pipeline-stack.ts index 040275c26..9c1cfc408 100644 --- a/lib/pipeline/orcabus-stateless-pipeline-stack.ts +++ b/lib/pipeline/orcabus-stateless-pipeline-stack.ts @@ -21,15 +21,43 @@ export class StatelessPipelineStack extends cdk.Stack { } ); + const infrastructureTestReports = new codebuild.ReportGroup( + this, + `OrcaBusInfrastructureTestReport`, + { + reportGroupName: `OrcaBusInfrastructureTestReport`, + removalPolicy: cdk.RemovalPolicy.DESTROY, + } + ); + const synthAction = new pipelines.CodeBuildStep('Synth', { commands: [ 'yarn install --frozen-lockfile', 'make suite', - 'yarn run yarn run cdk-stateless-pipeline synth synth', + 'yarn run cdk-stateless-pipeline synth', ], input: sourceFile, primaryOutputDirectory: 'cdk.out', + partialBuildSpec: codebuild.BuildSpec.fromObject({ + reports: { + cdk: { + files: ['target/test/*.xml'], + 'file-format': 'JUNITXML', + }, + }, + }), rolePolicyStatements: [ + new iam.PolicyStatement({ + effect: iam.Effect.ALLOW, + actions: [ + 'codebuild:CreateReportGroup', + 'codebuild:CreateReport', + 'codebuild:UpdateReport', + 'codebuild:BatchPutTestCases', + 'codebuild:BatchPutCodeCoverages', + ], + resources: [infrastructureTestReports.reportGroupArn], + }), new iam.PolicyStatement({ effect: iam.Effect.ALLOW, actions: ['sts:AssumeRole'], diff --git a/package.json b/package.json index ee2759b45..2eccfb29e 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "jest": "^29.6.1", + "jest-junit": "^16.0.0", "prettier": "^3.2.4", "ts-jest": "^29.1.1", "ts-node": "^10.9.1", diff --git a/test/construct/stateful/databaseConstruct.test.ts b/test/stateful/databaseConstruct.test.ts similarity index 92% rename from test/construct/stateful/databaseConstruct.test.ts rename to test/stateful/databaseConstruct.test.ts index 53e89e9bc..c949487d8 100644 --- a/test/construct/stateful/databaseConstruct.test.ts +++ b/test/stateful/databaseConstruct.test.ts @@ -1,8 +1,8 @@ import * as cdk from 'aws-cdk-lib'; import { Template } from 'aws-cdk-lib/assertions'; -import { DatabaseConstruct } from '../../../lib/workload/stateful/database/component'; +import { DatabaseConstruct } from '../../lib/workload/stateful/database/component'; import * as ec2 from 'aws-cdk-lib/aws-ec2'; -import { getEnvironmentConfig } from '../../../config/constants'; +import { getEnvironmentConfig } from '../../config/constants'; let stack: cdk.Stack; let vpc: ec2.Vpc; diff --git a/test/construct/stateful/eventbusConstruct.test.ts b/test/stateful/eventbusConstruct.test.ts similarity index 79% rename from test/construct/stateful/eventbusConstruct.test.ts rename to test/stateful/eventbusConstruct.test.ts index 422dd354b..179a34ad5 100644 --- a/test/construct/stateful/eventbusConstruct.test.ts +++ b/test/stateful/eventbusConstruct.test.ts @@ -1,7 +1,7 @@ import * as cdk from 'aws-cdk-lib'; import { Template } from 'aws-cdk-lib/assertions'; -import { getEnvironmentConfig } from '../../../config/constants'; -import { EventBusConstruct } from '../../../lib/workload/stateful/eventbridge/component'; +import { getEnvironmentConfig } from '../../config/constants'; +import { EventBusConstruct } from '../../lib/workload/stateful/eventbridge/component'; let stack: cdk.Stack; diff --git a/test/construct/stateful/schemaRegistryConstruct.test.ts b/test/stateful/schemaRegistryConstruct.test.ts similarity index 79% rename from test/construct/stateful/schemaRegistryConstruct.test.ts rename to test/stateful/schemaRegistryConstruct.test.ts index 355e78475..3e75cdcb4 100644 --- a/test/construct/stateful/schemaRegistryConstruct.test.ts +++ b/test/stateful/schemaRegistryConstruct.test.ts @@ -1,7 +1,7 @@ import * as cdk from 'aws-cdk-lib'; import { Template } from 'aws-cdk-lib/assertions'; -import { getEnvironmentConfig } from '../../../config/constants'; -import { SchemaRegistryConstruct } from '../../../lib/workload/stateful/schemaregistry/component'; +import { getEnvironmentConfig } from '../../config/constants'; +import { SchemaRegistryConstruct } from '../../lib/workload/stateful/schemaregistry/component'; let stack: cdk.Stack; diff --git a/test/construct/stateful/securityGroupConstruct.test.ts b/test/stateful/securityGroupConstruct.test.ts similarity index 84% rename from test/construct/stateful/securityGroupConstruct.test.ts rename to test/stateful/securityGroupConstruct.test.ts index 76a9f983f..3e4501949 100644 --- a/test/construct/stateful/securityGroupConstruct.test.ts +++ b/test/stateful/securityGroupConstruct.test.ts @@ -1,8 +1,8 @@ import * as cdk from 'aws-cdk-lib'; import * as ec2 from 'aws-cdk-lib/aws-ec2'; import { Template } from 'aws-cdk-lib/assertions'; -import { getEnvironmentConfig } from '../../../config/constants'; -import { SecurityGroupConstruct } from '../../../lib/workload/stateful/securitygroup/component'; +import { getEnvironmentConfig } from '../../config/constants'; +import { SecurityGroupConstruct } from '../../lib/workload/stateful/securitygroup/component'; let stack: cdk.Stack; let vpc: ec2.Vpc; diff --git a/test/cdkNag/stateful-deployment.test.ts b/test/stateful/stateful-deployment.test.ts similarity index 100% rename from test/cdkNag/stateful-deployment.test.ts rename to test/stateful/stateful-deployment.test.ts diff --git a/test/stateful/stateful-pipeline.test.ts b/test/stateful/stateful-pipeline.test.ts new file mode 100644 index 000000000..9c161c850 --- /dev/null +++ b/test/stateful/stateful-pipeline.test.ts @@ -0,0 +1,47 @@ +import { App, Aspects } from 'aws-cdk-lib'; +import { Annotations, Match } from 'aws-cdk-lib/assertions'; +import { SynthesisMessage } from 'aws-cdk-lib/cx-api'; +import { AwsSolutionsChecks, NagSuppressions } from 'cdk-nag'; +import { StatefulPipelineStack } from '../../lib/pipeline/orcabus-stateful-pipeline-stack'; + +function synthesisMessageToString(sm: SynthesisMessage): string { + return `${sm.entry.data} [${sm.id}]`; +} + +describe('cdk-nag-stateful-pipeline', () => { + let stack: StatefulPipelineStack; + let app: App; + + beforeEach(() => { + app = new App({}); + stack = new StatefulPipelineStack(app, 'TestStack', { + env: { + account: '123456789', + region: 'ap-southeast-2', + }, + }); + Aspects.of(stack).add(new AwsSolutionsChecks()); + + NagSuppressions.addStackSuppressions(stack, [ + { id: 'AwsSolutions-IAM4', reason: 'Allow CDK Pipeline' }, + { id: 'AwsSolutions-IAM5', reason: 'Allow CDK Pipeline' }, + { id: 'AwsSolutions-S1', reason: 'Allow CDK Pipeline' }, + { id: 'AwsSolutions-KMS5', reason: 'Allow CDK Pipeline' }, + { id: 'AwsSolutions-CB3', reason: 'Allow CDK Pipeline' }, + ]); + }); + + test('cdk-nag AwsSolutions Pack errors', () => { + const errors = Annotations.fromStack(stack) + .findError('*', Match.stringLikeRegexp('AwsSolutions-.*')) + .map(synthesisMessageToString); + expect(errors).toHaveLength(0); + }); + + test('cdk-nag AwsSolutions Pack warnings', () => { + const warnings = Annotations.fromStack(stack) + .findWarning('*', Match.stringLikeRegexp('AwsSolutions-.*')) + .map(synthesisMessageToString); + expect(warnings).toHaveLength(0); + }); +}); diff --git a/test/cdkNag/stateless-deployment.test.ts b/test/stateless/stateless-deployment.test.ts similarity index 100% rename from test/cdkNag/stateless-deployment.test.ts rename to test/stateless/stateless-deployment.test.ts diff --git a/test/cdkNag/pipeline.test.ts b/test/stateless/stateless-pipeline.test.ts similarity index 55% rename from test/cdkNag/pipeline.test.ts rename to test/stateless/stateless-pipeline.test.ts index 1d6cc71f1..99452085e 100644 --- a/test/cdkNag/pipeline.test.ts +++ b/test/stateless/stateless-pipeline.test.ts @@ -3,7 +3,6 @@ import { Annotations, Match } from 'aws-cdk-lib/assertions'; import { SynthesisMessage } from 'aws-cdk-lib/cx-api'; import { AwsSolutionsChecks, NagSuppressions } from 'cdk-nag'; import { StatelessPipelineStack } from '../../lib/pipeline/orcabus-stateless-pipeline-stack'; -import { StatefulPipelineStack } from '../../lib/pipeline/orcabus-stateful-pipeline-stack'; function synthesisMessageToString(sm: SynthesisMessage): string { return `${sm.entry.data} [${sm.id}]`; @@ -47,41 +46,3 @@ describe('cdk-nag-stateless-pipeline', () => { expect(warnings).toHaveLength(0); }); }); - -describe('cdk-nag-stateful-pipeline', () => { - let stack: StatefulPipelineStack; - let app: App; - - beforeEach(() => { - app = new App({}); - stack = new StatefulPipelineStack(app, 'TestStack', { - env: { - account: '123456789', - region: 'ap-southeast-2', - }, - }); - Aspects.of(stack).add(new AwsSolutionsChecks()); - - NagSuppressions.addStackSuppressions(stack, [ - { id: 'AwsSolutions-IAM4', reason: 'Allow CDK Pipeline' }, - { id: 'AwsSolutions-IAM5', reason: 'Allow CDK Pipeline' }, - { id: 'AwsSolutions-S1', reason: 'Allow CDK Pipeline' }, - { id: 'AwsSolutions-KMS5', reason: 'Allow CDK Pipeline' }, - { id: 'AwsSolutions-CB3', reason: 'Allow CDK Pipeline' }, - ]); - }); - - test('cdk-nag AwsSolutions Pack errors', () => { - const errors = Annotations.fromStack(stack) - .findError('*', Match.stringLikeRegexp('AwsSolutions-.*')) - .map(synthesisMessageToString); - expect(errors).toHaveLength(0); - }); - - test('cdk-nag AwsSolutions Pack warnings', () => { - const warnings = Annotations.fromStack(stack) - .findWarning('*', Match.stringLikeRegexp('AwsSolutions-.*')) - .map(synthesisMessageToString); - expect(warnings).toHaveLength(0); - }); -}); diff --git a/yarn.lock b/yarn.lock index 6b02032a0..35f2a707f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3156,6 +3156,18 @@ __metadata: languageName: node linkType: hard +"jest-junit@npm:^16.0.0": + version: 16.0.0 + resolution: "jest-junit@npm:16.0.0" + dependencies: + mkdirp: ^1.0.4 + strip-ansi: ^6.0.1 + uuid: ^8.3.2 + xml: ^1.0.1 + checksum: 412aa4bfeec4254a9b34f417fda79107c7cbd295e56ffeb299ac9c977545910fbabe57c91c6cd1f12b700d4a1f60f79872b0075003f02da87d463e30fc2d9d78 + languageName: node + linkType: hard + "jest-leak-detector@npm:^29.7.0": version: 29.7.0 resolution: "jest-leak-detector@npm:29.7.0" @@ -3812,7 +3824,7 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:^1.0.3": +"mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4": version: 1.0.4 resolution: "mkdirp@npm:1.0.4" bin: @@ -3974,6 +3986,7 @@ __metadata: eslint-config-prettier: ^9.1.0 eslint-plugin-prettier: ^5.1.3 jest: ^29.6.1 + jest-junit: ^16.0.0 prettier: ^3.2.4 rust.aws-cdk-lambda: ^1.2.1 source-map-support: ^0.5.21 @@ -4933,6 +4946,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:^8.3.2": + version: 8.3.2 + resolution: "uuid@npm:8.3.2" + bin: + uuid: dist/bin/uuid + checksum: 5575a8a75c13120e2f10e6ddc801b2c7ed7d8f3c8ac22c7ed0c7b2ba6383ec0abda88c905085d630e251719e0777045ae3236f04c812184b7c765f63a70e58df + languageName: node + linkType: hard + "v8-compile-cache-lib@npm:^3.0.1": version: 3.0.1 resolution: "v8-compile-cache-lib@npm:3.0.1" @@ -5028,6 +5050,13 @@ __metadata: languageName: node linkType: hard +"xml@npm:^1.0.1": + version: 1.0.1 + resolution: "xml@npm:1.0.1" + checksum: 11b5545ef3f8fec3fa29ce251f50ad7b6c97c103ed4d851306ec23366f5fa4699dd6a942262df52313a0cd1840ab26256da253c023bad3309d8ce46fe6020ca0 + languageName: node + linkType: hard + "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" From 5ab7f0b8d78bf378986e3e9ee94fcaf92bdaab60 Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Fri, 2 Feb 2024 16:21:07 +1100 Subject: [PATCH 13/21] Update orcabus-stateless-pipeline-stack.ts --- lib/pipeline/orcabus-stateless-pipeline-stack.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pipeline/orcabus-stateless-pipeline-stack.ts b/lib/pipeline/orcabus-stateless-pipeline-stack.ts index 9c1cfc408..a488b4c1d 100644 --- a/lib/pipeline/orcabus-stateless-pipeline-stack.ts +++ b/lib/pipeline/orcabus-stateless-pipeline-stack.ts @@ -109,7 +109,8 @@ export class StatelessPipelineStack extends cdk.Stack { { account: gammaConfig.accountId, } - ) + ), + { pre: [new pipelines.ManualApprovalStep('PromoteToGamma')] } ); /** From d34e89f665cf382d0d6361329bf01d63ab08a8b6 Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Fri, 2 Feb 2024 17:51:16 +1100 Subject: [PATCH 14/21] seperate cdk testing stateful --- Makefile | 8 ++++- jest.config.js | 9 ------ .../orcabus-stateful-pipeline-stack.ts | 2 +- .../orcabus-stateless-pipeline-stack.ts | 20 ------------ package.json | 1 - yarn.lock | 31 +------------------ 6 files changed, 9 insertions(+), 62 deletions(-) diff --git a/Makefile b/Makefile index 7c516fc13..0e036df35 100644 --- a/Makefile +++ b/Makefile @@ -23,11 +23,17 @@ baseline: test: @yarn test +# Test only section +test-stateful: + @yarn run test ./test/stateful +test-stateless: + @yarn run test ./test/stateless + # Run all test suites - i.e. cdk app unit tests + each microservice app test suites # Each app root should have Makefile `test` target; that run your app test pipeline including compose stack up/down # Note by running `make suite` target from repo root means your local dev env is okay with all app toolchains i.e. # Python (conda or venv), Rust and Cargo, TypeScript and Node environment, Docker and Container runtimes -suite: test +suite: test-stateless @(cd lib/workload/stateless/sequence_run_manager && $(MAKE) test) @(cd lib/workload/stateless/metadata_manager && $(MAKE) test) @#(cd lib/workload/stateless/filemanager && $(MAKE) test) # FIXME uncomment when ready @Marko diff --git a/jest.config.js b/jest.config.js index 1dd85861e..44ead8540 100644 --- a/jest.config.js +++ b/jest.config.js @@ -5,13 +5,4 @@ module.exports = { transform: { '^.+\\.tsx?$': 'ts-jest', }, - reporters: [ - 'default', - [ - 'jest-junit', - { - outputDirectory: './target', - }, - ], - ], }; diff --git a/lib/pipeline/orcabus-stateful-pipeline-stack.ts b/lib/pipeline/orcabus-stateful-pipeline-stack.ts index 16d815885..bc52d8a15 100644 --- a/lib/pipeline/orcabus-stateful-pipeline-stack.ts +++ b/lib/pipeline/orcabus-stateful-pipeline-stack.ts @@ -24,7 +24,7 @@ export class StatefulPipelineStack extends cdk.Stack { const synthAction = new pipelines.CodeBuildStep('Synth', { commands: [ 'yarn install --frozen-lockfile', - 'make test', + 'make test-stateful', 'yarn run cdk-stateful-pipeline synth', ], input: sourceFile, diff --git a/lib/pipeline/orcabus-stateless-pipeline-stack.ts b/lib/pipeline/orcabus-stateless-pipeline-stack.ts index a488b4c1d..6cbaf3144 100644 --- a/lib/pipeline/orcabus-stateless-pipeline-stack.ts +++ b/lib/pipeline/orcabus-stateless-pipeline-stack.ts @@ -21,15 +21,6 @@ export class StatelessPipelineStack extends cdk.Stack { } ); - const infrastructureTestReports = new codebuild.ReportGroup( - this, - `OrcaBusInfrastructureTestReport`, - { - reportGroupName: `OrcaBusInfrastructureTestReport`, - removalPolicy: cdk.RemovalPolicy.DESTROY, - } - ); - const synthAction = new pipelines.CodeBuildStep('Synth', { commands: [ 'yarn install --frozen-lockfile', @@ -47,17 +38,6 @@ export class StatelessPipelineStack extends cdk.Stack { }, }), rolePolicyStatements: [ - new iam.PolicyStatement({ - effect: iam.Effect.ALLOW, - actions: [ - 'codebuild:CreateReportGroup', - 'codebuild:CreateReport', - 'codebuild:UpdateReport', - 'codebuild:BatchPutTestCases', - 'codebuild:BatchPutCodeCoverages', - ], - resources: [infrastructureTestReports.reportGroupArn], - }), new iam.PolicyStatement({ effect: iam.Effect.ALLOW, actions: ['sts:AssumeRole'], diff --git a/package.json b/package.json index 2eccfb29e..ee2759b45 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,6 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "jest": "^29.6.1", - "jest-junit": "^16.0.0", "prettier": "^3.2.4", "ts-jest": "^29.1.1", "ts-node": "^10.9.1", diff --git a/yarn.lock b/yarn.lock index 35f2a707f..6b02032a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3156,18 +3156,6 @@ __metadata: languageName: node linkType: hard -"jest-junit@npm:^16.0.0": - version: 16.0.0 - resolution: "jest-junit@npm:16.0.0" - dependencies: - mkdirp: ^1.0.4 - strip-ansi: ^6.0.1 - uuid: ^8.3.2 - xml: ^1.0.1 - checksum: 412aa4bfeec4254a9b34f417fda79107c7cbd295e56ffeb299ac9c977545910fbabe57c91c6cd1f12b700d4a1f60f79872b0075003f02da87d463e30fc2d9d78 - languageName: node - linkType: hard - "jest-leak-detector@npm:^29.7.0": version: 29.7.0 resolution: "jest-leak-detector@npm:29.7.0" @@ -3824,7 +3812,7 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4": +"mkdirp@npm:^1.0.3": version: 1.0.4 resolution: "mkdirp@npm:1.0.4" bin: @@ -3986,7 +3974,6 @@ __metadata: eslint-config-prettier: ^9.1.0 eslint-plugin-prettier: ^5.1.3 jest: ^29.6.1 - jest-junit: ^16.0.0 prettier: ^3.2.4 rust.aws-cdk-lambda: ^1.2.1 source-map-support: ^0.5.21 @@ -4946,15 +4933,6 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^8.3.2": - version: 8.3.2 - resolution: "uuid@npm:8.3.2" - bin: - uuid: dist/bin/uuid - checksum: 5575a8a75c13120e2f10e6ddc801b2c7ed7d8f3c8ac22c7ed0c7b2ba6383ec0abda88c905085d630e251719e0777045ae3236f04c812184b7c765f63a70e58df - languageName: node - linkType: hard - "v8-compile-cache-lib@npm:^3.0.1": version: 3.0.1 resolution: "v8-compile-cache-lib@npm:3.0.1" @@ -5050,13 +5028,6 @@ __metadata: languageName: node linkType: hard -"xml@npm:^1.0.1": - version: 1.0.1 - resolution: "xml@npm:1.0.1" - checksum: 11b5545ef3f8fec3fa29ce251f50ad7b6c97c103ed4d851306ec23366f5fa4699dd6a942262df52313a0cd1840ab26256da253c023bad3309d8ce46fe6020ca0 - languageName: node - linkType: hard - "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" From 9be6c9555a98ad373cf228f27ce77645593180a5 Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:33:11 +1100 Subject: [PATCH 15/21] Change to main branch --- .../orcabus-stateful-pipeline-stack.ts | 3 ++- .../orcabus-stateless-pipeline-stack.ts | 18 +++--------------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/lib/pipeline/orcabus-stateful-pipeline-stack.ts b/lib/pipeline/orcabus-stateful-pipeline-stack.ts index bc52d8a15..f90541eb9 100644 --- a/lib/pipeline/orcabus-stateful-pipeline-stack.ts +++ b/lib/pipeline/orcabus-stateful-pipeline-stack.ts @@ -76,7 +76,8 @@ export class StatefulPipelineStack extends cdk.Stack { pipeline.addStage( new OrcaBusStatefulDeploymentStage(this, 'GammaDeployment', gammaConfig.stackProps, { account: gammaConfig.accountId, - }) + }), + { pre: [new pipelines.ManualApprovalStep('PromoteToGamma')] } ); /** diff --git a/lib/pipeline/orcabus-stateless-pipeline-stack.ts b/lib/pipeline/orcabus-stateless-pipeline-stack.ts index 6cbaf3144..c653d4c2a 100644 --- a/lib/pipeline/orcabus-stateless-pipeline-stack.ts +++ b/lib/pipeline/orcabus-stateless-pipeline-stack.ts @@ -13,13 +13,9 @@ export class StatelessPipelineStack extends cdk.Stack { // A connection where the pipeline get its source code const codeStarArn = ssm.StringParameter.valueForStringParameter(this, 'codestar_github_arn'); - const sourceFile = pipelines.CodePipelineSource.connection( - 'umccr/orcabus', - 'feature/base-cdk-codepipeline', - { - connectionArn: codeStarArn, - } - ); + const sourceFile = pipelines.CodePipelineSource.connection('umccr/orcabus', 'main', { + connectionArn: codeStarArn, + }); const synthAction = new pipelines.CodeBuildStep('Synth', { commands: [ @@ -29,14 +25,6 @@ export class StatelessPipelineStack extends cdk.Stack { ], input: sourceFile, primaryOutputDirectory: 'cdk.out', - partialBuildSpec: codebuild.BuildSpec.fromObject({ - reports: { - cdk: { - files: ['target/test/*.xml'], - 'file-format': 'JUNITXML', - }, - }, - }), rolePolicyStatements: [ new iam.PolicyStatement({ effect: iam.Effect.ALLOW, From c70a3262487592afba7aa38a24f96053a04ae77e Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Tue, 6 Feb 2024 14:01:11 +1100 Subject: [PATCH 16/21] junit --- .gitignore | 2 + jest.config.js | 10 ++++ .../orcabus-stateless-pipeline-stack.ts | 55 +++++++++++++++++-- .../stateless/metadata_manager/jest.config.js | 10 ++++ .../stateless/metadata_manager/package.json | 1 + .../stateless/metadata_manager/yarn.lock | 31 ++++++++++- .../stateless/sequence_run_manager/Makefile | 9 +-- package.json | 1 + yarn.lock | 31 ++++++++++- 9 files changed, 135 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index f91e2d7d5..6c1075b69 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,5 @@ data/ Brewfile.lock.json *.xml + +target/ diff --git a/jest.config.js b/jest.config.js index 44ead8540..6b107fd0f 100644 --- a/jest.config.js +++ b/jest.config.js @@ -5,4 +5,14 @@ module.exports = { transform: { '^.+\\.tsx?$': 'ts-jest', }, + reporters: [ + 'default', + [ + 'jest-junit', + { + outputDirectory: 'target/report', + outputName: 'infrastructureTest.xml', + }, + ], + ], }; diff --git a/lib/pipeline/orcabus-stateless-pipeline-stack.ts b/lib/pipeline/orcabus-stateless-pipeline-stack.ts index c653d4c2a..b56fcb282 100644 --- a/lib/pipeline/orcabus-stateless-pipeline-stack.ts +++ b/lib/pipeline/orcabus-stateless-pipeline-stack.ts @@ -17,13 +17,56 @@ export class StatelessPipelineStack extends cdk.Stack { connectionArn: codeStarArn, }); - const synthAction = new pipelines.CodeBuildStep('Synth', { - commands: [ - 'yarn install --frozen-lockfile', - 'make suite', - 'yarn run cdk-stateless-pipeline synth', - ], + const unitTestReports = new codebuild.ReportGroup(this, `CodebuildTestReport`, { + reportGroupName: `UnitTestReport`, + removalPolicy: cdk.RemovalPolicy.DESTROY, + }); + + const unitTest = new pipelines.CodeBuildStep('UnitTest', { + commands: ['yarn install --frozen-lockfile', 'make suite'], input: sourceFile, + primaryOutputDirectory: '.', + buildEnvironment: { + privileged: true, + computeType: codebuild.ComputeType.LARGE, + buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0, + environmentVariables: { + NODE_OPTIONS: { + value: '--max-old-space-size=8192', + }, + }, + }, + partialBuildSpec: codebuild.BuildSpec.fromObject({ + reports: { + infrastructureReports: { + files: ['target/report/*.xml'], + 'file-format': 'JUNITXML', + }, + microserviceReports: { + files: ['**/target/report/*.xml'], + 'file-format': 'JUNITXML', + }, + }, + version: '0.2', + }), + rolePolicyStatements: [ + new iam.PolicyStatement({ + effect: iam.Effect.ALLOW, + actions: [ + 'codebuild:CreateReportGroup', + 'codebuild:CreateReport', + 'codebuild:UpdateReport', + 'codebuild:BatchPutTestCases', + 'codebuild:BatchPutCodeCoverages', + ], + resources: [unitTestReports.reportGroupArn], + }), + ], + }); + + const synthAction = new pipelines.CodeBuildStep('Synth', { + commands: ['yarn install --frozen-lockfile', 'yarn run cdk-stateless-pipeline synth'], + input: unitTest, primaryOutputDirectory: 'cdk.out', rolePolicyStatements: [ new iam.PolicyStatement({ diff --git a/lib/workload/stateless/metadata_manager/jest.config.js b/lib/workload/stateless/metadata_manager/jest.config.js index c865147a9..4cdb675e9 100644 --- a/lib/workload/stateless/metadata_manager/jest.config.js +++ b/lib/workload/stateless/metadata_manager/jest.config.js @@ -2,4 +2,14 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', roots: ['/tests/'], + reporters: [ + 'default', + [ + 'jest-junit', + { + outputDirectory: 'target/report', + outputName: 'metadataManager.xml', + }, + ], + ], }; diff --git a/lib/workload/stateless/metadata_manager/package.json b/lib/workload/stateless/metadata_manager/package.json index 4d9953b15..9b96aad6e 100644 --- a/lib/workload/stateless/metadata_manager/package.json +++ b/lib/workload/stateless/metadata_manager/package.json @@ -36,6 +36,7 @@ "@types/lodash": "^4.14.202", "@types/node": "^20.11.5", "jest": "^29.7.0", + "jest-junit": "^16.0.0", "nodemon": "^3.0.3", "ts-jest": "^29.1.1", "ts-to-zod": "^3.6.1", diff --git a/lib/workload/stateless/metadata_manager/yarn.lock b/lib/workload/stateless/metadata_manager/yarn.lock index 92f2ea861..f5c73f0d0 100644 --- a/lib/workload/stateless/metadata_manager/yarn.lock +++ b/lib/workload/stateless/metadata_manager/yarn.lock @@ -3670,6 +3670,18 @@ __metadata: languageName: node linkType: hard +"jest-junit@npm:^16.0.0": + version: 16.0.0 + resolution: "jest-junit@npm:16.0.0" + dependencies: + mkdirp: ^1.0.4 + strip-ansi: ^6.0.1 + uuid: ^8.3.2 + xml: ^1.0.1 + checksum: 412aa4bfeec4254a9b34f417fda79107c7cbd295e56ffeb299ac9c977545910fbabe57c91c6cd1f12b700d4a1f60f79872b0075003f02da87d463e30fc2d9d78 + languageName: node + linkType: hard + "jest-leak-detector@npm:^29.7.0": version: 29.7.0 resolution: "jest-leak-detector@npm:29.7.0" @@ -4382,7 +4394,7 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:^1.0.3": +"mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4": version: 1.0.4 resolution: "mkdirp@npm:1.0.4" bin: @@ -5384,6 +5396,7 @@ __metadata: google-auth-library: ^9.4.2 google-spreadsheet: ^4.1.1 jest: ^29.7.0 + jest-junit: ^16.0.0 lodash: ^4.17.21 nodemon: ^3.0.3 pino: ^8.17.2 @@ -5953,6 +5966,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:^8.3.2": + version: 8.3.2 + resolution: "uuid@npm:8.3.2" + bin: + uuid: dist/bin/uuid + checksum: 5575a8a75c13120e2f10e6ddc801b2c7ed7d8f3c8ac22c7ed0c7b2ba6383ec0abda88c905085d630e251719e0777045ae3236f04c812184b7c765f63a70e58df + languageName: node + linkType: hard + "v8-compile-cache-lib@npm:^3.0.1": version: 3.0.1 resolution: "v8-compile-cache-lib@npm:3.0.1" @@ -6138,6 +6160,13 @@ __metadata: languageName: node linkType: hard +"xml@npm:^1.0.1": + version: 1.0.1 + resolution: "xml@npm:1.0.1" + checksum: 11b5545ef3f8fec3fa29ce251f50ad7b6c97c103ed4d851306ec23366f5fa4699dd6a942262df52313a0cd1840ab26256da253c023bad3309d8ce46fe6020ca0 + languageName: node + linkType: hard + "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" diff --git a/lib/workload/stateless/sequence_run_manager/Makefile b/lib/workload/stateless/sequence_run_manager/Makefile index 33b2065ac..355195f94 100644 --- a/lib/workload/stateless/sequence_run_manager/Makefile +++ b/lib/workload/stateless/sequence_run_manager/Makefile @@ -11,13 +11,8 @@ lint: lint-fix: @black -t py312 ./src --exclude skel --exclude .venv -# full mock suite test pipeline - install deps, bring up compose stack, wait a bit, run suite, bring down compose stack -test: install up wait suite down - -# heuristic wait 8s to make sure the database is fully up -# todo we could improve this -wait: - @sleep 8 +# full mock suite test pipeline - install deps, bring up compose stack, run suite, bring down compose stack +test: install up suite down suite: @python manage.py test diff --git a/package.json b/package.json index ee2759b45..2eccfb29e 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", "jest": "^29.6.1", + "jest-junit": "^16.0.0", "prettier": "^3.2.4", "ts-jest": "^29.1.1", "ts-node": "^10.9.1", diff --git a/yarn.lock b/yarn.lock index 6b02032a0..35f2a707f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3156,6 +3156,18 @@ __metadata: languageName: node linkType: hard +"jest-junit@npm:^16.0.0": + version: 16.0.0 + resolution: "jest-junit@npm:16.0.0" + dependencies: + mkdirp: ^1.0.4 + strip-ansi: ^6.0.1 + uuid: ^8.3.2 + xml: ^1.0.1 + checksum: 412aa4bfeec4254a9b34f417fda79107c7cbd295e56ffeb299ac9c977545910fbabe57c91c6cd1f12b700d4a1f60f79872b0075003f02da87d463e30fc2d9d78 + languageName: node + linkType: hard + "jest-leak-detector@npm:^29.7.0": version: 29.7.0 resolution: "jest-leak-detector@npm:29.7.0" @@ -3812,7 +3824,7 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:^1.0.3": +"mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4": version: 1.0.4 resolution: "mkdirp@npm:1.0.4" bin: @@ -3974,6 +3986,7 @@ __metadata: eslint-config-prettier: ^9.1.0 eslint-plugin-prettier: ^5.1.3 jest: ^29.6.1 + jest-junit: ^16.0.0 prettier: ^3.2.4 rust.aws-cdk-lambda: ^1.2.1 source-map-support: ^0.5.21 @@ -4933,6 +4946,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:^8.3.2": + version: 8.3.2 + resolution: "uuid@npm:8.3.2" + bin: + uuid: dist/bin/uuid + checksum: 5575a8a75c13120e2f10e6ddc801b2c7ed7d8f3c8ac22c7ed0c7b2ba6383ec0abda88c905085d630e251719e0777045ae3236f04c812184b7c765f63a70e58df + languageName: node + linkType: hard + "v8-compile-cache-lib@npm:^3.0.1": version: 3.0.1 resolution: "v8-compile-cache-lib@npm:3.0.1" @@ -5028,6 +5050,13 @@ __metadata: languageName: node linkType: hard +"xml@npm:^1.0.1": + version: 1.0.1 + resolution: "xml@npm:1.0.1" + checksum: 11b5545ef3f8fec3fa29ce251f50ad7b6c97c103ed4d851306ec23366f5fa4699dd6a942262df52313a0cd1840ab26256da253c023bad3309d8ce46fe6020ca0 + languageName: node + linkType: hard + "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" From 1ebb36bf5bfa9e1e6c01218bbd1ed37b86533940 Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Tue, 6 Feb 2024 14:26:08 +1100 Subject: [PATCH 17/21] Update orcabus-stateless-pipeline-stack.ts --- lib/pipeline/orcabus-stateless-pipeline-stack.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pipeline/orcabus-stateless-pipeline-stack.ts b/lib/pipeline/orcabus-stateless-pipeline-stack.ts index b56fcb282..073162870 100644 --- a/lib/pipeline/orcabus-stateless-pipeline-stack.ts +++ b/lib/pipeline/orcabus-stateless-pipeline-stack.ts @@ -43,7 +43,7 @@ export class StatelessPipelineStack extends cdk.Stack { 'file-format': 'JUNITXML', }, microserviceReports: { - files: ['**/target/report/*.xml'], + files: ['workload/**/target/report/*.xml'], 'file-format': 'JUNITXML', }, }, From 72b8d9f166864e0723f022e02d8b0cc59178a353 Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Tue, 6 Feb 2024 15:01:16 +1100 Subject: [PATCH 18/21] junit branch stateful --- .../orcabus-stateful-pipeline-stack.ts | 61 +++++++++++++++---- .../orcabus-stateless-pipeline-stack.ts | 8 +-- 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/lib/pipeline/orcabus-stateful-pipeline-stack.ts b/lib/pipeline/orcabus-stateful-pipeline-stack.ts index f90541eb9..9c8d19c93 100644 --- a/lib/pipeline/orcabus-stateful-pipeline-stack.ts +++ b/lib/pipeline/orcabus-stateful-pipeline-stack.ts @@ -13,21 +13,56 @@ export class StatefulPipelineStack extends cdk.Stack { // A connection where the pipeline get its source code const codeStarArn = ssm.StringParameter.valueForStringParameter(this, 'codestar_github_arn'); - const sourceFile = pipelines.CodePipelineSource.connection( - 'umccr/orcabus', - 'feature/base-cdk-codepipeline', - { - connectionArn: codeStarArn, - } - ); + const sourceFile = pipelines.CodePipelineSource.connection('umccr/orcabus', 'main', { + connectionArn: codeStarArn, + }); - const synthAction = new pipelines.CodeBuildStep('Synth', { - commands: [ - 'yarn install --frozen-lockfile', - 'make test-stateful', - 'yarn run cdk-stateful-pipeline synth', - ], + const unitTestReports = new codebuild.ReportGroup(this, `CodebuildStatefulTestReport`, { + reportGroupName: `UnitTestStatefulReport`, + removalPolicy: cdk.RemovalPolicy.DESTROY, + }); + + const unitTest = new pipelines.CodeBuildStep('UnitTest', { + commands: ['yarn install --frozen-lockfile', 'make test-stateful'], input: sourceFile, + primaryOutputDirectory: '.', + buildEnvironment: { + privileged: true, + computeType: codebuild.ComputeType.LARGE, + buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0, + environmentVariables: { + NODE_OPTIONS: { + value: '--max-old-space-size=8192', + }, + }, + }, + partialBuildSpec: codebuild.BuildSpec.fromObject({ + reports: { + infrastructureStatefulReports: { + files: ['target/report/*.xml'], + 'file-format': 'JUNITXML', + }, + }, + version: '0.2', + }), + rolePolicyStatements: [ + new iam.PolicyStatement({ + effect: iam.Effect.ALLOW, + actions: [ + 'codebuild:CreateReportGroup', + 'codebuild:CreateReport', + 'codebuild:UpdateReport', + 'codebuild:BatchPutTestCases', + 'codebuild:BatchPutCodeCoverages', + ], + resources: [unitTestReports.reportGroupArn], + }), + ], + }); + + const synthAction = new pipelines.CodeBuildStep('Synth', { + commands: ['yarn install --frozen-lockfile', 'yarn run cdk-stateful-pipeline synth'], + input: unitTest, primaryOutputDirectory: 'cdk.out', rolePolicyStatements: [ new iam.PolicyStatement({ diff --git a/lib/pipeline/orcabus-stateless-pipeline-stack.ts b/lib/pipeline/orcabus-stateless-pipeline-stack.ts index 073162870..cb16438e8 100644 --- a/lib/pipeline/orcabus-stateless-pipeline-stack.ts +++ b/lib/pipeline/orcabus-stateless-pipeline-stack.ts @@ -17,8 +17,8 @@ export class StatelessPipelineStack extends cdk.Stack { connectionArn: codeStarArn, }); - const unitTestReports = new codebuild.ReportGroup(this, `CodebuildTestReport`, { - reportGroupName: `UnitTestReport`, + const unitTestReports = new codebuild.ReportGroup(this, `CodebuildTestStatelessReport`, { + reportGroupName: `UnitTestStatelessReport`, removalPolicy: cdk.RemovalPolicy.DESTROY, }); @@ -38,12 +38,12 @@ export class StatelessPipelineStack extends cdk.Stack { }, partialBuildSpec: codebuild.BuildSpec.fromObject({ reports: { - infrastructureReports: { + infrastructureStatelessReports: { files: ['target/report/*.xml'], 'file-format': 'JUNITXML', }, microserviceReports: { - files: ['workload/**/target/report/*.xml'], + files: ['lib/workload/**/target/report/*.xml'], 'file-format': 'JUNITXML', }, }, From 2d595da491e3ab204014df4a1db954bc99a9f3f4 Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Tue, 6 Feb 2024 15:47:49 +1100 Subject: [PATCH 19/21] refine group reports --- .../orcabus-stateful-pipeline-stack.ts | 20 +---------------- .../orcabus-stateless-pipeline-stack.ts | 22 ++----------------- 2 files changed, 3 insertions(+), 39 deletions(-) diff --git a/lib/pipeline/orcabus-stateful-pipeline-stack.ts b/lib/pipeline/orcabus-stateful-pipeline-stack.ts index 9c8d19c93..07f4c79e0 100644 --- a/lib/pipeline/orcabus-stateful-pipeline-stack.ts +++ b/lib/pipeline/orcabus-stateful-pipeline-stack.ts @@ -17,11 +17,6 @@ export class StatefulPipelineStack extends cdk.Stack { connectionArn: codeStarArn, }); - const unitTestReports = new codebuild.ReportGroup(this, `CodebuildStatefulTestReport`, { - reportGroupName: `UnitTestStatefulReport`, - removalPolicy: cdk.RemovalPolicy.DESTROY, - }); - const unitTest = new pipelines.CodeBuildStep('UnitTest', { commands: ['yarn install --frozen-lockfile', 'make test-stateful'], input: sourceFile, @@ -37,7 +32,7 @@ export class StatefulPipelineStack extends cdk.Stack { }, }, partialBuildSpec: codebuild.BuildSpec.fromObject({ - reports: { + 'orcabus-infrastructureStatefulReports': { infrastructureStatefulReports: { files: ['target/report/*.xml'], 'file-format': 'JUNITXML', @@ -45,19 +40,6 @@ export class StatefulPipelineStack extends cdk.Stack { }, version: '0.2', }), - rolePolicyStatements: [ - new iam.PolicyStatement({ - effect: iam.Effect.ALLOW, - actions: [ - 'codebuild:CreateReportGroup', - 'codebuild:CreateReport', - 'codebuild:UpdateReport', - 'codebuild:BatchPutTestCases', - 'codebuild:BatchPutCodeCoverages', - ], - resources: [unitTestReports.reportGroupArn], - }), - ], }); const synthAction = new pipelines.CodeBuildStep('Synth', { diff --git a/lib/pipeline/orcabus-stateless-pipeline-stack.ts b/lib/pipeline/orcabus-stateless-pipeline-stack.ts index cb16438e8..d542c0434 100644 --- a/lib/pipeline/orcabus-stateless-pipeline-stack.ts +++ b/lib/pipeline/orcabus-stateless-pipeline-stack.ts @@ -17,11 +17,6 @@ export class StatelessPipelineStack extends cdk.Stack { connectionArn: codeStarArn, }); - const unitTestReports = new codebuild.ReportGroup(this, `CodebuildTestStatelessReport`, { - reportGroupName: `UnitTestStatelessReport`, - removalPolicy: cdk.RemovalPolicy.DESTROY, - }); - const unitTest = new pipelines.CodeBuildStep('UnitTest', { commands: ['yarn install --frozen-lockfile', 'make suite'], input: sourceFile, @@ -38,30 +33,17 @@ export class StatelessPipelineStack extends cdk.Stack { }, partialBuildSpec: codebuild.BuildSpec.fromObject({ reports: { - infrastructureStatelessReports: { + 'orcabus-infrastructureStatelessReports': { files: ['target/report/*.xml'], 'file-format': 'JUNITXML', }, - microserviceReports: { + 'orcabus-microserviceReports': { files: ['lib/workload/**/target/report/*.xml'], 'file-format': 'JUNITXML', }, }, version: '0.2', }), - rolePolicyStatements: [ - new iam.PolicyStatement({ - effect: iam.Effect.ALLOW, - actions: [ - 'codebuild:CreateReportGroup', - 'codebuild:CreateReport', - 'codebuild:UpdateReport', - 'codebuild:BatchPutTestCases', - 'codebuild:BatchPutCodeCoverages', - ], - resources: [unitTestReports.reportGroupArn], - }), - ], }); const synthAction = new pipelines.CodeBuildStep('Synth', { From 245841076f621ad71091845c8bdbd24f4a9c1bfa Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Tue, 6 Feb 2024 16:17:11 +1100 Subject: [PATCH 20/21] Update orcabus-stateful-pipeline-stack.ts --- lib/pipeline/orcabus-stateful-pipeline-stack.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pipeline/orcabus-stateful-pipeline-stack.ts b/lib/pipeline/orcabus-stateful-pipeline-stack.ts index 07f4c79e0..2e725703a 100644 --- a/lib/pipeline/orcabus-stateful-pipeline-stack.ts +++ b/lib/pipeline/orcabus-stateful-pipeline-stack.ts @@ -32,8 +32,8 @@ export class StatefulPipelineStack extends cdk.Stack { }, }, partialBuildSpec: codebuild.BuildSpec.fromObject({ - 'orcabus-infrastructureStatefulReports': { - infrastructureStatefulReports: { + reports: { + 'orcabus-infrastructureStatefulReports': { files: ['target/report/*.xml'], 'file-format': 'JUNITXML', }, From b9ff51d9c85f508853657391f361db7cc7c27e4c Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:53:49 +1100 Subject: [PATCH 21/21] feedback --- README.md | 31 +++++++++++++++--------------- bin/orcabus.ts | 0 cdk.json | 2 +- config/constants.ts | 6 +++--- package.json | 5 ++--- yarn.lock | 46 ++++++++++++++++++++++++++++++++++++--------- 6 files changed, 58 insertions(+), 32 deletions(-) mode change 100644 => 100755 bin/orcabus.ts diff --git a/README.md b/README.md index 8bfc9dfe5..01cf9182b 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Please note; this is the _INVERSE_ of some typical standalone project setup such In this repo, we flip this view such that the Git repo root is the TypeScript CDK project; that wraps our applications into `./lib/` directory. You may [sparse checkout](https://git-scm.com/docs/git-sparse-checkout) or directly open subdirectory to set up the application project alone if you wish; e.g. `webstorm lib/workload/stateless/metadata_manager` or `code lib/workload/stateless/metadata_manager` or `pycharm lib/workload/stateless/sequence_run_manager` or `rustrover lib/workload/stateless/filemanager`. However, `code .` is a CDK TypeScript project. -This root level CDK app contains 3 major stacks: `pipeline`, `stateful` and `stateless`. Pipeline stack is the CI/CD automation with CodePipeline setup. The `stateful` stack holds and manages some long-running AWS infrastructure resources. The `stateless` stack manages self-mutating CodePipeline reusable CDK Constructs for the [MicroService Applications](docs/developer/MICROSERVICE.md). In terms of CDK deployment point-of-view, the microservice application will be "stateless" application such that it will be changing/mutating over time; whereas "the data" its holds like PostgreSQL server infrastructure won't be changing that frequent. When updating "stateful" resources, there involves additional cares, steps and ops-procedures such as backing up database, downtime planning and so on; hence stateful. We use [configuration constants](./config) to decouple the reference between `stateful` and `stateless` AWS resources. +This root level CDK app contains 4 major stacks: `stateful-pipeline`,`stateless-pipeline` , `stateful` and `stateless`. Pipeline stack is the CI/CD automation with CodePipeline setup. The `stateful` stack holds and manages some long-running AWS infrastructure resources. The `stateless` stack manages self-mutating CodePipeline reusable CDK Constructs for the [MicroService Applications](docs/developer/MICROSERVICE.md). In terms of CDK deployment point-of-view, the microservice application will be "stateless" application such that it will be changing/mutating over time; whereas "the data" its holds like PostgreSQL server infrastructure won't be changing that frequent. When updating "stateful" resources, there involves additional cares, steps and ops-procedures such as backing up database, downtime planning and so on; hence stateful. We use [configuration constants](./config) to decouple the reference between `stateful` and `stateless` AWS resources. In most cases, we deploy with automation across operational target environments or AWS accounts: `beta`, `gamma`, `prod`. For some particular purpose (such as onboarding procedure, isolated experimentation), we can spin up the whole infrastructure into some unique isolated AWS account. These key CDK entrypoints are documented in the following sections: Automation and Manual. @@ -18,20 +18,19 @@ In most cases, we deploy with automation across operational target environments _CI/CD through CodePipeline automation from AWS toolchain account_ +There are 2 pipeline stacks in this project, one for the stateful and one for the stateless stack deployment. There is a +script to access the `cdk` command for each pipeline: +-`cdk-stateless-pipeline` - for stateless pipeline +-`cdk-stateful-pipeline` - for stateful pipeline + ``` make install make check make test -yarn cdk list - -yarn cdk synth -yarn cdk diff -yarn cdk deploy - -yarn cdk synth -yarn cdk diff -yarn cdk deploy --all +yarn cdk-stateless-pipeline synth +yarn cdk-stateless-pipeline diff +yarn cdk-stateless-pipeline deploy ``` ### Manual @@ -47,12 +46,12 @@ make test yarn orcabus --help -yarn orcabus list -yarn orcabus synth OrcaBusStatefulStack -yarn orcabus diff OrcaBusStatefulStack -yarn orcabus deploy OrcaBusStatefulStack -yarn orcabus deploy --all -yarn orcabus destroy --all +yarn cdk-orcabus list +yarn cdk-orcabus synth OrcaBusStatefulStack +yarn cdk-orcabus diff OrcaBusStatefulStack +yarn cdk-orcabus deploy OrcaBusStatefulStack +yarn cdk-orcabus deploy --all +yarn cdk-orcabus destroy --all ``` ## Development diff --git a/bin/orcabus.ts b/bin/orcabus.ts old mode 100644 new mode 100755 diff --git a/cdk.json b/cdk.json index faf5362ca..d38614e06 100644 --- a/cdk.json +++ b/cdk.json @@ -1,5 +1,5 @@ { - "app": "yarn run ts-node --prefer-ts-exts bin/orcabus.ts", + "app": "yarn run -B ts-node --prefer-ts-exts bin/orcabus.ts", "watch": { "include": [ "**" diff --git a/config/constants.ts b/config/constants.ts index 294254d2d..b1dd3398c 100644 --- a/config/constants.ts +++ b/config/constants.ts @@ -91,7 +91,7 @@ export const getEnvironmentConfig = ( ...orcaBusStatefulConfig.databaseProps, numberOfInstance: 1, minACU: 0.5, - maxACU: 1, + maxACU: 16, enhancedMonitoringInterval: Duration.seconds(60), enablePerformanceInsights: true, removalPolicy: RemovalPolicy.DESTROY, @@ -121,7 +121,7 @@ export const getEnvironmentConfig = ( ...orcaBusStatefulConfig.databaseProps, numberOfInstance: 1, minACU: 0.5, - maxACU: 1, + maxACU: 16, enhancedMonitoringInterval: Duration.seconds(60), enablePerformanceInsights: true, removalPolicy: RemovalPolicy.DESTROY, @@ -151,7 +151,7 @@ export const getEnvironmentConfig = ( ...orcaBusStatefulConfig.databaseProps, numberOfInstance: 1, minACU: 0.5, - maxACU: 1, + maxACU: 16, removalPolicy: RemovalPolicy.RETAIN, }, securityGroupProps: { diff --git a/package.json b/package.json index 2eccfb29e..644197e23 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,6 @@ "type": "git" }, "license": "MIT", - "bin": "bin/pipeline.js", "scripts": { "test": "tsc && jest", "build": "cdk synth -q", @@ -29,7 +28,7 @@ "@aws-cdk/aws-apigatewayv2-authorizers-alpha": "^2.110.0-alpha.0", "@aws-cdk/aws-apigatewayv2-integrations-alpha": "^2.110.0-alpha.0", "@aws-cdk/aws-lambda-python-alpha": "2.110.0-alpha.0", - "aws-cdk-lib": "^2.110.0", + "aws-cdk-lib": "^2.126.0", "cdk-nag": "^2.28.27", "constructs": "^10.2.69", "dotenv": "^16.3.1", @@ -41,7 +40,7 @@ "@types/node": "^20.4.0", "@typescript-eslint/eslint-plugin": "^6.19.1", "@typescript-eslint/parser": "^6.19.1", - "aws-cdk": "2.110.0", + "aws-cdk": "^2.126.0", "eslint": "^8.44.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", diff --git a/yarn.lock b/yarn.lock index 35f2a707f..d4757c4b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29,6 +29,13 @@ __metadata: languageName: node linkType: hard +"@aws-cdk/asset-awscli-v1@npm:^2.2.202": + version: 2.2.202 + resolution: "@aws-cdk/asset-awscli-v1@npm:2.2.202" + checksum: 40a536008f1de5587ab0b1d7018942c048888c43b145ac10b030e841ab017839a02ad102daac3a29ae4b2242007b2dea499195b4807dc90944973b107427108b + languageName: node + linkType: hard + "@aws-cdk/asset-kubectl-v20@npm:^2.1.2": version: 2.1.2 resolution: "@aws-cdk/asset-kubectl-v20@npm:2.1.2" @@ -1484,7 +1491,7 @@ __metadata: languageName: node linkType: hard -"aws-cdk-lib@npm:^2.*, aws-cdk-lib@npm:^2.110.0": +"aws-cdk-lib@npm:^2.*": version: 2.115.0 resolution: "aws-cdk-lib@npm:2.115.0" dependencies: @@ -1507,9 +1514,32 @@ __metadata: languageName: node linkType: hard -"aws-cdk@npm:2.110.0": - version: 2.110.0 - resolution: "aws-cdk@npm:2.110.0" +"aws-cdk-lib@npm:^2.126.0": + version: 2.126.0 + resolution: "aws-cdk-lib@npm:2.126.0" + dependencies: + "@aws-cdk/asset-awscli-v1": ^2.2.202 + "@aws-cdk/asset-kubectl-v20": ^2.1.2 + "@aws-cdk/asset-node-proxy-agent-v6": ^2.0.1 + "@balena/dockerignore": ^1.0.2 + case: 1.6.3 + fs-extra: ^11.2.0 + ignore: ^5.3.0 + jsonschema: ^1.4.1 + minimatch: ^3.1.2 + punycode: ^2.3.1 + semver: ^7.5.4 + table: ^6.8.1 + yaml: 1.10.2 + peerDependencies: + constructs: ^10.0.0 + checksum: 62d46d108fba4ef2c76e7c46767bddfe7019b2f96ad1bfb1b8ae348eeefb889dc6314b56fa5da16c299477ebc1463354de93df45a0ca72cc4d6faee5a0eb9656 + languageName: node + linkType: hard + +"aws-cdk@npm:^2.126.0": + version: 2.126.0 + resolution: "aws-cdk@npm:2.126.0" dependencies: fsevents: 2.3.2 dependenciesMeta: @@ -1517,7 +1547,7 @@ __metadata: optional: true bin: cdk: bin/cdk - checksum: 69ea8ca2d764a00c7b52889f55ad611655298a49c00cbdd3f976e94fd375c9d48c0e646b24c243555af5ac9e68437f078a9a3c08d3ffa96908d90e2a76845eb6 + checksum: 93c82ccb949059ef07e88a2952df7fe025dc60a8d3e687c26497660de5ac2433bf719f0dbff415fa41eef2c1a64caf37a77110d3d2a4c6de9f122dcd1f293506 languageName: node linkType: hard @@ -3977,8 +4007,8 @@ __metadata: "@types/node": ^20.4.0 "@typescript-eslint/eslint-plugin": ^6.19.1 "@typescript-eslint/parser": ^6.19.1 - aws-cdk: 2.110.0 - aws-cdk-lib: ^2.110.0 + aws-cdk: ^2.126.0 + aws-cdk-lib: ^2.126.0 cdk-nag: ^2.28.27 constructs: ^10.2.69 dotenv: ^16.3.1 @@ -3993,8 +4023,6 @@ __metadata: ts-jest: ^29.1.1 ts-node: ^10.9.1 typescript: ^5.1.6 - bin: - orcabus: bin/pipeline.js languageName: unknown linkType: soft