> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/harness-platform/use-harness-platform/delegates/delegate/install-delegates/docker-delegate-to-ecs-fargate.md).

# Deploy a Docker delegate to Amazon ECS or AWS Fargate

Harness Delegate carries out the tasks in your Continuous Integration (CI) and Continuous Delivery (CD) pipelines. The delegate is a software component that installs in your environment and registers with Harness Manager. The delegate connects to Harness Manager for the assignment and completion of CI/CD tasks.

You can use Harness to deploy a Docker delegate to Amazon Elastic Container Service (ECS) or AWS Fargate.

### Considerations before using ECS-configured Docker delegates <a href="#considerations-before-using-ecs-configured-docker-delegates" id="considerations-before-using-ecs-configured-docker-delegates"></a>

Review the following information about using Harness ECS-configured Docker delegates to ensure seamless and secure deployment of your applications and services.

* **ECS-configured Docker delegates do not auto-update:** If you are using a delegate configured through ECS, auto-update of the delegate is not supported.
* **Concerns with auto-upgrading the delegate:** The convenience of automatic updates is obvious, but it raises certain security concerns. As delegates are updated, new binaries and tools may be introduced. There is no way to scan these additions, which can lead to potential vulnerabilities. Due to these concerns, Harness recommends using custom delegates for production use. If you use the Docker delegate on AWS ECS Fargate, Harness recommends that you manually update the delegate on a regular cadence, either every 3 or 6 months. This ensures a balance between security and feature updates.
* **Limitations with Docker delegate on an AWS ECS Fargate-backed instance:** When operating ECS delegates on AWS Fargate, it's critical to note that AWS Fargate will terminate the delegate if the tasks running on the delegate exceed the infrastructure's specified limits. This is a limitation inherent in using infrastructure not owned by the customer. Harness Delegate cannot circumvent this restriction. However, ECS delegates operating on an EC2 instance do not have this issue. To avoid this limitation, consider using Kubernetes delegates where the infrastructure and associated YAML definitions address these issues.

### Deploy a delegate to Amazon ECS <a href="#deploy-a-delegate-to-amazon-ecs" id="deploy-a-delegate-to-amazon-ecs"></a>

Use these steps to deploy a delegate to an ECS cluster as an ECS service. The installed delegate connects to your AWS resources.

This process requires a delegate with an immutable image type. For more information, go to [Delegate image types](/harness-platform/use-harness-platform/delegates/delegate/delegate-concepts/delegate-image-types.md).

