Manually Install Consul Service Mesh on AWS ECS (Elastic Container Service).
---
# Manual Installation
While the [Consul ECS Terraform module](/docs/ecs/install) is the easiest way to use Consul on ECS,
this page will describe how to directly create the ECS task definition using the [`consul-ecs` Docker image](https://gallery.ecr.aws/hashicorp/consul-ecs)
for use without Terraform.
## Pre-requisites
* This page assumes you are familiar with AWS ECS. See [What is Amazon Elastic Container Service](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html) for more details.
* This page does not show how to create all necessary AWS resources, such as a VPC or the ECS Cluster.
For complete runnable examples, see the links in the [Getting Started](/docs/ecs#getting-started) section.
in the task definition. Ensure that the `dependsOn` field is set as shown below so that your application container starts in the correct order (see [task startup](/docs/ecs/architecture#task-startup) for more information):
| `name` | string | The name of your application container. |
| `image` | string | The container image used to run your application. |
| `essential` | boolean | Set this to `true` ensures your application container ties into the health of the task. All tasks must have at least one essential container. |
| `dependsOn` | list | Container dependendencies are used to ensure the service mesh is ready before your application starts. |
See the [ECS Task Definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html) documentation for a complete reference.
## `sidecar-proxy` container
The sidecar proxy container runs [Envoy proxy](/docs/connect/proxies/envoy) for Consul Connect.
| `name` | string | The name of the container, which should always be `sidecar-proxy`. |
| `image` | string | The container image for Envoy. We recommend using `envoyproxy/envoy-alpine`. |
| `dependsOn` | list | Envoy must start after `consul-ecs-mesh-init`, which creates the bootstrap configuration file for Envoy. |
| `healthCheck` | list | A health check should be definied for Envoy's primary listener port. |
| `mountPoints` | list | The mounts the `/consul` data volume which contains the Envoy configuration file. |
| `ulimits` | list | Set the file descriptor limit, `nofile`, to a sufficiently high value so that Envoy does not fail to open sockets. |
| `entrypoint` | list | A custom entrypoint binary is used to help facilitate graceful shutdown. |
| `command` | list | The startup command. This passes the bootstrap configuration to Envoy. |
-> **NOTE**: Envoy and Consul must be compatible versions. See the [supported versions of Envoy](https://www.consul.io/docs/connect/proxies/envoy#supported-versions) for each Consul release.
| `bootstrapDir` | string | This is the path of a shared volume the is mounted to other containers, where `mesh-init` will write out Envoy configuration. |
| `proxy.upstreams` | list | The upstream services that your application calls over the service mesh, if any. |
| `service.name` | string | The name used to register this service into the Consul service catalog. |
| `service.port` | number | The port your application listens on. Set to `0` if your application does not listen on any port. |
| `service.checks` | list | Consul [checks](/docs/discovery/checks) to include, to have Consul run health checks against your application. |
See the [`consul-ecs JSON Schema`](https://github.com/hashicorp/consul-ecs/blob/main/config/schema.json) for a complete reference of fields.
## `consul-ecs-health-sync` container
Optionally, Consul ECS can sync health checks for this task into Consul checks.
This allows you to configure a health check for your application in one place, and
see a consistent health status in both ECS and Consul.
First, you'll need to add an ECS health check command to the container definition for your application.
This configures a health check command that runs `curl localhost:9090/health` to check the application health:
See the [ECS health check documentation](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definition_healthcheck) for details on defining ECS health checks.
Next, you must tell Consul ECS which containers will have their health status synced into Consul. To do this,
set the `healthSyncContainers` field of the `CONSUL_ECS_CONFIG_JSON` variable to include your application container name.
Here is the expanded configuration:
```json
{
"bootstrapDir": "/consul",
"healthSyncContainers": ["example-client-app"],
"proxy": {
"upstreams": [
{
"destinationName": "example-server-app",
"localBindPort": 1234
}
]
},
"service": {
"checks": [],
"meta": {},
"name": "example-client-app",
"port": 9090,
"tags": []
}
}
```
Then, update the task definition so that the `consul-ecs-mesh-init` container uses new configuration.
You should compact and escape the JSON configuration above, and copy the result into the `CONSUL_ECS_CONFIG_JSON`
| `name` | string | The container name which should be `consul-ecs-health-sync`. |
| `image` | string | The `consul-ecs` image. Use our public AWS registry, `public.ecr.aws/hashicorp/consul-ecs`, to avoid rate limits. |
| `command` | list | Set to `["health-sync"]` to run the `consul-ecs health-sync` command. |
| `dependsOn` | list | The `health-sync` container should not start until `mesh-init` has finished service and proxy registration. |
| `environment` | list | Set the `CONSUL_ECS_CONFIG_JSON` variable to pass configuration to the `consul-ecs health-sync command. |
# Next Steps
* Create the task definition using the [AWS Console](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html) or the [AWS CLI](https://docs.aws.amazon.com/cli/latest/reference/ecs/register-task-definition.html), or another method of your choice.
* Create an [ECS Service](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs_services.html) to start tasks using the task definition.