Skip to content

Commit

Permalink
add enableBatchBuilds() and auto enable when needed
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Jenkinson committed Jan 18, 2021
1 parent 48617a2 commit a854534
Show file tree
Hide file tree
Showing 9 changed files with 371 additions and 58 deletions.
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-codebuild/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const gitHubSource = codebuild.Source.gitHub({
owner: 'awslabs',
repo: 'aws-cdk',
webhook: true, // optional, default: true if `webhookFilters` were provided, false otherwise
webhookTriggersBatchBuild: true, // optional, default is false. If true `supportBatchBuildType` required on project
webhookTriggersBatchBuild: true, // optional, default is false
webhookFilters: [
codebuild.FilterGroup
.inEventOf(codebuild.EventAction.PUSH)
Expand Down
75 changes: 59 additions & 16 deletions packages/@aws-cdk/aws-codebuild/lib/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ export interface IProject extends IResource, iam.IGrantable, ec2.IConnectable {
/** The IAM service Role of this Project. Undefined for imported Projects. */
readonly role?: iam.IRole;

/** The batch IAM service Role of this Project. Undefined for imported Projects or Projects that have not configured batch builds. */
readonly batchRole?: iam.IRole;

/**
* Enable batch builds.
*/
enableBatchBuilds(): void;

addToRolePolicy(policyStatement: iam.PolicyStatement): void;

/**
Expand Down Expand Up @@ -178,6 +186,9 @@ abstract class ProjectBase extends Resource implements IProject {
/** The IAM service Role of this Project. */
public abstract readonly role?: iam.IRole;

/** The IAM batch service Role of this Project. */
public abstract readonly batchRole?: iam.IRole;

/**
* Actual connections object for this Project.
* May be unset, in which case this Project is not configured to use a VPC.
Expand All @@ -196,6 +207,11 @@ abstract class ProjectBase extends Resource implements IProject {
return this._connections;
}

/**
* Enable batch builds.
*/
public abstract enableBatchBuilds(): void

/**
* Add a permission only if there's a policy attached.
* @param statement The permissions statement to add
Expand Down Expand Up @@ -624,11 +640,14 @@ export class Project extends ProjectBase {
public readonly projectArn = projectArn;
public readonly projectName = Stack.of(scope).parseArn(projectArn).resourceName!;
public readonly role?: iam.Role = undefined;
public readonly batchRole?: iam.Role = undefined;

constructor(s: Construct, i: string) {
super(s, i);
this.grantPrincipal = new iam.UnknownPrincipal({ resource: this });
}

public enableBatchBuilds(): void {}
}

return new Import(scope, id);
Expand All @@ -655,6 +674,7 @@ export class Project extends ProjectBase {
public readonly projectArn: string;
public readonly projectName: string;
public readonly role?: iam.Role = undefined;
public readonly batchRole?: iam.Role = undefined;

constructor(s: Construct, i: string) {
super(s, i);
Expand All @@ -668,6 +688,8 @@ export class Project extends ProjectBase {
this.grantPrincipal = new iam.UnknownPrincipal({ resource: this });
this.projectName = projectName;
}

public enableBatchBuilds(): void {}
}

return new Import(scope, id);
Expand Down Expand Up @@ -721,6 +743,13 @@ export class Project extends ProjectBase {
*/
public readonly role?: iam.IRole;

/**
* The batch IAM role for this project. May be undefined if batch builds have not been enabled.
*/
public get batchRole(): iam.IRole | undefined {
return this._batchServiceRole;
}

/**
* The ARN of the project.
*/
Expand All @@ -738,7 +767,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;
private _batchServiceRole?: iam.Role;

constructor(scope: Construct, id: string, props: ProjectProps) {
super(scope, id, {
Expand All @@ -752,13 +781,6 @@ export class Project extends ProjectBase {

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 @@ -831,9 +853,14 @@ 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,
buildBatchConfig: Lazy.any({
produce: () => {
const config: CfnProject.ProjectBuildBatchConfigProperty | undefined = this._batchServiceRole ? {
serviceRole: this._batchServiceRole.roleArn,
} : undefined;
return config;
},
}),
});

this.addVpcRequiredPermissions(props, resource);
Expand All @@ -845,11 +872,6 @@ 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 All @@ -872,13 +894,34 @@ export class Project extends ProjectBase {
this.encryptionKey = props.encryptionKey;
}

if (props.supportBatchBuildType) {
this.enableBatchBuilds();
}

// bind
const bindFunction = (this.buildImage as any).bind;
if (bindFunction) {
bindFunction.call(this.buildImage, this, this, {});
}
}

/**
* Enable batch builds.
*/
// TODO still have an option to call this at construction?
public enableBatchBuilds(): void {
if (this._batchServiceRole) return;

this._batchServiceRole = new iam.Role(this, 'BatchServiceRole', {
roleName: PhysicalName.GENERATE_IF_NEEDED,
assumedBy: new iam.ServicePrincipal('codebuild.amazonaws.com'),
});
this._batchServiceRole.addToPrincipalPolicy(new iam.PolicyStatement({
resources: [this.projectArn],
actions: ['codebuild:StartBuild', 'codebuild:StopBuild', 'codebuild:RetryBuild'],
}));
}

/**
* Adds a secondary source to the Project.
*
Expand Down
7 changes: 6 additions & 1 deletion packages/@aws-cdk/aws-codebuild/lib/source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ 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.
* Enabling this will enable batch builds on the CodeBuild project.
*
* @default false
*/
Expand Down Expand Up @@ -533,6 +533,11 @@ abstract class ThirdPartyGitSource extends GitSource {
}

const superConfig = super.bind(_scope, _project);

if (this.webhookTriggersBatchBuild) {
_project.enableBatchBuilds();
}

return {
sourceProperty: {
...superConfig.sourceProperty,
Expand Down
68 changes: 34 additions & 34 deletions packages/@aws-cdk/aws-codebuild/test/integ.batch.lit.expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,40 @@
]
}
},
"MyBatchProject0B8E069D": {
"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": [
"MyBatchProjectRole9252113B",
"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": [
"MyBatchProjectBatchServiceRole5EDFDEB9",
"Arn"
]
}
},
"EncryptionKey": "alias/aws/s3"
}
},
"MyBatchProjectBatchServiceRole5EDFDEB9": {
"Type": "AWS::IAM::Role",
"Properties": {
Expand Down Expand Up @@ -170,40 +204,6 @@
}
]
}
},
"MyBatchProject0B8E069D": {
"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": [
"MyBatchProjectRole9252113B",
"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": [
"MyBatchProjectBatchServiceRole5EDFDEB9",
"Arn"
]
}
},
"EncryptionKey": "alias/aws/s3"
}
}
}
}
Loading

0 comments on commit a854534

Please sign in to comment.