Skip to content

Task Definitions Guide

Task definitions are blueprints for your applications that specify how containers should run. This guide covers creating and managing task definitions in KECS.

Understanding Task Definitions

What is a Task Definition?

A task definition is a JSON document that describes one or more containers that form your application. It specifies:

  • Docker images to use
  • CPU and memory requirements
  • Networking mode
  • Logging configuration
  • Environment variables
  • IAM roles

Task Definition Families

Task definitions are grouped into families. Each revision of a task definition increments the revision number within the family.

webapp:1  → webapp:2  → webapp:3
   ↓          ↓           ↓
 First    Updated     Latest
revision   image      revision

Creating Task Definitions

Basic Task Definition

json
{
  "family": "simple-app",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512",
  "containerDefinitions": [
    {
      "name": "app",
      "image": "nginx:latest",
      "essential": true,
      "portMappings": [
        {
          "containerPort": 80,
          "protocol": "tcp"
        }
      ]
    }
  ]
}

Multi-Container Task Definition

json
{
  "family": "webapp-with-sidecar",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "512",
  "memory": "1024",
  "containerDefinitions": [
    {
      "name": "webapp",
      "image": "myapp:latest",
      "essential": true,
      "portMappings": [
        {
          "containerPort": 8080
        }
      ],
      "environment": [
        {
          "name": "LOG_LEVEL",
          "value": "info"
        }
      ],
      "dependsOn": [
        {
          "containerName": "log-router",
          "condition": "START"
        }
      ]
    },
    {
      "name": "log-router",
      "image": "fluentd:latest",
      "essential": true,
      "firelensConfiguration": {
        "type": "fluentd"
      }
    }
  ]
}

Container Definitions

Essential Properties

json
{
  "name": "myapp",
  "image": "myregistry/myapp:v1.2.3",
  "essential": true,
  "memory": 512,
  "memoryReservation": 256,
  "cpu": 256
}
  • name: Unique name within the task
  • image: Docker image to use
  • essential: If true, task fails if container stops
  • memory: Hard memory limit (MiB)
  • memoryReservation: Soft memory limit
  • cpu: CPU units (1024 = 1 vCPU)

Port Mappings

json
{
  "portMappings": [
    {
      "containerPort": 8080,
      "hostPort": 80,
      "protocol": "tcp",
      "name": "web"
    }
  ]
}

Environment Configuration

Environment Variables

json
{
  "environment": [
    {
      "name": "APP_ENV",
      "value": "production"
    },
    {
      "name": "API_URL",
      "value": "https://api.example.com"
    }
  ]
}

Secrets

json
{
  "secrets": [
    {
      "name": "DB_PASSWORD",
      "valueFrom": "arn:aws:secretsmanager:region:account:secret:db-password"
    },
    {
      "name": "API_KEY",
      "valueFrom": "arn:aws:ssm:region:account:parameter/api-key"
    }
  ]
}

Health Checks

json
{
  "healthCheck": {
    "command": ["CMD-SHELL", "curl -f http://localhost/health || exit 1"],
    "interval": 30,
    "timeout": 5,
    "retries": 3,
    "startPeriod": 60
  }
}

Logging Configuration

CloudWatch Logs

json
{
  "logConfiguration": {
    "logDriver": "awslogs",
    "options": {
      "awslogs-group": "/ecs/myapp",
      "awslogs-region": "us-east-1",
      "awslogs-stream-prefix": "webapp"
    }
  }
}

FireLens

json
{
  "logConfiguration": {
    "logDriver": "awsfirelens",
    "options": {
      "Name": "cloudwatch",
      "region": "us-east-1",
      "log_group_name": "/ecs/myapp",
      "log_stream_prefix": "firelens/"
    }
  }
}

Advanced Features

Container Dependencies

json
{
  "containerDefinitions": [
    {
      "name": "database",
      "image": "postgres:13",
      "essential": true
    },
    {
      "name": "app",
      "image": "myapp:latest",
      "essential": true,
      "dependsOn": [
        {
          "containerName": "database",
          "condition": "HEALTHY"
        }
      ]
    }
  ]
}

Dependency conditions:

  • START: Container has started
  • COMPLETE: Container has run to completion
  • SUCCESS: Container exited successfully
  • HEALTHY: Container is healthy

Volumes

Bind Mounts

json
{
  "volumes": [
    {
      "name": "app-config",
      "host": {
        "sourcePath": "/etc/myapp"
      }
    }
  ],
  "containerDefinitions": [
    {
      "name": "app",
      "mountPoints": [
        {
          "sourceVolume": "app-config",
          "containerPath": "/config",
          "readOnly": true
        }
      ]
    }
  ]
}

EFS Volumes

