From 6f00783c4ffafe7a74609a76544232689b9cca1b Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Mon, 6 Apr 2020 15:36:50 +0200 Subject: [PATCH] fix(events): Batch target does not work (#7191) The AWS Batch Event Rule target recently added actually did not emit BatchParameters, and so did not work. Also, the permission set was wrong. Unclear why this passed integration test previously, maybe the service has added validation in the mean time. Fixes #7137. --- .../@aws-cdk/aws-events-targets/lib/batch.ts | 36 +-- .../test/batch/batch.test.ts | 46 +-- .../integ.job-definition-events.expected.json | 304 +++++++++--------- packages/@aws-cdk/aws-events/lib/rule.ts | 1 + 4 files changed, 189 insertions(+), 198 deletions(-) diff --git a/packages/@aws-cdk/aws-events-targets/lib/batch.ts b/packages/@aws-cdk/aws-events-targets/lib/batch.ts index b21f234b82cae..26e5de92dcd90 100644 --- a/packages/@aws-cdk/aws-events-targets/lib/batch.ts +++ b/packages/@aws-cdk/aws-events-targets/lib/batch.ts @@ -32,6 +32,13 @@ export interface BatchJobProps { * @default no retryStrategy is set */ readonly attempts?: number; + + /** + * The name of the submitted job + * + * @default - Automatically generated + */ + readonly jobName?: string; } /** @@ -49,33 +56,26 @@ export class BatchJob implements events.IRuleTarget { * 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 = { + public bind(rule: events.IRule, _id?: string): events.RuleTargetConfig { + const batchParameters: events.CfnRule.BatchParametersProperty = { jobDefinition: this.jobDefinition.jobDefinitionArn, - jobName: this.jobDefinition.jobDefinitionName + jobName: this.props.jobName ?? rule.node.uniqueId, + arrayProperties: this.props.size ? { size: this.props.size } : undefined, + retryStrategy: this.props.attempts ? { attempts: this.props.attempts } : undefined, }; - 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, + // When scoping resource-level access for job submission, you must provide both job queue and job definition resource types. + // https://docs.aws.amazon.com/batch/latest/userguide/ExamplePolicies_BATCH.html#iam-example-restrict-job-def role: singletonEventRole(this.jobDefinition, [ new iam.PolicyStatement({ actions: ['batch:SubmitJob'], - resources: [this.jobDefinition.jobDefinitionArn] + resources: [ + this.jobDefinition.jobDefinitionArn, + this.jobQueue.jobQueueArn, + ] }) ]), input: this.props.event, diff --git a/packages/@aws-cdk/aws-events-targets/test/batch/batch.test.ts b/packages/@aws-cdk/aws-events-targets/test/batch/batch.test.ts index a11fd2fd3cc77..cde0b9e87e7ff 100644 --- a/packages/@aws-cdk/aws-events-targets/test/batch/batch.test.ts +++ b/packages/@aws-cdk/aws-events-targets/test/batch/batch.test.ts @@ -45,35 +45,11 @@ test('use aws batch job as an eventrule target', () => { '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' - ] - ] + }, + BatchParameters: { + JobDefinition: { Ref: 'MyJob8719E923' }, + JobName: 'Rule' + }, } ] })); @@ -84,18 +60,16 @@ test('use aws batch job as an eventrule target', () => { { Action: 'batch:SubmitJob', Effect: 'Allow', - Resource: { - Ref: 'MyJob8719E923' - } + Resource: [ + { Ref: 'MyJob8719E923' }, + { Ref: 'MyQueueE6CA6235' } + ], } ], Version: '2012-10-17' }, - PolicyName: 'MyJobEventsRoleDefaultPolicy7266D3A7', Roles: [ - { - Ref: 'MyJobEventsRoleCF43C336' - } + { Ref: 'MyJobEventsRoleCF43C336' } ] })); }); diff --git a/packages/@aws-cdk/aws-events-targets/test/batch/integ.job-definition-events.expected.json b/packages/@aws-cdk/aws-events-targets/test/batch/integ.job-definition-events.expected.json index ca10cd8e713b9..9319f72814c38 100644 --- a/packages/@aws-cdk/aws-events-targets/test/batch/integ.job-definition-events.expected.json +++ b/packages/@aws-cdk/aws-events-targets/test/batch/integ.job-definition-events.expected.json @@ -1,163 +1,179 @@ { - "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": [ + "Resources": { + "ComputeEnvironmentResourceServiceInstanceRoleDC6D4445": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ { - "ComputeEnvironment": { - "Ref": "ComputeEnvironmentC570994D" - }, - "Order": 1 + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "batch.amazonaws.com" + } } ], - "Priority": 1, - "State": "ENABLED" - } - }, - "ComputeEnvironmentC570994D": { - "Type": "AWS::Batch::ComputeEnvironment", - "Properties": { - "ServiceRole": { - "Fn::GetAtt": [ - "ComputeEnvironmentResourceServiceInstanceRoleDC6D4445", - "Arn" + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSBatchServiceRole" + ] ] - }, - "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": [ + ] + } + }, + "ComputeEnvironmentC570994D": { + "Type": "AWS::Batch::ComputeEnvironment", + "Properties": { + "ServiceRole": { + "Fn::GetAtt": [ + "ComputeEnvironmentResourceServiceInstanceRoleDC6D4445", + "Arn" + ] + }, + "Type": "UNMANAGED", + "State": "ENABLED" + } + }, + "MyQueueE6CA6235": { + "Type": "AWS::Batch::JobQueue", + "Properties": { + "ComputeEnvironmentOrder": [ + { + "ComputeEnvironment": { + "Ref": "ComputeEnvironmentC570994D" + }, + "Order": 1 + } + ], + "Priority": 1, + "State": "ENABLED" + } + }, + "MyJob8719E923": { + "Type": "AWS::Batch::JobDefinition", + "Properties": { + "Type": "container", + "ContainerProperties": { + "Image": "test-repo", + "Memory": 4, + "Privileged": false, + "ReadonlyRootFilesystem": false, + "Vcpus": 1 + }, + "RetryStrategy": { + "Attempts": 1 + }, + "Timeout": {} + } + }, + "MyJobEventsRoleCF43C336": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSBatchServiceRole" - ] - ] + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + } } - ] + ], + "Version": "2012-10-17" } - }, - "MyJobEventsRoleDefaultPolicy7266D3A7": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": "batch:SubmitJob", - "Effect": "Allow", - "Resource": { + } + }, + "MyJobEventsRoleDefaultPolicy7266D3A7": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "batch:SubmitJob", + "Effect": "Allow", + "Resource": [ + { "Ref": "MyJob8719E923" + }, + { + "Ref": "MyQueueE6CA6235" } - } - ], - "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" + ], + "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" + }, + "BatchParameters": { + "JobDefinition": { + "Ref": "MyJob8719E923" }, - "Id": "Target0", - "RoleArn": { - "Fn::GetAtt": [ - "MyJobEventsRoleCF43C336", - "Arn" - ] - } + "JobName": "batcheventsTimer32212B30" + }, + "Id": "Target0", + "RoleArn": { + "Fn::GetAtt": [ + "MyJobEventsRoleCF43C336", + "Arn" + ] } - ] - } - }, - "Timer2B6F162E9": { - "Type": "AWS::Events::Rule", - "Properties": { - "ScheduleExpression": "rate(2 minutes)", - "State": "ENABLED", - "Targets": [ - { - "Arn": { - "Ref": "MyQueueE6CA6235" + } + ] + } + }, + "Timer2B6F162E9": { + "Type": "AWS::Events::Rule", + "Properties": { + "ScheduleExpression": "rate(2 minutes)", + "State": "ENABLED", + "Targets": [ + { + "Arn": { + "Ref": "MyQueueE6CA6235" + }, + "BatchParameters": { + "JobDefinition": { + "Ref": "MyJob8719E923" }, - "Id": "Target0", - "RoleArn": { - "Fn::GetAtt": [ - "MyJobEventsRoleCF43C336", - "Arn" - ] - } + "JobName": "batcheventsTimer232549135" + }, + "Id": "Target0", + "RoleArn": { + "Fn::GetAtt": [ + "MyJobEventsRoleCF43C336", + "Arn" + ] } - ] - } + } + ] } } } - \ No newline at end of file +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-events/lib/rule.ts b/packages/@aws-cdk/aws-events/lib/rule.ts index dc0a29277bab6..5272350296e1f 100644 --- a/packages/@aws-cdk/aws-events/lib/rule.ts +++ b/packages/@aws-cdk/aws-events/lib/rule.ts @@ -283,6 +283,7 @@ export class Rule extends Resource implements IRule { ecsParameters: targetProps.ecsParameters, kinesisParameters: targetProps.kinesisParameters, runCommandParameters: targetProps.runCommandParameters, + batchParameters: targetProps.batchParameters, sqsParameters: targetProps.sqsParameters, input: inputProps && inputProps.input, inputPath: inputProps && inputProps.inputPath,