AWS ECS

How to manually delete a cluster in case the pipelines do not work?

  1. Find the target cluster to delete -> Go to Tasks tab -> Hit Stop All button
  2. Go back to Services tab -> Click on the service -> Hit Delete button
  3. Go to ALB page under EC2 service -> Find target ALB you want to delete -> Go to its Listeners tab -> Go into the listeners list and find target groups associated with that listener (default and current ones if applicable) -> Find those target groups in the Target Groups view
  4. Go back to ALB Listeners tab -> Delete that listener
  5. Go to the Target Groups view -> Delete those target group(s). Make sure you search for all the target groups for that stack. Look for prefix (search by the name of your application) to identify the target groups belonged to that stack
  6. Go to the Auto Scaling Groups view -> Delete the auto scaling group(s)
  7. Go to the Launch Configuration view -> Delete the launch configuration(s)
  8. Go to the Load Balancer view -> Delete the target load balancer (you will need to edit the ALB attribute, and disable the Delete Protection option)
  9. Go to the Target Groups view -> Look for any target group associated with that stack.
  10. Go to the ECS view -> Delete the target cluster
  11. Done

How to get environment variables in ECS container?

Environment variables are defined inside the container and some are passed in the task definition. So you can use describe-task-definition to see the extra variables.

If you are using the console, just go the task definition and look at “Environment variables”.

How to deploy a previous version of a service in ECS if an incorrect version of code is deployed by mistake?

ECS -> Clusters -> service-group -> services -> name-of-the-application -> Update

In the dropdown for “Revision”, pick an older version.

Select “Force new deployment” radio button and run it.

That will deploy the older version.

Monitor the tasks to see that tasks with newer version go away and tasks with older version get created.

Task definition

How can you find out which version of your application is deployed in a given environment?

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html

A task definition is a blueprint for your application. It is a text file in JSON format that describes the parameters and one or more containers that form your application.

How to send requests to containers in a cluster directly?

Sending requests directly to containers within an AWS ECS cluster is possible, but the best approach depends heavily on why you need to send the request: for debugging/troubleshooting or for production service-to-service communication.

Containers in a cluster are usually isolated within a private VPC network and are constantly replaced, which is why a Load Balancer is the standard entry point.

Here are the methods for direct container access:

1. The Standard Way: Load Balancer / Service Discovery (Production Traffic)

For standard traffic (HTTP/S) meant for the application, you should never send requests directly to an ephemeral container IP. Instead, use the service layer provided by AWS.

  • External Access (Internet/Client): Use an Application Load Balancer (ALB) or Network Load Balancer (NLB). The ALB/NLB handles public exposure, routing, health checks, and distributes traffic to the healthy containers based on their private IP addresses. See AWS - Application Load Balancer (ALB)
    curl -k "https://my-alb-1234567890.us-east-1.elb.amazonaws.com/api/v1/items"
    
  • Internal Access (Service-to-Service): Use ECS Service Discovery (which leverages AWS Cloud Map). This allows one service to query a domain name (e.g., backend-api.local) that resolves to the private IP addresses of the backend service’s healthy containers, all within the VPC.

2. The Direct Way: ECS Execute Command (Debugging/Troubleshooting ONLY)

For debugging, running commands, or establishing an interactive shell on a single, specific running container, use AWS ECS Execute Command (ECS Exec). This is the modern, secure way to connect directly to a container without using SSH or exposing ports.

How ECS Exec Works

ECS Exec uses AWS Systems Manager (SSM) Session Manager to create a secure, encrypted tunnel from your local machine (via the AWS CLI) to the container. This works for both ECS tasks running on EC2 and those on AWS Fargate.

Prerequisites

  1. Enable ECS Exec: You must enable the feature when you create or update the ECS Service (--enable-execute-command).
  2. IAM Permissions: The Task IAM Role must have the necessary policies to communicate with SSM Session Manager (e.g., ssmmessages:CreateControlChannel, ssmmessages:OpenControlChannel).
  3. Client Setup: You must have the AWS CLI and the SSM Session Manager Plugin installed on your local machine.

The Command

To open an interactive shell on a specific container:

aws ecs execute-command \
    --cluster <your-cluster-name> \
    --task <task-id-or-arn> \
    --container <container-name> \
    --interactive \
    --command "/bin/bash"
  • This command drops you directly into a shell inside the running container, allowing you to use tools like curl, ping, or check logs and configuration within that specific container instance.

3. The Low-Level Way: Direct IP Access (Temporary/Advanced)

If you absolutely need to access a container via its private IP address (e.g., for very specific networking tests), you can technically do so, but it is not recommended for general use.

  1. Find the Private IP: Use the AWS CLI or Console to find the specific Task and get its private IP address from the network configuration.
  2. Ensure Connectivity:
    • You must be running your request from a machine (like a Bastion Host, EC2 instance, or your local machine connected via VPN/Direct Connect) inside the same VPC as the container.
    • The Security Group attached to the ECS Task’s Elastic Network Interface (ENI) must allow inbound traffic on the container’s port (e.g., port 8000) from the source IP/Security Group of your testing machine.
  3. Send Request: Send your request directly to that private IP and port:
    curl http://<private-task-ip>:<container-port>/
    

Links to this note