services.deploy

The deploy section allows to set various settings around how the container should be deployed, and what compute resources are required to run the service.

For more details on the deploy, see docker documentation for deploy here

At the moment, all keys are not supported, mostly due to the way Fargate by nature is expecting settings to be.

resources

The resources allow you to define the CPU/RAM reservations and limits. In AWS ECS, the CPU only has one attribute, so ECS Compose-X will use the highest value of the two if both set .

Once the container definitions have been generated, the CPU and RAM requirements are added up together. From there, it will automatically select the closest valid Fargate CPU/RAM combination and set the parameter for the Task.

Important

CPUs should be set between 0.25 and 4 to be valid for Fargate, otherwise you will have an error.

replicas

This setting allows you to define how many tasks should be running for a given service. The value is used to define MicroserviceCount .

labels

These labels aren’t used for much in native Docker compose as per the documentation. They are only used for the service, but not for the containers themselves. Which is great for us, as we can then leverage that structure to implement a merge of services.

In AWS ECS, a Task definition is a group of one or more containers which are going to be running as a one task. The most usual use-case for this, is with web applications, which need to have a reverse proxy (ie. nginx) in front of the actual application. But also, if you used the use_xray option, you realized that ECS ComposeX automatically adds the x-ray-daemon sidecar. Equally, when we implement AppMesh, we will also have another side-car container for this.

So, here is the tag that will allow you to merge your reverse proxy or waf (if you used a WAF in container) fronting your web application:

ecs.task.family

For example, you would have:

---
# base file for services with the x-keys for BDD
version: '3.8'
secrets:
  abcd: {}
  john: {}

  zyx: {}
services:
  app01:
    logging:
      driver: awslogs
      options:
        awslogs-group: a-custom-name
        awslogs-create-group: "true"
    sysctls:
      - net.core.somaxconn=2048
      - net.ipv4.tcp_syncookies=1
    cap_add:
      - ALL
#    env_file: ./use-cases/env-files/dummy.env
    deploy:
      update_config:
        failure_action: rollback
      labels:
        ecs.ephemeral.storage: 65
        ecs.task.family: bignicefamily
      resources:
        reservations:
          cpus: '0.25'
          memory: 1GB
    environment:
      LOGLEVEL: DEBUG
      SHELLY: /bin/bash
      TERMY: screen
    image: nginx
    volumes:
      - type: tmpfs
        target: /tmp
        tmpfs:
          size: 1024
      - normal-vol:/var/tmp/shared
      - some-volume:/var/anotherpath:ro
    links:
      - app03:dateteller
    ports:
      - mode: awsvpc
        protocol: tcp
        published: 5000
        target: 5000
    secrets:
      - zyx
    x-logging:
      RetentionInDays: 42
      CreateLogGroup: False
    x-network:
      IsPublic: False
      UseCloudmap: True
      Ingress:
        Myself: False
        AwsSources:
          - Type: PrefixList
            Id: pl-6da54004
    x-iam:
      Policies:
        - PolicyName: AllowPublishToCw
          PolicyDocument:
            Statement:
              - Action:
                  - cloudwatch:PutMetricData
                Effect: Allow
                Resource:
                  - '*'
                Sid: AllowPublishMetricsToCw
    x-xray: false
    x-scaling:
      Range: "1-4"
  app02:
    depends_on:
      - app01
      - bignicefamily
