Skip to content

Commit

Permalink
Merge branch 'master' into benisrae/eks-prune
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Dec 10, 2020
2 parents 48b4cb0 + 0d289cc commit fa13592
Show file tree
Hide file tree
Showing 29 changed files with 1,386 additions and 493 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,11 @@ export class AppMeshExtension extends ServiceExtension {
this.virtualNode = new appmesh.VirtualNode(this.scope, `${this.parentService.id}-virtual-node`, {
mesh: this.mesh,
virtualNodeName: this.parentService.id,
cloudMapService: service.cloudMapService,
serviceDiscovery: service.cloudMapService
? appmesh.ServiceDiscovery.cloudMap({
service: service.cloudMapService,
})
: undefined,
listeners: [addListener(this.protocol, containerextension.trafficPort)],
});

Expand Down
16 changes: 11 additions & 5 deletions packages/@aws-cdk/aws-appmesh/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ mesh.addVirtualService('virtual-service', {

A `virtual node` acts as a logical pointer to a particular task group, such as an Amazon ECS service or a Kubernetes deployment.

When you create a `virtual node`, you must specify the DNS service discovery hostname for your task group. Any inbound traffic that your `virtual node` expects should be specified as a listener. Any outbound traffic that your `virtual node` expects to reach should be specified as a backend.
When you create a `virtual node`, any inbound traffic that your `virtual node` expects should be specified as a listener. Any outbound traffic that your `virtual node` expects to reach should be specified as a backend.

The response metadata for your new `virtual node` contains the Amazon Resource Name (ARN) that is associated with the `virtual node`. Set this value (either the full ARN or the truncated resource name) as the APPMESH_VIRTUAL_NODE_NAME environment variable for your task group's Envoy proxy container in your task definition or pod spec. For example, the value could be mesh/default/virtualNode/simpleapp. This is then mapped to the node.id and node.cluster Envoy parameters.

Expand All @@ -146,7 +146,9 @@ const namespace = new servicediscovery.PrivateDnsNamespace(this, 'test-namespace
const service = namespace.createService('Svc');

const node = mesh.addVirtualNode('virtual-node', {
cloudMapService: service,
serviceDiscovery: appmesh.ServiceDiscovery.cloudMap({
service: service,
}),
listeners: [appmesh.VirtualNodeListener.httpNodeListener({
port: 8081,
healthCheck: {
Expand All @@ -168,7 +170,9 @@ Create a `VirtualNode` with the constructor and add tags.
```ts
const node = new VirtualNode(this, 'node', {
mesh,
cloudMapService: service,
serviceDiscovery: appmesh.ServiceDiscovery.cloudMap({
service: service,
}),
listeners: [appmesh.VirtualNodeListener.httpNodeListener({
port: 8080,
healthCheck: {
Expand Down Expand Up @@ -198,7 +202,9 @@ Create a `VirtualNode` with the constructor and add backend virtual service.
```ts
const node = new VirtualNode(this, 'node', {
mesh,
cloudMapService: service,
serviceDiscovery: appmesh.ServiceDiscovery.cloudMap({
service: service,
}),
listeners: [appmesh.VirtualNodeListener.httpNodeListener({
port: 8080,
healthCheck: {
Expand All @@ -218,7 +224,7 @@ const node = new VirtualNode(this, 'node', {
});

const virtualService = new appmesh.VirtualService(stack, 'service-1', {
virtualServiceName: 'service1.domain.local',
serviceDiscovery: appmesh.ServiceDiscovery.dns('service1.domain.local'),
mesh,
clientPolicy: appmesh.ClientPolicy.fileTrust({
certificateChain: '/keys/local_cert_chain.pem',
Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-appmesh/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
export * from './appmesh.generated';
export * from './mesh';
export * from './route';
export * from './service-discovery';
export * from './route-spec';
export * from './shared-interfaces';
export * from './virtual-node';
Expand Down
110 changes: 110 additions & 0 deletions packages/@aws-cdk/aws-appmesh/lib/service-discovery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import * as cloudmap from '@aws-cdk/aws-servicediscovery';
import * as cdk from '@aws-cdk/core';
import { CfnVirtualNode } from './appmesh.generated';


/**
* Represents the properties needed to define CloudMap Service Discovery
*/
export interface CloudMapServiceDiscoveryOptions {
/**
* The AWS Cloud Map Service to use for service discovery
*/
readonly service: cloudmap.IService;

/**
* A string map that contains attributes with values that you can use to
* filter instances by any custom attribute that you specified when you
* registered the instance. Only instances that match all of the specified
* key/value pairs will be returned.
*
* @default - no instance attributes
*/
readonly instanceAttributes?: {[key: string]: string};
}

/**
* Properties for VirtualNode Service Discovery
*/
export interface ServiceDiscoveryConfig {
/**
* DNS based Service Discovery
*
* @default - no DNS based service discovery
*/
readonly dns?: CfnVirtualNode.DnsServiceDiscoveryProperty;

/**
* Cloud Map based Service Discovery
*
* @default - no Cloud Map based service discovery
*/
readonly cloudmap?: CfnVirtualNode.AwsCloudMapServiceDiscoveryProperty;
}

/**
* Provides the Service Discovery method a VirtualNode uses
*/
export abstract class ServiceDiscovery {
/**
* Returns DNS based service discovery
*/
public static dns(hostname: string): ServiceDiscovery {
return new DnsServiceDiscovery(hostname);
}

/**
* Returns Cloud Map based service discovery
*/
public static cloudMap(options: CloudMapServiceDiscoveryOptions): ServiceDiscovery {
return new CloudMapServiceDiscovery(options);
}

/**
* Binds the current object when adding Service Discovery to a VirtualNode
*/
public abstract bind(scope: cdk.Construct): ServiceDiscoveryConfig;
}

class DnsServiceDiscovery extends ServiceDiscovery {
private readonly hostname: string;

constructor(hostname: string) {
super();
this.hostname = hostname;
}

public bind(_scope: cdk.Construct): ServiceDiscoveryConfig {
return {
dns: {
hostname: this.hostname,
},
};
}
}

class CloudMapServiceDiscovery extends ServiceDiscovery {
private readonly service: cloudmap.IService;
private readonly instanceAttributes?: {[key: string]: string};

constructor(options: CloudMapServiceDiscoveryOptions) {
super();
this.service = options.service;
this.instanceAttributes = options.instanceAttributes;
}

public bind(_scope: cdk.Construct): ServiceDiscoveryConfig {
return {
cloudmap: {
namespaceName: this.service.namespace.namespaceName,
serviceName: this.service.serviceName,
attributes: renderAttributes(this.instanceAttributes),
},
};
}
}

function renderAttributes(attrs?: {[key: string]: string}) {
if (attrs === undefined) { return undefined; }
return Object.entries(attrs).map(([key, value]) => ({ key, value }));
}
41 changes: 7 additions & 34 deletions packages/@aws-cdk/aws-appmesh/lib/virtual-node.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as cloudmap from '@aws-cdk/aws-servicediscovery';
import * as cdk from '@aws-cdk/core';
import { Construct } from 'constructs';
import { CfnVirtualNode } from './appmesh.generated';
import { ClientPolicy } from './client-policy';
import { IMesh, Mesh } from './mesh';
import { ServiceDiscovery } from './service-discovery';
import { AccessLog } from './shared-interfaces';
import { VirtualNodeListener, VirtualNodeListenerConfig } from './virtual-node-listener';
import { IVirtualService } from './virtual-service';
Expand Down Expand Up @@ -48,32 +48,13 @@ export interface VirtualNodeBaseProps {
*/
readonly virtualNodeName?: string;

/**
* Host name of DNS record used to discover Virtual Node members
*
* The IP addresses returned by querying this DNS record will be considered
* part of the Virtual Node.
*
* @default - Don't use DNS-based service discovery
*/
readonly dnsHostName?: string;

/**
* CloudMap service where Virtual Node members register themselves
*
* Instances registering themselves into this CloudMap will
* be considered part of the Virtual Node.
* Defines how upstream clients will discover this VirtualNode
*
* @default - Don't use CloudMap-based service discovery
* @default - No Service Discovery
*/
readonly cloudMapService?: cloudmap.IService;

/**
* Filter down the list of CloudMap service instance
*
* @default - No CloudMap instance filter
*/
readonly cloudMapServiceInstanceAttributes?: {[key: string]: string};
readonly serviceDiscovery?: ServiceDiscovery;

/**
* Virtual Services that this is node expected to send outbound traffic to
Expand Down Expand Up @@ -196,6 +177,7 @@ export class VirtualNode extends VirtualNodeBase {
props.backends?.forEach(backend => this.addBackend(backend));
props.listeners?.forEach(listener => this.addListener(listener));
const accessLogging = props.accessLog?.bind(this);
const serviceDiscovery = props.serviceDiscovery?.bind(this);

const node = new CfnVirtualNode(this, 'Resource', {
virtualNodeName: this.physicalName,
Expand All @@ -205,12 +187,8 @@ export class VirtualNode extends VirtualNodeBase {
listeners: cdk.Lazy.anyValue({ produce: () => this.listeners.map(listener => listener.listener) }, { omitEmptyArray: true }),
backendDefaults: props.backendsDefaultClientPolicy?.bind(this),
serviceDiscovery: {
dns: props.dnsHostName !== undefined ? { hostname: props.dnsHostName } : undefined,
awsCloudMap: props.cloudMapService !== undefined ? {
serviceName: props.cloudMapService.serviceName,
namespaceName: props.cloudMapService.namespace.namespaceName,
attributes: renderAttributes(props.cloudMapServiceInstanceAttributes),
} : undefined,
dns: serviceDiscovery?.dns,
awsCloudMap: serviceDiscovery?.cloudmap,
},
logging: accessLogging !== undefined ? {
accessLog: accessLogging.virtualNodeAccessLog,
Expand Down Expand Up @@ -246,11 +224,6 @@ export class VirtualNode extends VirtualNodeBase {
}
}

function renderAttributes(attrs?: {[key: string]: string}) {
if (attrs === undefined) { return undefined; }
return Object.entries(attrs).map(([key, value]) => ({ key, value }));
}

/**
* Interface with properties necessary to import a reusable VirtualNode
*/
Expand Down
6 changes: 3 additions & 3 deletions packages/@aws-cdk/aws-appmesh/test/integ.mesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const virtualService = mesh.addVirtualService('service', {
});

const node = mesh.addVirtualNode('node', {
dnsHostName: `node1.${namespace.namespaceName}`,
serviceDiscovery: appmesh.ServiceDiscovery.dns(`node1.${namespace.namespaceName}`),
listeners: [appmesh.VirtualNodeListener.http({
healthCheck: {
healthyThreshold: 3,
Expand Down Expand Up @@ -65,7 +65,7 @@ router.addRoute('route-1', {
const certificateAuthorityArn = 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/12345678-1234-1234-1234-123456789012';

const node2 = mesh.addVirtualNode('node2', {
dnsHostName: `node2.${namespace.namespaceName}`,
serviceDiscovery: appmesh.ServiceDiscovery.dns(`node2.${namespace.namespaceName}`),
listeners: [appmesh.VirtualNodeListener.http({
healthCheck: {
healthyThreshold: 3,
Expand All @@ -89,7 +89,7 @@ const node2 = mesh.addVirtualNode('node2', {
});

const node3 = mesh.addVirtualNode('node3', {
dnsHostName: `node3.${namespace.namespaceName}`,
serviceDiscovery: appmesh.ServiceDiscovery.dns(`node3.${namespace.namespaceName}`),
listeners: [appmesh.VirtualNodeListener.http({
healthCheck: {
healthyThreshold: 3,
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-appmesh/test/test.health-check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const getNode = (stack: cdk.Stack) => {
meshName: 'test-mesh',
});
return mesh.addVirtualNode(`virtual-node-${idCounter}`, {
dnsHostName: 'test-node',
serviceDiscovery: appmesh.ServiceDiscovery.dns('test-node'),
});
};

Expand Down
16 changes: 9 additions & 7 deletions packages/@aws-cdk/aws-appmesh/test/test.mesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ export = {
// WHEN
new appmesh.VirtualNode(stack, 'test-node', {
mesh,
cloudMapService: service,
serviceDiscovery: appmesh.ServiceDiscovery.cloudMap({
service: service,
}),
});

// THEN
Expand Down Expand Up @@ -136,7 +138,7 @@ export = {

const testNode = new appmesh.VirtualNode(stack, 'test-node', {
mesh,
dnsHostName: 'test-node',
serviceDiscovery: appmesh.ServiceDiscovery.dns('test-node'),
});

const testRouter = mesh.addVirtualRouter('router', {
Expand Down Expand Up @@ -207,7 +209,7 @@ export = {
});

const node = mesh.addVirtualNode('test-node', {
dnsHostName: 'test.domain.local',
serviceDiscovery: appmesh.ServiceDiscovery.dns('test.domain.local'),
listeners: [appmesh.VirtualNodeListener.http({
port: 8080,
})],
Expand Down Expand Up @@ -249,7 +251,7 @@ export = {
});

mesh.addVirtualNode('test-node', {
dnsHostName: 'test.domain.local',
serviceDiscovery: appmesh.ServiceDiscovery.dns('test.domain.local'),
});

// THEN
Expand Down Expand Up @@ -283,7 +285,7 @@ export = {
});

mesh.addVirtualNode('test-node', {
dnsHostName: 'test.domain.local',
serviceDiscovery: appmesh.ServiceDiscovery.dns('test.domain.local'),
listeners: [appmesh.VirtualNodeListener.http({
port: 8080,
})],
Expand Down Expand Up @@ -322,7 +324,7 @@ export = {
});

mesh.addVirtualNode('test-node', {
dnsHostName: 'test.domain.local',
serviceDiscovery: appmesh.ServiceDiscovery.dns('test.domain.local'),
listeners: [appmesh.VirtualNodeListener.http({
port: 8080,
healthCheck: {
Expand Down Expand Up @@ -378,7 +380,7 @@ export = {
});

mesh.addVirtualNode('test-node', {
dnsHostName: 'test.domain.local',
serviceDiscovery: appmesh.ServiceDiscovery.dns('test.domain.local'),
listeners: [appmesh.VirtualNodeListener.http({
port: 8080,
})],
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-appmesh/test/test.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export = {

// WHEN
const node = mesh.addVirtualNode('test-node', {
dnsHostName: 'test',
serviceDiscovery: appmesh.ServiceDiscovery.dns('test'),
listeners: [appmesh.VirtualNodeListener.http()],
});

Expand Down Expand Up @@ -174,7 +174,7 @@ export = {

// WHEN
const node = mesh.addVirtualNode('test-node', {
dnsHostName: 'test',
serviceDiscovery: appmesh.ServiceDiscovery.dns('test'),
listeners: [appmesh.VirtualNodeListener.http()],
});

Expand Down
Loading

0 comments on commit fa13592

Please sign in to comment.