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 repositoryRepoPassword: The password for your container repositorycontainerCPU: 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: