1. Answers
  2. Implementing Sidecar Patterns in ECS

How do I implement sidecar patterns in ECS?

Introduction

In this guide, we’ll explore setting up the sidecar pattern on Amazon ECS (Elastic Container Service). The sidecar pattern involves deploying helper containers alongside the primary application container within the same task definition. This approach is commonly used to offload certain tasks, like logging or proxy services, from the main application container.

We’ll create an ECS Task Definition with two containers: a primary application container and a sidecar container for logging.

Detailed Explanation

The key resources used will include:

  • An ECS task definition which specifies both the main application and sidecar containers.
  • An IAM role for ECS tasks to allow necessary permissions.
  • A CloudWatch log group to aggregate logs from the sidecar container.

The following program defines these resources and sets up the essential configurations to implement the sidecar pattern.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const ecsTaskExecutionRole = new aws.iam.Role("ecs_task_execution_role", {
    name: "ecsTaskExecutionRole",
    assumeRolePolicy: `{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs-tasks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
`,
});
const ecsTaskExecutionRolePolicy = new aws.iam.RolePolicyAttachment("ecs_task_execution_role_policy", {
    role: ecsTaskExecutionRole.name,
    policyArn: "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy",
});
const ecsLogs = new aws.cloudwatch.LogGroup("ecs_logs", {
    name: "/aws/ecs/containerlogs",
    retentionInDays: 7,
});
const appWithSidecar = new aws.ecs.TaskDefinition("app_with_sidecar", {
    family: "example-task-family",
    requiresCompatibilities: ["FARGATE"],
    networkMode: "awsvpc",
    cpu: "256",
    memory: "512",
    executionRoleArn: ecsTaskExecutionRole.arn,
    containerDefinitions: pulumi.interpolate`[
  {
    "name": "app",
    "image": "nginx",
    "essential": true,
    "logConfiguration": {
      "logDriver": "awslogs",
      "options": {
        "awslogs-group": "${ecsLogs.name}",
        "awslogs-region": "us-west-2",
        "awslogs-stream-prefix": "app"
      }
    }
  },
  {
    "name": "sidecar",
    "image": "busybox",
    "essential": false,
    "command": ["sh", "-c", "while true; do echo 'Hello from sidecar' >> /dev/stdout; sleep 5; done"],
    "logConfiguration": {
      "logDriver": "awslogs",
      "options": {
        "awslogs-group": "${ecsLogs.name}",
        "awslogs-region": "us-west-2",
        "awslogs-stream-prefix": "sidecar"
      }
    }
  }
]
`,
});
export const taskDefinitionArn = appWithSidecar.arn;

Key Points

  • IAM Role: An IAM role is required for ECS to interact with AWS services on your behalf.
  • Log Group: This defines where the logs from both containers will be collected.
  • Task Definition: This specifies both the primary and sidecar containers along with the necessary configurations.

Conclusion

We’ve successfully defined a simple ECS Task Definition that uses the sidecar pattern. The primary application container is responsible for running the main application, while the sidecar container handles auxiliary tasks like logging. This setup helps in managing and separating concerns within an ECS Task.

Deploy this code

Want to deploy this code? Sign up for a free Pulumi account to deploy in a few clicks.

Sign up

New to Pulumi?

Want to deploy this code? Sign up with Pulumi to deploy in a few clicks.

Sign up