diff --git a/infra/cdk/lib/stacks/env/ci/ciBackend.ts b/infra/cdk/lib/stacks/env/ci/ciBackend.ts index 565e8f99e..78cb1e38c 100644 --- a/infra/cdk/lib/stacks/env/ci/ciBackend.ts +++ b/infra/cdk/lib/stacks/env/ci/ciBackend.ts @@ -27,16 +27,19 @@ export class BackendCiConfig extends ServiceCiConfig { const apiDeployProject = this.createApiDeployProject(props); props.deployStage.addAction(this.createDeployAction('api', { project: apiDeployProject, + runOrder: 2, }, props)); const adminPanelDeployProject = this.createAdminPanelDeployProject(props); props.deployStage.addAction(this.createDeployAction('admin', { project: adminPanelDeployProject, + runOrder: 2, }, props)); const migrationsDeployProject = this.createMigrationsDeployProject(props); props.deployStage.addAction(this.createDeployAction('migrations', { project: migrationsDeployProject, + runOrder: 2, }, props)); } diff --git a/infra/cdk/lib/stacks/env/ci/ciComponents.ts b/infra/cdk/lib/stacks/env/ci/ciComponents.ts new file mode 100644 index 000000000..def1c7b74 --- /dev/null +++ b/infra/cdk/lib/stacks/env/ci/ciComponents.ts @@ -0,0 +1,78 @@ +import {Construct, Stack} from "@aws-cdk/core"; +import {BuildSpec, Cache, LocalCacheMode, Project} from "@aws-cdk/aws-codebuild"; +import {CodeBuildAction, CodeBuildActionProps} from "@aws-cdk/aws-codepipeline-actions"; +import {Artifact, IStage} from "@aws-cdk/aws-codepipeline"; +import {Effect, PolicyStatement} from "@aws-cdk/aws-iam"; + +import {EnvConstructProps} from "../../../types"; +import {ServiceCiConfig} from "../../../patterns/serviceCiConfig"; + +interface ComponentsCiConfigProps extends EnvConstructProps { + inputArtifact: Artifact; + buildStage: IStage; + deployStage: IStage; +} + +export class ComponentsCiConfig extends ServiceCiConfig { + constructor(scope: Construct, id: string, props: ComponentsCiConfigProps) { + super(scope, id, {envSettings: props.envSettings}); + + props.deployStage.addAction(this.createDeployAction({ + project: this.createDeployProject(props), + }, props)); + } + + private createDeployAction(actionProps: Partial, props: ComponentsCiConfigProps) { + return new CodeBuildAction({ + ...actionProps, + project: actionProps.project, + actionName: `${props.envSettings.projectEnvName}-deploy-components`, + input: props.inputArtifact, + runOrder: 1, + }); + } + + private createDeployProject(props: ComponentsCiConfigProps) { + const stack = Stack.of(this); + const project = new Project(this, "ComponentsDeployProject", { + projectName: `${props.envSettings.projectEnvName}-deploy-components`, + buildSpec: BuildSpec.fromObject({ + version: '0.2', + phases: { + pre_build: {commands: ['make -C infra/cdk install']}, + build: {commands: ['make -C infra/cdk deploy-components']} + }, + cache: { + paths: [...this.defaultCachePaths], + }, + }), + environmentVariables: {...this.defaultEnvVariables}, + cache: Cache.local(LocalCacheMode.CUSTOM), + }); + + project.addToRolePolicy(new PolicyStatement({ + effect: Effect.ALLOW, + actions: [ + 'cloudformation:*', + ], + resources: [ + `arn:aws:cloudformation:${stack.region}:${stack.account}:stack/CDKToolkit/*`, + `arn:aws:cloudformation:${stack.region}:${stack.account}:stack/${props.envSettings.projectEnvName}-ComponentsStack/*`, + ], + })); + + project.addToRolePolicy(new PolicyStatement({ + effect: Effect.ALLOW, + actions: [ + 'iam:*', + 'logs:*', + 's3:*', + 'sqs:*', + 'events:*', + ], + resources: ['*'], + })); + + return project; + } +} diff --git a/infra/cdk/lib/stacks/env/ci/ciPipeline.ts b/infra/cdk/lib/stacks/env/ci/ciPipeline.ts index 5ff5e1182..8fa0337f6 100644 --- a/infra/cdk/lib/stacks/env/ci/ciPipeline.ts +++ b/infra/cdk/lib/stacks/env/ci/ciPipeline.ts @@ -11,6 +11,7 @@ import {BackendCiConfig} from "./ciBackend"; import {WebappCiConfig} from "./ciWebApp"; import {ServerlessCiConfig} from "./ciServerless"; import {UploadVersionCiConfig} from "./ciUploadVersion"; +import {ComponentsCiConfig} from "./ciComponents"; export interface CiPipelineProps extends EnvConstructProps { @@ -38,6 +39,13 @@ export class CiPipeline extends Construct { const buildStage = this.selectStage(this.buildStageName, pipeline); const deployStage = this.selectStage(this.deployStageName, pipeline); + new ComponentsCiConfig(this, "ComponentsConfig", { + buildStage, + deployStage, + envSettings: props.envSettings, + inputArtifact: sourceOutputArtifact, + }); + new BackendCiConfig(this, "BackendConfig", { buildStage, deployStage, diff --git a/infra/cdk/lib/stacks/env/ci/ciServerless.ts b/infra/cdk/lib/stacks/env/ci/ciServerless.ts index b08018999..e5ac8d8ce 100644 --- a/infra/cdk/lib/stacks/env/ci/ciServerless.ts +++ b/infra/cdk/lib/stacks/env/ci/ciServerless.ts @@ -31,6 +31,7 @@ export class ServerlessCiConfig extends ServiceCiConfig { props.deployStage.addAction(this.createDeployAction({ project: deployProject, input: buildArtifact, + runOrder: 2, }, props)); } diff --git a/infra/cdk/lib/stacks/env/ci/ciUploadVersion.ts b/infra/cdk/lib/stacks/env/ci/ciUploadVersion.ts index 6b2d79500..d2b2a1964 100644 --- a/infra/cdk/lib/stacks/env/ci/ciUploadVersion.ts +++ b/infra/cdk/lib/stacks/env/ci/ciUploadVersion.ts @@ -21,6 +21,7 @@ export class UploadVersionCiConfig extends ServiceCiConfig { props.deployStage.addAction(this.createDeployAction({ project: deployProject, input: props.inputArtifact, + runOrder: 3, }, props)); } @@ -28,7 +29,6 @@ export class UploadVersionCiConfig extends ServiceCiConfig { return new CodeBuildAction({ ...actionProps, actionName: `${props.envSettings.projectEnvName}-upload-version`, - runOrder: 2, }); } diff --git a/infra/cdk/lib/stacks/env/ci/ciWebApp.ts b/infra/cdk/lib/stacks/env/ci/ciWebApp.ts index 01715654d..59b0e0c7a 100644 --- a/infra/cdk/lib/stacks/env/ci/ciWebApp.ts +++ b/infra/cdk/lib/stacks/env/ci/ciWebApp.ts @@ -30,6 +30,7 @@ export class WebappCiConfig extends ServiceCiConfig { props.deployStage.addAction(this.createDeployAction({ project: deployProject, input: buildArtifact, + runOrder: 2, }, props)); }