{% hint style="info" %}
You can also [use a Terraform module to deploy a delegate to an ECS cluster](#deploy-a-delegate-using-terraform).
{% endhint %}

#### Create the cluster <a href="#create-the-cluster" id="create-the-cluster"></a>

Create an ECS cluster. Use an EC2 instance type with networking. For more information, go to [EC2 instance types](https://aws.amazon.com/ec2/instance-types/) in the AWS documentation.

#### Create the task definition <a href="#create-the-task-definition" id="create-the-task-definition"></a>

1. Copy the following task `spec` into a file. Save the file as `task-spec.json`.

   ```json
    {
      "containerDefinitions": [
        {
          "cpu": 1,
          "environment": [
            {
              "name": "ACCOUNT_ID",
              "value": "<ACCOUNT_ID>"
            },
            {
              "name": "DELEGATE_TOKEN",
              "value": "<DELEGATE_TOKEN>"
            },
            {
              "name": "MANAGER_HOST_AND_PORT",
              "value": "<MANAGER_HOST_AND_PORT>"
            },           
            {
              "name": "DELEGATE_NAME",
              "value": "<DELEGATE_NAME>"
            },            
            {
              "name": "DELEGATE_TAGS",
              "value": ""
            },
            {
              "name": "INIT_SCRIPT",
              "value": ""
            },
            {
              "name": "DELEGATE_TYPE",
              "value": "DOCKER"
            },
            {
              "name": "NEXT_GEN",
              "value": "true"
            }
          ],
          "memory": 2048,
          "image": "<IMAGE>",
          "essential": true,
          "hostname": "<DELEGATE_HOST>",
          "name": "<DELEGATE_NAME>"
        }
      ],
      "memory": "2048",
      "requiresCompatibilities": [
        "EC2"
      ],
      "cpu": "1024",
      "family": "harness-delegate-task-spec"
    }
   ```
2. Copy and paste the above JSON into task definition on Amazon ECS console. Refer the image below:

   ![](/files/5E3n0wEKBw0QY7Ki6oS6)
3. Enter the fields of the task definition as follows:

   | **Field**               | **Description**                                                                                                                                                                                            |
   | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   | `ACCOUNT_ID`            | Your Harness account ID.                                                                                                                                                                                   |
   | `DELEGATE_TOKEN`        | The delegate token stored in your Harness account.                                                                                                                                                         |
   | `MANAGER_HOST_AND_PORT` | Information about your manager host. This depends on the Harness production cluster you use: Prod1: <https://app.harness.io>, Prod2: <https://app.harness.io/gratis>, or Prod3: <https://app3.harness.io>. |
   | `DELEGATE_NAME`         | The name you gave your delegate. This is usually the name you specified during delegate installation.                                                                                                      |
   | `IMAGE`                 | Use the most recent delegate image from <https://hub.docker.com/r/harness/delegate/tags>. The correct image uses an image tag in the following format: `harness/delegate:yy.mm.xxxxx`.                     |

#### Create your services <a href="#create-your-services" id="create-your-services"></a>

Use the following steps to create a service.

1. Open AWS CLI. Use the following instruction to create your AWS services:

   ```
   aws ecs create-service --service-name <SERVICE_NAME> --task-definition harness-delegate-task-spec --cluster <CLUSTER_NAME> --desired-count 1
   ```

   Replace `service-name` with the unique name of your service. Replace `task-definition` with the task definition that the service runs. For information on the specification of ECS service parameters, go to [`create-service`](https://docs.aws.amazon.com/cli/latest/reference/ecs/create-service.html).
2. Use the following instruction to increase the count of replica pods to the desired number:

   ```
   harness-delegate-task-spec --cluster <CLUSTER_NAME> --desired-count 1
   ```

### Deploy a delegate to Amazon Fargate <a href="#deploy-a-delegate-to-amazon-fargate" id="deploy-a-delegate-to-amazon-fargate"></a>

Use the following steps to deploy a delegate to an Amazon Fargate cluster. This process requires a delegate with an immutable image. For more information, go to [Delegate image types](/harness-platform/use-harness-platform/delegates/delegate/delegate-concepts/delegate-image-types.md).

#### Create the cluster <a href="#create-the-cluster" id="create-the-cluster"></a>

Create a cluster on Amazon Fargate. Use an instance type with networking. For more information, go to [EC2 instance types](https://aws.amazon.com/ec2/instance-types/) in the AWS documentation.

#### Create the task definition <a href="#create-the-task-definition" id="create-the-task-definition"></a>

Use the following steps to create a task definition. For information about task definitions in Amazon ECS, go to [Task definition template](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-definition-template.html).

1. Copy the following task `spec` into a file. Save the file as `task-spec.json`.

   ```json
    {
      "containerDefinitions": [
        {
          "cpu": 1,
          "environment": [
            {
              "name": "ACCOUNT_ID",
              "value": "<ACCOUNT_ID>"
            },
            {
              "name": "DELEGATE_TOKEN",
              "value": "<DELEGATE_TOKEN>"
            },
            {
              "name": "MANAGER_HOST_AND_PORT",
              "value": "<MANAGER_HOST_AND_PORT>"
            },           
            {
              "name": "DELEGATE_NAME",
              "value": "<DELEGATE_NAME>"
            },            
            {
              "name": "DELEGATE_TAGS",
              "value": ""
            },
            {
              "name": "INIT_SCRIPT",
              "value": ""
            },
            {
              "name": "DELEGATE_TYPE",
              "value": "DOCKER"
            },
            {
              "name": "NEXT_GEN",
              "value": "true"
            }
          ],
          "memory": 2048,
          "image": "<IMAGE>",
          "essential": true,
          "name": "ecs-delegate-im"
        }
      ],
      "executionRoleArn": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/ecsTaskExecutionRole",
      "memory": "6144",
      "requiresCompatibilities": [
        "FARGATE"
      ],
      "networkMode": "awsvpc",
      "cpu": "1024",
      "family": "harness-delegate-task-spec"
    }
   ```
2. Edit the fields of the task definition as follows.

   | **Field**               | **Description**                                                                                                                                                                                            |
   | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   | `ACCOUNT_ID`            | Your Harness account ID.                                                                                                                                                                                   |
   | `DELEGATE_TOKEN`        | The delegate token stored in your Harness account.                                                                                                                                                         |
   | `MANAGER_HOST_AND_PORT` | Information about your manager host. This depends on the Harness production cluster you use: Prod1: <https://app.harness.io>, Prod2: <https://app.harness.io/gratis>, or Prod3: <https://app3.harness.io>. |
   | `DELEGATE_NAME`         | The name you gave your delegate. This is usually the name you specified during delegate installation.                                                                                                      |
   | `IMAGE`                 | Use the most recent delegate image from <https://hub.docker.com/r/harness/delegate/tags>. The correct image uses an image tag in the following format: `harness/delegate:yy.mm.xxxxx`.                     |
   | `AWS_ACCOUNT_ID`        | Your AWS account ID.                                                                                                                                                                                       |

#### Create the service <a href="#create-the-service" id="create-the-service"></a>

1. Edit the `service.json` file as follows:

   ```json
   {
      "launchType": "FARGATE",
      "cluster": "<CLUSTER_NAME>",
      "serviceName": "<SERVICE_NAME>",
      "taskDefinition": "harness-delegate-task-spec",
      "desiredCount": 1,
      "loadBalancers": [],
      "networkConfiguration": {
        "awsvpcConfiguration": {
          "subnets": [
            "<SUBNET>"
          ],
          "securityGroups": [
            "SEC_GROUP"
          ],
          "assignPublicIp": "ENABLED"
        }
      },
      "platformVersion": "LATEST",
      "schedulingStrategy": "REPLICA",
      "enableECSManagedTags": true
    }
   ```
2. After the service is created and modified, use the JSON files to register the task and service definitions.
3. From AWS CLI, use the following instructions to register the task definition:

   ```
   aws ecs register-task-definition --cli-input-json file://task-spec.json
   ```
4. Then register the service definition:

   ```
   aws ecs create-service --cli-input-json file://service.json
   ```

### Deploy a delegate using Terraform <a href="#deploy-a-delegate-using-terraform" id="deploy-a-delegate-using-terraform"></a>

The above steps to [deploy a delegate to ECS](#deploy-a-delegate-to-amazon-ecs) are also available in a Terraform module that you can reference directly or use as a starting point for your own automation. You can use an existing ECS cluster (EC2- or Fargate-based) or let the module create one for you.

To access the module, go to [Harness Community GitHub](https://github.com/harness-community/terraform-aws-harness-delegate-ecs-fargate).

{% hint style="warning" %}
**DISCLAIMER: COMMUNITY-MAINTAINED RESOURCE**

The [Terraform module](https://github.com/harness-community/terraform-aws-harness-delegate-ecs-fargate) for deploying a Harness delegate on ECS Fargate is hosted in a community-maintained GitHub repository and is provided as-is for reference.

* This solution is not officially supported or maintained by Harness.
* It may be outdated and might not support features like Auto-Upgrades.
* Users are advised to treat this as sample/example code only.
  {% endhint %}

```terraform
module "delegate" {
  source                    = "git::https://github.com/harness-community/terraform-aws-harness-delegate-ecs-fargate.git"
  name                      = "ecs"
  harness_account_id        = "<Harness account Id>"
  delegate_token_secret_arn = "arn:aws:secretsmanager:us-west-2:012345678901:secret:harness/delegate-zBsttc"
  delegate_policy_arns      = [
    aws_iam_policy.delegate_aws_access.arn
  ]
  security_groups = [
    module.vpc.default_security_group_id
  ]
  subnets = module.vpc.private_subnets
}

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 3.0"

  name = "this"
  cidr = "10.0.0.0/16"

  azs             = ["us-west-2a", "us-west-2b"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
  public_subnets  = ["10.0.4.0/24", "10.0.5.0/24"]

  enable_nat_gateway   = true
  single_nat_gateway   = true
  enable_dns_hostnames = true

  public_subnet_tags = {
    "type"                         = "public"
  }

  private_subnet_tags = {
    "type"                            = "private"
  }
}

resource "aws_iam_policy" "delegate_aws_access" {
  name        = "delegate_aws_access"
  description = "Policy for harness delegate aws access"

  policy = <<EOF
{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Sid": "GetArtifacts",
           "Effect": "Allow",
           "Action": [
               "s3:*"
           ],
           "Resource": [
              "${aws_s3_bucket.this.arn}",
              "${aws_s3_bucket.this.arn}/*"
           ]
       }
   ]
}
EOF
}
```
