Skip to content

Commit

Permalink
feat(events): AWS Batch event target (#6570)
Browse files Browse the repository at this point in the history
* add initial tests and constructure for batch job target

* add comments

* roll other pr into this one:

* Add experimental and remove yarn.lcok

* fix tests and update event target

* reset yarn.lock

* remove changes to yarn.lock

* revert yarn.lock

* fix yarn.lock

* add another readme update

* fix value setters

* Update batch.ts

* fix test

* fix integ test

* update tests

* Update package.json

Co-authored-by: Rico Huijbers <rix0rrr@gmail.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
3 people committed Mar 24, 2020
1 parent 1e92564 commit 73899a9
Show file tree
Hide file tree
Showing 9 changed files with 398 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-events-targets/README.md
Expand Up @@ -22,6 +22,7 @@ Currently supported are:
* Publish a message to an SNS topic
* Send a message to an SQS queue
* Start a StepFunctions state machine
* Queue a Batch job
* Make an AWS API call

See the README of the `@aws-cdk/aws-events` library for more information on
Expand Down
86 changes: 86 additions & 0 deletions packages/@aws-cdk/aws-events-targets/lib/batch.ts
@@ -0,0 +1,86 @@
import * as batch from '@aws-cdk/aws-batch';
import * as events from '@aws-cdk/aws-events';
import * as iam from '@aws-cdk/aws-iam';
import { singletonEventRole } from './util';

/**
* Customize the Batch Job Event Target
* @experimental
*/
export interface BatchJobProps {
/**
* The event to send to the Lambda
*
* This will be the payload sent to the Lambda Function.
*
* @default the entire CloudWatch event
*/
readonly event?: events.RuleTargetInput;

/**
* The size of the array, if this is an array batch job.
*
* Valid values are integers between 2 and 10,000.
*
* @default no arrayProperties are set
*/
readonly size?: number;

/**
* The number of times to attempt to retry, if the job fails. Valid values are 1–10.
*
* @default no retryStrategy is set
*/
readonly attempts?: number;
}

/**
* Use an AWS Batch Job / Queue as an event rule target.
* @experimental
*/
export class BatchJob implements events.IRuleTarget {
constructor(
private readonly jobQueue: batch.IJobQueue,
private readonly jobDefinition: batch.IJobDefinition,
private readonly props: BatchJobProps = {}
) { }

/**
* Returns a RuleTarget that can be used to trigger queue this batch job as a
* result from a CloudWatch event.
*/
public bind(_rule: events.IRule, _id?: string): events.RuleTargetConfig {
const baseBatchParameters: any = {
jobDefinition: this.jobDefinition.jobDefinitionArn,
jobName: this.jobDefinition.jobDefinitionName
};

if (this.props.size) {
baseBatchParameters.arrayProperties = {
size: this.props.size
};
}

if (this.props.attempts) {
baseBatchParameters.retryStrategy = {
attempts: this.props.attempts
};
}

const batchParameters: events.CfnRule.BatchParametersProperty = baseBatchParameters;

return {
id: '',
arn: this.jobQueue.jobQueueArn,
role: singletonEventRole(this.jobDefinition, [
new iam.PolicyStatement({
actions: ['batch:SubmitJob'],
resources: [this.jobDefinition.jobDefinitionArn]
})
]),
input: this.props.event,
targetResource: this.jobQueue,
batchParameters
};
}
}
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-events-targets/lib/index.ts
@@ -1,3 +1,4 @@
export * from './batch';
export * from './codepipeline';
export * from './sns';
export * from './sqs';
Expand Down
2 changes: 2 additions & 0 deletions packages/@aws-cdk/aws-events-targets/package.json
Expand Up @@ -106,6 +106,7 @@
"@aws-cdk/aws-sns-subscriptions": "0.0.0",
"@aws-cdk/aws-sqs": "0.0.0",
"@aws-cdk/aws-stepfunctions": "0.0.0",
"@aws-cdk/aws-batch": "0.0.0",
"@aws-cdk/core": "0.0.0",
"constructs": "^2.0.0"
},
Expand All @@ -123,6 +124,7 @@
"@aws-cdk/aws-sns-subscriptions": "0.0.0",
"@aws-cdk/aws-sqs": "0.0.0",
"@aws-cdk/aws-stepfunctions": "0.0.0",
"@aws-cdk/aws-batch": "0.0.0",
"@aws-cdk/core": "0.0.0",
"constructs": "^2.0.0"
},
Expand Down
101 changes: 101 additions & 0 deletions packages/@aws-cdk/aws-events-targets/test/batch/batch.test.ts
@@ -0,0 +1,101 @@
import { expect, haveResource } from '@aws-cdk/assert';
import * as batch from '@aws-cdk/aws-batch';
import { ContainerImage } from '@aws-cdk/aws-ecs';
import * as events from '@aws-cdk/aws-events';
import { Stack } from '@aws-cdk/core';
import * as targets from '../../lib';

