Skip to content

Commit

Permalink
feat(aws-codebuild): add supportBatchBuildType option to Project
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Jenkinson committed Jan 15, 2021
1 parent 581f6af commit 8eade4c
Show file tree
Hide file tree
Showing 6 changed files with 354 additions and 20 deletions.
42 changes: 34 additions & 8 deletions packages/@aws-cdk/aws-codebuild/lib/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,15 @@ export interface ProjectProps extends CommonProjectProps {
* @see https://docs.aws.amazon.com/codebuild/latest/userguide/sample-multi-in-out.html
*/
readonly secondaryArtifacts?: IArtifacts[];

/**
* Support the batch build type.
*
* Set to `true` if you want to be able to run this project as a batch build.
*
* @default false
*/
readonly supportBatchBuildType?: boolean;
}

/**
Expand Down Expand Up @@ -729,6 +738,7 @@ export class Project extends ProjectBase {
private readonly _secondaryArtifacts: CfnProject.ArtifactsProperty[];
private _encryptionKey?: kms.IKey;
private readonly _fileSystemLocations: CfnProject.ProjectFileSystemLocationProperty[];
private readonly _batchServiceRole?: iam.Role;

constructor(scope: Construct, id: string, props: ProjectProps) {
super(scope, id, {
Expand All @@ -739,8 +749,16 @@ export class Project extends ProjectBase {
roleName: PhysicalName.GENERATE_IF_NEEDED,
assumedBy: new iam.ServicePrincipal('codebuild.amazonaws.com'),
});

this.grantPrincipal = this.role;

if (props.supportBatchBuildType) {
this._batchServiceRole = new iam.Role(this, 'BatchServiceRole', {
roleName: PhysicalName.GENERATE_IF_NEEDED,
assumedBy: new iam.ServicePrincipal('codebuild.amazonaws.com'),
});
}

this.buildImage = (props.environment && props.environment.buildImage) || LinuxBuildImage.STANDARD_1_0;

// let source "bind" to the project. this usually involves granting permissions
Expand Down Expand Up @@ -813,6 +831,9 @@ export class Project extends ProjectBase {
sourceVersion: sourceConfig.sourceVersion,
vpcConfig: this.configureVpc(props),
logsConfig: this.renderLoggingConfiguration(props.logging),
buildBatchConfig: props.supportBatchBuildType && this._batchServiceRole ? {
serviceRole: this._batchServiceRole.roleArn,
} : undefined,
});

this.addVpcRequiredPermissions(props, resource);
Expand All @@ -824,6 +845,11 @@ export class Project extends ProjectBase {
});
this.projectName = this.getResourceNameAttribute(resource.ref);

this._batchServiceRole?.addToPrincipalPolicy(new iam.PolicyStatement({
resources: [this.projectArn],
actions: ['codebuild:StartBuild', 'codebuild:StopBuild', 'codebuild:RetryBuild'],
}));

this.addToRolePolicy(this.createLoggingPermission());
this.addEnvVariablesPermissions(props.environmentVariables);
// add permissions to create and use test report groups
Expand Down Expand Up @@ -912,7 +938,7 @@ export class Project extends ProjectBase {
const keyStack = Stack.of(options.artifactBucket.encryptionKey);
const projectStack = Stack.of(this);
if (!(options.artifactBucket.encryptionKey instanceof kms.Key &&
(keyStack.account !== projectStack.account || keyStack.region !== projectStack.region))) {
(keyStack.account !== projectStack.account || keyStack.region !== projectStack.region))) {
this.encryptionKey = options.artifactBucket.encryptionKey;
}
}
Expand Down Expand Up @@ -1139,8 +1165,8 @@ export class Project extends ProjectBase {
return undefined;
}

let s3Config: CfnProject.S3LogsConfigProperty|undefined = undefined;
let cloudwatchConfig: CfnProject.CloudWatchLogsConfigProperty|undefined = undefined;
let s3Config: CfnProject.S3LogsConfigProperty | undefined = undefined;
let cloudwatchConfig: CfnProject.CloudWatchLogsConfigProperty | undefined = undefined;

if (props.s3) {
const s3Logs = props.s3;
Expand Down Expand Up @@ -1221,8 +1247,8 @@ export class Project extends ProjectBase {
const artifactsType = artifacts.type;

if ((sourceType === CODEPIPELINE_SOURCE_ARTIFACTS_TYPE ||
artifactsType === CODEPIPELINE_SOURCE_ARTIFACTS_TYPE) &&
(sourceType !== artifactsType)) {
artifactsType === CODEPIPELINE_SOURCE_ARTIFACTS_TYPE) &&
(sourceType !== artifactsType)) {
throw new Error('Both source and artifacts must be set to CodePipeline');
}
}
Expand Down Expand Up @@ -1350,10 +1376,10 @@ export interface IBuildImage {
}

/** Optional arguments to {@link IBuildImage.binder} - currently empty. */
export interface BuildImageBindOptions {}
export interface BuildImageBindOptions { }