json
{
  "volumes": [
    {
      "name": "efs-storage",
      "efsVolumeConfiguration": {
        "fileSystemId": "fs-12345678",
        "rootDirectory": "/data",
        "transitEncryption": "ENABLED",
        "authorizationConfig": {
          "accessPointId": "fsap-12345678",
          "iam": "ENABLED"
        }
      }
    }
  ]
}

Resource Requirements

json
{
  "requiresCompatibilities": ["EC2"],
  "placementConstraints": [
    {
      "type": "memberOf",
      "expression": "attribute:ecs.instance-type =~ c5.*"
    }
  ],
  "cpu": "2048",
  "memory": "4096",
  "gpuCount": 1
}

Network Configuration

Network Modes

  • awsvpc: Each task gets its own network interface
  • bridge: Uses Docker's built-in bridge network
  • host: Uses the host's network
  • none: No networking
json
{
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"]
}

IAM Roles

Task Role

Grants containers permissions to AWS services:

json
{
  "taskRoleArn": "arn:aws:iam::account:role/ecsTaskRole"
}

Execution Role

Grants ECS permissions to pull images and write logs:

json
{
  "executionRoleArn": "arn:aws:iam::account:role/ecsTaskExecutionRole"
}

Working with Task Definitions

Register a Task Definition

bash
# From file
aws ecs register-task-definition \
  --cli-input-json file://task-definition.json \
  --endpoint-url http://localhost:8080

# Inline
aws ecs register-task-definition \
  --family webapp \
  --network-mode awsvpc \
  --requires-compatibilities FARGATE \
  --cpu 256 \
  --memory 512 \
  --container-definitions '[
    {
      "name": "web",
      "image": "nginx:latest",
      "portMappings": [{"containerPort": 80}],
      "essential": true
    }
  ]' \
  --endpoint-url http://localhost:8080

List Task Definitions

bash
# List families
aws ecs list-task-definition-families \
  --endpoint-url http://localhost:8080

# List revisions
aws ecs list-task-definitions \
  --family-prefix webapp \
  --endpoint-url http://localhost:8080

Describe Task Definition

bash
# Latest revision
aws ecs describe-task-definition \
  --task-definition webapp \
  --endpoint-url http://localhost:8080

# Specific revision
aws ecs describe-task-definition \
  --task-definition webapp:3 \
  --endpoint-url http://localhost:8080

Deregister Task Definition

bash
aws ecs deregister-task-definition \
  --task-definition webapp:1 \
  --endpoint-url http://localhost:8080

Best Practices

1. Container Images

  • Use specific tags, not latest
  • Keep images small and secure
  • Use multi-stage builds
  • Scan images for vulnerabilities

2. Resource Allocation

  • Set both limits and requests
  • Leave headroom for spikes
  • Monitor actual usage
  • Use resource reservations wisely

3. Configuration

  • Use environment variables for configuration
  • Store secrets in Secrets Manager or SSM
  • Use parameter store for non-sensitive config
  • Version your task definitions

4. Logging

  • Always configure logging
  • Use structured logging
  • Set appropriate retention periods
  • Consider log aggregation

5. Health Checks

  • Implement application health endpoints
  • Set reasonable timeouts and intervals
  • Use startup periods for slow-starting apps
  • Monitor health check metrics

Common Patterns

Sidecar Pattern

json
{
  "containerDefinitions": [
    {
      "name": "app",
      "image": "myapp:latest"
    },
    {
      "name": "proxy",
      "image": "envoyproxy/envoy:latest",
      "links": ["app"]
    }
  ]
}

Init Container Pattern

json
{
  "containerDefinitions": [
    {
      "name": "init",
      "image": "busybox",
      "essential": false,
      "command": ["sh", "-c", "echo 'Initializing...'"]
    },
    {
      "name": "app",
      "image": "myapp:latest",
      "essential": true,
      "dependsOn": [{
        "containerName": "init",
        "condition": "SUCCESS"
      }]
    }
  ]
}

Ambassador Pattern

json
{
  "containerDefinitions": [
    {
      "name": "app",
      "image": "myapp:latest",
      "environment": [{
        "name": "PROXY_URL",
        "value": "http://localhost:8080"
      }]
    },
    {
      "name": "ambassador",
      "image": "ambassador:latest",
      "portMappings": [{
        "containerPort": 8080
      }]
    }
  ]
}

Troubleshooting

Task Definition Validation Errors

  • Check JSON syntax
  • Verify required fields
  • Validate CPU/memory combinations
  • Ensure image accessibility

Container Start Failures

  • Check image pull permissions
  • Verify environment variables
  • Review health check commands
  • Check volume mount paths

Performance Issues

  • Monitor resource utilization
  • Check for memory leaks
  • Review CPU throttling
  • Optimize container startup

For more troubleshooting help, see our Troubleshooting Guide.

Released under the Apache 2.0 License.