Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
TODO: look at permissions?
  • Loading branch information
SoManyHs committed Mar 20, 2019
1 parent d2b3e2f commit 314f75a
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 12 deletions.
8 changes: 4 additions & 4 deletions packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,25 +200,25 @@ export class Ec2Service extends BaseService implements elb.ILoadBalancerTarget {
throw new Error("Cannot enable service discovery if a Cloudmap Namespace has not been created in the cluster.");
}

// This is why it's defined here not in fargate service
// Determine DNS type based on network mode
const networkMode = this.taskDefinition.networkMode;

if (networkMode === NetworkMode.None) {
throw new Error("Cannot use a service discovery if NetworkMode is None. Use Host or AwsVpc instead.");
throw new Error("Cannot use a service discovery if NetworkMode is None. Use Bridge, Host or AwsVpc instead.");
}

// Bridge or host network mode requires SRV records
// FIXME
let dnsRecordType = options.dnsRecordType;

if (networkMode === NetworkMode.Bridge || networkMode === NetworkMode.Host) {
if (dnsRecordType !== cloudmap.DnsRecordType.SRV) {
throw new Error("Cannot use a service discovery if NetworkMode is None. Use Host or AwsVpc instead.");
throw new Error("SRV records must be used when network mode is Bridge or Host.");
}
dnsRecordType = cloudmap.DnsRecordType.SRV;
}

if (networkMode === NetworkMode.AwsVpc && options.dnsRecordType === undefined ) {
if (networkMode === NetworkMode.AwsVpc && options.dnsRecordType === undefined && sdNamespace.type !== cloudmap.NamespaceType.Http) {
// ECS does not currently support IPv6, so AAAA records not possible
dnsRecordType = cloudmap.DnsRecordType.A;
}
Expand Down
40 changes: 39 additions & 1 deletion packages/@aws-cdk/aws-ecs/lib/fargate/fargate-service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ec2 = require('@aws-cdk/aws-ec2');
import cloudmap = require('@aws-cdk/aws-servicediscovery');
import cdk = require('@aws-cdk/cdk');
import { BaseService, BaseServiceProps } from '../base/base-service';
import { BaseService, BaseServiceProps, ServiceDiscoveryOptions } from '../base/base-service';
import { TaskDefinition } from '../base/task-definition';
import { isFargateCompatible } from '../util';

Expand Down Expand Up @@ -70,6 +71,43 @@ export class FargateService extends BaseService {
throw new Error('A TaskDefinition must have at least one essential container');
}
}

public enableServiceDiscovery(options: ServiceDiscoveryOptions): cloudmap.Service {
const sdNamespace = this.cluster.serviceDiscoveryNamespace();
if (sdNamespace === undefined) {
throw new Error("Cannot enable service discovery if a Cloudmap Namespace has not been created in the cluster.");
}

if (options.dnsRecordType !== undefined && sdNamespace.type === cloudmap.NamespaceType.Http) {
throw new Error("Cannot specify a dnsRecordType with HTTP namespaces.");
}

const dnsRecordType = options.dnsRecordType === undefined
&& sdNamespace.type !== cloudmap.NamespaceType.Http ? cloudmap.DnsRecordType.A : undefined;

// If the task definition that your service task specifies uses the awsvpc network mode and a type SRV DNS record
// is used, you must specify a containerName and containerPort combination
const containerName = options.dnsRecordType === cloudmap.DnsRecordType.SRV ? this.taskDefinition.defaultContainer!.node.id : undefined;
const containerPort = options.dnsRecordType === cloudmap.DnsRecordType.SRV ? this.taskDefinition.defaultContainer!.containerPort : undefined;

const cloudmapService = new cloudmap.Service(this, 'CloudmapService', {
namespace: sdNamespace,
name: options.name,
dnsRecordType: dnsRecordType!,
customHealthCheck: { failureThreshold: options.failureThreshold || 1 }
});

const serviceArn = cloudmapService.serviceArn;

// add Cloudmap service to the ECS Service's serviceRegistry
this.addServiceRegistry({
arn: serviceArn,
containerName,
containerPort
});

return cloudmapService;
}
}