test('use aws batch job as an eventrule target', () => {
// GIVEN
const stack = new Stack();
const jobQueue = new batch.JobQueue(stack, 'MyQueue', {
computeEnvironments: [
{
computeEnvironment: new batch.ComputeEnvironment(stack, 'ComputeEnvironment', {
managed: false
}),
order: 1
}
]
});
const jobDefinition = new batch.JobDefinition(stack, 'MyJob', {
container: {
image: ContainerImage.fromRegistry('test-repo')
}
});
const rule = new events.Rule(stack, 'Rule', {
schedule: events.Schedule.expression('rate(1 min)')
});

// WHEN
rule.addTarget(new targets.BatchJob(jobQueue, jobDefinition));

// THEN
expect(stack).to(haveResource('AWS::Events::Rule', {
ScheduleExpression: "rate(1 min)",
State: "ENABLED",
Targets: [
{
Arn: {
Ref: "MyQueueE6CA6235"
},
Id: "Target0",
RoleArn: {
"Fn::GetAtt": [
"MyJobEventsRoleCF43C336",
"Arn"
]
}
}
]
}));
expect(stack).to(haveResource('AWS::IAM::Role', {
AssumeRolePolicyDocument: {
Statement: [
{
Action: "sts:AssumeRole",
Effect: "Allow",
Principal: {
Service: "batch.amazonaws.com"
}
}
],
Version: "2012-10-17"
},
ManagedPolicyArns: [
{
"Fn::Join": [
"",
[
"arn:",
{
Ref: "AWS::Partition"
},
":iam::aws:policy/service-role/AWSBatchServiceRole"
]
]
}
]
}));

expect(stack).to(haveResource('AWS::IAM::Policy', {
PolicyDocument: {
Statement: [
{
Action: "batch:SubmitJob",
Effect: "Allow",
Resource: {
Ref: "MyJob8719E923"
}
}
],
Version: "2012-10-17"
},
PolicyName: "MyJobEventsRoleDefaultPolicy7266D3A7",
Roles: [
{
Ref: "MyJobEventsRoleCF43C336"
}
]
}));
});
@@ -0,0 +1,163 @@
{
"Resources": {
"MyJob8719E923": {
"Type": "AWS::Batch::JobDefinition",
"Properties": {
"ContainerProperties": {
"Image": "test-repo",
"Memory": 4,
"Privileged": false,
"ReadonlyRootFilesystem": false,
"Vcpus": 1
},
"RetryStrategy": {
"Attempts": 1
},
"Timeout": {},
"Type": "container"
}
},
"MyQueueE6CA6235": {
"Type": "AWS::Batch::JobQueue",
"Properties": {
"ComputeEnvironmentOrder": [
{
"ComputeEnvironment": {
"Ref": "ComputeEnvironmentC570994D"
},
"Order": 1
}
],
"Priority": 1,
"State": "ENABLED"
}
},
"ComputeEnvironmentC570994D": {
"Type": "AWS::Batch::ComputeEnvironment",
"Properties": {
"ServiceRole": {
"Fn::GetAtt": [
"ComputeEnvironmentResourceServiceInstanceRoleDC6D4445",
"Arn"
]
},
"State": "ENABLED",
"Type": "UNMANAGED"
}
},
"MyJobEventsRoleCF43C336": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
}
}
],
"Version": "2012-10-17"
}
}
},
"ComputeEnvironmentResourceServiceInstanceRoleDC6D4445": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "batch.amazonaws.com"
}
}
],
"Version": "2012-10-17"
},
"ManagedPolicyArns": [
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::aws:policy/service-role/AWSBatchServiceRole"
]
]
}
]
}
},
"MyJobEventsRoleDefaultPolicy7266D3A7": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": "batch:SubmitJob",
"Effect": "Allow",
"Resource": {
"Ref": "MyJob8719E923"
}
}
],
"Version": "2012-10-17"
},
"PolicyName": "MyJobEventsRoleDefaultPolicy7266D3A7",
"Roles": [
{
"Ref": "MyJobEventsRoleCF43C336"
}
]
}
},
"TimerBF6F831F": {
"Type": "AWS::Events::Rule",
"Properties": {
"ScheduleExpression": "rate(1 minute)",
"State": "ENABLED",
"Targets": [
{
"Arn": {
"Ref": "MyQueueE6CA6235"
},
"Id": "Target0",
"RoleArn": {
"Fn::GetAtt": [
"MyJobEventsRoleCF43C336",
"Arn"
]
}
}
]
}
},
"Timer2B6F162E9": {
"Type": "AWS::Events::Rule",
"Properties": {
"ScheduleExpression": "rate(2 minutes)",
"State": "ENABLED",
"Targets": [
{
"Arn": {
"Ref": "MyQueueE6CA6235"
},
"Id": "Target0",
"RoleArn": {
"Fn::GetAtt": [
"MyJobEventsRoleCF43C336",
"Arn"
]
}
}
]
}
}
}
}

0 comments on commit 73899a9

Please sign in to comment.