From b059b8dcbaf66ce14aaeab578a036199a7d5c8fb Mon Sep 17 00:00:00 2001 From: Adam Ruka Date: Wed, 23 Dec 2020 13:24:43 -0800 Subject: [PATCH] fix(codebuild): Project lacks permissions to its log destinations In #11444, we added the option of setting the logging configuration of the Project. Unfortuantely, the Project's Role was not given permissions to write into that destination, which means executing the Project's build would fail. Fixes #12179 --- .../@aws-cdk/aws-codebuild/lib/project.ts | 6 +- .../test/integ.project-logging.expected.json | 223 ++++++++++++++++++ .../test/integ.project-logging.ts | 25 ++ .../aws-codebuild/test/test.project.ts | 5 +- 4 files changed, 253 insertions(+), 6 deletions(-) create mode 100644 packages/@aws-cdk/aws-codebuild/test/integ.project-logging.expected.json create mode 100644 packages/@aws-cdk/aws-codebuild/test/integ.project-logging.ts diff --git a/packages/@aws-cdk/aws-codebuild/lib/project.ts b/packages/@aws-cdk/aws-codebuild/lib/project.ts index dede5ddd9cf87..b8235dd70997e 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/project.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/project.ts @@ -1098,7 +1098,7 @@ export class Project extends ProjectBase { private renderLoggingConfiguration(props: LoggingOptions | undefined): CfnProject.LogsConfigProperty | undefined { if (props === undefined) { return undefined; - }; + } let s3Config: CfnProject.S3LogsConfigProperty|undefined = undefined; let cloudwatchConfig: CfnProject.CloudWatchLogsConfigProperty|undefined = undefined; @@ -1107,9 +1107,10 @@ export class Project extends ProjectBase { const s3Logs = props.s3; s3Config = { status: (s3Logs.enabled ?? true) ? 'ENABLED' : 'DISABLED', - location: `${s3Logs.bucket.bucketName}/${s3Logs.prefix}`, + location: `${s3Logs.bucket.bucketName}` + (s3Logs.prefix ? `/${s3Logs.prefix}` : ''), encryptionDisabled: s3Logs.encrypted, }; + s3Logs.bucket?.grantWrite(this); } if (props.cloudWatch) { @@ -1119,6 +1120,7 @@ export class Project extends ProjectBase { if (status === 'ENABLED' && !(cloudWatchLogs.logGroup)) { throw new Error('Specifying a LogGroup is required if CloudWatch logging for CodeBuild is enabled'); } + cloudWatchLogs.logGroup?.grantWrite(this); cloudwatchConfig = { status, diff --git a/packages/@aws-cdk/aws-codebuild/test/integ.project-logging.expected.json b/packages/@aws-cdk/aws-codebuild/test/integ.project-logging.expected.json new file mode 100644 index 0000000000000..e68bc6b47d2b4 --- /dev/null +++ b/packages/@aws-cdk/aws-codebuild/test/integ.project-logging.expected.json @@ -0,0 +1,223 @@ +{ + "Resources": { + "LogingGroupE599B53B": { + "Type": "AWS::Logs::LogGroup", + "Properties": { + "RetentionInDays": 731 + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "LoggingBucket1E5A6F3B": { + "Type": "AWS::S3::Bucket", + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "ProjectRole4CCB274E": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "codebuild.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "ProjectRoleDefaultPolicy7F29461B": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject*", + "s3:PutObject*", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "LoggingBucket1E5A6F3B", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "LoggingBucket1E5A6F3B", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "LogingGroupE599B53B", + "Arn" + ] + } + }, + { + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:/aws/codebuild/", + { + "Ref": "ProjectC78D97AD" + } + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:/aws/codebuild/", + { + "Ref": "ProjectC78D97AD" + }, + ":*" + ] + ] + } + ] + }, + { + "Action": [ + "codebuild:CreateReportGroup", + "codebuild:CreateReport", + "codebuild:UpdateReport", + "codebuild:BatchPutTestCases", + "codebuild:BatchPutCodeCoverages" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":codebuild:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":report-group/", + { + "Ref": "ProjectC78D97AD" + }, + "-*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "ProjectRoleDefaultPolicy7F29461B", + "Roles": [ + { + "Ref": "ProjectRole4CCB274E" + } + ] + } + }, + "ProjectC78D97AD": { + "Type": "AWS::CodeBuild::Project", + "Properties": { + "Artifacts": { + "Type": "CODEPIPELINE" + }, + "Environment": { + "ComputeType": "BUILD_GENERAL1_SMALL", + "Image": "aws/codebuild/standard:1.0", + "ImagePullCredentialsType": "CODEBUILD", + "PrivilegedMode": false, + "Type": "LINUX_CONTAINER" + }, + "ServiceRole": { + "Fn::GetAtt": [ + "ProjectRole4CCB274E", + "Arn" + ] + }, + "Source": { + "Type": "CODEPIPELINE" + }, + "EncryptionKey": "alias/aws/s3", + "LogsConfig": { + "CloudWatchLogs": { + "GroupName": { + "Ref": "LogingGroupE599B53B" + }, + "Status": "ENABLED" + }, + "S3Logs": { + "Location": { + "Ref": "LoggingBucket1E5A6F3B" + }, + "Status": "ENABLED" + } + } + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-codebuild/test/integ.project-logging.ts b/packages/@aws-cdk/aws-codebuild/test/integ.project-logging.ts new file mode 100644 index 0000000000000..b0134178bac30 --- /dev/null +++ b/packages/@aws-cdk/aws-codebuild/test/integ.project-logging.ts @@ -0,0 +1,25 @@ +import * as logs from '@aws-cdk/aws-logs'; +import * as s3 from '@aws-cdk/aws-s3'; +import * as cdk from '@aws-cdk/core'; +import * as codebuild from '../lib'; + +const app = new cdk.App(); + +const stack = new cdk.Stack(app, 'aws-cdk-codebuild-logging'); + +new codebuild.PipelineProject(stack, 'Project', { + logging: { + cloudWatch: { + logGroup: new logs.LogGroup(stack, 'LogingGroup', { + removalPolicy: cdk.RemovalPolicy.DESTROY, + }), + }, + s3: { + bucket: new s3.Bucket(stack, 'LoggingBucket', { + removalPolicy: cdk.RemovalPolicy.DESTROY, + }), + }, + }, +}); + +app.synth(); diff --git a/packages/@aws-cdk/aws-codebuild/test/test.project.ts b/packages/@aws-cdk/aws-codebuild/test/test.project.ts index 8a0cb370dd006..0735128dc4f69 100644 --- a/packages/@aws-cdk/aws-codebuild/test/test.project.ts +++ b/packages/@aws-cdk/aws-codebuild/test/test.project.ts @@ -711,11 +711,9 @@ export = { logging: { cloudWatch: { logGroup, - prefix: '/my-logs', }, s3: { bucket, - prefix: 'my-logs', }, }, }); @@ -726,10 +724,9 @@ export = { CloudWatchLogs: { GroupName: 'MyLogGroupName', Status: 'ENABLED', - StreamName: '/my-logs', }, S3Logs: { - Location: 'MyBucketName/my-logs', + Location: 'MyBucketName', Status: 'ENABLED', }, }),