/**
Expand Down
15 changes: 8 additions & 7 deletions packages/@aws-cdk/aws-ecs/test/ec2/integ.sd-bridge-nw.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import ec2 = require('@aws-cdk/aws-ec2');
// import ecr = require('@aws-cdk/aws-ecr');
// import cloudmap = require('@aws-cdk/aws-servicediscovery');
import cdk = require('@aws-cdk/cdk');
import ecs = require('../../lib');
// import { NetworkMode } from '../../lib';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'aws-ecs-integ-ecs');
Expand All @@ -15,11 +14,13 @@ cluster.addCapacity('DefaultAutoScalingGroup', {
instanceType: new ec2.InstanceType('t2.micro')
});

// const domainName = "scorekeep.com";
// cluster.addNamespace({name: domainName});
// Add HTTP Namespace
const domainName = "scorekeep.com";
cluster.addNamespace({ name: domainName });

// Create frontend service
const frontendTD = new ecs.Ec2TaskDefinition(stack, 'frontendTD');
const frontendTD = new ecs.FargateTaskDefinition(stack, 'frontendTD', {
});

const frontend = frontendTD.addContainer('frontend', {
image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"),
Expand All @@ -28,11 +29,11 @@ const frontend = frontendTD.addContainer('frontend', {

frontend.addPortMappings({
containerPort: 80,
hostPort: 8080,
hostPort: 80,
protocol: ecs.Protocol.Tcp
});

const frontendService = new ecs.Ec2Service(stack, "FrontendService", {
const frontendService = new ecs.FargateService(stack, "FrontendService", {
cluster,
taskDefinition: frontendTD,
});
Expand Down
141 changes: 141 additions & 0 deletions packages/@aws-cdk/aws-ecs/test/fargate/test.fargate-service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { expect, haveResource, haveResourceLike } from '@aws-cdk/assert';
import ec2 = require('@aws-cdk/aws-ec2');
import elbv2 = require("@aws-cdk/aws-elasticloadbalancingv2");
import cloudmap = require('@aws-cdk/aws-servicediscovery');
import cdk = require('@aws-cdk/cdk');
import { Test } from 'nodeunit';
import ecs = require('../../lib');
Expand Down Expand Up @@ -237,6 +238,146 @@ export = {

test.done();
}
},

'When enabling service discovery': {
'creates cloud map service for Http namespace'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {});
const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc });
const taskDefinition = new ecs.FargateTaskDefinition(stack, 'FargateTaskDef');
const container = taskDefinition.addContainer('MainContainer', {
image: ContainerImage.fromRegistry('hello'),
});
container.addPortMappings({ containerPort: 8000 });
const service = new ecs.FargateService(stack, 'Service', { cluster, taskDefinition });
// WHEN
cluster.addNamespace({ name: 'foo.com' });
service.enableServiceDiscovery({
name: 'myApp',
});

// THEN
expect(stack).to(haveResource('AWS::ServiceDiscovery::Service', {
HealthCheckCustomConfig: {
FailureThreshold: 1
},
Name: "myApp",
NamespaceId: {
'Fn::GetAtt': [
"EcsClusterDefaultServiceDiscoveryNamespaceB0971B2F",
"Id"
]
}
}));

test.done();
},

'creates cloud map service for Private DNS namespace'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {});
const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc });
const taskDefinition = new ecs.FargateTaskDefinition(stack, 'FargateTaskDef');
const container = taskDefinition.addContainer('MainContainer', {
image: ContainerImage.fromRegistry('hello'),
});
container.addPortMappings({ containerPort: 8000 });
const service = new ecs.FargateService(stack, 'Service', { cluster, taskDefinition });
// WHEN
cluster.addNamespace({
name: 'foo.com',
type: cloudmap.NamespaceType.DnsPrivate
});
service.enableServiceDiscovery({
name: 'myApp',
});

// THEN
expect(stack).to(haveResource('AWS::ServiceDiscovery::Service', {
DnsConfig: {
DnsRecords: [
{
TTL: "60",
Type: "A"
}
],
NamespaceId: {
"Fn::GetAtt": [
"EcsClusterDefaultServiceDiscoveryNamespaceB0971B2F",
"Id"
]
},
RoutingPolicy: "MULTIVALUE"
},
HealthCheckCustomConfig: {
FailureThreshold: 1
},
Name: "myApp",
NamespaceId: {
'Fn::GetAtt': [
"EcsClusterDefaultServiceDiscoveryNamespaceB0971B2F",
"Id"
]
}
}));

test.done();
},

// FIXME
'creates cloud map service for Public DNS namespace'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.VpcNetwork(stack, 'MyVpc', {});
const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc });
const taskDefinition = new ecs.FargateTaskDefinition(stack, 'FargateTaskDef');
const container = taskDefinition.addContainer('MainContainer', {
image: ContainerImage.fromRegistry('hello'),
});
container.addPortMappings({ containerPort: 8000 });
const service = new ecs.FargateService(stack, 'Service', { cluster, taskDefinition });
// WHEN
cluster.addNamespace({
name: 'foo.com',
type: cloudmap.NamespaceType.DnsPublic
});
service.enableServiceDiscovery({
name: 'myApp',
});

// THEN
expect(stack).to(haveResource('AWS::ServiceDiscovery::Service', {
DnsConfig: {
DnsRecords: [
{
TTL: "60",
Type: "A"
}
],
NamespaceId: {
"Fn::GetAtt": [
"EcsClusterDefaultServiceDiscoveryNamespaceB0971B2F",
"Id"
]
},
RoutingPolicy: "MULTIVALUE"
},
HealthCheckConfig: {
FailureThreshold: 1
},
Name: "myApp",
NamespaceId: {
'Fn::GetAtt': [
"EcsClusterDefaultServiceDiscoveryNamespaceB0971B2F",
"Id"
]
}
}));

test.done();
},
}
};

0 comments on commit 314f75a

Please sign in to comment.