Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(aws-codebuild): add enableBatchBuilds() to Project #12531

Merged
merged 20 commits into from
Jan 26, 2021
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-codebuild/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ new codebuild.Project(this, 'MyProject', {
bucket,
path: 'path/to/file.zip',
}),
supportBatchBuildType: true // optional, default is false
});
```

Expand Down
84 changes: 76 additions & 8 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;
tjenkinson marked this conversation as resolved.
Show resolved Hide resolved

/**
* 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.
*/
tjenkinson marked this conversation as resolved.
Show resolved Hide resolved
public abstract enableBatchBuilds(): void
tjenkinson marked this conversation as resolved.
Show resolved Hide resolved

/**
* Add a permission only if there's a policy attached.
* @param statement The permissions statement to add
Expand Down Expand Up @@ -592,6 +608,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;
tjenkinson marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand All @@ -615,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 @@ -646,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 @@ -659,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 @@ -712,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 @@ -729,6 +767,7 @@ export class Project extends ProjectBase {
private readonly _secondaryArtifacts: CfnProject.ArtifactsProperty[];
private _encryptionKey?: kms.IKey;
private readonly _fileSystemLocations: CfnProject.ProjectFileSystemLocationProperty[];
private _batchServiceRole?: iam.Role;

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

this.grantPrincipal = this.role;

this.buildImage = (props.environment && props.environment.buildImage) || LinuxBuildImage.STANDARD_1_0;
Expand Down Expand Up @@ -813,6 +853,14 @@ export class Project extends ProjectBase {
sourceVersion: sourceConfig.sourceVersion,
vpcConfig: this.configureVpc(props),
logsConfig: this.renderLoggingConfiguration(props.logging),
buildBatchConfig: Lazy.any({
produce: () => {
const config: CfnProject.ProjectBuildBatchConfigProperty | undefined = this._batchServiceRole ? {
serviceRole: this._batchServiceRole.roleArn,
} : undefined;
return config;
},
}),
skinny85 marked this conversation as resolved.
Show resolved Hide resolved
});

this.addVpcRequiredPermissions(props, resource);
Expand Down Expand Up @@ -846,13 +894,33 @@ 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.
*/
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 Expand Up @@ -912,7 +980,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))) {
tjenkinson marked this conversation as resolved.
Show resolved Hide resolved
this.encryptionKey = options.artifactBucket.encryptionKey;
}
}
Expand Down Expand Up @@ -1139,8 +1207,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 +1289,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) &&
tjenkinson marked this conversation as resolved.
Show resolved Hide resolved
(sourceType !== artifactsType)) {
throw new Error('Both source and artifacts must be set to CodePipeline');
}
}
Expand Down Expand Up @@ -1350,10 +1418,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 +1445,7 @@ class ArmBuildImage implements IBuildImage {
public validate(buildEnvironment: BuildEnvironment): string[] {
const ret = [];
if (buildEnvironment.computeType &&
buildEnvironment.computeType !== ComputeType.LARGE) {
buildEnvironment.computeType !== ComputeType.LARGE) {
tjenkinson marked this conversation as resolved.
Show resolved Hide resolved
ret.push(`ARM images only support ComputeType '${ComputeType.LARGE}' - ` +
`'${buildEnvironment.computeType}' was given`);
}
Expand Down
7 changes: 7 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.
*
* Enabling this will enable batch builds on the CodeBuild project.
*
* @default false
*/
readonly webhookTriggersBatchBuild?: boolean;
Expand Down Expand Up @@ -531,6 +533,11 @@ abstract class ThirdPartyGitSource extends GitSource {
}

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

if (this.webhookTriggersBatchBuild) {
_project.enableBatchBuilds();
tjenkinson marked this conversation as resolved.
Show resolved Hide resolved
}

return {
sourceProperty: {
...superConfig.sourceProperty,
Expand Down
Loading