/** The return type from {@link IBuildImage.binder} - currently empty. */
export interface BuildImageConfig {}
export interface BuildImageConfig { }

// @deprecated(not in tsdoc on purpose): add bind() to IBuildImage
// and get rid of IBindableBuildImage
Expand All @@ -1377,7 +1403,7 @@ class ArmBuildImage implements IBuildImage {
public validate(buildEnvironment: BuildEnvironment): string[] {
const ret = [];
if (buildEnvironment.computeType &&
buildEnvironment.computeType !== ComputeType.LARGE) {
buildEnvironment.computeType !== ComputeType.LARGE) {
ret.push(`ARM images only support ComputeType '${ComputeType.LARGE}' - ` +
`'${buildEnvironment.computeType}' was given`);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/@aws-cdk/aws-codebuild/lib/source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,8 @@ interface ThirdPartyGitSourceProps extends GitSourceProps {
/**
* Trigger a batch build from a webhook instead of a standard one.
*
* If you enable this you must also enable `supportBatchBuildType` on the project.
*
* @default false
*/
readonly webhookTriggersBatchBuild?: boolean;
Expand Down
209 changes: 209 additions & 0 deletions packages/@aws-cdk/aws-codebuild/test/integ.batch.lit.expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
{
"Resources": {
"MyProjectRole9BBE5233": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "codebuild.amazonaws.com"
}
}
],
"Version": "2012-10-17"
}
}
},
"MyProjectRoleDefaultPolicyB19B7C29": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"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": "MyProject39F7B0AE"
}
]
]
},
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":logs:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":log-group:/aws/codebuild/",
{
"Ref": "MyProject39F7B0AE"
},
":*"
]
]
}
]
},
{
"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": "MyProject39F7B0AE"
},
"-*"
]
]
}
}
],
"Version": "2012-10-17"
},
"PolicyName": "MyProjectRoleDefaultPolicyB19B7C29",
"Roles": [
{
"Ref": "MyProjectRole9BBE5233"
}
]
}
},
"MyProjectBatchServiceRole6B35CF0E": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "codebuild.amazonaws.com"
}
}
],
"Version": "2012-10-17"
}
}
},
"MyProjectBatchServiceRoleDefaultPolicy7A0E5721": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": [
"codebuild:StartBuild",
"codebuild:StopBuild",
"codebuild:RetryBuild"
],
"Effect": "Allow",
"Resource": {
"Fn::GetAtt": [
"MyProject39F7B0AE",
"Arn"
]
}
}
],
"Version": "2012-10-17"
},
"PolicyName": "MyProjectBatchServiceRoleDefaultPolicy7A0E5721",
"Roles": [
{
"Ref": "MyProjectBatchServiceRole6B35CF0E"
}
]
}
},
"MyProject39F7B0AE": {
"Type": "AWS::CodeBuild::Project",
"Properties": {
"Artifacts": {
"Type": "NO_ARTIFACTS"
},
"Environment": {
"ComputeType": "BUILD_GENERAL1_SMALL",
"Image": "aws/codebuild/standard:1.0",
"ImagePullCredentialsType": "CODEBUILD",
"PrivilegedMode": false,
"Type": "LINUX_CONTAINER"
},
"ServiceRole": {
"Fn::GetAtt": [
"MyProjectRole9BBE5233",
"Arn"
]
},
"Source": {
"BuildSpec": "{\n \"version\": 0.2,\n \"batch\": {\n \"build-list\": [\n {\n \"identifier\": \"build_1\"\n }\n ]\n },\n \"phases\": {\n \"build\": {\n \"commands\": [\n \"echo \\\"Hello, CodeBuild!\\\"\"\n ]\n }\n }\n}",
"Type": "NO_SOURCE"
},
"BuildBatchConfig": {
"ServiceRole": {
"Fn::GetAtt": [
"MyProjectBatchServiceRole6B35CF0E",
"Arn"
]
}
},
"EncryptionKey": "alias/aws/s3"
}
}
}
}
35 changes: 35 additions & 0 deletions packages/@aws-cdk/aws-codebuild/test/integ.batch.lit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import * as cdk from '@aws-cdk/core';
import * as codebuild from '../lib';

class TestStack extends cdk.Stack {
constructor(scope: cdk.App, id: string) {
super(scope, id);

/// !show
new codebuild.Project(this, 'MyProject', {
supportBatchBuildType: true,
buildSpec: codebuild.BuildSpec.fromObject({
version: 0.2,
batch: {
'build-list': [
{ identifier: 'build_1' },
],
},
phases: {
build: {
commands: [
'echo "Hello, CodeBuild!"',
],
},
},
}),
});
/// !hide
}
}

const app = new cdk.App();

new TestStack(app, 'codebuild-default-project');

app.synth();
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,4 @@
}
}
}
}
}
Loading

0 comments on commit 8eade4c

Please sign in to comment.