The following instructions describe how to manually create the ECS task definition using the consul-ecs Docker image without Terraform. Refer to the Consul ECS Terraform module documentation for an alternative method for installing Consul on ECS.
This topic does not include instructions for creating all AWS resources necessary to install Consul, such as a VPC or the ECS cluster. Refer to the linked guides in the Getting Started section for complete, runnable examples.
Your task definition must include the following top-level fields.
The volumes list contains two bind mounts,
named consul_data and consul_binary. Bind mounts are directories on the host which can be mounted into one or more containers
in order to share files among containers. For Consul on ECS, certain binaries and configuration are shared among containers
during task startup.
The tags list must include the following if you are using the ACL controller in a secure configuration.
Without these tags, the ACL controller will be unable to provision a service token for the task.
Tag Key
Tag Value
Description
consul.hashicorp.com/mesh
true (string)
The ACL controller ignores tasks without this tag set to true.
consul.hashicorp.com/service-name
Consul service name
Specifies the Consul service associated with this task. Required if the service name is different than the task family.
consul.hashicorp.com/partition
Consul admin partition
Enterprise
Specifies the Consul admin partition associated with this task. Defaults to the default admin partition if omitted.
consul.hashicorp.com/namespace
Consul namespace
Enterprise
Specifies the Consul namespace associated with this task. Defaults to the default namespace if omitted.
First, include your application container in the containerDefinitions list
in the task definition.
Ensure that the containerName and condition fields in the dependsOn list
are specified as described in the following example. These are container dependencies,
which must be used to enforce a specific startup order.
By using the following settings, your application container will start after consul-ecs-mesh-init
has completed task setup and after sidecar-proxy is ready to proxy traffic between
this task and the service mesh.
The sidecar-proxy container runs Envoy proxy for Consul Connect. In most cases, the container should contain the following parameters and values.
The mountPoints list must be set as shown in the following example. This will mount the shared consul_data volume into the
sidecar-proxy container at the path /consul. This volume is where the consul-ecs-mesh-init container copies the envoy-bootstrap.json
file and the consul-ecs binary, which are required to start Envoy. The dependsOn list must also be defined as follows to ensure the
sidecar-proxy container starts after consul-ecs-mesh-init has successfully written these files to the shared volume.
The following script is used to start the Consul client for Consul on ECS.
# Copy the consul binary to a shared volume for `consul-ecs-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]')# Write the Consul agent configuration file.cat<<EOF> /consul/agent-defaults.hcladdresses = { 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 = trueleave_on_terminate = trueports { 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
# Copy the consul binary to a shared volume for `consul-ecs-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]')# Write the Consul agent configuration file.cat<<EOF> /consul/agent-defaults.hcladdresses = { 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 = trueleave_on_terminate = trueports { 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
The following table describes the values that you should use to configure the command script:
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
Must be set to the task IP address so that other Consul agents know how to reach this agent.
client_addr
string
Must be set to an interface reachable by other Consul agents.
datacenter
string
Must be set to the Consul datacenter this task will join.
leave_on_terminate
boolean
Must be set to true so that the Consul agent leaves the cluster gracefully before exiting.
retry_join
string
Must be set to your Consul server location(s) so this agent can join the Consul cluster.
NOTE: 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.
The consul-ecs-mesh-init container runs at task startup to setup this instance for Consul service mesh.
It registers the service and proxy for this task with Consul and writes Envoy bootstrap
configuration to a shared volume.
Configuration is passed to the consul-ecs binary in JSON format using the CONSUL_ECS_CONFIG_JSON environment variable.
The following is an example of the configuration that might be used for a service named example-client-app with one upstream
service name example-server-app. The proxy and service blocks include information used by consul-ecs-mesh-init to perform
service registration with Consul during task startup. The same configuration format is used for
the 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.
For example, the following defines an ECS health check command that runs curl localhost:9090/health:
First, define which containers need their health status synced into Consul. To do this,
add the container name(s) to the healthSyncContainers list of the CONSUL_ECS_CONFIG_JSON variable,
as shown in the following example. This configuration must be passed to both the consul-ecs-mesh-init
and consul-ecs-health-sync containers.
Next, set the CONSUL_ECS_CONFIG_JSON variable for the consul-ecs-mesh-init container.
The following example shows how the CONSUL_ECS_CONFIG_JSON variable should be formatted.
The JSON configuration is compacted down to a single line and escaped.
Finally, include the consul-ecs-health-sync container in the containerDefinitions list.
Pass the same value for CONSUL_ECS_CONFIG_JSON for both the consul-ecs-health-sync
and consul-ecs-mesh-init containers.