Skip to content

Commit 705c736

Browse files
authored
Merge branch 'master' into sdamle-ec2
2 parents d9359d3 + 38de8ec commit 705c736

File tree

39 files changed

+1630
-124
lines changed

39 files changed

+1630
-124
lines changed

CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ For day-to-day development and normal contributions, the following SDKs and tool
5151
- [Node.js 10.13.0](https://nodejs.org/download/release/latest-v10.x/)
5252
- [Yarn >= 1.19.1](https://yarnpkg.com/lang/en/docs/install)
5353
- [Java OpenJDK 8](http://openjdk.java.net/install/)
54-
- [.NET Core SDK 3.0](https://www.microsoft.com/net/download)
54+
- [.NET Core SDK 3.1](https://www.microsoft.com/net/download)
5555
- [Python 3.6.5](https://www.python.org/downloads/release/python-365/)
5656
- [Ruby 2.5.1](https://www.ruby-lang.org/en/news/2018/03/28/ruby-2-5-1-released/)
5757

package.json

+4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
"graceful-fs": "^4.2.4",
2525
"typescript": "~3.8.3"
2626
},
27+
"resolutions-comment": "should be removed or reviewed when nodeunit dependency is dropped or adjusted",
28+
"resolutions": {
29+
"tap-mocha-reporter": "^5.0.1"
30+
},
2731
"repository": {
2832
"type": "git",
2933
"url": "git://github.com/aws/aws-cdk"

packages/@aws-cdk/aws-batch/lib/job-definition.ts

+3
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,9 @@ export class JobDefinition extends Resource implements IJobDefinition {
337337
memory: container.memoryLimitMiB || 4,
338338
mountPoints: container.mountPoints,
339339
privileged: container.privileged || false,
340+
resourceRequirements: container.gpuCount
341+
? [{ type: 'GPU', value: String(container.gpuCount) }]
342+
: undefined,
340343
readonlyRootFilesystem: container.readOnly || false,
341344
ulimits: container.ulimits,
342345
user: container.user,

packages/@aws-cdk/aws-batch/test/job-definition.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ describe('Batch Job Definition', () => {
7878
MountPoints: [],
7979
Privileged: jobDefProps.container.privileged,
8080
ReadonlyRootFilesystem: jobDefProps.container.readOnly,
81+
ResourceRequirements: [{ Type: 'GPU', Value: String(jobDefProps.container.gpuCount)}],
8182
Ulimits: [],
8283
User: jobDefProps.container.user,
8384
Vcpus: jobDefProps.container.vcpus,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// tslint:disable: no-console
2+
3+
export function handler(event: any) {
4+
console.log('I am a custom resource');
5+
console.log(event);
6+
return {
7+
PhysicalResourceId: event.ResourceProperties.physicalResourceId,
8+
Data: event.ResourceProperties.attributes,
9+
};
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
{
2+
"Resources": {
3+
"CustomReflectCustomResourceProviderRoleB4B29AEC": {
4+
"Type": "AWS::IAM::Role",
5+
"Properties": {
6+
"AssumeRolePolicyDocument": {
7+
"Version": "2012-10-17",
8+
"Statement": [
9+
{
10+
"Action": "sts:AssumeRole",
11+
"Effect": "Allow",
12+
"Principal": {
13+
"Service": "lambda.amazonaws.com"
14+
}
15+
}
16+
]
17+
},
18+
"ManagedPolicyArns": [
19+
{
20+
"Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
21+
}
22+
]
23+
}
24+
},
25+
"CustomReflectCustomResourceProviderHandler2E189D0B": {
26+
"Type": "AWS::Lambda::Function",
27+
"Properties": {
28+
"Code": {
29+
"S3Bucket": {
30+
"Ref": "AssetParametersd46d1ebe2c1958c6352664721f77acb9c78131013956eb82d3d36cf503098e7aS3Bucket1D703CB8"
31+
},
32+
"S3Key": {
33+
"Fn::Join": [
34+
"",
35+
[
36+
{
37+
"Fn::Select": [
38+
0,
39+
{
40+
"Fn::Split": [
41+
"||",
42+
{
43+
"Ref": "AssetParametersd46d1ebe2c1958c6352664721f77acb9c78131013956eb82d3d36cf503098e7aS3VersionKey01A97AE3"
44+
}
45+
]
46+
}
47+
]
48+
},
49+
{
50+
"Fn::Select": [
51+
1,
52+
{
53+
"Fn::Split": [
54+
"||",
55+
{
56+
"Ref": "AssetParametersd46d1ebe2c1958c6352664721f77acb9c78131013956eb82d3d36cf503098e7aS3VersionKey01A97AE3"
57+
}
58+
]
59+
}
60+
]
61+
}
62+
]
63+
]
64+
}
65+
},
66+
"Timeout": 900,
67+
"MemorySize": 128,
68+
"Handler": "__entrypoint__.handler",
69+
"Role": {
70+
"Fn::GetAtt": [
71+
"CustomReflectCustomResourceProviderRoleB4B29AEC",
72+
"Arn"
73+
]
74+
},
75+
"Runtime": "nodejs12.x"
76+
},
77+
"DependsOn": [
78+
"CustomReflectCustomResourceProviderRoleB4B29AEC"
79+
]
80+
},
81+
"MyResource": {
82+
"Type": "Custom::Reflect",
83+
"Properties": {
84+
"ServiceToken": {
85+
"Fn::GetAtt": [
86+
"CustomReflectCustomResourceProviderHandler2E189D0B",
87+
"Arn"
88+
]
89+
},
90+
"physicalResourceId": "MyPhysicalReflectBack",
91+
"attributes": {
92+
"Attribute1": "foo",
93+
"Attribute2": 1234
94+
}
95+
},
96+
"UpdateReplacePolicy": "Delete",
97+
"DeletionPolicy": "Delete"
98+
}
99+
},
100+
"Parameters": {
101+
"AssetParametersd46d1ebe2c1958c6352664721f77acb9c78131013956eb82d3d36cf503098e7aS3Bucket1D703CB8": {
102+
"Type": "String",
103+
"Description": "S3 bucket for asset \"d46d1ebe2c1958c6352664721f77acb9c78131013956eb82d3d36cf503098e7a\""
104+
},
105+
"AssetParametersd46d1ebe2c1958c6352664721f77acb9c78131013956eb82d3d36cf503098e7aS3VersionKey01A97AE3": {
106+
"Type": "String",
107+
"Description": "S3 key for asset version \"d46d1ebe2c1958c6352664721f77acb9c78131013956eb82d3d36cf503098e7a\""
108+
},
109+
"AssetParametersd46d1ebe2c1958c6352664721f77acb9c78131013956eb82d3d36cf503098e7aArtifactHash16A571C9": {
110+
"Type": "String",
111+
"Description": "Artifact hash for asset \"d46d1ebe2c1958c6352664721f77acb9c78131013956eb82d3d36cf503098e7a\""
112+
}
113+
},
114+
"Outputs": {
115+
"Ref": {
116+
"Value": {
117+
"Ref": "MyResource"
118+
}
119+
},
120+
"GetAttAttribute1": {
121+
"Value": {
122+
"Fn::GetAtt": [
123+
"MyResource",
124+
"Attribute1"
125+
]
126+
}
127+
},
128+
"GetAttAttribute2": {
129+
"Value": {
130+
"Fn::GetAtt": [
131+
"MyResource",
132+
"Attribute2"
133+
]
134+
}
135+
}
136+
}
137+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Stack verification steps:
3+
* - Deploy with `--no-clean`
4+
* - Verify that the CloudFormation stack outputs have the following values:
5+
* - Ref: "MyPhysicalReflectBack"
6+
* - GetAtt.Attribute1: "foo"
7+
* - GetAtt.Attribute2: 1234
8+
*/
9+
import { App, CfnOutput, Construct, CustomResource, CustomResourceProvider, CustomResourceProviderRuntime, Stack, Token } from '@aws-cdk/core';
10+
11+
class TestStack extends Stack {
12+
constructor(scope: Construct, id: string) {
13+
super(scope, id);
14+
15+
const resourceType = 'Custom::Reflect';
16+
17+
const serviceToken = CustomResourceProvider.getOrCreate(this, resourceType, {
18+
codeDirectory: `${__dirname}/core-custom-resource-provider-fixture`,
19+
runtime: CustomResourceProviderRuntime.NODEJS_12,
20+
});
21+
22+
const cr = new CustomResource(this, 'MyResource', {
23+
resourceType,
24+
serviceToken,
25+
properties: {
26+
physicalResourceId: 'MyPhysicalReflectBack',
27+
attributes: {
28+
Attribute1: 'foo',
29+
Attribute2: 1234,
30+
},
31+
},
32+
});
33+
34+
new CfnOutput(this, 'Ref', { value: cr.ref });
35+
new CfnOutput(this, 'GetAtt.Attribute1', { value: Token.asString(cr.getAtt('Attribute1')) });
36+
new CfnOutput(this, 'GetAtt.Attribute2', { value: Token.asString(cr.getAtt('Attribute2')) });
37+
}
38+
}
39+
40+
const app = new App();
41+
new TestStack(app, 'custom-resource-test');
42+
app.synth();

packages/@aws-cdk/aws-codepipeline-actions/package.json

+1-3
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,8 @@
5050
},
5151
"keywords": [
5252
"aws",
53-
"aws-clib",
54-
"aws-cloudlib",
5553
"cdk",
56-
"cloudlib",
54+
"constructs",
5755
"codepipeline",
5856
"pipeline"
5957
],

packages/@aws-cdk/aws-codepipeline/package.json

+1-3
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,8 @@
5555
},
5656
"keywords": [
5757
"aws",
58-
"aws-clib",
59-
"aws-cloudlib",
6058
"cdk",
61-
"cloudlib",
59+
"constructs",
6260
"codepipeline",
6361
"pipeline"
6462
],

packages/@aws-cdk/aws-ecs/lib/base/base-service.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -347,14 +347,18 @@ export abstract class BaseService extends Resource
347347
propagateTags: props.propagateTags === PropagatedTagSource.NONE ? undefined : props.propagateTags,
348348
enableEcsManagedTags: props.enableECSManagedTags === undefined ? false : props.enableECSManagedTags,
349349
deploymentController: props.deploymentController,
350-
launchType: props.launchType,
350+
launchType: props.deploymentController?.type === DeploymentControllerType.EXTERNAL ? undefined : props.launchType,
351351
healthCheckGracePeriodSeconds: this.evaluateHealthGracePeriod(props.healthCheckGracePeriod),
352352
/* role: never specified, supplanted by Service Linked Role */
353353
networkConfiguration: Lazy.anyValue({ produce: () => this.networkConfiguration }, { omitEmptyArray: true }),
354354
serviceRegistries: Lazy.anyValue({ produce: () => this.serviceRegistries }, { omitEmptyArray: true }),
355355
...additionalProps,
356356
});
357357

358+
if (props.deploymentController?.type === DeploymentControllerType.EXTERNAL) {
359+
this.node.addWarning('taskDefinition and launchType are blanked out when using external deployment controller.');
360+
}
361+
358362
this.serviceArn = this.getResourceArnAttribute(this.resource.ref, {
359363
service: 'ecs',
360364
resource: 'service',

packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as ec2 from '@aws-cdk/aws-ec2';
22
import { Construct, Lazy, Resource, Stack } from '@aws-cdk/core';
3-
import { BaseService, BaseServiceOptions, IBaseService, IService, LaunchType, PropagatedTagSource } from '../base/base-service';
3+
import { BaseService, BaseServiceOptions, DeploymentControllerType, IBaseService, IService, LaunchType, PropagatedTagSource } from '../base/base-service';
44
import { fromServiceAtrributes } from '../base/from-service-attributes';
55
import { NetworkMode, TaskDefinition } from '../base/task-definition';
66
import { ICluster } from '../cluster';
@@ -154,8 +154,8 @@ export class Ec2Service extends BaseService implements IEc2Service {
154154
throw new Error('Maximum percent must be 100 for daemon mode.');
155155
}
156156

157-
if (props.daemon && props.minHealthyPercent !== undefined && props.minHealthyPercent !== 0) {
158-
throw new Error('Minimum healthy percent must be 0 for daemon mode.');
157+
if (props.minHealthyPercent !== undefined && props.maxHealthyPercent !== undefined && props.minHealthyPercent >= props.maxHealthyPercent) {
158+
throw new Error('Minimum healthy percent must be less than maximum healthy percent.');
159159
}
160160

161161
if (!props.taskDefinition.isEc2Compatible) {
@@ -181,7 +181,7 @@ export class Ec2Service extends BaseService implements IEc2Service {
181181
},
182182
{
183183
cluster: props.cluster.clusterName,
184-
taskDefinition: props.taskDefinition.taskDefinitionArn,
184+
taskDefinition: props.deploymentController?.type === DeploymentControllerType.EXTERNAL ? undefined : props.taskDefinition.taskDefinitionArn,
185185
placementConstraints: Lazy.anyValue({ produce: () => this.constraints }, { omitEmptyArray: true }),
186186
placementStrategies: Lazy.anyValue({ produce: () => this.strategies }, { omitEmptyArray: true }),
187187
schedulingStrategy: props.daemon ? 'DAEMON' : 'REPLICA',

packages/@aws-cdk/aws-ecs/lib/fargate/fargate-service.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as ec2 from '@aws-cdk/aws-ec2';
22
import * as cdk from '@aws-cdk/core';
3-
import { BaseService, BaseServiceOptions, IBaseService, IService, LaunchType, PropagatedTagSource } from '../base/base-service';
3+
import { BaseService, BaseServiceOptions, DeploymentControllerType, IBaseService, IService, LaunchType, PropagatedTagSource } from '../base/base-service';
44
import { fromServiceAtrributes } from '../base/from-service-attributes';
55
import { TaskDefinition } from '../base/task-definition';
66
import { ICluster } from '../cluster';
@@ -139,7 +139,7 @@ export class FargateService extends BaseService implements IFargateService {
139139
enableECSManagedTags: props.enableECSManagedTags,
140140
}, {
141141
cluster: props.cluster.clusterName,
142-
taskDefinition: props.taskDefinition.taskDefinitionArn,
142+
taskDefinition: props.deploymentController?.type === DeploymentControllerType.EXTERNAL ? undefined : props.taskDefinition.taskDefinitionArn,
143143
platformVersion: props.platformVersion,
144144
}, props.taskDefinition);
145145

packages/@aws-cdk/aws-ecs/test/ec2/test.ec2-service.ts

+44-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as cloudmap from '@aws-cdk/aws-servicediscovery';
66
import * as cdk from '@aws-cdk/core';
77
import { Test } from 'nodeunit';
88
import * as ecs from '../../lib';
9-
import { LaunchType, PropagatedTagSource } from '../../lib/base/base-service';
9+
import { DeploymentControllerType, LaunchType, PropagatedTagSource } from '../../lib/base/base-service';
1010
import { PlacementConstraint, PlacementStrategy } from '../../lib/placement';
1111

1212
export = {
@@ -262,6 +262,45 @@ export = {
262262
test.done();
263263
},
264264

265+
'ignore task definition and launch type if deployment controller is set to be EXTERNAL'(test: Test) {
266+
// GIVEN
267+
const stack = new cdk.Stack();
268+
const vpc = new ec2.Vpc(stack, 'MyVpc', {});
269+
const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc });
270+
cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: new ec2.InstanceType('t2.micro') });
271+
const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDef');
272+
273+
taskDefinition.addContainer('web', {
274+
image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
275+
memoryLimitMiB: 512,
276+
});
277+
278+
const service = new ecs.Ec2Service(stack, 'Ec2Service', {
279+
cluster,
280+
taskDefinition,
281+
deploymentController: {
282+
type: DeploymentControllerType.EXTERNAL,
283+
},
284+
});
285+
286+
// THEN
287+
test.deepEqual(service.node.metadata[0].data, 'taskDefinition and launchType are blanked out when using external deployment controller.');
288+
expect(stack).to(haveResource('AWS::ECS::Service', {
289+
Cluster: {
290+
Ref: 'EcsCluster97242B84',
291+
},
292+
DeploymentConfiguration: {
293+
MaximumPercent: 200,
294+
MinimumHealthyPercent: 50,
295+
},
296+
DesiredCount: 1,
297+
SchedulingStrategy: 'REPLICA',
298+
EnableECSManagedTags: false,
299+
}));
300+
301+
test.done();
302+
},
303+
265304
'errors if daemon and desiredCount both specified'(test: Test) {
266305
// GIVEN
267306
const stack = new cdk.Stack();
@@ -312,7 +351,7 @@ export = {
312351
test.done();
313352
},
314353

315-
'errors if daemon and minimum not 0'(test: Test) {
354+
'errors if minimum not less than maximum'(test: Test) {
316355
// GIVEN
317356
const stack = new cdk.Stack();
318357
const vpc = new ec2.Vpc(stack, 'MyVpc', {});
@@ -330,9 +369,10 @@ export = {
330369
cluster,
331370
taskDefinition,
332371
daemon: true,
333-
minHealthyPercent: 50,
372+
minHealthyPercent: 100,
373+
maxHealthyPercent: 100,
334374
});
335-
}, /Minimum healthy percent must be 0 for daemon mode./);
375+
}, /Minimum healthy percent must be less than maximum healthy percent./);
336376

337377
test.done();
338378
},

0 commit comments

Comments
 (0)