From b2ceb414c4b39d21df9ceb487a8b2cd2b61a4165 Mon Sep 17 00:00:00 2001 From: maz Date: Sun, 12 May 2024 01:26:15 +0900 Subject: [PATCH 01/22] feat: jobStateTimeLimitActions property added --- ...efaultTestDeployAssertE5BAAC9B.assets.json | 19 + ...aultTestDeployAssertE5BAAC9B.template.json | 36 + .../__entrypoint__.js | 155 +++ .../index.js | 1 + .../batch-stack-job-queue.assets.json | 32 + .../batch-stack-job-queue.template.json | 680 +++++++++++ .../cdk.out | 1 + .../integ.json | 12 + .../manifest.json | 293 +++++ .../tree.json | 1019 +++++++++++++++++ ....job-queue-job-state-time-limit-actions.ts | 44 + packages/aws-cdk-lib/aws-batch/README.md | 20 +- .../aws-cdk-lib/aws-batch/lib/job-queue.ts | 87 +- .../aws-batch/test/job-queue.test.ts | 79 +- 14 files changed, 2474 insertions(+), 4 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/asset.bde7b5c89cb43285f884c94f0b9e17cdb0f5eb5345005114dd60342e0b8a85a1/__entrypoint__.js create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/asset.bde7b5c89cb43285f884c94f0b9e17cdb0f5eb5345005114dd60342e0b8a85a1/index.js create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/batch-stack-job-queue.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/batch-stack-job-queue.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.assets.json new file mode 100644 index 0000000000000..0dee86e8f3ad8 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/asset.bde7b5c89cb43285f884c94f0b9e17cdb0f5eb5345005114dd60342e0b8a85a1/__entrypoint__.js b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/asset.bde7b5c89cb43285f884c94f0b9e17cdb0f5eb5345005114dd60342e0b8a85a1/__entrypoint__.js new file mode 100644 index 0000000000000..02033f55cf612 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/asset.bde7b5c89cb43285f884c94f0b9e17cdb0f5eb5345005114dd60342e0b8a85a1/__entrypoint__.js @@ -0,0 +1,155 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.withRetries = exports.handler = exports.external = void 0; +const https = require("https"); +const url = require("url"); +// for unit tests +exports.external = { + sendHttpRequest: defaultSendHttpRequest, + log: defaultLog, + includeStackTraces: true, + userHandlerIndex: './index', +}; +const CREATE_FAILED_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::CREATE_FAILED'; +const MISSING_PHYSICAL_ID_MARKER = 'AWSCDK::CustomResourceProviderFramework::MISSING_PHYSICAL_ID'; +async function handler(event, context) { + const sanitizedEvent = { ...event, ResponseURL: '...' }; + exports.external.log(JSON.stringify(sanitizedEvent, undefined, 2)); + // ignore DELETE event when the physical resource ID is the marker that + // indicates that this DELETE is a subsequent DELETE to a failed CREATE + // operation. + if (event.RequestType === 'Delete' && event.PhysicalResourceId === CREATE_FAILED_PHYSICAL_ID_MARKER) { + exports.external.log('ignoring DELETE event caused by a failed CREATE event'); + await submitResponse('SUCCESS', event); + return; + } + try { + // invoke the user handler. this is intentionally inside the try-catch to + // ensure that if there is an error it's reported as a failure to + // cloudformation (otherwise cfn waits). + // eslint-disable-next-line @typescript-eslint/no-require-imports + const userHandler = require(exports.external.userHandlerIndex).handler; + const result = await userHandler(sanitizedEvent, context); + // validate user response and create the combined event + const responseEvent = renderResponse(event, result); + // submit to cfn as success + await submitResponse('SUCCESS', responseEvent); + } + catch (e) { + const resp = { + ...event, + Reason: exports.external.includeStackTraces ? e.stack : e.message, + }; + if (!resp.PhysicalResourceId) { + // special case: if CREATE fails, which usually implies, we usually don't + // have a physical resource id. in this case, the subsequent DELETE + // operation does not have any meaning, and will likely fail as well. to + // address this, we use a marker so the provider framework can simply + // ignore the subsequent DELETE. + if (event.RequestType === 'Create') { + exports.external.log('CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored'); + resp.PhysicalResourceId = CREATE_FAILED_PHYSICAL_ID_MARKER; + } + else { + // otherwise, if PhysicalResourceId is not specified, something is + // terribly wrong because all other events should have an ID. + exports.external.log(`ERROR: Malformed event. "PhysicalResourceId" is required: ${JSON.stringify(event)}`); + } + } + // this is an actual error, fail the activity altogether and exist. + await submitResponse('FAILED', resp); + } +} +exports.handler = handler; +function renderResponse(cfnRequest, handlerResponse = {}) { + // if physical ID is not returned, we have some defaults for you based + // on the request type. + const physicalResourceId = handlerResponse.PhysicalResourceId ?? cfnRequest.PhysicalResourceId ?? cfnRequest.RequestId; + // if we are in DELETE and physical ID was changed, it's an error. + if (cfnRequest.RequestType === 'Delete' && physicalResourceId !== cfnRequest.PhysicalResourceId) { + throw new Error(`DELETE: cannot change the physical resource ID from "${cfnRequest.PhysicalResourceId}" to "${handlerResponse.PhysicalResourceId}" during deletion`); + } + // merge request event and result event (result prevails). + return { + ...cfnRequest, + ...handlerResponse, + PhysicalResourceId: physicalResourceId, + }; +} +async function submitResponse(status, event) { + const json = { + Status: status, + Reason: event.Reason ?? status, + StackId: event.StackId, + RequestId: event.RequestId, + PhysicalResourceId: event.PhysicalResourceId || MISSING_PHYSICAL_ID_MARKER, + LogicalResourceId: event.LogicalResourceId, + NoEcho: event.NoEcho, + Data: event.Data, + }; + const parsedUrl = url.parse(event.ResponseURL); + const loggingSafeUrl = `${parsedUrl.protocol}//${parsedUrl.hostname}/${parsedUrl.pathname}?***`; + exports.external.log('submit response to cloudformation', loggingSafeUrl, json); + const responseBody = JSON.stringify(json); + const req = { + hostname: parsedUrl.hostname, + path: parsedUrl.path, + method: 'PUT', + headers: { + 'content-type': '', + 'content-length': Buffer.byteLength(responseBody, 'utf8'), + }, + }; + const retryOptions = { + attempts: 5, + sleep: 1000, + }; + await withRetries(retryOptions, exports.external.sendHttpRequest)(req, responseBody); +} +async function defaultSendHttpRequest(options, requestBody) { + return new Promise((resolve, reject) => { + try { + const request = https.request(options, (response) => { + response.resume(); // Consume the response but don't care about it + if (!response.statusCode || response.statusCode >= 400) { + reject(new Error(`Unsuccessful HTTP response: ${response.statusCode}`)); + } + else { + resolve(); + } + }); + request.on('error', reject); + request.write(requestBody); + request.end(); + } + catch (e) { + reject(e); + } + }); +} +function defaultLog(fmt, ...params) { + // eslint-disable-next-line no-console + console.log(fmt, ...params); +} +function withRetries(options, fn) { + return async (...xs) => { + let attempts = options.attempts; + let ms = options.sleep; + while (true) { + try { + return await fn(...xs); + } + catch (e) { + if (attempts-- <= 0) { + throw e; + } + await sleep(Math.floor(Math.random() * ms)); + ms *= 2; + } + } + }; +} +exports.withRetries = withRetries; +async function sleep(ms) { + return new Promise((ok) => setTimeout(ok, ms)); +} diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/asset.bde7b5c89cb43285f884c94f0b9e17cdb0f5eb5345005114dd60342e0b8a85a1/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/asset.bde7b5c89cb43285f884c94f0b9e17cdb0f5eb5345005114dd60342e0b8a85a1/index.js new file mode 100644 index 0000000000000..013bcaffd8fe5 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/asset.bde7b5c89cb43285f884c94f0b9e17cdb0f5eb5345005114dd60342e0b8a85a1/index.js @@ -0,0 +1 @@ +"use strict";var I=Object.create;var t=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var G=(r,e)=>{for(var o in e)t(r,o,{get:e[o],enumerable:!0})},n=(r,e,o,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of P(e))!l.call(r,s)&&s!==o&&t(r,s,{get:()=>e[s],enumerable:!(i=y(e,s))||i.enumerable});return r};var R=(r,e,o)=>(o=r!=null?I(g(r)):{},n(e||!r||!r.__esModule?t(o,"default",{value:r,enumerable:!0}):o,r)),S=r=>n(t({},"__esModule",{value:!0}),r);var k={};G(k,{handler:()=>f});module.exports=S(k);var a=R(require("@aws-sdk/client-ec2")),u=new a.EC2({});function c(r,e){return{GroupId:r,IpPermissions:[{UserIdGroupPairs:[{GroupId:r,UserId:e}],IpProtocol:"-1"}]}}function d(r){return{GroupId:r,IpPermissions:[{IpRanges:[{CidrIp:"0.0.0.0/0"}],IpProtocol:"-1"}]}}async function f(r){let e=r.ResourceProperties.DefaultSecurityGroupId,o=r.ResourceProperties.Account;switch(r.RequestType){case"Create":return p(e,o);case"Update":return h(r);case"Delete":return m(e,o)}}async function h(r){let e=r.OldResourceProperties.DefaultSecurityGroupId,o=r.ResourceProperties.DefaultSecurityGroupId;e!==o&&(await m(e,r.ResourceProperties.Account),await p(o,r.ResourceProperties.Account))}async function p(r,e){try{await u.revokeSecurityGroupEgress(d(r))}catch(o){if(o.name!=="InvalidPermission.NotFound")throw o}try{await u.revokeSecurityGroupIngress(c(r,e))}catch(o){if(o.name!=="InvalidPermission.NotFound")throw o}}async function m(r,e){await u.authorizeSecurityGroupIngress(c(r,e)),await u.authorizeSecurityGroupEgress(d(r))}0&&(module.exports={handler}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/batch-stack-job-queue.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/batch-stack-job-queue.assets.json new file mode 100644 index 0000000000000..04b4061f5b7fb --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/batch-stack-job-queue.assets.json @@ -0,0 +1,32 @@ +{ + "version": "36.0.0", + "files": { + "bde7b5c89cb43285f884c94f0b9e17cdb0f5eb5345005114dd60342e0b8a85a1": { + "source": { + "path": "asset.bde7b5c89cb43285f884c94f0b9e17cdb0f5eb5345005114dd60342e0b8a85a1", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "bde7b5c89cb43285f884c94f0b9e17cdb0f5eb5345005114dd60342e0b8a85a1.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "cd1dbad52916ab85868e8674c87afe0b40a455f77d8064050cff52b1de2e252c": { + "source": { + "path": "batch-stack-job-queue.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "cd1dbad52916ab85868e8674c87afe0b40a455f77d8064050cff52b1de2e252c.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/batch-stack-job-queue.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/batch-stack-job-queue.template.json new file mode 100644 index 0000000000000..41ff9581ca5f3 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/batch-stack-job-queue.template.json @@ -0,0 +1,680 @@ +{ + "Resources": { + "vpcA2121C38": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "batch-stack-job-queue/vpc" + } + ] + } + }, + "vpcPublicSubnet1Subnet2E65531E": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.0.0/18", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "batch-stack-job-queue/vpc/PublicSubnet1" + } + ], + "VpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "vpcPublicSubnet1RouteTable48A2DF9B": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "batch-stack-job-queue/vpc/PublicSubnet1" + } + ], + "VpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "vpcPublicSubnet1RouteTableAssociation5D3F4579": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "vpcPublicSubnet1RouteTable48A2DF9B" + }, + "SubnetId": { + "Ref": "vpcPublicSubnet1Subnet2E65531E" + } + } + }, + "vpcPublicSubnet1DefaultRoute10708846": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "vpcIGWE57CBDCA" + }, + "RouteTableId": { + "Ref": "vpcPublicSubnet1RouteTable48A2DF9B" + } + }, + "DependsOn": [ + "vpcVPCGW7984C166" + ] + }, + "vpcPublicSubnet1EIPDA49DCBE": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "batch-stack-job-queue/vpc/PublicSubnet1" + } + ] + } + }, + "vpcPublicSubnet1NATGateway9C16659E": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "vpcPublicSubnet1EIPDA49DCBE", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "vpcPublicSubnet1Subnet2E65531E" + }, + "Tags": [ + { + "Key": "Name", + "Value": "batch-stack-job-queue/vpc/PublicSubnet1" + } + ] + }, + "DependsOn": [ + "vpcPublicSubnet1DefaultRoute10708846", + "vpcPublicSubnet1RouteTableAssociation5D3F4579" + ] + }, + "vpcPublicSubnet2Subnet009B674F": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.64.0/18", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "batch-stack-job-queue/vpc/PublicSubnet2" + } + ], + "VpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "vpcPublicSubnet2RouteTableEB40D4CB": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "batch-stack-job-queue/vpc/PublicSubnet2" + } + ], + "VpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "vpcPublicSubnet2RouteTableAssociation21F81B59": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "vpcPublicSubnet2RouteTableEB40D4CB" + }, + "SubnetId": { + "Ref": "vpcPublicSubnet2Subnet009B674F" + } + } + }, + "vpcPublicSubnet2DefaultRouteA1EC0F60": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "vpcIGWE57CBDCA" + }, + "RouteTableId": { + "Ref": "vpcPublicSubnet2RouteTableEB40D4CB" + } + }, + "DependsOn": [ + "vpcVPCGW7984C166" + ] + }, + "vpcPublicSubnet2EIP9B3743B1": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "batch-stack-job-queue/vpc/PublicSubnet2" + } + ] + } + }, + "vpcPublicSubnet2NATGateway9B8AE11A": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "vpcPublicSubnet2EIP9B3743B1", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "vpcPublicSubnet2Subnet009B674F" + }, + "Tags": [ + { + "Key": "Name", + "Value": "batch-stack-job-queue/vpc/PublicSubnet2" + } + ] + }, + "DependsOn": [ + "vpcPublicSubnet2DefaultRouteA1EC0F60", + "vpcPublicSubnet2RouteTableAssociation21F81B59" + ] + }, + "vpcPrivateSubnet1Subnet934893E8": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.128.0/18", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "batch-stack-job-queue/vpc/PrivateSubnet1" + } + ], + "VpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "vpcPrivateSubnet1RouteTableB41A48CC": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "batch-stack-job-queue/vpc/PrivateSubnet1" + } + ], + "VpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "vpcPrivateSubnet1RouteTableAssociation67945127": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "vpcPrivateSubnet1RouteTableB41A48CC" + }, + "SubnetId": { + "Ref": "vpcPrivateSubnet1Subnet934893E8" + } + } + }, + "vpcPrivateSubnet1DefaultRoute1AA8E2E5": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "vpcPublicSubnet1NATGateway9C16659E" + }, + "RouteTableId": { + "Ref": "vpcPrivateSubnet1RouteTableB41A48CC" + } + } + }, + "vpcPrivateSubnet2Subnet7031C2BA": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.192.0/18", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "batch-stack-job-queue/vpc/PrivateSubnet2" + } + ], + "VpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "vpcPrivateSubnet2RouteTable7280F23E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "batch-stack-job-queue/vpc/PrivateSubnet2" + } + ], + "VpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "vpcPrivateSubnet2RouteTableAssociation007E94D3": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "vpcPrivateSubnet2RouteTable7280F23E" + }, + "SubnetId": { + "Ref": "vpcPrivateSubnet2Subnet7031C2BA" + } + } + }, + "vpcPrivateSubnet2DefaultRouteB0E07F99": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "vpcPublicSubnet2NATGateway9B8AE11A" + }, + "RouteTableId": { + "Ref": "vpcPrivateSubnet2RouteTable7280F23E" + } + } + }, + "vpcIGWE57CBDCA": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "batch-stack-job-queue/vpc" + } + ] + } + }, + "vpcVPCGW7984C166": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "InternetGatewayId": { + "Ref": "vpcIGWE57CBDCA" + }, + "VpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "vpcRestrictDefaultSecurityGroupCustomResourceA6EBC6D0": { + "Type": "Custom::VpcRestrictDefaultSG", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "CustomVpcRestrictDefaultSGCustomResourceProviderHandlerDC833E5E", + "Arn" + ] + }, + "DefaultSecurityGroupId": { + "Fn::GetAtt": [ + "vpcA2121C38", + "DefaultSecurityGroup" + ] + }, + "Account": { + "Ref": "AWS::AccountId" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "CustomVpcRestrictDefaultSGCustomResourceProviderRole26592FE0": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ] + }, + "ManagedPolicyArns": [ + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + } + ], + "Policies": [ + { + "PolicyName": "Inline", + "PolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:AuthorizeSecurityGroupEgress", + "ec2:RevokeSecurityGroupIngress", + "ec2:RevokeSecurityGroupEgress" + ], + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":ec2:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":security-group/", + { + "Fn::GetAtt": [ + "vpcA2121C38", + "DefaultSecurityGroup" + ] + } + ] + ] + } + ] + } + ] + } + } + ] + } + }, + "CustomVpcRestrictDefaultSGCustomResourceProviderHandlerDC833E5E": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "bde7b5c89cb43285f884c94f0b9e17cdb0f5eb5345005114dd60342e0b8a85a1.zip" + }, + "Timeout": 900, + "MemorySize": 128, + "Handler": "__entrypoint__.handler", + "Role": { + "Fn::GetAtt": [ + "CustomVpcRestrictDefaultSGCustomResourceProviderRole26592FE0", + "Arn" + ] + }, + "Runtime": "nodejs18.x", + "Description": "Lambda function for removing all inbound/outbound rules from the VPC default security group" + }, + "DependsOn": [ + "CustomVpcRestrictDefaultSGCustomResourceProviderRole26592FE0" + ] + }, + "CESecurityGroup6653FE7C": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "batch-stack-job-queue/CE/SecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "CEInstanceProfileRoleB7AE11E8": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" + ] + ] + } + ] + } + }, + "CEInstanceProfileF34B754D": { + "Type": "AWS::IAM::InstanceProfile", + "Properties": { + "Roles": [ + { + "Ref": "CEInstanceProfileRoleB7AE11E8" + } + ] + } + }, + "CE1BFE03A1": { + "Type": "AWS::Batch::ComputeEnvironment", + "Properties": { + "ComputeResources": { + "AllocationStrategy": "BEST_FIT_PROGRESSIVE", + "InstanceRole": { + "Fn::GetAtt": [ + "CEInstanceProfileF34B754D", + "Arn" + ] + }, + "InstanceTypes": [ + "optimal" + ], + "MaxvCpus": 256, + "MinvCpus": 0, + "SecurityGroupIds": [ + { + "Fn::GetAtt": [ + "CESecurityGroup6653FE7C", + "GroupId" + ] + } + ], + "Subnets": [ + { + "Ref": "vpcPrivateSubnet1Subnet934893E8" + }, + { + "Ref": "vpcPrivateSubnet2Subnet7031C2BA" + } + ], + "Type": "EC2" + }, + "ReplaceComputeEnvironment": false, + "State": "ENABLED", + "Type": "managed", + "UpdatePolicy": {} + } + }, + "joBBQ9FD52DAF": { + "Type": "AWS::Batch::JobQueue", + "Properties": { + "ComputeEnvironmentOrder": [ + { + "ComputeEnvironment": { + "Fn::GetAtt": [ + "CE1BFE03A1", + "ComputeEnvironmentArn" + ] + }, + "Order": 1 + } + ], + "JobStateTimeLimitActions": [ + { + "Action": "CANCEL", + "MaxTimeSeconds": 600, + "Reason": "CAPACITY:INSUFFICIENT_INSTANCE_CAPACITY", + "State": "RUNNABLE" + }, + { + "Action": "CANCEL", + "MaxTimeSeconds": 600, + "Reason": "MISCONFIGURATION:COMPUTE_ENVIRONMENT_MAX_RESOURCE", + "State": "RUNNABLE" + }, + { + "Action": "CANCEL", + "MaxTimeSeconds": 600, + "Reason": "MISCONFIGURATION:JOB_RESOURCE_REQUIREMENT", + "State": "RUNNABLE" + } + ], + "Priority": 1, + "State": "ENABLED" + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/cdk.out new file mode 100644 index 0000000000000..1f0068d32659a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/integ.json new file mode 100644 index 0000000000000..cb4b16b555a53 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "36.0.0", + "testCases": { + "BatchEcsJobDefinitionTest/DefaultTest": { + "stacks": [ + "batch-stack-job-queue" + ], + "assertionStack": "BatchEcsJobDefinitionTest/DefaultTest/DeployAssert", + "assertionStackName": "BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/manifest.json new file mode 100644 index 0000000000000..577cae95ce233 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/manifest.json @@ -0,0 +1,293 @@ +{ + "version": "36.0.0", + "artifacts": { + "batch-stack-job-queue.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "batch-stack-job-queue.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "batch-stack-job-queue": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "batch-stack-job-queue.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/cd1dbad52916ab85868e8674c87afe0b40a455f77d8064050cff52b1de2e252c.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "batch-stack-job-queue.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "batch-stack-job-queue.assets" + ], + "metadata": { + "/batch-stack-job-queue/vpc/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcA2121C38" + } + ], + "/batch-stack-job-queue/vpc/PublicSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPublicSubnet1Subnet2E65531E" + } + ], + "/batch-stack-job-queue/vpc/PublicSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPublicSubnet1RouteTable48A2DF9B" + } + ], + "/batch-stack-job-queue/vpc/PublicSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPublicSubnet1RouteTableAssociation5D3F4579" + } + ], + "/batch-stack-job-queue/vpc/PublicSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPublicSubnet1DefaultRoute10708846" + } + ], + "/batch-stack-job-queue/vpc/PublicSubnet1/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPublicSubnet1EIPDA49DCBE" + } + ], + "/batch-stack-job-queue/vpc/PublicSubnet1/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPublicSubnet1NATGateway9C16659E" + } + ], + "/batch-stack-job-queue/vpc/PublicSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPublicSubnet2Subnet009B674F" + } + ], + "/batch-stack-job-queue/vpc/PublicSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPublicSubnet2RouteTableEB40D4CB" + } + ], + "/batch-stack-job-queue/vpc/PublicSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPublicSubnet2RouteTableAssociation21F81B59" + } + ], + "/batch-stack-job-queue/vpc/PublicSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPublicSubnet2DefaultRouteA1EC0F60" + } + ], + "/batch-stack-job-queue/vpc/PublicSubnet2/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPublicSubnet2EIP9B3743B1" + } + ], + "/batch-stack-job-queue/vpc/PublicSubnet2/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPublicSubnet2NATGateway9B8AE11A" + } + ], + "/batch-stack-job-queue/vpc/PrivateSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPrivateSubnet1Subnet934893E8" + } + ], + "/batch-stack-job-queue/vpc/PrivateSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPrivateSubnet1RouteTableB41A48CC" + } + ], + "/batch-stack-job-queue/vpc/PrivateSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPrivateSubnet1RouteTableAssociation67945127" + } + ], + "/batch-stack-job-queue/vpc/PrivateSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPrivateSubnet1DefaultRoute1AA8E2E5" + } + ], + "/batch-stack-job-queue/vpc/PrivateSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPrivateSubnet2Subnet7031C2BA" + } + ], + "/batch-stack-job-queue/vpc/PrivateSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPrivateSubnet2RouteTable7280F23E" + } + ], + "/batch-stack-job-queue/vpc/PrivateSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPrivateSubnet2RouteTableAssociation007E94D3" + } + ], + "/batch-stack-job-queue/vpc/PrivateSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcPrivateSubnet2DefaultRouteB0E07F99" + } + ], + "/batch-stack-job-queue/vpc/IGW": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcIGWE57CBDCA" + } + ], + "/batch-stack-job-queue/vpc/VPCGW": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcVPCGW7984C166" + } + ], + "/batch-stack-job-queue/vpc/RestrictDefaultSecurityGroupCustomResource/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "vpcRestrictDefaultSecurityGroupCustomResourceA6EBC6D0" + } + ], + "/batch-stack-job-queue/Custom::VpcRestrictDefaultSGCustomResourceProvider/Role": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomVpcRestrictDefaultSGCustomResourceProviderRole26592FE0" + } + ], + "/batch-stack-job-queue/Custom::VpcRestrictDefaultSGCustomResourceProvider/Handler": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomVpcRestrictDefaultSGCustomResourceProviderHandlerDC833E5E" + } + ], + "/batch-stack-job-queue/CE/SecurityGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "CESecurityGroup6653FE7C" + } + ], + "/batch-stack-job-queue/CE/InstanceProfileRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "CEInstanceProfileRoleB7AE11E8" + } + ], + "/batch-stack-job-queue/CE/InstanceProfile": [ + { + "type": "aws:cdk:logicalId", + "data": "CEInstanceProfileF34B754D" + } + ], + "/batch-stack-job-queue/CE/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "CE1BFE03A1" + } + ], + "/batch-stack-job-queue/joBBQ/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "joBBQ9FD52DAF" + } + ], + "/batch-stack-job-queue/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/batch-stack-job-queue/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "batch-stack-job-queue" + }, + "BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "BatchEcsJobDefinitionTestDefaultTestDeployAssertE5BAAC9B.assets" + ], + "metadata": { + "/BatchEcsJobDefinitionTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/BatchEcsJobDefinitionTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "BatchEcsJobDefinitionTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/tree.json new file mode 100644 index 0000000000000..3cc8d8a4a0f7b --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.js.snapshot/tree.json @@ -0,0 +1,1019 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "batch-stack-job-queue": { + "id": "batch-stack-job-queue", + "path": "batch-stack-job-queue", + "children": { + "vpc": { + "id": "vpc", + "path": "batch-stack-job-queue/vpc", + "children": { + "Resource": { + "id": "Resource", + "path": "batch-stack-job-queue/vpc/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPC", + "aws:cdk:cloudformation:props": { + "cidrBlock": "10.0.0.0/16", + "enableDnsHostnames": true, + "enableDnsSupport": true, + "instanceTenancy": "default", + "tags": [ + { + "key": "Name", + "value": "batch-stack-job-queue/vpc" + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "PublicSubnet1": { + "id": "PublicSubnet1", + "path": "batch-stack-job-queue/vpc/PublicSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "batch-stack-job-queue/vpc/PublicSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.0.0/18", + "mapPublicIpOnLaunch": true, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "batch-stack-job-queue/vpc/PublicSubnet1" + } + ], + "vpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Acl": { + "id": "Acl", + "path": "batch-stack-job-queue/vpc/PublicSubnet1/Acl", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "batch-stack-job-queue/vpc/PublicSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "batch-stack-job-queue/vpc/PublicSubnet1" + } + ], + "vpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "batch-stack-job-queue/vpc/PublicSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "vpcPublicSubnet1RouteTable48A2DF9B" + }, + "subnetId": { + "Ref": "vpcPublicSubnet1Subnet2E65531E" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "batch-stack-job-queue/vpc/PublicSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "vpcIGWE57CBDCA" + }, + "routeTableId": { + "Ref": "vpcPublicSubnet1RouteTable48A2DF9B" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "EIP": { + "id": "EIP", + "path": "batch-stack-job-queue/vpc/PublicSubnet1/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "batch-stack-job-queue/vpc/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "batch-stack-job-queue/vpc/PublicSubnet1/NATGateway", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", + "aws:cdk:cloudformation:props": { + "allocationId": { + "Fn::GetAtt": [ + "vpcPublicSubnet1EIPDA49DCBE", + "AllocationId" + ] + }, + "subnetId": { + "Ref": "vpcPublicSubnet1Subnet2E65531E" + }, + "tags": [ + { + "key": "Name", + "value": "batch-stack-job-queue/vpc/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "PublicSubnet2": { + "id": "PublicSubnet2", + "path": "batch-stack-job-queue/vpc/PublicSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "batch-stack-job-queue/vpc/PublicSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.64.0/18", + "mapPublicIpOnLaunch": true, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "batch-stack-job-queue/vpc/PublicSubnet2" + } + ], + "vpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Acl": { + "id": "Acl", + "path": "batch-stack-job-queue/vpc/PublicSubnet2/Acl", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "batch-stack-job-queue/vpc/PublicSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "batch-stack-job-queue/vpc/PublicSubnet2" + } + ], + "vpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "batch-stack-job-queue/vpc/PublicSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "vpcPublicSubnet2RouteTableEB40D4CB" + }, + "subnetId": { + "Ref": "vpcPublicSubnet2Subnet009B674F" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "batch-stack-job-queue/vpc/PublicSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "vpcIGWE57CBDCA" + }, + "routeTableId": { + "Ref": "vpcPublicSubnet2RouteTableEB40D4CB" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "EIP": { + "id": "EIP", + "path": "batch-stack-job-queue/vpc/PublicSubnet2/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "batch-stack-job-queue/vpc/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "batch-stack-job-queue/vpc/PublicSubnet2/NATGateway", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", + "aws:cdk:cloudformation:props": { + "allocationId": { + "Fn::GetAtt": [ + "vpcPublicSubnet2EIP9B3743B1", + "AllocationId" + ] + }, + "subnetId": { + "Ref": "vpcPublicSubnet2Subnet009B674F" + }, + "tags": [ + { + "key": "Name", + "value": "batch-stack-job-queue/vpc/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "PrivateSubnet1": { + "id": "PrivateSubnet1", + "path": "batch-stack-job-queue/vpc/PrivateSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "batch-stack-job-queue/vpc/PrivateSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.128.0/18", + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Private" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Private" + }, + { + "key": "Name", + "value": "batch-stack-job-queue/vpc/PrivateSubnet1" + } + ], + "vpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Acl": { + "id": "Acl", + "path": "batch-stack-job-queue/vpc/PrivateSubnet1/Acl", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "batch-stack-job-queue/vpc/PrivateSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "batch-stack-job-queue/vpc/PrivateSubnet1" + } + ], + "vpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "batch-stack-job-queue/vpc/PrivateSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "vpcPrivateSubnet1RouteTableB41A48CC" + }, + "subnetId": { + "Ref": "vpcPrivateSubnet1Subnet934893E8" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "batch-stack-job-queue/vpc/PrivateSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "vpcPublicSubnet1NATGateway9C16659E" + }, + "routeTableId": { + "Ref": "vpcPrivateSubnet1RouteTableB41A48CC" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "PrivateSubnet2": { + "id": "PrivateSubnet2", + "path": "batch-stack-job-queue/vpc/PrivateSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "batch-stack-job-queue/vpc/PrivateSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.192.0/18", + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Private" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Private" + }, + { + "key": "Name", + "value": "batch-stack-job-queue/vpc/PrivateSubnet2" + } + ], + "vpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Acl": { + "id": "Acl", + "path": "batch-stack-job-queue/vpc/PrivateSubnet2/Acl", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "batch-stack-job-queue/vpc/PrivateSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "batch-stack-job-queue/vpc/PrivateSubnet2" + } + ], + "vpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "batch-stack-job-queue/vpc/PrivateSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "vpcPrivateSubnet2RouteTable7280F23E" + }, + "subnetId": { + "Ref": "vpcPrivateSubnet2Subnet7031C2BA" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "batch-stack-job-queue/vpc/PrivateSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "vpcPublicSubnet2NATGateway9B8AE11A" + }, + "routeTableId": { + "Ref": "vpcPrivateSubnet2RouteTable7280F23E" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "IGW": { + "id": "IGW", + "path": "batch-stack-job-queue/vpc/IGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::InternetGateway", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "batch-stack-job-queue/vpc" + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "VPCGW": { + "id": "VPCGW", + "path": "batch-stack-job-queue/vpc/VPCGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", + "aws:cdk:cloudformation:props": { + "internetGatewayId": { + "Ref": "vpcIGWE57CBDCA" + }, + "vpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "RestrictDefaultSecurityGroupCustomResource": { + "id": "RestrictDefaultSecurityGroupCustomResource", + "path": "batch-stack-job-queue/vpc/RestrictDefaultSecurityGroupCustomResource", + "children": { + "Default": { + "id": "Default", + "path": "batch-stack-job-queue/vpc/RestrictDefaultSecurityGroupCustomResource/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Custom::VpcRestrictDefaultSGCustomResourceProvider": { + "id": "Custom::VpcRestrictDefaultSGCustomResourceProvider", + "path": "batch-stack-job-queue/Custom::VpcRestrictDefaultSGCustomResourceProvider", + "children": { + "Staging": { + "id": "Staging", + "path": "batch-stack-job-queue/Custom::VpcRestrictDefaultSGCustomResourceProvider/Staging", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Role": { + "id": "Role", + "path": "batch-stack-job-queue/Custom::VpcRestrictDefaultSGCustomResourceProvider/Role", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Handler": { + "id": "Handler", + "path": "batch-stack-job-queue/Custom::VpcRestrictDefaultSGCustomResourceProvider/Handler", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "CE": { + "id": "CE", + "path": "batch-stack-job-queue/CE", + "children": { + "SecurityGroup": { + "id": "SecurityGroup", + "path": "batch-stack-job-queue/CE/SecurityGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "batch-stack-job-queue/CE/SecurityGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "batch-stack-job-queue/CE/SecurityGroup", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "vpcId": { + "Ref": "vpcA2121C38" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "InstanceProfileRole": { + "id": "InstanceProfileRole", + "path": "batch-stack-job-queue/CE/InstanceProfileRole", + "children": { + "ImportInstanceProfileRole": { + "id": "ImportInstanceProfileRole", + "path": "batch-stack-job-queue/CE/InstanceProfileRole/ImportInstanceProfileRole", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Resource": { + "id": "Resource", + "path": "batch-stack-job-queue/CE/InstanceProfileRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "InstanceProfile": { + "id": "InstanceProfile", + "path": "batch-stack-job-queue/CE/InstanceProfile", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::InstanceProfile", + "aws:cdk:cloudformation:props": { + "roles": [ + { + "Ref": "CEInstanceProfileRoleB7AE11E8" + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Resource": { + "id": "Resource", + "path": "batch-stack-job-queue/CE/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Batch::ComputeEnvironment", + "aws:cdk:cloudformation:props": { + "computeResources": { + "maxvCpus": 256, + "type": "EC2", + "securityGroupIds": [ + { + "Fn::GetAtt": [ + "CESecurityGroup6653FE7C", + "GroupId" + ] + } + ], + "subnets": [ + { + "Ref": "vpcPrivateSubnet1Subnet934893E8" + }, + { + "Ref": "vpcPrivateSubnet2Subnet7031C2BA" + } + ], + "minvCpus": 0, + "instanceRole": { + "Fn::GetAtt": [ + "CEInstanceProfileF34B754D", + "Arn" + ] + }, + "instanceTypes": [ + "optimal" + ], + "allocationStrategy": "BEST_FIT_PROGRESSIVE" + }, + "replaceComputeEnvironment": false, + "state": "ENABLED", + "type": "managed", + "updatePolicy": {} + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "joBBQ": { + "id": "joBBQ", + "path": "batch-stack-job-queue/joBBQ", + "children": { + "Resource": { + "id": "Resource", + "path": "batch-stack-job-queue/joBBQ/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Batch::JobQueue", + "aws:cdk:cloudformation:props": { + "computeEnvironmentOrder": [ + { + "computeEnvironment": { + "Fn::GetAtt": [ + "CE1BFE03A1", + "ComputeEnvironmentArn" + ] + }, + "order": 1 + } + ], + "jobStateTimeLimitActions": [ + { + "action": "CANCEL", + "maxTimeSeconds": 600, + "reason": "CAPACITY:INSUFFICIENT_INSTANCE_CAPACITY", + "state": "RUNNABLE" + }, + { + "action": "CANCEL", + "maxTimeSeconds": 600, + "reason": "MISCONFIGURATION:COMPUTE_ENVIRONMENT_MAX_RESOURCE", + "state": "RUNNABLE" + }, + { + "action": "CANCEL", + "maxTimeSeconds": 600, + "reason": "MISCONFIGURATION:JOB_RESOURCE_REQUIREMENT", + "state": "RUNNABLE" + } + ], + "priority": 1, + "state": "ENABLED" + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "batch-stack-job-queue/BootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "batch-stack-job-queue/CheckBootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "BatchEcsJobDefinitionTest": { + "id": "BatchEcsJobDefinitionTest", + "path": "BatchEcsJobDefinitionTest", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "BatchEcsJobDefinitionTest/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "BatchEcsJobDefinitionTest/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "BatchEcsJobDefinitionTest/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "BatchEcsJobDefinitionTest/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "BatchEcsJobDefinitionTest/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.ts new file mode 100644 index 0000000000000..9dd1fdc743d2c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.ts @@ -0,0 +1,44 @@ +import { Vpc } from 'aws-cdk-lib/aws-ec2'; +import { App, Stack, Duration } from 'aws-cdk-lib/core'; +import * as integ from '@aws-cdk/integ-tests-alpha'; +import * as batch from 'aws-cdk-lib/aws-batch'; + +const app = new App(); +const stack = new Stack(app, 'batch-stack-job-queue'); +const vpc = new Vpc(stack, 'vpc'); + +// WHEN +new batch.JobQueue(stack, 'joBBQ', { + computeEnvironments: [{ + computeEnvironment: new batch.ManagedEc2EcsComputeEnvironment(stack, 'CE', { + vpc, + }), + order: 1, + }], + jobStateTimeLimitActions: [ + { + action: batch.JobStateTimeLimitActionsAction.CANCEL, + maxTimeSeconds: Duration.minutes(10), + reason: batch.JobStateTimeLimitActionsReason.INSUFFICIENT_INSTANCE_CAPACITY, + state: batch.JobStateTimeLimitActionsState.RUNNABLE, + }, + { + action: batch.JobStateTimeLimitActionsAction.CANCEL, + maxTimeSeconds: Duration.minutes(10), + reason: batch.JobStateTimeLimitActionsReason.COMPUTE_ENVIRONMENT_MAX_RESOURCE, + state: batch.JobStateTimeLimitActionsState.RUNNABLE, + }, + { + action: batch.JobStateTimeLimitActionsAction.CANCEL, + maxTimeSeconds: Duration.minutes(10), + reason: batch.JobStateTimeLimitActionsReason.JOB_RESOURCE_REQUIREMENT, + state: batch.JobStateTimeLimitActionsState.RUNNABLE, + }, + ], +}); + +new integ.IntegTest(app, 'BatchEcsJobDefinitionTest', { + testCases: [stack], +}); + +app.synth(); diff --git a/packages/aws-cdk-lib/aws-batch/README.md b/packages/aws-cdk-lib/aws-batch/README.md index 1a2acd741c867..a7d56e02767e9 100644 --- a/packages/aws-cdk-lib/aws-batch/README.md +++ b/packages/aws-cdk-lib/aws-batch/README.md @@ -178,7 +178,7 @@ const computeEnv = new batch.ManagedEc2EcsComputeEnvironment(this, 'myEc2Compute You can specify the maximum and minimum vCPUs a managed `ComputeEnvironment` can have at any given time. Batch will *always* maintain `minvCpus` worth of instances in your ComputeEnvironment, even if it is not executing any jobs, and even if it is disabled. Batch will scale the instances up to `maxvCpus` worth of instances as -jobs exit the JobQueue and enter the ComputeEnvironment. If you use `AllocationStrategy.BEST_FIT_PROGRESSIVE`, +jobs exit the JobQueue and enter the ComputeEnvironment. If you use `AllocationStrategy.BEST_FIT_PROGRESSIVE`, `AllocationStrategy.SPOT_PRICE_CAPACITY_OPTIMIZED`, or `AllocationStrategy.SPOT_CAPACITY_OPTIMIZED`, batch may exceed `maxvCpus`; it will never exceed `maxvCpus` by more than a single instance type. This example configures a `minvCpus` of 10 and a `maxvCpus` of 100: @@ -234,6 +234,24 @@ lowPriorityQueue.addComputeEnvironment(sharedComputeEnv, 1); highPriorityQueue.addComputeEnvironment(sharedComputeEnv, 1); ``` +### React to jobs stuck in RUNNABLE state +You can react to jobs stuck in RUNNABLE state by setting a `jobStateTimeLimitActions` in `JobQueue`. +Specifies an action that AWS Batch will take after the job has remained at the head of the queue in the +specified state for longer than the specified time. + +```ts +new batch.JobQueue(this, 'JobQueue', { + jobStateTimeLimitActions: [ + { + action: JobStateTimeLimitActionsAction.CANCEL, + maxTimeSeconds: Duration.minutes(10), + reason: JobStateTimeLimitActionsReason.INSUFFICIENT_INSTANCE_CAPACITY, + state: JobStateTimeLimitActionsState.RUNNABLE, + }, + ] +}); +``` + ### Fairshare Scheduling Batch `JobQueue`s execute Jobs submitted to them in FIFO order unless you specify a `SchedulingPolicy`. diff --git a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts index 1d2a8c73d74d9..3ebc6c8691c81 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts @@ -2,7 +2,7 @@ import { Construct } from 'constructs'; import { CfnJobQueue } from './batch.generated'; import { IComputeEnvironment } from './compute-environment-base'; import { ISchedulingPolicy } from './scheduling-policy'; -import { ArnFormat, IResource, Lazy, Resource, Stack } from '../../core'; +import { ArnFormat, Duration, IResource, Lazy, Resource, Stack } from '../../core'; /** * Represents a JobQueue @@ -117,6 +117,14 @@ export interface JobQueueProps { * @default - no scheduling policy */ readonly schedulingPolicy?: ISchedulingPolicy; + + /** + * Specifies an action that AWS Batch will take after the job has remained at the head of the queue + * in the specified state for longer than the specified time. + * + * @default - no actions set + */ + readonly jobStateTimeLimitActions?: JobStateTimeLimitAction[]; } /** @@ -135,6 +143,62 @@ export interface OrderedComputeEnvironment { readonly order: number; } +/** + * Specifies an action that AWS Batch will take after the job has remained at + * the head of the queue in the specified state for longer than the specified time. + */ + +export interface JobStateTimeLimitAction { + /** + * The action to take when a job is at the head of the job queue in the specified state + * for the specified period of time. + */ + readonly action: JobStateTimeLimitActionsAction; + + /** + * The approximate amount of time, in seconds, that must pass with the job in the specified + * state before the action is taken. + * The minimum value is 600 (10 minutes) and the maximum value is 86,400 (24 hours). + */ + readonly maxTimeSeconds: Duration; + + /** + * The reason to log for the action being taken. + * @see https://docs.aws.amazon.com/batch/latest/userguide/troubleshooting.html#job_stuck_in_runnable + */ + readonly reason: JobStateTimeLimitActionsReason; + + /** + * The state of the job needed to trigger the action. + */ + readonly state: JobStateTimeLimitActionsState; +} + +/** + * The action to take when a job is at the head of the job queue in the specified state + * for the specified period of time. + */ +export enum JobStateTimeLimitActionsAction { + CANCEL = 'CANCEL', +} + +/** + * The reason to log for the action being taken. + * @see https://docs.aws.amazon.com/batch/latest/userguide/troubleshooting.html#job_stuck_in_runnable + */ +export enum JobStateTimeLimitActionsReason { + INSUFFICIENT_INSTANCE_CAPACITY = 'CAPACITY:INSUFFICIENT_INSTANCE_CAPACITY', + COMPUTE_ENVIRONMENT_MAX_RESOURCE = 'MISCONFIGURATION:COMPUTE_ENVIRONMENT_MAX_RESOURCE', + JOB_RESOURCE_REQUIREMENT = 'MISCONFIGURATION:JOB_RESOURCE_REQUIREMENT', +} + +/** + * The state of the job needed to trigger the action. + */ +export enum JobStateTimeLimitActionsState { + RUNNABLE = 'RUNNABLE', +} + /** * JobQueues can receive Jobs, which are removed from the queue when * sent to the linked ComputeEnvironment(s) to be executed. @@ -191,6 +255,8 @@ export class JobQueue extends Resource implements IJobQueue { jobQueueName: props?.jobQueueName, state: (this.enabled ?? true) ? 'ENABLED' : 'DISABLED', schedulingPolicyArn: this.schedulingPolicy?.schedulingPolicyArn, + jobStateTimeLimitActions: props?.jobStateTimeLimitActions !== undefined ? + this.parseJobStateTimeLimitActions(props.jobStateTimeLimitActions) : undefined, }); this.jobQueueArn = this.getResourceArnAttribute(resource.attrJobQueueArn, { @@ -209,6 +275,25 @@ export class JobQueue extends Resource implements IJobQueue { order, }); } + + private parseJobStateTimeLimitActions(jobStateTimeLimitActions: JobStateTimeLimitAction[]): CfnJobQueue.JobStateTimeLimitActionProperty[] { + return jobStateTimeLimitActions.map(parseJobStateTimeLimitAction); + + function parseJobStateTimeLimitAction(jobStateTimeLimitAction: JobStateTimeLimitAction): CfnJobQueue.JobStateTimeLimitActionProperty { + const maxTimeSeconds = jobStateTimeLimitAction.maxTimeSeconds.toSeconds(); + + if (maxTimeSeconds < 600 || maxTimeSeconds > 86400) { + throw new Error(`maxTimeSeconds must be between 60 and 86400, got ${maxTimeSeconds}`); + } + + return { + action: jobStateTimeLimitAction.action, + maxTimeSeconds, + reason: jobStateTimeLimitAction.reason, + state: jobStateTimeLimitAction.state, + }; + } + } } function validateOrderedComputeEnvironments(computeEnvironments: OrderedComputeEnvironment[]): string[] { diff --git a/packages/aws-cdk-lib/aws-batch/test/job-queue.test.ts b/packages/aws-cdk-lib/aws-batch/test/job-queue.test.ts index d5ad7aee45998..6c4a06c1b05ff 100644 --- a/packages/aws-cdk-lib/aws-batch/test/job-queue.test.ts +++ b/packages/aws-cdk-lib/aws-batch/test/job-queue.test.ts @@ -1,7 +1,7 @@ import { Template } from '../../assertions'; import * as ec2 from '../../aws-ec2'; -import { DefaultTokenResolver, Stack, StringConcat, Tokenization } from '../../core'; -import { FairshareSchedulingPolicy, JobQueue, ManagedEc2EcsComputeEnvironment } from '../lib'; +import { DefaultTokenResolver, Duration, Stack, StringConcat, Tokenization } from '../../core'; +import { FairshareSchedulingPolicy, JobQueue, ManagedEc2EcsComputeEnvironment, JobStateTimeLimitActionsAction, JobStateTimeLimitActionsReason, JobStateTimeLimitActionsState } from '../lib'; test('JobQueue respects computeEnvironments', () => { // GIVEN @@ -259,3 +259,78 @@ test('JobQueue throws when there are no linked ComputeEnvironments', () => { Template.fromStack(stack); }).toThrow(/This JobQueue does not link any ComputeEnvironments/); }); + +test('JobQueue with JobStateTimeLimitActions', () => { + // GIVEN + const stack = new Stack(); + const vpc = new ec2.Vpc(stack, 'vpc'); + + // WHEN + new JobQueue(stack, 'joBBQ', { + computeEnvironments: [{ + computeEnvironment: new ManagedEc2EcsComputeEnvironment(stack, 'CE', { + vpc, + }), + order: 1, + }], + jobStateTimeLimitActions: [ + { + action: JobStateTimeLimitActionsAction.CANCEL, + maxTimeSeconds: Duration.minutes(10), + reason: JobStateTimeLimitActionsReason.INSUFFICIENT_INSTANCE_CAPACITY, + state: JobStateTimeLimitActionsState.RUNNABLE, + }, + { + action: JobStateTimeLimitActionsAction.CANCEL, + maxTimeSeconds: Duration.minutes(10), + reason: JobStateTimeLimitActionsReason.COMPUTE_ENVIRONMENT_MAX_RESOURCE, + state: JobStateTimeLimitActionsState.RUNNABLE, + }, + { + action: JobStateTimeLimitActionsAction.CANCEL, + maxTimeSeconds: Duration.minutes(10), + reason: JobStateTimeLimitActionsReason.JOB_RESOURCE_REQUIREMENT, + state: JobStateTimeLimitActionsState.RUNNABLE, + }, + ], + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Batch::JobQueue', { + JobStateTimeLimitActions: [ + { + Action: 'CANCEL', + MaxTimeSeconds: 600, + Reason: 'CAPACITY:INSUFFICIENT_INSTANCE_CAPACITY', + State: 'RUNNABLE', + }, + { + Action: 'CANCEL', + MaxTimeSeconds: 600, + Reason: 'MISCONFIGURATION:COMPUTE_ENVIRONMENT_MAX_RESOURCE', + State: 'RUNNABLE', + }, + { + Action: 'CANCEL', + MaxTimeSeconds: 600, + Reason: 'MISCONFIGURATION:JOB_RESOURCE_REQUIREMENT', + State: 'RUNNABLE', + }, + ], + }); +}); + +test('JobQueue with JobStateTimeLimitActions throws when maxTimeSeconds has an illegal value', () => { + const stack = new Stack(); + + expect(() => new JobQueue(stack, 'joBBQ', { + jobStateTimeLimitActions: [ + { + action: JobStateTimeLimitActionsAction.CANCEL, + maxTimeSeconds: Duration.seconds(90000), + reason: JobStateTimeLimitActionsReason.COMPUTE_ENVIRONMENT_MAX_RESOURCE, + state: JobStateTimeLimitActionsState.RUNNABLE, + }, + ], + })).toThrow('maxTimeSeconds must be between 60 and 86400, got 90000'); +}); \ No newline at end of file From ca0cc7f2b66da20c2bdbeb99507e46df85f3dfce Mon Sep 17 00:00:00 2001 From: maz Date: Sun, 12 May 2024 10:40:14 +0900 Subject: [PATCH 02/22] fix: add docs to enum --- packages/aws-cdk-lib/aws-batch/lib/job-queue.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts index 3ebc6c8691c81..4c8a4b99719c8 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts @@ -179,6 +179,9 @@ export interface JobStateTimeLimitAction { * for the specified period of time. */ export enum JobStateTimeLimitActionsAction { + /** + * Cancel the job. + */ CANCEL = 'CANCEL', } @@ -187,8 +190,19 @@ export enum JobStateTimeLimitActionsAction { * @see https://docs.aws.amazon.com/batch/latest/userguide/troubleshooting.html#job_stuck_in_runnable */ export enum JobStateTimeLimitActionsReason { + /** + * All connected compute environments have insufficient capacity errors. + */ INSUFFICIENT_INSTANCE_CAPACITY = 'CAPACITY:INSUFFICIENT_INSTANCE_CAPACITY', + + /** + * All compute environments have a maxvCpus parameter that is smaller than the job requirements. + */ COMPUTE_ENVIRONMENT_MAX_RESOURCE = 'MISCONFIGURATION:COMPUTE_ENVIRONMENT_MAX_RESOURCE', + + /** + * None of the compute environments have instances that meet the job requirements. + */ JOB_RESOURCE_REQUIREMENT = 'MISCONFIGURATION:JOB_RESOURCE_REQUIREMENT', } @@ -196,6 +210,9 @@ export enum JobStateTimeLimitActionsReason { * The state of the job needed to trigger the action. */ export enum JobStateTimeLimitActionsState { + /** + * RUNNABLE state triggers the action. + */ RUNNABLE = 'RUNNABLE', } From 8524e16053485c3067bf66d94689da2460cf0c58 Mon Sep 17 00:00:00 2001 From: maz Date: Sun, 12 May 2024 11:35:17 +0900 Subject: [PATCH 03/22] fix: README --- packages/aws-cdk-lib/aws-batch/README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/aws-cdk-lib/aws-batch/README.md b/packages/aws-cdk-lib/aws-batch/README.md index a7d56e02767e9..bce660cbe2ce7 100644 --- a/packages/aws-cdk-lib/aws-batch/README.md +++ b/packages/aws-cdk-lib/aws-batch/README.md @@ -240,13 +240,15 @@ Specifies an action that AWS Batch will take after the job has remained at the h specified state for longer than the specified time. ```ts +import * as cdk from 'aws-cdk-lib'; + new batch.JobQueue(this, 'JobQueue', { jobStateTimeLimitActions: [ { - action: JobStateTimeLimitActionsAction.CANCEL, - maxTimeSeconds: Duration.minutes(10), - reason: JobStateTimeLimitActionsReason.INSUFFICIENT_INSTANCE_CAPACITY, - state: JobStateTimeLimitActionsState.RUNNABLE, + action: batch.JobStateTimeLimitActionsAction.CANCEL, + maxTimeSeconds: cdk.Duration.minutes(10), + reason: batch.JobStateTimeLimitActionsReason.INSUFFICIENT_INSTANCE_CAPACITY, + state: batch.JobStateTimeLimitActionsState.RUNNABLE, }, ] }); From 45337717a3cb8f409bacdc8c8542641439b736ff Mon Sep 17 00:00:00 2001 From: maz Date: Sun, 12 May 2024 12:06:42 +0900 Subject: [PATCH 04/22] fix: README --- packages/aws-cdk-lib/aws-batch/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/aws-cdk-lib/aws-batch/README.md b/packages/aws-cdk-lib/aws-batch/README.md index bce660cbe2ce7..12ec883643dd7 100644 --- a/packages/aws-cdk-lib/aws-batch/README.md +++ b/packages/aws-cdk-lib/aws-batch/README.md @@ -240,8 +240,6 @@ Specifies an action that AWS Batch will take after the job has remained at the h specified state for longer than the specified time. ```ts -import * as cdk from 'aws-cdk-lib'; - new batch.JobQueue(this, 'JobQueue', { jobStateTimeLimitActions: [ { From 402d5b924347d0c7a0e4122d956cc19a13f1c9da Mon Sep 17 00:00:00 2001 From: maz Date: Sun, 12 May 2024 12:55:05 +0900 Subject: [PATCH 05/22] fix: typo --- packages/aws-cdk-lib/aws-batch/lib/job-queue.ts | 2 +- packages/aws-cdk-lib/aws-batch/test/job-queue.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts index 4c8a4b99719c8..4a5d07aa3ff2c 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts @@ -300,7 +300,7 @@ export class JobQueue extends Resource implements IJobQueue { const maxTimeSeconds = jobStateTimeLimitAction.maxTimeSeconds.toSeconds(); if (maxTimeSeconds < 600 || maxTimeSeconds > 86400) { - throw new Error(`maxTimeSeconds must be between 60 and 86400, got ${maxTimeSeconds}`); + throw new Error(`maxTimeSeconds must be between 600 and 86400, got ${maxTimeSeconds}`); } return { diff --git a/packages/aws-cdk-lib/aws-batch/test/job-queue.test.ts b/packages/aws-cdk-lib/aws-batch/test/job-queue.test.ts index 6c4a06c1b05ff..21c8c96b41f1f 100644 --- a/packages/aws-cdk-lib/aws-batch/test/job-queue.test.ts +++ b/packages/aws-cdk-lib/aws-batch/test/job-queue.test.ts @@ -332,5 +332,5 @@ test('JobQueue with JobStateTimeLimitActions throws when maxTimeSeconds has an i state: JobStateTimeLimitActionsState.RUNNABLE, }, ], - })).toThrow('maxTimeSeconds must be between 60 and 86400, got 90000'); + })).toThrow('maxTimeSeconds must be between 600 and 86400, got 90000'); }); \ No newline at end of file From 6d610e69e291402060b4e49cea2424118ddc8a67 Mon Sep 17 00:00:00 2001 From: maz Date: Sun, 12 May 2024 14:18:42 +0900 Subject: [PATCH 06/22] refactor: set default value enum --- .../integ.job-queue-job-state-time-limit-actions.ts | 2 -- packages/aws-cdk-lib/aws-batch/lib/job-queue.ts | 12 ++++++++---- .../aws-cdk-lib/aws-batch/test/job-queue.test.ts | 2 -- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.ts index 9dd1fdc743d2c..a8646cded491a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.ts @@ -29,10 +29,8 @@ new batch.JobQueue(stack, 'joBBQ', { state: batch.JobStateTimeLimitActionsState.RUNNABLE, }, { - action: batch.JobStateTimeLimitActionsAction.CANCEL, maxTimeSeconds: Duration.minutes(10), reason: batch.JobStateTimeLimitActionsReason.JOB_RESOURCE_REQUIREMENT, - state: batch.JobStateTimeLimitActionsState.RUNNABLE, }, ], }); diff --git a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts index 4a5d07aa3ff2c..b560530a8da66 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts @@ -152,8 +152,10 @@ export interface JobStateTimeLimitAction { /** * The action to take when a job is at the head of the job queue in the specified state * for the specified period of time. + * + * @default JobStateTimeLimitActionsAction.CANCEL */ - readonly action: JobStateTimeLimitActionsAction; + readonly action?: JobStateTimeLimitActionsAction; /** * The approximate amount of time, in seconds, that must pass with the job in the specified @@ -170,8 +172,10 @@ export interface JobStateTimeLimitAction { /** * The state of the job needed to trigger the action. + * + * @default JobStateTimeLimitActionsState.RUNNABLE */ - readonly state: JobStateTimeLimitActionsState; + readonly state?: JobStateTimeLimitActionsState; } /** @@ -304,10 +308,10 @@ export class JobQueue extends Resource implements IJobQueue { } return { - action: jobStateTimeLimitAction.action, + action: jobStateTimeLimitAction.action ?? JobStateTimeLimitActionsAction.CANCEL, maxTimeSeconds, reason: jobStateTimeLimitAction.reason, - state: jobStateTimeLimitAction.state, + state: jobStateTimeLimitAction.state ?? JobStateTimeLimitActionsState.RUNNABLE, }; } } diff --git a/packages/aws-cdk-lib/aws-batch/test/job-queue.test.ts b/packages/aws-cdk-lib/aws-batch/test/job-queue.test.ts index 21c8c96b41f1f..38ccdca438902 100644 --- a/packages/aws-cdk-lib/aws-batch/test/job-queue.test.ts +++ b/packages/aws-cdk-lib/aws-batch/test/job-queue.test.ts @@ -287,10 +287,8 @@ test('JobQueue with JobStateTimeLimitActions', () => { state: JobStateTimeLimitActionsState.RUNNABLE, }, { - action: JobStateTimeLimitActionsAction.CANCEL, maxTimeSeconds: Duration.minutes(10), reason: JobStateTimeLimitActionsReason.JOB_RESOURCE_REQUIREMENT, - state: JobStateTimeLimitActionsState.RUNNABLE, }, ], }); From 8dfc79c592c11763034929cfc501957b4b328c0c Mon Sep 17 00:00:00 2001 From: mazyu36 Date: Thu, 16 May 2024 00:22:22 +0900 Subject: [PATCH 07/22] Update packages/aws-cdk-lib/aws-batch/README.md Co-authored-by: k.goto <24818752+go-to-k@users.noreply.github.com> --- packages/aws-cdk-lib/aws-batch/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/aws-cdk-lib/aws-batch/README.md b/packages/aws-cdk-lib/aws-batch/README.md index 12ec883643dd7..70fc79d0e6e48 100644 --- a/packages/aws-cdk-lib/aws-batch/README.md +++ b/packages/aws-cdk-lib/aws-batch/README.md @@ -235,6 +235,7 @@ highPriorityQueue.addComputeEnvironment(sharedComputeEnv, 1); ``` ### React to jobs stuck in RUNNABLE state + You can react to jobs stuck in RUNNABLE state by setting a `jobStateTimeLimitActions` in `JobQueue`. Specifies an action that AWS Batch will take after the job has remained at the head of the queue in the specified state for longer than the specified time. From cf683371b39678acb1fb2037e3623b47dc1da680 Mon Sep 17 00:00:00 2001 From: mazyu36 Date: Thu, 16 May 2024 00:22:34 +0900 Subject: [PATCH 08/22] Update packages/aws-cdk-lib/aws-batch/lib/job-queue.ts Co-authored-by: k.goto <24818752+go-to-k@users.noreply.github.com> --- packages/aws-cdk-lib/aws-batch/lib/job-queue.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts index b560530a8da66..18f03a22a8072 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts @@ -122,7 +122,7 @@ export interface JobQueueProps { * Specifies an action that AWS Batch will take after the job has remained at the head of the queue * in the specified state for longer than the specified time. * - * @default - no actions set + * @default - no actions */ readonly jobStateTimeLimitActions?: JobStateTimeLimitAction[]; } From f831e9c7ec841698858b96a42b96cc01d689c1e9 Mon Sep 17 00:00:00 2001 From: mazyu36 Date: Thu, 16 May 2024 00:22:47 +0900 Subject: [PATCH 09/22] Update packages/aws-cdk-lib/aws-batch/lib/job-queue.ts Co-authored-by: k.goto <24818752+go-to-k@users.noreply.github.com> --- packages/aws-cdk-lib/aws-batch/lib/job-queue.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts index 18f03a22a8072..f6dcdeeb63156 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts @@ -147,7 +147,6 @@ export interface OrderedComputeEnvironment { * Specifies an action that AWS Batch will take after the job has remained at * the head of the queue in the specified state for longer than the specified time. */ - export interface JobStateTimeLimitAction { /** * The action to take when a job is at the head of the job queue in the specified state From 1489031d1174a3b6129a9f67d509f7961dd613b5 Mon Sep 17 00:00:00 2001 From: mazyu36 Date: Thu, 16 May 2024 00:23:50 +0900 Subject: [PATCH 10/22] Update packages/aws-cdk-lib/aws-batch/lib/job-queue.ts Co-authored-by: k.goto <24818752+go-to-k@users.noreply.github.com> --- packages/aws-cdk-lib/aws-batch/lib/job-queue.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts index f6dcdeeb63156..9d9ea11936c05 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts @@ -157,11 +157,12 @@ export interface JobStateTimeLimitAction { readonly action?: JobStateTimeLimitActionsAction; /** - * The approximate amount of time, in seconds, that must pass with the job in the specified + * The approximate amount of time, that must pass with the job in the specified * state before the action is taken. - * The minimum value is 600 (10 minutes) and the maximum value is 86,400 (24 hours). + * + * The minimum value is 10 minutes and the maximum value is 24 hours. */ - readonly maxTimeSeconds: Duration; + readonly maxTime: Duration; /** * The reason to log for the action being taken. From 47017376294970e3c1f7a29b6d0a24722c063556 Mon Sep 17 00:00:00 2001 From: mazyu36 Date: Thu, 16 May 2024 00:23:58 +0900 Subject: [PATCH 11/22] Update packages/aws-cdk-lib/aws-batch/lib/job-queue.ts Co-authored-by: k.goto <24818752+go-to-k@users.noreply.github.com> --- packages/aws-cdk-lib/aws-batch/lib/job-queue.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts index 9d9ea11936c05..f76bef55ea09b 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts @@ -166,6 +166,7 @@ export interface JobStateTimeLimitAction { /** * The reason to log for the action being taken. + * * @see https://docs.aws.amazon.com/batch/latest/userguide/troubleshooting.html#job_stuck_in_runnable */ readonly reason: JobStateTimeLimitActionsReason; From f42dbf5fa556afb1aad5492638b46490b2fd7829 Mon Sep 17 00:00:00 2001 From: mazyu36 Date: Thu, 16 May 2024 00:24:11 +0900 Subject: [PATCH 12/22] Update packages/aws-cdk-lib/aws-batch/lib/job-queue.ts Co-authored-by: k.goto <24818752+go-to-k@users.noreply.github.com> --- packages/aws-cdk-lib/aws-batch/lib/job-queue.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts index f76bef55ea09b..b3354205ebbc6 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts @@ -149,11 +149,11 @@ export interface OrderedComputeEnvironment { */ export interface JobStateTimeLimitAction { /** - * The action to take when a job is at the head of the job queue in the specified state - * for the specified period of time. - * - * @default JobStateTimeLimitActionsAction.CANCEL - */ + * The action to take when a job is at the head of the job queue in the specified state + * for the specified period of time. + * + * @default JobStateTimeLimitActionsAction.CANCEL + */ readonly action?: JobStateTimeLimitActionsAction; /** From 9537e0704f85c9524158c1840011eba9da5be332 Mon Sep 17 00:00:00 2001 From: mazyu36 Date: Thu, 16 May 2024 00:24:22 +0900 Subject: [PATCH 13/22] Update packages/aws-cdk-lib/aws-batch/lib/job-queue.ts Co-authored-by: k.goto <24818752+go-to-k@users.noreply.github.com> --- packages/aws-cdk-lib/aws-batch/lib/job-queue.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts index b3354205ebbc6..7de1d3c8a5bbc 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts @@ -192,6 +192,7 @@ export enum JobStateTimeLimitActionsAction { /** * The reason to log for the action being taken. + * * @see https://docs.aws.amazon.com/batch/latest/userguide/troubleshooting.html#job_stuck_in_runnable */ export enum JobStateTimeLimitActionsReason { From 98b110f881423538e22a3b5f005b731eabce9bc4 Mon Sep 17 00:00:00 2001 From: mazyu36 Date: Thu, 16 May 2024 00:24:33 +0900 Subject: [PATCH 14/22] Update packages/aws-cdk-lib/aws-batch/lib/job-queue.ts Co-authored-by: k.goto <24818752+go-to-k@users.noreply.github.com> --- packages/aws-cdk-lib/aws-batch/lib/job-queue.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts index 7de1d3c8a5bbc..f4a6539f8bc60 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts @@ -185,8 +185,8 @@ export interface JobStateTimeLimitAction { */ export enum JobStateTimeLimitActionsAction { /** - * Cancel the job. - */ + * Cancel the job. + */ CANCEL = 'CANCEL', } From 8a1241e0af4ca382e41b011d9160b4c79379cfc9 Mon Sep 17 00:00:00 2001 From: mazyu36 Date: Thu, 16 May 2024 00:24:43 +0900 Subject: [PATCH 15/22] Update packages/aws-cdk-lib/aws-batch/lib/job-queue.ts Co-authored-by: k.goto <24818752+go-to-k@users.noreply.github.com> --- packages/aws-cdk-lib/aws-batch/lib/job-queue.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts index f4a6539f8bc60..95bf86766b468 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts @@ -197,18 +197,18 @@ export enum JobStateTimeLimitActionsAction { */ export enum JobStateTimeLimitActionsReason { /** - * All connected compute environments have insufficient capacity errors. - */ + * All connected compute environments have insufficient capacity errors. + */ INSUFFICIENT_INSTANCE_CAPACITY = 'CAPACITY:INSUFFICIENT_INSTANCE_CAPACITY', /** - * All compute environments have a maxvCpus parameter that is smaller than the job requirements. - */ + * All compute environments have a maxvCpus parameter that is smaller than the job requirements. + */ COMPUTE_ENVIRONMENT_MAX_RESOURCE = 'MISCONFIGURATION:COMPUTE_ENVIRONMENT_MAX_RESOURCE', /** - * None of the compute environments have instances that meet the job requirements. - */ + * None of the compute environments have instances that meet the job requirements. + */ JOB_RESOURCE_REQUIREMENT = 'MISCONFIGURATION:JOB_RESOURCE_REQUIREMENT', } From 2e0836ea093a8143b49c8386fec99f6821829800 Mon Sep 17 00:00:00 2001 From: mazyu36 Date: Thu, 16 May 2024 00:24:53 +0900 Subject: [PATCH 16/22] Update packages/aws-cdk-lib/aws-batch/lib/job-queue.ts Co-authored-by: k.goto <24818752+go-to-k@users.noreply.github.com> --- packages/aws-cdk-lib/aws-batch/lib/job-queue.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts index 95bf86766b468..6b8111c147a65 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts @@ -217,8 +217,8 @@ export enum JobStateTimeLimitActionsReason { */ export enum JobStateTimeLimitActionsState { /** - * RUNNABLE state triggers the action. - */ + * RUNNABLE state triggers the action. + */ RUNNABLE = 'RUNNABLE', } From 3a629eb5b54e5cb03722e69e5b835bc6bb73d8bf Mon Sep 17 00:00:00 2001 From: mazyu36 Date: Thu, 16 May 2024 00:26:09 +0900 Subject: [PATCH 17/22] Update packages/aws-cdk-lib/aws-batch/lib/job-queue.ts Co-authored-by: k.goto <24818752+go-to-k@users.noreply.github.com> --- packages/aws-cdk-lib/aws-batch/lib/job-queue.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts index 6b8111c147a65..88e368b245591 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts @@ -119,8 +119,8 @@ export interface JobQueueProps { readonly schedulingPolicy?: ISchedulingPolicy; /** - * Specifies an action that AWS Batch will take after the job has remained at the head of the queue - * in the specified state for longer than the specified time. + * The set of actions that AWS Batch perform on jobs that remain at the head of the job queue in + * the specified state longer than specified times. * * @default - no actions */ From 9d3210c97dfb619574f69a33390d3038c22fd255 Mon Sep 17 00:00:00 2001 From: mazyu36 Date: Thu, 16 May 2024 00:26:21 +0900 Subject: [PATCH 18/22] Update packages/aws-cdk-lib/aws-batch/README.md Co-authored-by: k.goto <24818752+go-to-k@users.noreply.github.com> --- packages/aws-cdk-lib/aws-batch/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-batch/README.md b/packages/aws-cdk-lib/aws-batch/README.md index 70fc79d0e6e48..c9136b494fac2 100644 --- a/packages/aws-cdk-lib/aws-batch/README.md +++ b/packages/aws-cdk-lib/aws-batch/README.md @@ -237,7 +237,7 @@ highPriorityQueue.addComputeEnvironment(sharedComputeEnv, 1); ### React to jobs stuck in RUNNABLE state You can react to jobs stuck in RUNNABLE state by setting a `jobStateTimeLimitActions` in `JobQueue`. -Specifies an action that AWS Batch will take after the job has remained at the head of the queue in the +Specifies actions that AWS Batch will take after the job has remained at the head of the queue in the specified state for longer than the specified time. ```ts From 80efc2be60a8a517fa61c51ded813fb334c7ff9e Mon Sep 17 00:00:00 2001 From: mazyu36 Date: Thu, 16 May 2024 00:28:18 +0900 Subject: [PATCH 19/22] Update packages/aws-cdk-lib/aws-batch/lib/job-queue.ts Co-authored-by: k.goto <24818752+go-to-k@users.noreply.github.com> --- .../aws-cdk-lib/aws-batch/lib/job-queue.ts | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts index 88e368b245591..38b3af4e1ec2a 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts @@ -299,14 +299,23 @@ export class JobQueue extends Resource implements IJobQueue { }); } - private parseJobStateTimeLimitActions(jobStateTimeLimitActions: JobStateTimeLimitAction[]): CfnJobQueue.JobStateTimeLimitActionProperty[] { - return jobStateTimeLimitActions.map(parseJobStateTimeLimitAction); + private renderJobStateTimeLimitActions( + jobStateTimeLimitActions?: JobStateTimeLimitAction[], + ): CfnJobQueue.JobStateTimeLimitActionProperty[] | undefined { + if (!jobStateTimeLimitActions || jobStateTimeLimitActions.length === 0) { + return; + } + + return jobStateTimeLimitActions.map((action, index) => renderJobStateTimeLimitAction(action, index)); - function parseJobStateTimeLimitAction(jobStateTimeLimitAction: JobStateTimeLimitAction): CfnJobQueue.JobStateTimeLimitActionProperty { - const maxTimeSeconds = jobStateTimeLimitAction.maxTimeSeconds.toSeconds(); + function renderJobStateTimeLimitAction( + jobStateTimeLimitAction: JobStateTimeLimitAction, + index: number, + ): CfnJobQueue.JobStateTimeLimitActionProperty { + const maxTimeSeconds = jobStateTimeLimitAction.maxTime.toSeconds(); if (maxTimeSeconds < 600 || maxTimeSeconds > 86400) { - throw new Error(`maxTimeSeconds must be between 600 and 86400, got ${maxTimeSeconds}`); + throw new Error(`maxTime must be between 600 and 86400 seconds, got ${maxTimeSeconds} seconds at jobStateTimeLimitActions[${index}]`); } return { @@ -318,6 +327,7 @@ export class JobQueue extends Resource implements IJobQueue { } } } +} function validateOrderedComputeEnvironments(computeEnvironments: OrderedComputeEnvironment[]): string[] { const seenOrders: number[] = []; From ddec3eae3cbe8be8240d50c4bed02c3b3206766b Mon Sep 17 00:00:00 2001 From: mazyu36 Date: Thu, 16 May 2024 00:28:26 +0900 Subject: [PATCH 20/22] Update packages/aws-cdk-lib/aws-batch/lib/job-queue.ts Co-authored-by: k.goto <24818752+go-to-k@users.noreply.github.com> --- packages/aws-cdk-lib/aws-batch/lib/job-queue.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts index 38b3af4e1ec2a..0908b4a588c24 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts @@ -278,8 +278,7 @@ export class JobQueue extends Resource implements IJobQueue { jobQueueName: props?.jobQueueName, state: (this.enabled ?? true) ? 'ENABLED' : 'DISABLED', schedulingPolicyArn: this.schedulingPolicy?.schedulingPolicyArn, - jobStateTimeLimitActions: props?.jobStateTimeLimitActions !== undefined ? - this.parseJobStateTimeLimitActions(props.jobStateTimeLimitActions) : undefined, + jobStateTimeLimitActions: this.renderJobStateTimeLimitActions(props?.jobStateTimeLimitActions), }); this.jobQueueArn = this.getResourceArnAttribute(resource.attrJobQueueArn, { From 5c79c6564f8389826ce0a581f333fcc69dcee683 Mon Sep 17 00:00:00 2001 From: maz Date: Thu, 16 May 2024 01:05:00 +0900 Subject: [PATCH 21/22] fix: unit tests and integ tests. --- ....job-queue-job-state-time-limit-actions.ts | 6 +-- .../aws-cdk-lib/aws-batch/lib/job-queue.ts | 1 - .../aws-batch/test/job-queue.test.ts | 38 +++++++++++++++---- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.ts index a8646cded491a..146edab2d652a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-batch/test/integ.job-queue-job-state-time-limit-actions.ts @@ -18,18 +18,18 @@ new batch.JobQueue(stack, 'joBBQ', { jobStateTimeLimitActions: [ { action: batch.JobStateTimeLimitActionsAction.CANCEL, - maxTimeSeconds: Duration.minutes(10), + maxTime: Duration.minutes(10), reason: batch.JobStateTimeLimitActionsReason.INSUFFICIENT_INSTANCE_CAPACITY, state: batch.JobStateTimeLimitActionsState.RUNNABLE, }, { action: batch.JobStateTimeLimitActionsAction.CANCEL, - maxTimeSeconds: Duration.minutes(10), + maxTime: Duration.minutes(10), reason: batch.JobStateTimeLimitActionsReason.COMPUTE_ENVIRONMENT_MAX_RESOURCE, state: batch.JobStateTimeLimitActionsState.RUNNABLE, }, { - maxTimeSeconds: Duration.minutes(10), + maxTime: Duration.minutes(10), reason: batch.JobStateTimeLimitActionsReason.JOB_RESOURCE_REQUIREMENT, }, ], diff --git a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts index 0908b4a588c24..691f2d2850af0 100644 --- a/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts +++ b/packages/aws-cdk-lib/aws-batch/lib/job-queue.ts @@ -326,7 +326,6 @@ export class JobQueue extends Resource implements IJobQueue { } } } -} function validateOrderedComputeEnvironments(computeEnvironments: OrderedComputeEnvironment[]): string[] { const seenOrders: number[] = []; diff --git a/packages/aws-cdk-lib/aws-batch/test/job-queue.test.ts b/packages/aws-cdk-lib/aws-batch/test/job-queue.test.ts index 38ccdca438902..f818777545443 100644 --- a/packages/aws-cdk-lib/aws-batch/test/job-queue.test.ts +++ b/packages/aws-cdk-lib/aws-batch/test/job-queue.test.ts @@ -1,4 +1,4 @@ -import { Template } from '../../assertions'; +import { Match, Template } from '../../assertions'; import * as ec2 from '../../aws-ec2'; import { DefaultTokenResolver, Duration, Stack, StringConcat, Tokenization } from '../../core'; import { FairshareSchedulingPolicy, JobQueue, ManagedEc2EcsComputeEnvironment, JobStateTimeLimitActionsAction, JobStateTimeLimitActionsReason, JobStateTimeLimitActionsState } from '../lib'; @@ -276,18 +276,18 @@ test('JobQueue with JobStateTimeLimitActions', () => { jobStateTimeLimitActions: [ { action: JobStateTimeLimitActionsAction.CANCEL, - maxTimeSeconds: Duration.minutes(10), + maxTime: Duration.minutes(10), reason: JobStateTimeLimitActionsReason.INSUFFICIENT_INSTANCE_CAPACITY, state: JobStateTimeLimitActionsState.RUNNABLE, }, { action: JobStateTimeLimitActionsAction.CANCEL, - maxTimeSeconds: Duration.minutes(10), + maxTime: Duration.minutes(10), reason: JobStateTimeLimitActionsReason.COMPUTE_ENVIRONMENT_MAX_RESOURCE, state: JobStateTimeLimitActionsState.RUNNABLE, }, { - maxTimeSeconds: Duration.minutes(10), + maxTime: Duration.minutes(10), reason: JobStateTimeLimitActionsReason.JOB_RESOURCE_REQUIREMENT, }, ], @@ -318,17 +318,39 @@ test('JobQueue with JobStateTimeLimitActions', () => { }); }); -test('JobQueue with JobStateTimeLimitActions throws when maxTimeSeconds has an illegal value', () => { +test('JobQueue with JobStateTimeLimitActions throws when maxTime has an illegal value', () => { const stack = new Stack(); expect(() => new JobQueue(stack, 'joBBQ', { jobStateTimeLimitActions: [ { action: JobStateTimeLimitActionsAction.CANCEL, - maxTimeSeconds: Duration.seconds(90000), + maxTime: Duration.seconds(90000), reason: JobStateTimeLimitActionsReason.COMPUTE_ENVIRONMENT_MAX_RESOURCE, state: JobStateTimeLimitActionsState.RUNNABLE, }, ], - })).toThrow('maxTimeSeconds must be between 600 and 86400, got 90000'); -}); \ No newline at end of file + })).toThrow('maxTime must be between 600 and 86400 seconds, got 90000 seconds at jobStateTimeLimitActions[0]'); +}); + +test('JobQueue with an empty array of JobStateTimeLimitActions', () => { + // GIVEN + const stack = new Stack(); + const vpc = new ec2.Vpc(stack, 'vpc'); + + // WHEN + new JobQueue(stack, 'joBBQ', { + computeEnvironments: [{ + computeEnvironment: new ManagedEc2EcsComputeEnvironment(stack, 'CE', { + vpc, + }), + order: 1, + }], + jobStateTimeLimitActions: [], + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Batch::JobQueue', { + JobStateTimeLimitActions: Match.absent(), + }); +}); From 64968295fd11a78c2da7fccbd6ec2b47e3d8e0fb Mon Sep 17 00:00:00 2001 From: maz Date: Thu, 16 May 2024 01:36:45 +0900 Subject: [PATCH 22/22] fix: README --- packages/aws-cdk-lib/aws-batch/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-batch/README.md b/packages/aws-cdk-lib/aws-batch/README.md index c9136b494fac2..6b7e3eeb89a99 100644 --- a/packages/aws-cdk-lib/aws-batch/README.md +++ b/packages/aws-cdk-lib/aws-batch/README.md @@ -245,7 +245,7 @@ new batch.JobQueue(this, 'JobQueue', { jobStateTimeLimitActions: [ { action: batch.JobStateTimeLimitActionsAction.CANCEL, - maxTimeSeconds: cdk.Duration.minutes(10), + maxTime: cdk.Duration.minutes(10), reason: batch.JobStateTimeLimitActionsReason.INSUFFICIENT_INSTANCE_CAPACITY, state: batch.JobStateTimeLimitActionsState.RUNNABLE, },