../../_images/aws_ecs.png

Amazon Elastic Container Service

Prerequisites

Amazon Elastic Container Instances is a quick way to deploy your container into Docker host within AWS, without having to provision the underlying servers first (VM + OS).

  • AWS account

  • AWS access profile

  • AWS VPC and available subnet

CLI tools

The AWS command line tool will be used to programmatically access your AWS account. To install the CLI tool, follow the link below and choose the correct operating sytem:

Obtain the latest CloudFormation template

Save the following ESP CloudFormation template to your local environment as ecs.template.yml.

Parameters:
  appLicense:
    Type: String
    Description: L7 ESP application License
  appPassword:
    Type: String
    Description: L7 ESP application login password
  ImageRepo:
    Type: String
    Description: Azure Container Registry Image URL
  ContainerName:
    Type: String
    Description: ECS Container name
  containerCPU:
    Type: String
    Description: ECS CPU Resource Allocation
  appPortHTTP:
    Type: String
    Description: App Port
  containerMemory:
    Type: String
    Description: ECS Memory Resource Allocation
  MyTaskDefinition:
    Type: String
    Description: Task Definition Name
  ServiceName:
    Type: String
    Description: ECS Service name
  subnetID:
    Type: String
    Description: The SubnetID where ECS will be deployed
  RepoUsername:
    Type: String
    Description: Private Repository username
  RepoPassword:
    Type: String
    Description: Private Repository password
    NoEcho: True

Resources:
  ECSClusterRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${AWS::StackName}-Role
      AssumeRolePolicyDocument:
        Version: 2008-10-17
        Statement:
          Effect: "Allow"
          Principal:
            Service: "ecs-tasks.amazonaws.com"
          Action: "sts:AssumeRole"
      Description: ESP role for deployment
      Policies:
        - PolicyName: EmbeddedInlinePolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action: "ecs:*"
                Resource: "*"
              - Effect: Allow
                Action:
                  - "kms:Decrypt"
                  - "secretsmanager:GetSecretValue"
                Resource:
                  - !Ref RepoCreds
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/CloudWatchFullAccess"

  ECSCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: !Sub '${AWS::StackName}-cluster'

  RepoCreds:
    Type: AWS::SecretsManager::Secret
    Properties:
      Description: Docker Hub credentials for pulling ESP image for ECS deployment
      Name: !Sub '${AWS::StackName}-repocreds'
      SecretString: !Sub '{"username" : "${RepoUsername}","password" : "${RepoPassword}" }'

  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    DependsOn: ECSClusterRole
    Properties:
      Family: !Ref MyTaskDefinition
      Cpu: !Ref containerCPU
      Memory: !Ref containerMemory
      ExecutionRoleArn: !Ref ECSClusterRole
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE
      ContainerDefinitions:
        - Name: !Ref ContainerName
          Image: !Ref ImageRepo
          RepositoryCredentials:
            CredentialsParameter: !Ref RepoCreds
          MountPoints:
            - ContainerPath: /opt/l7esp/data/project
              SourceVolume: !Sub ${ContainerName}-volume
          PortMappings:
            - ContainerPort: !Ref appPortHTTP
              HostPort: !Ref appPortHTTP
          Environment:
            - Name: L7ESP_PASSWORD
              Value: !Ref appPassword
            - Name: L7ESP_LICENSE
              Value: !Ref appLicense
          LogConfiguration:
            LogDriver: awslogs
            Options:
              awslogs-group: !Ref LogGroup
              awslogs-region: !Ref AWS::Region
              awslogs-stream-prefix: !Ref ContainerName
      Volumes:
        - Name: !Sub ${ContainerName}-volume
  Service:
    Type: AWS::ECS::Service
    DependsOn: ECSCluster
    Properties:
      Cluster: !Ref ECSCluster
      ServiceName: !Ref ServiceName
      TaskDefinition: !Ref TaskDefinition
      DesiredCount: 1
      LaunchType: FARGATE
      NetworkConfiguration:
        AwsvpcConfiguration:
          AssignPublicIp: ENABLED
          Subnets:
            - !Ref subnetID

  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub /ecs/${AWS::StackName}

Outputs:
  ClusterName:
    Value: !Ref ECSCluster
  ServiceName:
    Value: !Ref Service

Deploy Cloudformation template with desired parameters

Save the below example parameters file in your local environment as ecs.parameters.json:

[
  {
    "ParameterKey": "appLicense",
    "ParameterValue": ""
  },
  {
    "ParameterKey": "appPortHTTP",
    "ParameterValue": "8002"
  },
  {
    "ParameterKey": "appPassword",
    "ParameterValue": ""
  },
  {
    "ParameterKey": "containerCPU",
    "ParameterValue": "2048"
  },
  {
    "ParameterKey": "containerMemory",
    "ParameterValue": "8192"
  },
  {
    "ParameterKey": "ImageRepo",
    "ParameterValue": ""
  },
  {
    "ParameterKey": "ContainerName",
    "ParameterValue": "l7esp"
  },
  {
    "ParameterKey": "RepoUsername",
    "ParameterValue": ""
  },
  {
    "ParameterKey": "RepoPassword",
    "ParameterValue": ""
  },
  {
    "ParameterKey": "MyTaskDefinition",
    "ParameterValue": "ExampleESPTaskDefinition"
  },
  {
    "ParameterKey": "ServiceName",
    "ParameterValue": "L7 ESP"
  },
  {
    "ParameterKey": "subnetID",
    "ParameterValue": ""
  }
]

Edit this file to include your specific AWS environment parameters:

  • containerName - This will be the name of the ESP container that runs in your CloudFormation stack (default: l7esp-example)

  • appLicense : L7|ESP software license (optional; JSON string)

  • appPassword - L7|ESP admin password (required; initial ESP password)

  • appPortHTTP : L7|ESP web UI port (default: 8002)

  • ImageRepo: Container Image (e.g. docker.io/acme/l7esp:3.0.0)

  • RepoUsername: The username for your container repository

  • RepoPassword: The password for your container repository

  • containerCPU : Container CPU cores (default: 2 vCPU, expressed as ‘2048’) [AWS vCPU values explained]

  • containerMemory : Container Memory (default: 6GB RAM)

  • ClusterName : ECS cluster name (e.g. L7ECS)

  • TaskDefinitionName : ECS Task name (e.g. ExampleESPTaskDefinition)

  • ServiceName: ECS Service name (e.g. ExampleESPService)

  • subnetID : The ID of your AWS subnet (e.g. subnet-<id>)

Run Cloudformation template pipeline to create ECS

Configure AWS profile from your AWS CLI to access aws account.

$ aws configure

List your AWS Profile:

$ aws configure list-profiles

Select the correct profile by setting the profile environmental variable

$ export AWS_PROFILE=profilename

Deploy the AWS cloudformation

$ aws cloudformation deploy \
      --stack-name ESP-ECS-example \
      --template-file ecs.template.yml \
      --parameter-overrides file://ecs.parameters.json \
      --capabilities CAPABILITY_NAMED_IAM

You can add the --debug flag for additional debugging output.

Validate Resource Creation

In the AWS portal, navigate to ecs and verify that the L7|ESP container instance was created and that it ends up in the Running state:

../../_images/ecsdeployment.png