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(stepfunctions-tasks): add support for CodeBuild StartBuild API #9757

Merged
merged 10 commits into from
Aug 21, 2020
41 changes: 41 additions & 0 deletions packages/@aws-cdk/aws-stepfunctions-tasks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aw
- [Evaluate Expression](#evaluate-expression)
- [Batch](#batch)
- [SubmitJob](#submitjob)
- [CodeBuild](#codebuild)
- [StartBuild](#startbuild)
- [DynamoDB](#dynamodb)
- [GetItem](#getitem)
- [PutItem](#putitem)
Expand Down Expand Up @@ -235,6 +237,45 @@ const task = new tasks.BatchSubmitJob(this, 'Submit Job', {
});
```

## CodeBuild

Step Functions supports [CodeBuild](https://docs.aws.amazon.com/step-functions/latest/dg/connect-codebuild.html) through the service integration pattern.

### StartBuild

[StartBuild](https://docs.aws.amazon.com/codebuild/latest/APIReference/API_StartBuild.html) starts a CodeBuild Project by Project Name.

```ts
import * as codebuild from '@aws-cdk/aws-codebuild';
import * as tasks from '@aws-cdk/aws-stepfunctions-tasks';
import * as sfn from '@aws-cdk/aws-stepfunctions';

const codebuildProject = new codebuild.Project(stack, 'Project', {
projectName: 'MyTestProject',
buildSpec: codebuild.BuildSpec.fromObject({
version: '0.2',
phases: {
build: {
commands: [
'echo "Hello, CodeBuild!"',
],
},
},
}),
});

const task = new tasks.CodeBuildStartBuild(stack, 'Task', {
project: codebuildProject,
integrationPattern: sfn.IntegrationPattern.RUN_JOB,
environmentVariablesOverride: {
ZONE: {
type: codebuild.BuildEnvironmentVariableType.PLAINTEXT,
value: sfn.JsonPath.stringAt('$.envVariables.zone'),
},
},
});
```

## DynamoDB

You can call DynamoDB APIs from a `Task` state.
Expand Down
109 changes: 109 additions & 0 deletions packages/@aws-cdk/aws-stepfunctions-tasks/lib/codebuild/start-build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import * as codebuild from '@aws-cdk/aws-codebuild';
import * as iam from '@aws-cdk/aws-iam';
import * as sfn from '@aws-cdk/aws-stepfunctions';
import * as cdk from '@aws-cdk/core';
import { integrationResourceArn, validatePatternSupported } from '../private/task-utils';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this file feels really large, can we break it down?
would any of this apply for StopBuild - if so we should start moving shared types out.

take a look at the EcsRunTask service integration for inspiration on how to break this down


/**
* Properties for CodeBuildStartBuild
*/
export interface CodeBuildStartBuildProps extends sfn.TaskStateBaseProps {
/**
* CodeBuild project to start
*/
readonly project: codebuild.IProject;
/**
* A set of environment variables to be used for this build only.
*
* @default - the latest environment variables already defined in the build project.
*/
readonly environmentVariablesOverride?: { [name: string]: codebuild.BuildEnvironmentVariable };
}

/**
* Start a CodeBuild Build as a task
*
* @see https://docs.aws.amazon.com/step-functions/latest/dg/connect-codebuild.html
*/
export class CodeBuildStartBuild extends sfn.TaskStateBase {
private static readonly SUPPORTED_INTEGRATION_PATTERNS: sfn.IntegrationPattern[] = [
sfn.IntegrationPattern.REQUEST_RESPONSE,
sfn.IntegrationPattern.RUN_JOB,
];

protected readonly taskMetrics?: sfn.TaskMetricsConfig;
protected readonly taskPolicies?: iam.PolicyStatement[];

private readonly integrationPattern: sfn.IntegrationPattern;

constructor(scope: cdk.Construct, id: string, private readonly props: CodeBuildStartBuildProps) {
super(scope, id, props);
this.integrationPattern = props.integrationPattern ?? sfn.IntegrationPattern.REQUEST_RESPONSE;

validatePatternSupported(this.integrationPattern, CodeBuildStartBuild.SUPPORTED_INTEGRATION_PATTERNS);

this.taskMetrics = {
metricPrefixSingular: 'CodeBuildProject',
metricPrefixPlural: 'CodeBuildProjects',
metricDimensions: {
ProjectArn: this.props.project.projectArn,
},
};

this.taskPolicies = this.configurePolicyStatements();
}

private configurePolicyStatements(): iam.PolicyStatement[] {
let policyStatements = [
new iam.PolicyStatement({
resources: [this.props.project.projectArn],
actions: [
'codebuild:StartBuild',
'codebuild:StopBuild',
],
}),
];

if (this.integrationPattern === sfn.IntegrationPattern.RUN_JOB) {
policyStatements.push(
new iam.PolicyStatement({
actions: ['events:PutTargets', 'events:PutRule', 'events:DescribeRule'],
resources: [
cdk.Stack.of(this).formatArn({
service: 'events',
resource: 'rule/StepFunctionsGetEventForCodeBuildStartBuildRule',
}),
],
}),
);
}

return policyStatements;
}

/**
* Provides the CodeBuild StartBuild service integration task configuration
*/
/**
* @internal
*/
protected _renderTask(): any {
DaWyz marked this conversation as resolved.
Show resolved Hide resolved
return {
Resource: integrationResourceArn('codebuild', 'startBuild', this.integrationPattern),
Parameters: sfn.FieldUtils.renderObject({
ProjectName: this.props.project.projectName,
EnvironmentVariablesOverride: this.props.environmentVariablesOverride
? this.serializeEnvVariables(this.props.environmentVariablesOverride)
: undefined,
}),
};
}

private serializeEnvVariables(environmentVariables: { [name: string]: codebuild.BuildEnvironmentVariable }) {
return Object.keys(environmentVariables).map(name => ({
Name: name,
Type: environmentVariables[name].type || codebuild.BuildEnvironmentVariableType.PLAINTEXT,
Value: environmentVariables[name].value,
}));
}
}
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-stepfunctions-tasks/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ export * from './dynamodb/put-item';
export * from './dynamodb/update-item';
export * from './dynamodb/delete-item';
export * from './dynamodb/shared-types';
export * from './codebuild/start-build';
2 changes: 2 additions & 0 deletions packages/@aws-cdk/aws-stepfunctions-tasks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"@aws-cdk/assets": "0.0.0",
"@aws-cdk/aws-batch": "0.0.0",
"@aws-cdk/aws-cloudwatch": "0.0.0",
"@aws-cdk/aws-codebuild": "0.0.0",
"@aws-cdk/aws-dynamodb": "0.0.0",
"@aws-cdk/aws-ec2": "0.0.0",
"@aws-cdk/aws-ecr": "0.0.0",
Expand All @@ -92,6 +93,7 @@
"@aws-cdk/assets": "0.0.0",
"@aws-cdk/aws-batch": "0.0.0",
"@aws-cdk/aws-cloudwatch": "0.0.0",
"@aws-cdk/aws-codebuild": "0.0.0",
"@aws-cdk/aws-dynamodb": "0.0.0",
"@aws-cdk/aws-ec2": "0.0.0",
"@aws-cdk/aws-ecr": "0.0.0",
Expand Down
Loading