From e21f33c3ab7dd5d8036f7fe9c489e279489a36f0 Mon Sep 17 00:00:00 2001 From: cvrajeesh Date: Sun, 29 Nov 2020 09:36:26 +0000 Subject: [PATCH 1/2] fix(aws-codebuild): grant parameter store read permission for pipeline project --- .../@aws-cdk/aws-codebuild/lib/project.ts | 25 +++ .../aws-codebuild/test/test.project.ts | 155 +++++++++++++++++- 2 files changed, 179 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-codebuild/lib/project.ts b/packages/@aws-cdk/aws-codebuild/lib/project.ts index 7810c82287f4c..75c3b79f76b66 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/project.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/project.ts @@ -792,6 +792,7 @@ export class Project extends ProjectBase { this.projectName = this.getResourceNameAttribute(resource.ref); this.addToRolePolicy(this.createLoggingPermission()); + this.addParameterStorePermission(props); // add permissions to create and use test report groups // with names starting with the project's name, // unless the customer explicitly opts out of it @@ -923,6 +924,30 @@ export class Project extends ProjectBase { }); } + private addParameterStorePermission(props: ProjectProps) { + if (!props.environmentVariables) { + return; + } + + const resources = Object.values(props.environmentVariables) + .filter(envVariable => envVariable.type === BuildEnvironmentVariableType.PARAMETER_STORE) + .map(envVariable => Stack.of(this).formatArn({ + service: 'ssm', + resource: 'parameter', + sep: ':', + resourceName: envVariable.value, + })); + + if (resources.length === 0) { + return; + } + + this.addToRolePolicy(new iam.PolicyStatement({ + actions: ['ssm:GetParameters'], + resources, + })); + } + private renderEnvironment( env: BuildEnvironment = {}, projectVars: { [name: string]: BuildEnvironmentVariable } = {}): CfnProject.EnvironmentProperty { diff --git a/packages/@aws-cdk/aws-codebuild/test/test.project.ts b/packages/@aws-cdk/aws-codebuild/test/test.project.ts index 439427588afdb..b444275bedf94 100644 --- a/packages/@aws-cdk/aws-codebuild/test/test.project.ts +++ b/packages/@aws-cdk/aws-codebuild/test/test.project.ts @@ -1,4 +1,4 @@ -import { countResources, expect, haveResource, haveResourceLike, objectLike, not, ResourcePart } from '@aws-cdk/assert'; +import { countResources, expect, haveResource, haveResourceLike, objectLike, not, ResourcePart, arrayWith } from '@aws-cdk/assert'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; import * as logs from '@aws-cdk/aws-logs'; @@ -7,6 +7,7 @@ import * as secretsmanager from '@aws-cdk/aws-secretsmanager'; import * as cdk from '@aws-cdk/core'; import { Test } from 'nodeunit'; import * as codebuild from '../lib'; +import { BuildEnvironmentVariableType } from '../lib'; /* eslint-disable quote-props */ @@ -738,4 +739,156 @@ export = { test.done(); }, }, + + 'EnvironmentVariables': { + 'can use environment variables from parameter store'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new codebuild.Project(stack, 'Project', { + source: codebuild.Source.s3({ + bucket: new s3.Bucket(stack, 'Bucket'), + path: 'path', + }), + environment: { + buildImage: codebuild.LinuxBuildImage.fromDockerRegistry('myimage'), + }, + environmentVariables: { + 'ENV_VAR1': { + type: BuildEnvironmentVariableType.PARAMETER_STORE, + value: '/params/param1', + }, + }, + }); + + // THEN + expect(stack).to(haveResourceLike('AWS::CodeBuild::Project', { + Environment: objectLike({ + EnvironmentVariables: [{ + Name: 'ENV_VAR1', + Type: 'PARAMETER_STORE', + Value: '/params/param1', + }], + }), + })); + + test.done(); + }, + + + 'grant read permission for parameter store variables'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new codebuild.Project(stack, 'Project', { + source: codebuild.Source.s3({ + bucket: new s3.Bucket(stack, 'Bucket'), + path: 'path', + }), + environment: { + buildImage: codebuild.LinuxBuildImage.fromDockerRegistry('myimage'), + }, + environmentVariables: { + 'ENV_VAR1': { + type: BuildEnvironmentVariableType.PARAMETER_STORE, + value: '/params/param1', + }, + 'ENV_VAR2': { + type: BuildEnvironmentVariableType.PARAMETER_STORE, + value: '/params/param2', + }, + }, + }); + + // THEN + expect(stack).to(haveResourceLike('AWS::IAM::Policy', { + 'PolicyDocument': { + 'Statement': arrayWith(objectLike({ + 'Action': 'ssm:GetParameters', + 'Effect': 'Allow', + 'Resource': [{ + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ssm:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':parameter:/params/param1', + ], + ], + }, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':ssm:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':parameter:/params/param2', + ], + ], + }], + })), + }, + })); + + + test.done(); + }, + + 'should not grant read permission when variables are not from parameter store'(test: Test) { + + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new codebuild.Project(stack, 'Project', { + source: codebuild.Source.s3({ + bucket: new s3.Bucket(stack, 'Bucket'), + path: 'path', + }), + environment: { + buildImage: codebuild.LinuxBuildImage.fromDockerRegistry('myimage'), + }, + environmentVariables: { + 'ENV_VAR1': { + type: BuildEnvironmentVariableType.PLAINTEXT, + value: 'var1-value', + }, + }, + }); + + // THEN + expect(stack).notTo(haveResourceLike('AWS::IAM::Policy', { + 'PolicyDocument': { + 'Statement': arrayWith(objectLike({ + 'Action': 'ssm:GetParameters', + 'Effect': 'Allow', + })), + }, + })); + + test.done(); + }, + }, }; From 0df9eb04753eedbbb658f0d3821c83155ca89d0e Mon Sep 17 00:00:00 2001 From: cvrajeesh Date: Sun, 29 Nov 2020 16:21:06 +0530 Subject: [PATCH 2/2] fix: remove unwanted import --- packages/@aws-cdk/aws-codebuild/test/test.project.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/@aws-cdk/aws-codebuild/test/test.project.ts b/packages/@aws-cdk/aws-codebuild/test/test.project.ts index b444275bedf94..ba7b804d779f1 100644 --- a/packages/@aws-cdk/aws-codebuild/test/test.project.ts +++ b/packages/@aws-cdk/aws-codebuild/test/test.project.ts @@ -7,7 +7,6 @@ import * as secretsmanager from '@aws-cdk/aws-secretsmanager'; import * as cdk from '@aws-cdk/core'; import { Test } from 'nodeunit'; import * as codebuild from '../lib'; -import { BuildEnvironmentVariableType } from '../lib'; /* eslint-disable quote-props */ @@ -756,7 +755,7 @@ export = { }, environmentVariables: { 'ENV_VAR1': { - type: BuildEnvironmentVariableType.PARAMETER_STORE, + type: codebuild.BuildEnvironmentVariableType.PARAMETER_STORE, value: '/params/param1', }, }, @@ -792,11 +791,11 @@ export = { }, environmentVariables: { 'ENV_VAR1': { - type: BuildEnvironmentVariableType.PARAMETER_STORE, + type: codebuild.BuildEnvironmentVariableType.PARAMETER_STORE, value: '/params/param1', }, 'ENV_VAR2': { - type: BuildEnvironmentVariableType.PARAMETER_STORE, + type: codebuild.BuildEnvironmentVariableType.PARAMETER_STORE, value: '/params/param2', }, }, @@ -872,7 +871,7 @@ export = { }, environmentVariables: { 'ENV_VAR1': { - type: BuildEnvironmentVariableType.PLAINTEXT, + type: codebuild.BuildEnvironmentVariableType.PLAINTEXT, value: 'var1-value', }, },