docs: Manual installation of Consul on ECS

This commit is contained in:
Paul Glass 2022-01-18 14:52:40 -06:00
parent 446355ff69
commit 5a98efcf56
4 changed files with 565 additions and 42 deletions

View File

@ -0,0 +1,492 @@
---
layout: docs
page_title: Manual Installation - AWS ECS
description: >-
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.
# Task Definition
You must define a Task Definition which includes the following containers:
* Your application container
* An Envoy sidecar-proxy container
* A Consul Agent container
* The `consul-ecs-mesh-init` container for service mesh setup
* Optionally, a `consul-ecs-health-sync` container to sync ECS health checks into Consul
## Top-level fields
In your task definition, you'll need to define these important top-level fields:
```json
{
"family": "my-example-client-app",
"networkMode": "awsvpc",
"volumes": [
{
"name": "consul_data",
},
{
"name": "consul_binary",
}
],
"containerDefinitions": [...]
}
```
| Field name | Type | Description |
| ------------- | ------ | --------------------------------------------------------------------------------------------------- |
| `family` | string | The task family name. This is used as the Consul service name, by default. |
| `networkMode` | string | Must be `awsvpc`, which is the only network mode supported by Consul on ECS. |
| `volumes` | list | These are volumes used to share information between containers, which is important for setup steps. |
| `containerDefinitions` | list | The list of containers to run in this task (see below). |
## Application container
First, include your application container in the `containerDefinitions` list
in the task definition:
```json
{
"containerDefinitions": [
{
"name": "example-client-app",
"image": "docker.io/org/my_task:v0.0.1",
"essential": true,
"dependsOn": [
{
"containerName": "consul-ecs-mesh-init",
"condition": "SUCCESS"
},
{
"containerName": "sidecar-proxy",
"condition": "HEALTHY"
}
]
}
]
}
```
| Field name | Type | Description |
| ----------- | ------- | ------------------------------------------------------------------------------------------------------------------------ |
| `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.
```json
{
"containerDefinitions": [
{
"name": "example-client-app",
"image": "docker.io/org/my_task:v0.0.1",
...
},
{
"name": "sidecar-proxy",
"image": "envoyproxy/envoy-alpine:<VERSION>",
"essential": false,
"dependsOn": [
{
"containerName": "consul-ecs-mesh-init",
"condition": "SUCCESS"
}
],
"healthCheck": {
"retries": 3,
"command": ["nc", "-z", "127.0.0.1", "20000"],
"timeout": 5,
"interval": 30
},
"mountPoints": [
{
"readOnly": true,
"containerPath": "/consul",
"sourceVolume": "consul_data"
}
],
"ulimits": [
{
"name": "nofile",
"softLimit": 1048576,
"hardLimit": 1048576
}
],
"command": ["envoy", "--config-path", "/consul/envoy-bootstrap.json"],
"entryPoint": ["/consul/consul-ecs", "envoy-entrypoint"],
}
]
}
```
| Field name | Type | Description |
| ----------- | ------- | ------------------------------------------------------------------------------------------------------------------ |
| `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.
## `consul-client` container
Each task must include a Consul agent container in order for the task to join your Consul cluster.
```json
{
"containerDefinitions": [
{
"name": "example-client-app",
"image": "docker.io/org/my_task:v0.0.1",
...
},
{
"name": "sidecar-proxy",
"image": "envoyproxy/envoy-alpine:<ENVOY_VERSION>",
...
}
{
"name": "consul-client"
"image": "public.ecr.aws/hashicorp/consul:<CONSUL_VERSION>",
"mountPoints": [
{
"readOnly": false,
"containerPath": "/consul",
"sourceVolume": "consul_data"
},
{
"containerPath": "/bin/consul-inject",
"sourceVolume": "consul_binary"
}
],
"entryPoint": ["/bin/sh", "-ec"],
"command": [
"cp /bin/consul /bin/consul-inject/consul\n\nECS_IPV4=$(curl -s $ECS_CONTAINER_METADATA_URI_V4 | jq -r '.Networks[0].IPv4Addresses[0]')\n\n\ncat << EOF > /consul/agent-defaults.hcl\naddresses = {\n dns = \"127.0.0.1\"\n grpc = \"127.0.0.1\"\n http = \"127.0.0.1\"\n}\nadvertise_addr = \"$ECS_IPV4\"\nadvertise_reconnect_timeout = \"15m\"\nclient_addr = \"0.0.0.0\"\ndatacenter = \"dc1\"\nenable_central_service_config = true\nleave_on_terminate = true\nports {\n grpc = 8502\n}\nretry_join = [\n \"<Consul server location>",\n]\ntelemetry {\n disable_compat_1.9 = true\n}\n\nEOF\n\ncat << EOF > /consul/agent-extra.hcl\naddresses = {\n dns = \"0.0.0.0\"\n}\nlog_level = \"debug\"\n\nEOF\n\nexec consul agent \\\n -data-dir /consul/data \\\n -config-file /consul/agent-defaults.hcl \\\n -config-file /consul/agent-extra.hcl\n"
]
}
]
}
```
| Field name | Type | Description |
| ----------- | ------- | ------------------------------------------------------------------------------------------------------------------------ |
| `name` | string | The name of the Consul agent container, which should always be `consul-client`. |
| `image` | string | The container image for Consul. Use our public AWS registry, `public.ecr.aws/hashicorp/consul`, to avoid rate limits. |
| `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 run Envoy, in order to facilitate graceful shutdown. |
| `command` | list | The startup command. See below for details.
The following is the recommended `command` script for the Consul agent.
This is the same as the above `command` field, but is unescaped and has comments added.
```shell
# Copy the consul binary to a shared volume for mesh-init to use to generate Envoy configuration.
cp /bin/consul /bin/consul-inject/consul
# At runtime, determine the IP address assigned to this ECS Task.
ECS_IPV4=$(curl -s $ECS_CONTAINER_METADATA_URI_V4 | jq -r '.Networks[0].IPv4Addresses[0]')
# Define the Consul agent configuration file.
cat << EOF > /consul/agent-defaults.hcl
addresses = {
dns = "127.0.0.1"
grpc = "127.0.0.1"
http = "127.0.0.1"
}
advertise_addr = "$ECS_IPV4"
advertise_reconnect_timeout = "15m"
client_addr = "0.0.0.0"
datacenter = "dc1"
enable_central_service_config = true
leave_on_terminate = true
ports {
grpc = 8502
}
retry_join = ["<consul server location>"]
telemetry {
disable_compat_1.9 = true
}
EOF
# Start the consul agent.
exec consul agent \
-data-dir /consul/data \
-config-file /consul/agent-defaults.hcl
```
You can tailor the configuration above for your use case, but it's important to set the following fields as show:
| Field name | Type | Description |
| -------------------- | ------- | ------------------------------------------------------------------------------------------------------------ |
| `addresses.*` | strings | Set the DNS, GRPC, and HTTP addresses to `127.0.0.1` to ensure these are not accessible outside of the task. |
| `advertise_addr` | string | This must be set to the task IP address so that other Consul agents know how to reach this agent. |
| `client_addr` | string | This must bind to an interface reacable by other Consul agents. |
| `leave_on_terminate` | boolean | This ensures this Consul agent will leave the cluster gracefully before exiting. |
| `retry_join` | string | This must be set to your Consul server location(s) so this agent can join the Consul cluster. |
-> **NOTE**: It is important to use `exec` to start the Consul agent, so that the Consul agent runs as PID 1. This ensures
the Consul agent directly receives signals from ECS, which is important for graceful shutdown of the Consul agent.
## `mesh-init` container
The mesh-init container runs at task startup to setup this instance for Consul service mesh.
It will register this service and proxy with Consul and write Envoy bootstrap configuration
to a shared volume.
```json
{
"containerDefinitions": [
{
"name": "example-client-app",
"image": "docker.io/org/my_task:v0.0.1",
...
},
{
"name": "sidecar-proxy",
"image": "envoyproxy/envoy-alpine:<ENVOY_VERSION>",
...
},
{
"name": "consul-client"
"image": "public.ecr.aws/hashicorp/consul:<CONSUL_VERSION>",
...
},
{
"name": "consul-ecs-mesh-init",
"image": "public.ecr.aws/hashicorp/consul-ecs:<CONSUL_ECS_VERSION>",
"command": ["mesh-init"],
"essential": false,
"environment": [
{
"name": "CONSUL_ECS_CONFIG_JSON",
"value": "{\"bootstrapDir\":\"/consul\",\"healthSyncContainers\":[],\"proxy\":{\"upstreams\":[{\"destinationName\":\"example-server-app\",\"localBindPort\":1234}]},\"service\":{\"checks\":[],\"meta\":{},\"name\":\"example-client-app\",\"port\":9090,\"tags\":[]}}"
}
],
"mountPoints": [
{
"readOnly": false,
"containerPath": "/consul",
"sourceVolume": "consul_data"
},
{
"readOnly": true,
"containerPath": "/bin/consul-inject",
"sourceVolume": "consul_binary"
}
]
}
]
}
```
| Field name | Type | Description |
| ----------- | ------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `name` | string | The container name should be `consul-ecs-mesh-init`. |
| `image` | string | The `consul-ecs` image. Use our public AWS registry, `public.ecr.aws/hashicorp/consul-ecs`, to avoid rate limits. |
| `mountPoints` | list | The mounts two volumes so that mesh-init can invoke the `consul` binary to write bootstrap Envoy configuration. |
| `command` | list | Set the `["mesh-init"]` so that the container runs the `consul-ecs mesh-init` command. |
| `environment` | list | This must include the `CONSUL_ECS_CONFIG_JSON` variable. See below for details. |
Additional configuration is passed to the `consul-ecs mesh-init` command in JSON format using the `CONSUL_ECS_CONFIG_JSON` environment variable.
Here is the sample config from above, expanded to be readable:
```json
{
"bootstrapDir": "/consul",
"healthSyncContainers": [],
"proxy": {
"upstreams": [
{
"destinationName": "example-server-app",
"localBindPort": 1234
}
]
},
"service": {
"checks": [],
"meta": {},
"name": "example-client-app",
"port": 9090,
"tags": []
}
}
```
| Field name | Type | Description |
| ----------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------ |
| `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:
```json
{
"containerDefinitions": [
{
"name": "example-client-app",
"image": "docker.io/org/my_task:v0.0.1",
"healthCheck": {
"retries": 3,
"command": ["CMD-SHELL", "curl localhost:9090/health"],
"timeout": 5,
"interval": 30
},
...
},
...
]
}
```
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`
environment variable:
```json
{
"containerDefinitions": [
{
"name": "consul-ecs-mesh-init",
"image": "public.ecr.aws/hashicorp/consul-ecs:<VERSION>",
"environment": [
{
"name": "CONSUL_ECS_CONFIG_JSON",
"value": "{\"bootstrapDir\":\"/consul\",\"healthSyncContainers\":[\"example-client-app\"],\"proxy\":{\"upstreams\":[{\"destinationName\":\"example-server-app\",\"localBindPort\":1234}]},\"service\":{\"checks\":[],\"meta\":{},\"name\":\"example-client-app\",\"port\":9090,\"tags\":[]}}"
}
],
...
},
...
]
}
```
Finally, include the `consul-ecs-health-sync` container in the `containerDefinitions` list.
Be sure to pass the same value as above for the `CONSUL_ECS_CONFIG_JSON` environment
variable:
```json
{
"containerDefinitions": [
{
"name": "example-client-app",
"image": "docker.io/org/my_task:v0.0.1",
...
},
{
"name": "sidecar-proxy",
"image": "envoyproxy/envoy-alpine:<ENVOY_VERSION>",
...
},
{
"name": "consul-client"
"image": "public.ecr.aws/hashicorp/consul:<CONSUL_VERSION>",
...
},
{
"name": "consul-ecs-mesh-init",
"image": "public.ecr.aws/hashicorp/consul-ecs:<CONSUL_ECS_VERSION>",
...
},
{
"name": "consul-ecs-health-sync",
"image": "public.ecr.aws/hashicorp/consul-ecs:<CONSUL_ECS_VERSION>",
"command": ["health-sync"],
"essential": false,
"dependsOn": [
{
"containerName": "consul-ecs-mesh-init",
"condition": "SUCCESS"
}
],
"environment": [
{
"name": "CONSUL_ECS_CONFIG_JSON",
"value": "{\"bootstrapDir\":\"/consul\",\"healthSyncContainers\":[\"example-client-app\"],\"proxy\":{\"upstreams\":[{\"destinationName\":\"example-server-app\",\"localBindPort\":1234}]},\"service\":{\"checks\":[],\"meta\":{},\"name\":\"example-client-app\",\"port\":9090,\"tags\":[]}}"
}
]
}
]
}
```
| Field name | Type | Description |
| ------------- | ------ | ----------------------------------------------------------------------------------------------------------------- |
| `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.

