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-service-extensions): create an Environment from attributes #10932

Merged
merged 13 commits into from
Nov 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions packages/@aws-cdk-containers/ecs-service-extensions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,3 +283,20 @@ The above code uses the well known service discovery name for each
service, and passes it as an environment variable to the container so
that the container knows what address to use when communicating to
the other service.

## Importing a pre-existing cluster

To create an environment with a pre-existing cluster, you must import the cluster first, then use `Environment.fromEnvironmentAttributes()`. When a cluster is imported into an environment, the cluster is treated as immutable. As a result, no extension may modify the cluster to change a setting.

```ts

const cluster = ecs.Cluster.fromClusterAttributes(stack, 'Cluster', {
...
});

const environment = Environment.fromEnvironmentAttributes(stack, 'Environment', {
capacityType: EnvironmentCapacityType.EC2, // or `FARGATE`
cluster,
});

```
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,50 @@ export interface EnvironmentProps {
readonly capacityType?: EnvironmentCapacityType
}

/**
* An environment into which to deploy a service.
*/
export interface IEnvironment {
/**
* The name of this environment.
*/
readonly id: string;

/**
* The VPC into which environment services should be placed.
*/
readonly vpc: ec2.IVpc;

/**
* The cluster that is providing capacity for this service.
*/
readonly cluster: ecs.ICluster;

/**
* The capacity type used by the service's cluster.
*/
readonly capacityType: EnvironmentCapacityType;

/**
* Add a default cloudmap namespace to the environment's cluster.
*/
addDefaultCloudMapNamespace(options: ecs.CloudMapNamespaceOptions): void;
}

/**
* An environment into which to deploy a service. This environment
* can either be instantiated with a preexisting AWS VPC and ECS cluster,
* or it can create it's own VPC and cluster. By default it will create
* a cluster with Fargate capacity.
*/
export class Environment extends cdk.Construct {
export class Environment extends cdk.Construct implements IEnvironment {
/**
* Import an existing environment from its attributes.
*/
public static fromEnvironmentAttributes(scope: cdk.Construct, id: string, attrs: EnvironmentAttributes): IEnvironment {
return new ImportedEnvironment(scope, id, attrs);
}

/**
* The name of this environment.
*/
Expand Down Expand Up @@ -81,4 +118,47 @@ export class Environment extends cdk.Construct {
this.capacityType = EnvironmentCapacityType.FARGATE;
}
}

/**
* Add a default cloudmap namespace to the environment's cluster.
*/
addDefaultCloudMapNamespace(options: ecs.CloudMapNamespaceOptions) {
this.cluster.addDefaultCloudMapNamespace(options);
}
}

export interface EnvironmentAttributes {
/**
* The capacity type used by the service's cluster.
*/
capacityType: EnvironmentCapacityType;

/**
* The cluster that is providing capacity for this service.
*/
cluster: ecs.ICluster;
}

export class ImportedEnvironment extends cdk.Construct implements IEnvironment {
public readonly capacityType: EnvironmentCapacityType;
public readonly cluster: ecs.ICluster;
public readonly id: string;
public readonly vpc: ec2.IVpc;

constructor(scope: cdk.Construct, id: string, props: EnvironmentAttributes) {
super(scope, id);

this.id = id;
this.capacityType = props.capacityType;
this.cluster = props.cluster;
this.vpc = props.cluster.vpc;
}

/**
* Refuses to add a default cloudmap namespace to the cluster as we don't
* own it.
*/
addDefaultCloudMapNamespace(_options: ecs.CloudMapNamespaceOptions) {
throw new Error('the cluster environment is immutable when imported');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class AppMeshExtension extends ServiceExtension {
// Make sure that the parent cluster for this service has
// a namespace attached.
if (!this.parentService.cluster.defaultCloudMapNamespace) {
this.parentService.cluster.addDefaultCloudMapNamespace({
this.parentService.environment.addDefaultCloudMapNamespace({
// Name the namespace after the environment name.
// Service DNS will be like <service id>.<environment id>
name: this.parentService.environment.id,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as ec2 from '@aws-cdk/aws-ec2';
import * as ecs from '@aws-cdk/aws-ecs';
import * as cdk from '@aws-cdk/core';
import { Environment } from './environment';
import { IEnvironment } from './environment';
import { EnvironmentCapacityType, ServiceBuild } from './extensions/extension-interfaces';
import { ServiceDescription } from './service-description';

Expand All @@ -17,7 +17,7 @@ export interface ServiceProps {
/**
* The environment to launch the service in
*/
readonly environment: Environment
readonly environment: IEnvironment
}

/**
Expand All @@ -44,7 +44,7 @@ export class Service extends cdk.Construct {
* The cluster that is providing capacity for this service
* [disable-awslint:ref-via-interface]
*/
public readonly cluster: ecs.Cluster;
public readonly cluster: ecs.ICluster;

/**
* The capacity type that this service will use
Expand All @@ -59,7 +59,7 @@ export class Service extends cdk.Construct {
/**
* The environment this service was launched in
*/
public readonly environment: Environment;
public readonly environment: IEnvironment;

/**
* The generated task definition for this service, is only
Expand Down
Loading