AWS
ECS
environment variables
task management
cloud computing

How to run AWS ECS Task overriding environment variables

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When running an AWS ECS task, you can override environment variables defined in the task definition by passing overrides to the run-task API call. This lets you use a single task definition for multiple purposes — different environments, one-off jobs, or configuration changes — without creating a new task definition revision each time. The override applies only to that specific task run and does not modify the task definition itself. Overrides are supported in both Fargate and EC2 launch types, and can be passed via the AWS CLI, SDK, or Console.

Task Definition with Default Environment Variables

json
1{
2  "family": "my-app",
3  "containerDefinitions": [
4    {
5      "name": "app",
6      "image": "123456789.dkr.ecr.us-east-1.amazonaws.com/my-app:latest",
7      "environment": [
8        { "name": "NODE_ENV", "value": "production" },
9        { "name": "DATABASE_URL", "value": "postgres://prod-db:5432/app" },
10        { "name": "LOG_LEVEL", "value": "info" }
11      ],
12      "essential": true,
13      "memory": 512,
14      "cpu": 256
15    }
16  ]
17}

These environment variables are the defaults for every task launched from this definition. Overrides replace specific variables while keeping the rest unchanged.

Overriding via AWS CLI

bash
1# Override environment variables when running a task
2aws ecs run-task \
3  --cluster my-cluster \
4  --task-definition my-app \
5  --launch-type FARGATE \
6  --network-configuration '{
7    "awsvpcConfiguration": {
8      "subnets": ["subnet-abc123"],
9      "securityGroups": ["sg-abc123"],
10      "assignPublicIp": "ENABLED"
11    }
12  }' \
13  --overrides '{
14    "containerOverrides": [
15      {
16        "name": "app",
17        "environment": [
18          { "name": "NODE_ENV", "value": "staging" },
19          { "name": "LOG_LEVEL", "value": "debug" },
20          { "name": "CUSTOM_FLAG", "value": "true" }
21        ]
22      }
23    ]
24  }'

The containerOverrides.environment list replaces specified variables and adds new ones. Variables not listed in the override retain their task definition defaults. In this example, DATABASE_URL keeps its production value while NODE_ENV and LOG_LEVEL are overridden.

Overriding via AWS SDK (Node.js)

javascript
1import { ECSClient, RunTaskCommand } from "@aws-sdk/client-ecs";
2
3const client = new ECSClient({ region: "us-east-1" });
4
5const command = new RunTaskCommand({
6  cluster: "my-cluster",
7  taskDefinition: "my-app",
8  launchType: "FARGATE",
9  networkConfiguration: {
10    awsvpcConfiguration: {
11      subnets: ["subnet-abc123"],
12      securityGroups: ["sg-abc123"],
13      assignPublicIp: "ENABLED",
14    },
15  },
16  overrides: {
17    containerOverrides: [
18      {
19        name: "app",
20        environment: [
21          { name: "NODE_ENV", value: "staging" },
22          { name: "DATABASE_URL", value: "postgres://staging-db:5432/app" },
23        ],
24      },
25    ],
26  },
27});
28
29const result = await client.send(command);
30console.log("Task ARN:", result.tasks[0].taskArn);

Overriding via AWS SDK (Python / Boto3)

python
1import boto3
2
3ecs = boto3.client("ecs", region_name="us-east-1")
4
5response = ecs.run_task(
6    cluster="my-cluster",
7    taskDefinition="my-app",
8    launchType="FARGATE",
9    networkConfiguration={
10        "awsvpcConfiguration": {
11            "subnets": ["subnet-abc123"],
12            "securityGroups": ["sg-abc123"],
13            "assignPublicIp": "ENABLED",
14        }
15    },
16    overrides={
17        "containerOverrides": [
18            {
19                "name": "app",
20                "environment": [
21                    {"name": "NODE_ENV", "value": "staging"},
22                    {"name": "MIGRATION_MODE", "value": "true"},
23                ],
24            }
25        ]
26    },
27)
28
29task_arn = response["tasks"][0]["taskArn"]
30print(f"Running task: {task_arn}")

Overriding CPU, Memory, and Command

bash
1# You can also override CPU, memory, and the command
2aws ecs run-task \
3  --cluster my-cluster \
4  --task-definition my-app \
5  --overrides '{
6    "cpu": "1024",
7    "memory": "2048",
8    "containerOverrides": [
9      {
10        "name": "app",
11        "command": ["python", "migrate.py", "--run-seeds"],
12        "environment": [
13          { "name": "DATABASE_URL", "value": "postgres://staging-db:5432/app" }
14        ],
15        "cpu": 512,
16        "memory": 1024
17      }
18    ]
19  }'

Overriding command runs a different entry point — useful for one-off tasks like database migrations, data exports, or health checks using the same container image.

Using with Scheduled Tasks (EventBridge)

json
1{
2  "Rule": "daily-report",
3  "Targets": [
4    {
5      "Arn": "arn:aws:ecs:us-east-1:123456789:cluster/my-cluster",
6      "EcsParameters": {
7        "TaskDefinitionArn": "arn:aws:ecs:us-east-1:123456789:task-definition/my-app:5",
8        "LaunchType": "FARGATE",
9        "NetworkConfiguration": {
10          "awsvpcConfiguration": {
11            "Subnets": ["subnet-abc123"],
12            "SecurityGroups": ["sg-abc123"]
13          }
14        }
15      },
16      "Input": "{\"containerOverrides\":[{\"name\":\"app\",\"environment\":[{\"name\":\"REPORT_TYPE\",\"value\":\"daily\"}]}]}"
17    }
18  ]
19}

EventBridge (CloudWatch Events) scheduled rules can pass overrides via the Input field, enabling scheduled tasks with different configurations from the same task definition.

Common Pitfalls

  • Wrong container name in overrides: The name in containerOverrides must exactly match the container name in the task definition. A mismatch silently ignores the override — no error, no warning, just the default values used instead.
  • Expecting overrides to modify the task definition: Overrides apply only to the specific task run. The task definition remains unchanged. If you need permanent changes, create a new task definition revision with register-task-definition.
  • Environment override replaces entire variable, not appends: If your task definition has DATABASE_URL=prod-url and you override with DATABASE_URL=staging-url, the production URL is completely replaced. There is no merge behavior for individual variables.
  • Using secrets in environment overrides instead of AWS Secrets Manager: Environment overrides appear in plain text in CloudTrail logs, task metadata, and the ECS console. For sensitive values (passwords, API keys), use secrets with AWS Secrets Manager or SSM Parameter Store references instead of environment.
  • Fargate CPU/memory override constraints: Fargate only supports specific CPU/memory combinations (e.g., 256 CPU with 512/1024/2048 memory). Overriding with an unsupported combination causes the task to fail with an InvalidParameterException. Check the Fargate task size documentation for valid pairs.

Summary

  • Pass overrides.containerOverrides[].environment to run-task to override environment variables for a single task run
  • The container name in overrides must match the task definition exactly
  • Overrides do not modify the task definition — they are per-run only
  • You can also override command, cpu, and memory in the same overrides object
  • Use overrides for one-off tasks (migrations, reports) without creating new task definition revisions
  • Store sensitive values in AWS Secrets Manager, not in environment overrides

Course illustration
Course illustration

All Rights Reserved.