Load balanced container service with ECS Service Extensions

Nathan Peck profile picture
Nathan Peck
Senior Developer Advocate at AWS

About

The ecs-service-extensions package is an extendable plugin system for defining Amazon ECS service deployments in AWS Cloud Development Kit.

This pattern shows how to use ecs-service-extensions to deploy a basic load balanced workload through ECS.

Setup Cloud Development Kit

To use this pattern you need TypeScript and Node. First, ensure that you have Node.js installed on your development machine. Then create the following files:

  • package.json
  • tsconfig.json
  • cdk.json
File: package.jsonLanguage: json
{
  "name": "ecs-service-extensions-load-balancer-cdk",
  "version": "1.0.0",
  "description": "Load balanced container app with ECS Service Extensions",
  "private": true,
  "scripts": {
    "build": "tsc",
    "watch": "tsc -w",
    "cdk": "cdk"
  },
  "author": {
    "name": "Amazon Web Services",
    "url": "https://aws.amazon.com",
    "organization": true
  },
  "license": "Apache-2.0",
  "devDependencies": {
    "@types/node": "^8.10.38",
    "aws-cdk": "2.102.0",
    "typescript": "~4.6.0",
    "ts-node": "^10.9.1"
  },
  "dependencies": {
    "aws-cdk-lib": "2.102.0",
    "constructs": "^10.0.0",
    "@aws-cdk-containers/ecs-service-extensions": "2.0.1-alpha.183"
  }
}

The files above serve the following purpose:

  • package.json - This file is used by NPM or Yarn to identify and install all the required dependencies:
  • tsconfig.json - Configures the TypeScript settings for the project:
  • cdk.json - Tells CDK what command to run, and provides a place to pass other contextual settings to CDK.

Run the following commands to install dependencies and setup your AWS account for the deployment:

Language: sh
npm install
npm run-script cdk bootstrap

Create the CDK app

Now create the following file to define the CDK application itself:

File: index.tsLanguage: ts
import ecs = require('aws-cdk-lib/aws-ecs');
import cdk = require('aws-cdk-lib');
import {
  Container,
  Environment,
  HttpLoadBalancerExtension,
  Service,
  ServiceDescription
} from '@aws-cdk-containers/ecs-service-extensions';

class ECSStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Create an environment to deploy a service in.
    const environment = new Environment(this, 'production');

    // Build out the service description
    const nameDescription = new ServiceDescription();

    // Define the container for the service.
    nameDescription.add(new Container({
      cpu: 1024,
      memoryMiB: 2048,
      trafficPort: 80,
      image: ecs.ContainerImage.fromRegistry('nathanpeck/name'),
      environment: {
        PORT: '80',
      },
    }));

    // Create a load balancer and attach it to the
    // container's traffic port.
    nameDescription.add(new HttpLoadBalancerExtension());

    // Use the service description to make a service
    // inside of the environment.
    new Service(this, 'name', {
      environment: environment,
      serviceDescription: nameDescription,
    });
  }
}

const app = new cdk.App();
new ECSStack(app, 'ECSStack');
app.synth();

The ECS Service Extensions library simplifies container deployment by providing an Environment resource which automatically creates the networking stack and ECS cluster on your behalf.

You can then create a ServiceDescription. This is a wrapper for all the settings associated with your container deployment. You can add your Container to the service definition. Attaching a load balancer is also done by adding the HttpLoadBalancerExtension to the service description.

Finally, the ServiceDescription is instantiated into a Service inside the Environment.

You can preview all the AWS resources to be created using the following command:

Language: sh
npm run-script cdk diff

Deploy the stack:

Language: sh
npm run-script cdk deploy

You will see an Outputs section that shows the DNS name of the load balancer that provides ingress to the service. When you load up that URL you should see a random name, and the address of the container instance, similar to this:

Language: txt
Catalina (ip-10-0-199-15.us-east-2.compute.internal)

Clean Up

You can tear down the stack using the following command:

Language: sh
npm run-script cdk destroy

Next Steps