---
layout: docs
page_title: Migrate Existing Tasks - AWS ECS
description: >-
  Migrate Existing Tasks
---

# Migrate Existing Tasks

This guide explains how to migrate your existing ECS Tasks to use our [`mesh-task` Terraform module](https://registry.terraform.io/modules/hashicorp/consul-ecs/aws/latest/submodules/mesh-task).

## Define Tasks in Terraform

Your tasks must first be specified in Terraform using [`ecs_task_definition`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_task_definition)
and [`ecs_service`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_service) resources so that
they can later be converted to use the [`mesh-task` module](https://registry.terraform.io/modules/hashicorp/consul-ecs/aws/latest/submodules/mesh-task).

For example, your tasks should be defined with Terraform similar to the following:

```hcl
resource "aws_ecs_task_definition" "my_task" {
  family                   = "my_task"
  requires_compatibilities = ["FARGATE"]
  network_mode             = "awsvpc"
  cpu                      = 256
  memory                   = 512
  execution_role_arn       = "arn:aws:iam::111111111111:role/execution-role"
  task_role_arn            = "arn:aws:iam::111111111111:role/task-role"
  container_definitions = jsonencode(
    [{
      name             = "example-client-app"
      image            = "docker.io/org/my_task:v0.0.1"
      essential        = true
      portMappings = [
        {
          containerPort = 9090
          hostPort      = 9090
          protocol      = "tcp"
        }
      ]
      cpu         = 0
      mountPoints = []
      volumesFrom = []
    }]
  )
}

resource "aws_ecs_service" "my_task" {
  name            = "my_task"
  cluster         = "arn:aws:ecs:us-east-1:111111111111:cluster/my-cluster"
  task_definition = aws_ecs_task_definition.my_task.arn
  desired_count   = 1
  network_configuration {
    subnets = ["subnet-abc123"]
  }
  launch_type            = "FARGATE"
}
```

## Convert Tasks to Mesh Module

In order to add the necessary sidecar containers for your task to join the mesh,
you must use the [`mesh-task` module](https://registry.terraform.io/modules/hashicorp/consul-ecs/aws/latest/submodules/mesh-task).

The `mesh-task` module uses inputs similar to your old ECS task definition but
creates a new version of the task definition with additional containers.

The `mesh-task` module is used as follows:

```hcl
module "my_task" {
  source  = "hashicorp/consul/aws-ecs//modules/mesh-task"
  version = "<latest version>"

  family              = "my_task"
  container_definitions = [
    {
      name             = "example-client-app"
      image            = "docker.io/org/my_task:v0.0.1"
      essential        = true
      portMappings = [
        {
          containerPort = 9090
          hostPort      = 9090
          protocol      = "tcp"
        }
      ]
      cpu         = 0
      mountPoints = []
      volumesFrom = []
    }
  ]

  port                       = "9090"
  retry_join                 = "<address of the Consul server>"
}
```

All possible inputs are documented on the [module reference documentation](https://registry.terraform.io/modules/hashicorp/consul-ecs/aws/latest/submodules/mesh-task?tab=inputs)
however there are some important inputs worth highlighting:

- You do not need the `execution_role_arn` or `task_role_arn` fields. The `mesh-task` module will create the task and execution roles.
- `family` is used as the [task definition family](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#family) and the name of the service that is registered in Consul.
- `container_definitions` accepts an array of [container definitions](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definitions).
  These are your application containers and are the same as `container_definitions` key in the
  `aws_ecs_task_definition` resource without the `jsonencode() function`.

  For example, if your original task definition looked like:

  ```hcl
  resource "aws_ecs_task_definition" "my_task" {
    ...
    container_definitions = jsonencode(
      [
        {
          name             = "example-client-app"
          image            = "docker.io/org/my_task:v0.0.1"
          essential        = true
          ...
        }
      ]
    )
  }
  ```

  Then remove the `jsonencode()` function and use the rest of the value
  as the input for the `mesh-task` module:

  ```hcl
  module "my_task" {
    source  = "hashicorp/consul/aws-ecs//modules/mesh-task"
    version = "<latest version>"

    ...
    container_definitions = [
      {
        name             = "example-client-app"
        image            = "docker.io/org/my_task:v0.0.1"
        essential        = true
        ...
      }
    ]
  }
  ```

- `port` is the port that your application listens on. This should be set to a
  string, not an integer, i.e. `port = "9090"`, not `port = 9090`.
- `retry_join` is passed to the `-retry-join` option for the Consul agent. This tells
  the agent the location of your Consul server so that it can join the Consul cluster.

The `mesh-task` module will create a new version of your task definition with the
necessary sidecar containers added so you can delete your existing `aws_ecs_task_definition`
resource.

Your `aws_ecs_service` resource can remain unchanged except for the `task_definition`
input which should reference the new module's output of the task definition's ARN:

```hcl
resource "aws_ecs_service" "my_task" {
  ...
  task_definition = module.my_task.task_definition_arn
}
```

-> **NOTE:** If your tasks run in a public subnet, they must have `assign_public_ip = true`
in their [`network_configuration`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_service#network_configuration) block so that ECS can pull the Docker images.

After running `terraform apply`, you should see your tasks registered in
the Consul UI.

## Complete Installation

Now that your task(s) are migrated to the `mesh-task` module, see the [Install Guide](/docs/ecs/get-started/install) to install Consul on ECS.