View File

@ -1,28 +1,30 @@
---
layout: docs
page_title: Installation - AWS ECS
page_title: Installation with Terraform - AWS ECS
description: >-
Install Consul Service Mesh on AWS ECS (Elastic Container Service).
Install Consul Service Mesh on AWS ECS with Terraform (Elastic Container Service).
---
# Installation
# Installation with Terraform
Installing Consul on ECS is a multi-part process:
This will describe how to use the [`mesh-task` module](https://registry.terraform.io/modules/hashicorp/consul-ecs/aws/latest/submodules/mesh-task) Terraform module to launch your application in AWS ECS as part of Consul service mesh.
1. [**Task Module:**](#task-module) Define the [`mesh-task` Terraform module](https://registry.terraform.io/modules/hashicorp/consul-ecs/aws/latest/submodules/mesh-task)
to create a task definition with the necessary sidecar containers for your application to join the service mesh.
1. [**Routing:**](#routing) With your tasks as part of the mesh, you must specify their upstream
services and change the URLs the tasks are using so that they're making requests through the service mesh.
1. [**Bind Address:**](#bind-address) Now that all communication is flowing through the service mesh,
you should change the address your application is listening on to `127.0.0.1`
so that it only receives requests through the sidecar proxy.
## Pre-requisites
-> **NOTE:** This page assumes you're familiar with ECS. See [What is Amazon Elastic Container Service](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html) for more details.
* This pages assumes you are familiar with Terraform. If you are new to Terraform, see the [Terraform documentation](https://www.terraform.io/docs) to
learn about infrastructure as code and how to get started with Terraform.
* 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.
## Task Module
## Using the Mesh Task 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):
To run an application in ECS with Consul service mesh, you must create an ECS task definition which includes your application container(s)
and additional sidecar containers, such as the Consul agent container and the Envoy sidecar proxy container.
The [`mesh-task` module](https://registry.terraform.io/modules/hashicorp/consul-ecs/aws/latest/submodules/mesh-task) will automatically include the necessary sidecar containers.
Here is an example Terraform configuration file which defines a task definition with an application container called `example-client-app`.
```hcl
module "my_task" {
@ -53,35 +55,52 @@ module "my_task" {
}
```
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),
All possible inputs are documented in 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:
- `family` is used as the [task definition family](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#family)
but it's also used as the name of the service that gets 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).
This is where you include application containers.
- `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`](/docs/agent/options#_retry_join) option for the Consul agent. This tells
the agent the location of your Consul servers so that it can join the Consul cluster.
-> **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.
| Input Variable | Type | Description |
| ----------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `source` and `version` | string | This specifies the source location and version of the `mesh-task` module. |
| `family` | string | The [ECS task definition family](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#family). The family is also used as the Consul service name, by default. |
| `container_definitions` | list | This is the list of [container definitions](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definitions) for the task definition. This is where you include your application containers. |
| `port` | number | The port that your application listens on, if any. If your application does not listen on a port, set `outbound_only = true`. |
| `retry_join` | list | The is the [`retry_join`](/docs/agent/options#_retry_join) option for the Consul agent, which specifies the locations of your Consul servers. |
## ECS Service
[ECS services](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs_services.html) are one of the most common
ways to start tasks using a task definition..
To define an ECS Service, reference the mesh-task module's `task_definition_arn` output value
in your `aws_ecs_service` resource:
```hcl
resource "aws_ecs_service" "my_task" {
...
name = "my_task_service"
task_definition = module.my_task.task_definition_arn
launch_type = "FARGATE"
propagate_tags = "TASK_DEFINITION"
...
}
```
After running `terraform apply`, you should see your tasks registered in
the Consul UI.
This is a partial configuration to highlight some important fields.
See the [`aws_ecs_service`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_service) documentation for a complete reference.
| Input Variable | Type | Description |
| ----------------- | ------- | ------------------------------------------------------------------------------------------------------------------- |
| `name` | string | The name of the ECS service. This is required by AWS but is not used by Consul service mesh. |
| `task_definition` | string | The task definition used to start tasks. Set this to the task definition ARN returned by the `mesh-task` module. |
| `launch_type` | string | The launch type. Consul on ECS supports the `FARGATE` and `EC2` launch types. |
| `propagate_tags` | string | This must be set to `TASK_DEFINITION` so that tags added by `mesh-task` to the task definition are copied to tasks. |
After defining the Terraform configuration for both the `mesh-task` and ECS service,
run `terraform apply` to create the ECS task definition and service resources. The ECS
service will soon start your application in a task. The task will automatically
register itself into the Consul service catalog.
-> **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.
## Routing
@ -94,25 +113,23 @@ needs to call. You then must modify your application to make requests to the sid
proxy on that port.
For example, if your application `web` makes calls to another application called `backend`, then you would first configure the `mesh-task` module's upstream(s):
`backend`.
```hcl
module "web" {
family = "web"
upstreams = [
{
destination_name = "backend"
local_bind_port = 8080
destinationName = "backend"
localBindPort = 8080
}
]
}
```
- Set the `destination_name` to the name of the upstream service (in this case `backend`)
- Set `local_bind_port` to an unused port. This is the port that the sidecar proxy
will listen on. Any requests to this port will be forwarded over to the `destination_name`.
This does not have to be the port that `backend` is listening on because the service mesh
will handle routing the request to the right port.
| Input Variable | Type | Description |
| ----------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `destinationName` | string | The name of the upstream service, as it is registered in the Consul service catalog. |
| `localBindPort` | number | Requests to this port will be forwarded by the proxy to the upstream service. This must be an unused port, but does not need to match the upstream service port. |
If you have multiple upstream services they each need to be listed here.
@ -127,8 +144,8 @@ module "web" {
family = "web"
upstreams = [
{
destination_name = "backend"
local_bind_port = 8080
destinationName = "backend"
localBindPort = 8080
}
]
container_definitions = [

View File

@ -9,8 +9,18 @@ description: >-
The following requirements must be met in order to install Consul on ECS:
1. **Terraform:** The tasks that you want to add to the service mesh must first be modeled in Terraform.
1. **Launch Type:** Fargate and EC2 launch types are supported.
1. **Subnets:** ECS Tasks can run in private or public subnets. Tasks must have [network access](https://aws.amazon.com/premiumsupport/knowledge-center/ecs-pull-container-api-error-ecr/) to Amazon ECR or other public container registries to pull images.
1. **Consul Servers:** You can use your own Consul servers running on virtual machines or use [HashiCorp Cloud Platform Consul](https://www.hashicorp.com/cloud-platform) to host the servers for you. For development purposes or testing, you may use the `dev-server` [Terraform module](https://github.com/hashicorp/terraform-aws-consul-ecs/tree/main) that runs the Consul server as an ECS task. The `dev-server` does not support persistent storage.
1. **ACL Controller:** If you are running a secure Consul installation with ACLs enabled, configure the ACL controller.
1. **Sidecar containers:** Consul on ECS requires two sidecar containers to run in each ECS task: a
Consul agent container and a sidecar proxy container. These additional sidecar containers must
be included in the ECS task definition. The Consul ECS Terraform modules will include these
sidecar containers for you. Or if you do not use Terraform, you can construct the task
definition yourself by following our documentation.
1. **Routing:** With your application running in tasks as part of the mesh, you must specify the
upstream services that your application calls. You will also need to change the URLs your
application uses to ensure the application is making requests through the service mesh.
1. **Bind Address:** Once all communication is flowing through the service mesh, you should change
the address your application is listening on to `127.0.0.1` so that it only receives requests
through the sidecar proxy.

View File

@ -612,7 +612,7 @@
"path": "ecs/requirements"
},
{
"title": "Installation",
"title": "Installation with Terraform",
"path": "ecs/install"
},
{
@ -630,6 +630,10 @@
{
"title": "Consul Enterprise",
"path": "ecs/enterprise"
},
{
"title": "Manual Installation",
"path": "ecs/install-no-terraform"
}
]
},