Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ecs): add support for ProxyConfiguration in ECS TaskDefinition #4007

Merged
merged 12 commits into from
Oct 2, 2019
9 changes: 9 additions & 0 deletions packages/@aws-cdk/aws-ecs/lib/base/task-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Construct, IResource, Lazy, Resource } from '@aws-cdk/core';
import { ContainerDefinition, ContainerDefinitionOptions, PortMapping, Protocol } from '../container-definition';
import { CfnTaskDefinition } from '../ecs.generated';
import { PlacementConstraint } from '../placement';
import { ProxyConfiguration } from '../proxy-configuration/proxy-configuration';

/**
* The interface for all task definitions.
Expand Down Expand Up @@ -64,6 +65,13 @@ export interface CommonTaskDefinitionProps {
*/
readonly taskRole?: iam.IRole;

/**
* The configuration details for the App Mesh proxy.
*
* @default - No proxy configuration.
*/
readonly proxyConfiguration?: ProxyConfiguration;

/**
* The list of volume definitions for the task. For more information, see
* [Task Definition Parameter Volumes](https://docs.aws.amazon.com/AmazonECS/latest/developerguide//task_definition_parameters.html#volumes).
Expand Down Expand Up @@ -279,6 +287,7 @@ export class TaskDefinition extends TaskDefinitionBase {
placementConstraints: Lazy.anyValue({ produce: () =>
!isFargateCompatible(this.compatibility) ? this.placementConstraints : undefined
}, { omitEmptyArray: true }),
proxyConfiguration: props.proxyConfiguration ? props.proxyConfiguration.bind(this.stack, this) : undefined,
cpu: props.cpu,
memory: props.memoryMiB,
});
Expand Down
4 changes: 4 additions & 0 deletions packages/@aws-cdk/aws-ecs/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ export * from './log-drivers/syslog-log-driver';
export * from './log-drivers/log-driver';
export * from './log-drivers/log-drivers';

export * from './proxy-configuration/app-mesh-proxy-configuration';
export * from './proxy-configuration/proxy-configuration';
export * from './proxy-configuration/proxy-configurations';

// AWS::ECS CloudFormation Resources:
//
export * from './ecs.generated';
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { Construct } from '@aws-cdk/core';
import { TaskDefinition } from '../base/task-definition';
import { CfnTaskDefinition } from '../ecs.generated';
import { ProxyConfiguration } from './proxy-configuration';

/**
* Interface for setting the properties of proxy configuration.
*/
export interface AppMeshProxyConfigurationProps {
/**
* The user ID (UID) of the proxy container as defined by the user parameter in a container definition.
* This is used to ensure the proxy ignores its own traffic. If IgnoredGID is specified, this field can be empty.
*/
readonly ignoredUID?: number;

/**
* The group ID (GID) of the proxy container as defined by the user parameter in a container definition.
* This is used to ensure the proxy ignores its own traffic. If IgnoredUID is specified, this field can be empty.
*/
readonly ignoredGID?: number;

/**
* The list of ports that the application uses.
* Network traffic to these ports is forwarded to the ProxyIngressPort and ProxyEgressPort.
*/
readonly appPorts: number[];

/**
* Specifies the port that incoming traffic to the AppPorts is directed to.
*/
readonly proxyIngressPort: number;

/**
* Specifies the port that outgoing traffic from the AppPorts is directed to.
*/
readonly proxyEgressPort: number;

/**
* The egress traffic going to these specified ports is ignored and not redirected to the ProxyEgressPort. It can be an empty list.
*/
readonly egressIgnoredPorts?: number[];
piradeepk marked this conversation as resolved.
Show resolved Hide resolved

/**
* The egress traffic going to these specified IP addresses is ignored and not redirected to the ProxyEgressPort. It can be an empty list.
*/
readonly egressIgnoredIPs?: string[];
piradeepk marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* The configuration to use when setting an App Mesh proxy configuration.
*/
export interface AppMeshProxyConfigurationConfigProps {
/**
* The name of the container that will serve as the App Mesh proxy.
*/
readonly containerName: string;

/**
* The set of network configuration parameters to provide the Container Network Interface (CNI) plugin.
*/
readonly properties: AppMeshProxyConfigurationProps;
}

/**
* The class for App Mesh proxy configurations.
*
* For tasks using the EC2 launch type, the container instances require at least version 1.26.0 of the container agent and at least version
* 1.26.0-1 of the ecs-init package to enable a proxy configuration. If your container instances are launched from the Amazon ECS-optimized
* AMI version 20190301 or later, then they contain the required versions of the container agent and ecs-init.
* For more information, see [Amazon ECS-optimized AMIs](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-optimized_AMI.html).
*
* For tasks using the Fargate launch type, the task or service requires platform version 1.3.0 or later.
*/
export class AppMeshProxyConfiguration extends ProxyConfiguration {
/**
* Constructs a new instance of the AppMeshProxyConfiguration class.
*/
constructor(private readonly props: AppMeshProxyConfigurationConfigProps) {
iamhopaul123 marked this conversation as resolved.
Show resolved Hide resolved
super();
if (props.properties) {
if (!props.properties.ignoredUID && !props.properties.ignoredGID) {
throw new Error("At least one of ignoredUID or ignoredGID should be specified.");
}
}
}

/**
* Called when the proxy configuration is configured on a task definition.
*/
public bind(_scope: Construct, _taskDefinition: TaskDefinition): CfnTaskDefinition.ProxyConfigurationProperty {
const configProps = this.props.properties;
const configType = "APPMESH";
return {
iamhopaul123 marked this conversation as resolved.
Show resolved Hide resolved
containerName: this.props.containerName,
proxyConfigurationProperties: renderProperties(configProps),
type: configType
};
}
}

function renderProperties(props: AppMeshProxyConfigurationProps): CfnTaskDefinition.KeyValuePairProperty[] {
const ret = [];
for (const [k, v] of Object.entries(props)) {
const key = String(k);
const value = String(v);
if (value !== "undefined" && value !== "") {
piradeepk marked this conversation as resolved.
Show resolved Hide resolved
const capitalizedKey = key.charAt(0).toUpperCase() + key.slice(1);
ret.push({ ["name"]: capitalizedKey, ["value"]: value });
}
}
return ret;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Construct } from '@aws-cdk/core';
import { TaskDefinition } from '../base/task-definition';
import { CfnTaskDefinition } from '../ecs.generated';

/**
* The base class for proxy configurations.
*/
export abstract class ProxyConfiguration {
/**
* Called when the proxy configuration is configured on a task definition.
*/
public abstract bind(_scope: Construct, _taskDefinition: TaskDefinition): CfnTaskDefinition.ProxyConfigurationProperty;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { AppMeshProxyConfiguration, AppMeshProxyConfigurationConfigProps } from './app-mesh-proxy-configuration';
import { ProxyConfiguration } from './proxy-configuration';

/**
* The base class for proxy configurations.
*/
export class ProxyConfigurations {
/**
* Constructs a new instance of the ProxyConfiguration class.
*/
public static appMeshProxyConfiguration(props: AppMeshProxyConfigurationConfigProps): ProxyConfiguration {
return new AppMeshProxyConfiguration(props);
}
}
Loading