#    env_file:
#      - ./use-cases/env-files/dummy.env
    deploy:
      update_config:
        failure_action: pause
      labels:
        ecs.ephemeral.storage: 12128GB
        ecs.task.family: youtoo
      replicas: 2
      resources:
        reservations:
          cpus: '0.1'
          memory: 64000kB
    environment:
      LOGLEVEL: DEBUG
    healthcheck:
      interval: 1m30s
      timeout: 10s
      start_period: 1h
      retries: 3
      test:
        - CMD
        - curl
        - localhost:5000/ping
    image: nginx
    ports:
      - mode: awsvpc
        protocol: tcp
        published: 5000
        target: 5000
    secrets:
      - zyx
    volumes:
      - source: some-volume
        target: /app/data
        type: volume
    x-iam:
      PermissionsBoundary: arn:aws:iam::aws:policy/AdministratorAccess
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AdministratorAccess
    x-scaling:
      Range: "1-5"
      TargetScaling:
        CpuTarget: 88
        DisableScaleIn: true
    x-xray: false
    tmpfs: /run
  app03:
    tmpfs:
      - /run
      - /tmp
    sysctls:
      net.core.somaxconn: 1024
      net.ipv4.tcp_syncookies: 0
    cap_add:
      - NET_ADMIN
      - SYS_PTRACE
    cap_drop:
      - SYS_ADMIN
    ulimits:
      nofile:
        soft: 1024
        hard: 2048
      nproc: 512
    x-aws-min_percent: 50
    x-aws-max_percent: 150
    deploy:
      labels:
        ecs.ephemeral.storage: 20
      resources:
        reservations:
          cpus: '0.25'
          memory: 134217728b
    environment:
      LOGLEVEL: DEBUG
    image: nginx
    ports:
      - mode: awsvpc
        protocol: tcp
        published: 5000
        target: 5000
    secrets:
      - abcd
      - zyx
      - john
    volumes:
      - /generated/volume/from/path
      - shared-images:/app/images
      - some-volume:/app/data:ro
    x-network:
      Ingress:
        Myself: False
        ExtSources:
          - IPv4: 0.0.0.0/0
            Name: ANYWHERE

    x-logging:
        RetentionInDays: 30
    x-scaling:
      Range: 1-10
  rproxy:
    logging:
      driver: awslogs
      options:
        awslogs-region: us-east-1
    depends_on:
      - app01
      - app02
    deploy:
      labels:
        ecs.task.family: bignicefamily,youtoo
        ecs.ephemeral.storage: 175
      replicas: 1
      resources:
        limits:
          cpus: '0.25'
          memory: 64M
        reservations:
          cpus: '0.1'
          memory: 32M
    image: nginx
    volumes:
      - normal-vol:/tmp/shared
    ports:
      - mode: awsvpc
        protocol: tcp
        published: 80
        target: 80
    x-iam:
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/ReadOnlyAccess
    x-xray: true
    x-network:
      IsPublic: False
      UseCloudmap: True

volumes:
  shared-images: {}
  some-volume: {}
  normal-vol: {}


x-dns:
  PrivateNamespace:
    Name: lambda.internal

x-tags:
  costcentre: lambda

Warning

The example above illustrates that you can either use, for deploy labels

  • a list of strings

  • a dictionary

ecs.depends.condition

This label allows to define what condition should this service be monitored under by ECS. Useful when container is set as a dependency to another.

label

ecs.depends.condition

Allowed Values

  • START

  • SUCCESS

  • HEALTHY

  • COMPLETE

Default

START

Hint

f you defined healthcheck on your service, changes to HEALTHY. See Dependency reference for more information

ecs.ephemeral.storage

This label allows you to extend the local capacity (ephemeral, which is destroyed after the task is stopped) of storage beyond the free 20GB coming by default.

label

ecs.ephemeral.storage

Minimum

21

Maximum

200

Hint

The minimum valid value is 21, maximum is 200. If below 21, it is ignored, if above 200, set to 200.

Warning

This parameter only when using Fargate. This will be ignored when using EC2 or EXTERNAL deployment modes. For more storage using EC2, provide more local storage for your EC2 nodes.

ecs.compute.platform

This setting allows you to define which compute platform to deploy your services onto. This is useful if you have cluster that has a mix of EC2 capacity (default behaviour) and Fargate ones. This can also allow you to define to deploy your container to ECS Anywhere (using EXTERNAL mode).

label

ecs.compute.platform

Allowed Values

  • EC2

  • FARGATE

  • EXTERNAL

Hint

By default, ECS Clusters created with ECS Compose-X will use AWS Fargate as the compute platform.

Hint

If you created your cluster without providing any Capacity Providers, Fargate cannot work. Compose-X, when using x-cluster.Lookup will attempt to determine whether the Fargate capacity providers are present, and if not, override to EC2 for all services

Tip

Below two ECS Clusters, one created via CLI without any arguments, the other created in the AWS Console.

ECS cluster created without capacity providers
aws ecs create-cluster --cluster-name testing
{
    "cluster": {
        "clusterArn": "arn:aws:ecs:eu-west-1:2111111111111:cluster/testing",
        "clusterName": "testing",
        "status": "ACTIVE",
        "registeredContainerInstancesCount": 0,
        "runningTasksCount": 0,
        "pendingTasksCount": 0,
        "activeServicesCount": 0,
        "statistics": [],
        "tags": [],
        "settings": [
            {
                "name": "containerInsights",
                "value": "enabled"
            }
        ],
        "capacityProviders": [],
        "defaultCapacityProviderStrategy": []
    }
}
Cluster created in the AWS Console which automatically adds FARGATE providers
[
  {
    "clusterArn": "arn:aws:ecs:eu-west-1:211111111111:cluster/testinginconsole",
    "clusterName": "testinginconsole",
    "status": "ACTIVE",
    "registeredContainerInstancesCount": 0,
    "runningTasksCount": 0,
    "pendingTasksCount": 0,
    "activeServicesCount": 0,
    "statistics": [],
    "tags": [],
    "settings": [
      {
        "name": "containerInsights",
        "value": "enabled"
      }
    ],
    "capacityProviders": [
      "FARGATE_SPOT",
      "FARGATE"
    ],
    "defaultCapacityProviderStrategy": []
  }
]