From cea5eb14aa518ae95434bb24dc3fde1196d11385 Mon Sep 17 00:00:00 2001 From: andrestone Date: Tue, 3 Mar 2020 11:41:46 +0100 Subject: [PATCH] fix(batch): fixing build / tests --- .../aws-batch/lib/compute-environment.ts | 12 +- .../test/compute-environment.test.ts | 57 ++--- .../aws-batch/test/integ.batch.expected.json | 199 ++++++++++++++++-- .../@aws-cdk/aws-batch/test/integ.batch.ts | 29 ++- .../@aws-cdk/aws-batch/test/job-queue.test.ts | 4 +- 5 files changed, 247 insertions(+), 54 deletions(-) diff --git a/packages/@aws-cdk/aws-batch/lib/compute-environment.ts b/packages/@aws-cdk/aws-batch/lib/compute-environment.ts index 8cae74a9b96c1..e25f144ffd53b 100644 --- a/packages/@aws-cdk/aws-batch/lib/compute-environment.ts +++ b/packages/@aws-cdk/aws-batch/lib/compute-environment.ts @@ -93,11 +93,15 @@ export interface ComputeResources { readonly launchTemplate?: LaunchTemplateSpecification; /** - * The IAM role applied to EC2 resources in the compute environment. + * The Amazon ECS instance profile applied to Amazon EC2 instances in a compute environment. You can specify + * the short name or full Amazon Resource Name (ARN) of an instance profile. For example, ecsInstanceRole or + * arn:aws:iam:::instance-profile/ecsInstanceRole . For more information, see Amazon ECS + * Instance Role in the AWS Batch User Guide. * * @default a new role will be created. + * @link https://docs.aws.amazon.com/batch/latest/userguide/instance_IAM_role.html */ - readonly instanceRole?: iam.IRole; + readonly instanceRole?: string; /** * The types of EC2 instances that may be launched in the compute environment. You can specify instance @@ -342,8 +346,8 @@ export class ComputeEnvironment extends Resource implements IComputeEnvironment desiredvCpus: props.computeResources.desiredvCpus, ec2KeyPair: props.computeResources.ec2KeyPair, imageId: props.computeResources.image && props.computeResources.image.getImage(this).imageId, - instanceRole: props.computeResources.instanceRole - ? props.computeResources.instanceRole.roleArn + instanceRole: props.computeResources.instanceRole + ? props.computeResources.instanceRole : new iam.CfnInstanceProfile(this, 'Instance-Profile', { roles: [ new iam.Role(this, 'Ecs-Instance-Role', { assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'), diff --git a/packages/@aws-cdk/aws-batch/test/compute-environment.test.ts b/packages/@aws-cdk/aws-batch/test/compute-environment.test.ts index 18cd77e5f3b15..fcee90c1ef92f 100644 --- a/packages/@aws-cdk/aws-batch/test/compute-environment.test.ts +++ b/packages/@aws-cdk/aws-batch/test/compute-environment.test.ts @@ -1,11 +1,11 @@ -import { expect, haveResource, haveResourceLike, ResourcePart } from '@aws-cdk/assert'; +import {expect, haveResource, haveResourceLike, ResourcePart} from '@aws-cdk/assert'; import '@aws-cdk/assert/jest'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as ecs from '@aws-cdk/aws-ecs'; import * as iam from '@aws-cdk/aws-iam'; import * as cdk from '@aws-cdk/core'; -import { throws } from 'assert'; -import * as batch from '../lib'; +import {throws} from 'assert'; +import * as batch from "../lib"; describe('Batch Compute Evironment', () => { let expectedManagedDefaultComputeProps: any; @@ -34,7 +34,7 @@ describe('Batch Compute Evironment', () => { AllocationStrategy: batch.AllocationStrategy.BEST_FIT, InstanceRole: { 'Fn::GetAtt': [ - 'testcomputeenvResourceInstanceRole7FD819B9', + 'testcomputeenvInstanceProfileCBD87EAB', 'Arn' ] }, @@ -59,37 +59,39 @@ describe('Batch Compute Evironment', () => { }); describe('when validating props', () => { - test('should deny setting compute resources when using type managed', () => { + test('should deny setting compute resources when using type unmanaged', () => { // THEN throws(() => { // WHEN new batch.ComputeEnvironment(stack, 'test-compute-env', { + managed: false, computeResources: { - vpc, + vpc }, }); }); }); - test('should deny if creating an unmanged environment with no provided compute resource props', () => { + test('should deny if creating a managed environment with no provided compute resource props', () => { // THEN throws(() => { // WHEN new batch.ComputeEnvironment(stack, 'test-compute-env', { - managed: false, + managed: true, }); }); }); }); describe('using spot resources', () => { - test('should provide a spotfleet role if one is not given', () => { + test('should provide a spot fleet role if one is not given and allocationStrategy is BEST_FIT', () => { // WHEN new batch.ComputeEnvironment(stack, 'test-compute-env', { - managed: false, + managed: true, computeResources: { type: batch.ComputeResourceType.SPOT, - vpc, + allocationStrategy: batch.AllocationStrategy.BEST_FIT, + vpc }, }); @@ -124,7 +126,7 @@ describe('Batch Compute Evironment', () => { throws(() => { // WHEN new batch.ComputeEnvironment(stack, 'test-compute-env', { - managed: false, + managed: true, computeResources: { vpc, type: batch.ComputeResourceType.SPOT, @@ -139,7 +141,7 @@ describe('Batch Compute Evironment', () => { throws(() => { // WHEN new batch.ComputeEnvironment(stack, 'test-compute-env', { - managed: false, + managed: true, computeResources: { vpc, type: batch.ComputeResourceType.SPOT, @@ -155,9 +157,9 @@ describe('Batch Compute Evironment', () => { test('renders the correct cloudformation properties', () => { // WHEN const props = { - allocationStrategy: batch.AllocationStrategy.BEST_FIT, computeEnvironmentName: 'my-test-compute-env', computeResources: { + allocationStrategy: batch.AllocationStrategy.BEST_FIT, vpc, computeResourcesTags: new cdk.Tag('foo', 'bar'), desiredvCpus: 1, @@ -166,9 +168,14 @@ describe('Batch Compute Evironment', () => { generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2, hardwareType: ecs.AmiHardwareType.STANDARD, }), - instanceRole: new iam.Role(stack, 'test-compute-env-instance-role', { - assumedBy: new iam.ServicePrincipal('batch.amazonaws.com'), - }), + instanceRole: new iam.CfnInstanceProfile(stack, 'Instance-Profile', { + roles: [ new iam.Role(stack, 'Ecs-Instance-Role', { + assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'), + managedPolicies: [ + iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonEC2ContainerServiceforEC2Role') + ] + }).roleName] + }).attrArn, instanceTypes: [ ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO), ], @@ -186,7 +193,7 @@ describe('Batch Compute Evironment', () => { }, } as batch.ComputeResources, enabled: false, - managed: false, + managed: true, }; new batch.ComputeEnvironment(stack, 'test-compute-env', props); @@ -211,7 +218,7 @@ describe('Batch Compute Evironment', () => { }, InstanceRole: { 'Fn::GetAtt': [ - props.computeResources.instanceRole ? `${props.computeResources.instanceRole.node.uniqueId}F3B86D94` : '', + props.computeResources.instanceRole ? "InstanceProfile" : '', 'Arn' ] }, @@ -251,7 +258,7 @@ describe('Batch Compute Evironment', () => { test('should default to a best_fit strategy', () => { // WHEN new batch.ComputeEnvironment(stack, 'test-compute-env', { - managed: false, + managed: true, computeResources: { vpc, }, @@ -303,7 +310,7 @@ describe('Batch Compute Evironment', () => { test('should default to 0', () => { // WHEN new batch.ComputeEnvironment(stack, 'test-compute-env', { - managed: false, + managed: true, computeResources: { vpc, }, @@ -323,7 +330,7 @@ describe('Batch Compute Evironment', () => { test('should default to 256', () => { // WHEN new batch.ComputeEnvironment(stack, 'test-compute-env', { - managed: false, + managed: true, computeResources: { vpc, }, @@ -342,7 +349,7 @@ describe('Batch Compute Evironment', () => { test('should generate a role for me', () => { // WHEN new batch.ComputeEnvironment(stack, 'test-compute-env', { - managed: false, + managed: true, computeResources: { vpc, }, @@ -358,7 +365,7 @@ describe('Batch Compute Evironment', () => { test('should default to optimal matching', () => { // WHEN new batch.ComputeEnvironment(stack, 'test-compute-env', { - managed: false, + managed: true, computeResources: { vpc, }, @@ -377,7 +384,7 @@ describe('Batch Compute Evironment', () => { test('should default to EC2', () => { // WHEN new batch.ComputeEnvironment(stack, 'test-compute-env', { - managed: false, + managed: true, computeResources: { vpc, }, diff --git a/packages/@aws-cdk/aws-batch/test/integ.batch.expected.json b/packages/@aws-cdk/aws-batch/test/integ.batch.expected.json index 7c367e0d37a08..6519a5c34bb36 100644 --- a/packages/@aws-cdk/aws-batch/test/integ.batch.expected.json +++ b/packages/@aws-cdk/aws-batch/test/integ.batch.expected.json @@ -514,7 +514,25 @@ } } }, - "batchmanagedcomputeenvResourceServiceInstanceRole3A9DC7D6": { + "ec2launchtemplate": { + "Type": "AWS::EC2::LaunchTemplate", + "Properties": { + "LaunchTemplateData": { + "BlockDeviceMappings": [ + { + "DeviceName": "/dev/xvdcz", + "Ebs": { + "Encrypted": true, + "VolumeSize": 100, + "VolumeType": "gp2" + } + } + ] + }, + "LaunchTemplateName": "EC2LaunchTemplate" + } + }, + "batchunmanagedcomputeenvResourceServiceInstanceRoleCA40AF77": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -545,12 +563,12 @@ ] } }, - "batchmanagedcomputeenv1AA975A9": { + "batchunmanagedcomputeenvED550298": { "Type": "AWS::Batch::ComputeEnvironment", "Properties": { "ServiceRole": { "Fn::GetAtt": [ - "batchmanagedcomputeenvResourceServiceInstanceRole3A9DC7D6", + "batchunmanagedcomputeenvResourceServiceInstanceRoleCA40AF77", "Arn" ] }, @@ -558,7 +576,7 @@ "State": "ENABLED" } }, - "batchdemandcomputeenvResourceInstanceRole8989496E": { + "batchdemandcomputeenvlaunchtemplateEcsInstanceRole24D4E799": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -567,12 +585,81 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "Service": "batch.amazonaws.com" + "Service": { + "Fn::Join": [ + "", + [ + "ec2.", + { + "Ref": "AWS::URLSuffix" + } + ] + ] + } } } ], "Version": "2012-10-17" - } + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" + ] + ] + } + ] + }, + "DependsOn": [ + "vpcIGWE57CBDCA", + "vpcPrivateSubnet1DefaultRoute1AA8E2E5", + "vpcPrivateSubnet1RouteTableB41A48CC", + "vpcPrivateSubnet1RouteTableAssociation67945127", + "vpcPrivateSubnet1Subnet934893E8", + "vpcPrivateSubnet2DefaultRouteB0E07F99", + "vpcPrivateSubnet2RouteTable7280F23E", + "vpcPrivateSubnet2RouteTableAssociation007E94D3", + "vpcPrivateSubnet2Subnet7031C2BA", + "vpcPrivateSubnet3DefaultRoute30C45F47", + "vpcPrivateSubnet3RouteTable24DA79A0", + "vpcPrivateSubnet3RouteTableAssociationC58B3C2C", + "vpcPrivateSubnet3Subnet985AC459", + "vpcPublicSubnet1DefaultRoute10708846", + "vpcPublicSubnet1EIPDA49DCBE", + "vpcPublicSubnet1NATGateway9C16659E", + "vpcPublicSubnet1RouteTable48A2DF9B", + "vpcPublicSubnet1RouteTableAssociation5D3F4579", + "vpcPublicSubnet1Subnet2E65531E", + "vpcPublicSubnet2DefaultRouteA1EC0F60", + "vpcPublicSubnet2EIP9B3743B1", + "vpcPublicSubnet2NATGateway9B8AE11A", + "vpcPublicSubnet2RouteTableEB40D4CB", + "vpcPublicSubnet2RouteTableAssociation21F81B59", + "vpcPublicSubnet2Subnet009B674F", + "vpcPublicSubnet3DefaultRoute3F356A11", + "vpcPublicSubnet3EIP2C3B9D91", + "vpcPublicSubnet3NATGateway82F6CA9E", + "vpcPublicSubnet3RouteTableA3C00665", + "vpcPublicSubnet3RouteTableAssociationD102D1C4", + "vpcPublicSubnet3Subnet11B92D7C", + "vpcA2121C38", + "vpcVPCGW7984C166" + ] + }, + "batchdemandcomputeenvlaunchtemplateInstanceProfile2DEC3A97": { + "Type": "AWS::IAM::InstanceProfile", + "Properties": { + "Roles": [ + { + "Ref": "batchdemandcomputeenvlaunchtemplateEcsInstanceRole24D4E799" + } + ] }, "DependsOn": [ "vpcIGWE57CBDCA", @@ -610,10 +697,10 @@ "vpcVPCGW7984C166" ] }, - "batchdemandcomputeenvResourceSecurityGroup64711D4D": { + "batchdemandcomputeenvlaunchtemplateResourceSecurityGroup23599B84": { "Type": "AWS::EC2::SecurityGroup", "Properties": { - "GroupDescription": "batch-stack/batch-demand-compute-env/Resource-Security-Group", + "GroupDescription": "batch-stack/batch-demand-compute-env-launch-template/Resource-Security-Group", "SecurityGroupEgress": [ { "CidrIp": "0.0.0.0/0", @@ -661,7 +748,7 @@ "vpcVPCGW7984C166" ] }, - "batchdemandcomputeenvResourceServiceInstanceRole8DF7CB96": { + "batchdemandcomputeenvlaunchtemplateResourceServiceInstanceRole76AD99CC": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -727,12 +814,12 @@ "vpcVPCGW7984C166" ] }, - "batchdemandcomputeenv6131030A": { + "batchdemandcomputeenvlaunchtemplateF8A5B233": { "Type": "AWS::Batch::ComputeEnvironment", "Properties": { "ServiceRole": { "Fn::GetAtt": [ - "batchdemandcomputeenvResourceServiceInstanceRole8DF7CB96", + "batchdemandcomputeenvlaunchtemplateResourceServiceInstanceRole76AD99CC", "Arn" ] }, @@ -741,19 +828,22 @@ "AllocationStrategy": "BEST_FIT", "InstanceRole": { "Fn::GetAtt": [ - "batchdemandcomputeenvResourceInstanceRole8989496E", + "batchdemandcomputeenvlaunchtemplateInstanceProfile2DEC3A97", "Arn" ] }, "InstanceTypes": [ "optimal" ], + "LaunchTemplate": { + "LaunchTemplateName": "EC2LaunchTemplate" + }, "MaxvCpus": 256, "MinvCpus": 0, "SecurityGroupIds": [ { "Fn::GetAtt": [ - "batchdemandcomputeenvResourceSecurityGroup64711D4D", + "batchdemandcomputeenvlaunchtemplateResourceSecurityGroup23599B84", "GroupId" ] } @@ -809,7 +899,7 @@ "vpcVPCGW7984C166" ] }, - "batchspotcomputeenvResourceInstanceRoleF6188F15": { + "batchspotcomputeenvEcsInstanceRoleE976826B": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -818,12 +908,81 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "Service": "batch.amazonaws.com" + "Service": { + "Fn::Join": [ + "", + [ + "ec2.", + { + "Ref": "AWS::URLSuffix" + } + ] + ] + } } } ], "Version": "2012-10-17" - } + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" + ] + ] + } + ] + }, + "DependsOn": [ + "vpcIGWE57CBDCA", + "vpcPrivateSubnet1DefaultRoute1AA8E2E5", + "vpcPrivateSubnet1RouteTableB41A48CC", + "vpcPrivateSubnet1RouteTableAssociation67945127", + "vpcPrivateSubnet1Subnet934893E8", + "vpcPrivateSubnet2DefaultRouteB0E07F99", + "vpcPrivateSubnet2RouteTable7280F23E", + "vpcPrivateSubnet2RouteTableAssociation007E94D3", + "vpcPrivateSubnet2Subnet7031C2BA", + "vpcPrivateSubnet3DefaultRoute30C45F47", + "vpcPrivateSubnet3RouteTable24DA79A0", + "vpcPrivateSubnet3RouteTableAssociationC58B3C2C", + "vpcPrivateSubnet3Subnet985AC459", + "vpcPublicSubnet1DefaultRoute10708846", + "vpcPublicSubnet1EIPDA49DCBE", + "vpcPublicSubnet1NATGateway9C16659E", + "vpcPublicSubnet1RouteTable48A2DF9B", + "vpcPublicSubnet1RouteTableAssociation5D3F4579", + "vpcPublicSubnet1Subnet2E65531E", + "vpcPublicSubnet2DefaultRouteA1EC0F60", + "vpcPublicSubnet2EIP9B3743B1", + "vpcPublicSubnet2NATGateway9B8AE11A", + "vpcPublicSubnet2RouteTableEB40D4CB", + "vpcPublicSubnet2RouteTableAssociation21F81B59", + "vpcPublicSubnet2Subnet009B674F", + "vpcPublicSubnet3DefaultRoute3F356A11", + "vpcPublicSubnet3EIP2C3B9D91", + "vpcPublicSubnet3NATGateway82F6CA9E", + "vpcPublicSubnet3RouteTableA3C00665", + "vpcPublicSubnet3RouteTableAssociationD102D1C4", + "vpcPublicSubnet3Subnet11B92D7C", + "vpcA2121C38", + "vpcVPCGW7984C166" + ] + }, + "batchspotcomputeenvInstanceProfileFA613AC2": { + "Type": "AWS::IAM::InstanceProfile", + "Properties": { + "Roles": [ + { + "Ref": "batchspotcomputeenvEcsInstanceRoleE976826B" + } + ] }, "DependsOn": [ "vpcIGWE57CBDCA", @@ -989,11 +1148,11 @@ }, "Type": "MANAGED", "ComputeResources": { - "AllocationStrategy": "BEST_FIT", + "AllocationStrategy": "SPOT_CAPACITY_OPTIMIZED", "BidPercentage": 80, "InstanceRole": { "Fn::GetAtt": [ - "batchspotcomputeenvResourceInstanceRoleF6188F15", + "batchspotcomputeenvInstanceProfileFA613AC2", "Arn" ] }, @@ -1083,13 +1242,13 @@ "ComputeEnvironmentOrder": [ { "ComputeEnvironment": { - "Ref": "batchmanagedcomputeenv1AA975A9" + "Ref": "batchunmanagedcomputeenvED550298" }, "Order": 1 }, { "ComputeEnvironment": { - "Ref": "batchdemandcomputeenv6131030A" + "Ref": "batchdemandcomputeenvlaunchtemplateF8A5B233" }, "Order": 2 }, diff --git a/packages/@aws-cdk/aws-batch/test/integ.batch.ts b/packages/@aws-cdk/aws-batch/test/integ.batch.ts index c28d7d4f2e159..37c95d925cbec 100644 --- a/packages/@aws-cdk/aws-batch/test/integ.batch.ts +++ b/packages/@aws-cdk/aws-batch/test/integ.batch.ts @@ -10,25 +10,46 @@ const stack = new cdk.Stack(app, 'batch-stack'); const vpc = new ec2.Vpc(stack, 'vpc'); +const launchTemplate = new ec2.CfnLaunchTemplate(stack, 'ec2-launch-template', { + launchTemplateName: 'EC2LaunchTemplate', + launchTemplateData: { + blockDeviceMappings: [ + { + deviceName: '/dev/xvdcz', + ebs: { + encrypted: true, + volumeSize: 100, + volumeType: 'gp2' + } + } + ] + } +}); + new batch.JobQueue(stack, 'batch-job-queue', { computeEnvironments: [ { - computeEnvironment: new batch.ComputeEnvironment(stack, 'batch-managed-compute-env'), + computeEnvironment: new batch.ComputeEnvironment(stack, 'batch-unmanaged-compute-env', { + managed: false + }), order: 1, }, { - computeEnvironment: new batch.ComputeEnvironment(stack, 'batch-demand-compute-env', { - managed: false, + computeEnvironment: new batch.ComputeEnvironment(stack, 'batch-demand-compute-env-launch-template', { + managed: true, computeResources: { type: batch.ComputeResourceType.ON_DEMAND, vpc, + launchTemplate: { + launchTemplateName: launchTemplate.launchTemplateName as string, + }, }, }), order: 2, }, { computeEnvironment: new batch.ComputeEnvironment(stack, 'batch-spot-compute-env', { - managed: false, + managed: true, computeResources: { type: batch.ComputeResourceType.SPOT, vpc, diff --git a/packages/@aws-cdk/aws-batch/test/job-queue.test.ts b/packages/@aws-cdk/aws-batch/test/job-queue.test.ts index d99a6ad82e8fe..9a20f0334a8ce 100644 --- a/packages/@aws-cdk/aws-batch/test/job-queue.test.ts +++ b/packages/@aws-cdk/aws-batch/test/job-queue.test.ts @@ -9,7 +9,9 @@ describe('Batch Job Queue', () => { beforeEach(() => { stack = new cdk.Stack(); - computeEnvironment = new batch.ComputeEnvironment(stack, 'test-compute-env'); + computeEnvironment = new batch.ComputeEnvironment(stack, 'test-compute-env', { + managed: false + }); }); it('can be imported from an ARN', () => {