Secure Configuration

For a production-ready installation of Consul on ECS, you will need to make sure that the cluster is secured. A secure Consul cluster should include the following:

  1. TLS Encryption for RPC communication between Consul clients and servers.
  2. Gossip Encryption for encrypting gossip traffic.
  3. Access Control (ACLs) for authentication and authorization for Consul clients and services on the mesh.

NOTE: In this topic, we assume that you have already configured your Consul server with the security-related features.

Prerequisites

  • You should already have followed the installation instructions to understand how to define the necessary components of the task definition for Consul on ECS.
  • You should be familiar with specifying sensitive data on ECS.
  • You should be familiar with configuring Consul’s secure features, including how to create ACL tokens and policies. Refer to the following Learn Guides for an introduction and the ACL system documentation for more information.

ACL Tokens

You must create two types of ACL tokens for Consul on ECS:

  • Client tokens: used by the consul-client containers to join the Consul cluster
  • Service tokens: used by sidecar containers for service registration and health syncing

The following sections describe the ACL polices which must be associated with these token types.

NOTE: This section describes how operators would create ACL tokens by hand. To ease operator burden, the ACL Controller can automatically create ACL tokens for Consul on ECS. Refer to the ACL Controller page for installation details.

Create Consul client token

You must create a token for the Consul client. This is a shared token used by the consul-client containers to join the Consul cluster.

The following is the ACL policy needed for the Consul client token:

  1. node_prefix "" {
  2. policy = "write"
  3. }
  4. service_prefix "" {
  5. policy = "read"
  6. }

This policy allows node:write for any node name, which is necessary because the Consul node names on ECS are not known until runtime.

Create service tokens

Service tokens should be associated with a service identity. The service identity includes service:write permissions for the service and sidecar proxy.

The following example shows how to use the Consul CLI to create a service token for a service named example-client-app:

  1. consul acl token create -service-identity=example-client-app ...

NOTE: You will need to create one service token for each registered Consul service in ECS, including when new services are added to the service mesh.

Secret storage

You should securely store the following secrets in order to make them available to ECS tasks.

  1. Consul Server CA certificate
  2. Consul gossip encryption key
  3. Consul client ACL token
  4. Consul service ACL tokens (one per service)

These secrets can be securely stored and passed to ECS tasks using either of the following AWS secret services:

Once the secrets are stored they can be referenced using their ARN. The following shows example secret ARNs when using AWS Secrets Manager:

SecretSample Secret ARN
Consul Server CA Certarn:aws:secretsmanager:us-west-2:000000000000:secret:my-consul-ca-cert
Gossip encryption keyarn:aws:secretsmanager:us-west-2:000000000000:secret:my-consul-gossip-key
Client tokenarn:aws:secretsmanager:us-west-2:000000000000:secret:my-consul-client-token
Service tokenarn:aws:secretsmanager:us-west-2:000000000000:secret:my-example-client-app-token

Configure consul-client

The following secrets must be passed to the consul-client container:

  • Consul server CA certificate
  • Gossip encryption key
  • Consul client ACL token

The following example shows how to include these secrets in the task definition. The secrets list specifies environment variable names that will be set to the secret values for this container. ECS automatically fetches the secret values specified in the valueFrom fields during task provisioning.

  1. {
  2. "containerDefinitions": [
  3. {
  4. "name": "consul-client"
  5. "image": "public.ecr.aws/hashicorp/consul:<CONSUL_VERSION>",
  6. "secrets": [
  7. {
  8. "name": "CONSUL_CACERT",
  9. "valueFrom": "arn:aws:secretsmanager:us-west-2:000000000000:secret:my-consul-ca-cert"
  10. },
  11. {
  12. "name": "CONSUL_GOSSIP_ENCRYPTION_KEY",
  13. "valueFrom": "arn:aws:secretsmanager:us-west-2:000000000000:secret:my-consul-gossip-key"
  14. },
  15. {
  16. "name": "AGENT_TOKEN",
  17. "valueFrom": "arn:aws:secretsmanager:us-west-2:000000000000:secret:my-consul-client-token"
  18. }
  19. ]
  20. },
  21. ...
  22. ]
  23. }

Next, update Consul configuration options to pass the secrets to the Consul client.

The following is an example of the additional content to include in the consul-client startup script. Refer to the install page for the remainder of the startup script and how to pass this script to the container.

  1. ...
  2. # Write the CA Cert to a file
  3. echo "$CONSUL_CACERT" > /tmp/consul-ca-cert.pem
  4. # Write the Consul agent configuration file.
  5. cat << EOF > /consul/agent-defaults.hcl
  6. ...
  7. # Configure gossip encryption key
  8. encrypt = "$CONSUL_GOSSIP_ENCRYPTION_KEY"
  9. # Configure TLS settings
  10. auto_encrypt = {
  11. tls = true
  12. ip_san = ["$ECS_IPV4"]
  13. }
  14. ca_file = "/tmp/consul-ca-cert.pem"
  15. verify_outgoing = true
  16. # Configure ACLs
  17. acl {
  18. enabled = true
  19. default_policy = "deny"
  20. down_policy = "async-cache"
  21. tokens {
  22. agent = "$AGENT_TOKEN"
  23. }
  24. }
  25. EOF

The following table describes the additional fields that must be included in the Consul client configuration file.

Field nameTypeDescription
encryptstringSpecifies the gossip encryption key
ca_filestringSpecifies the Consul server CA cert for TLS verification.
acl.enabledboolenEnable ACLs for this agent.
acl.tokens.agentstringSpecifies the Consul client token which authorizes this agent with Consul servers.

Configure consul-ecs-mesh-init and consul-ecs-health-sync

Both consul-ecs-mesh-init and consul-ecs-health-sync containers need to be configured with the service ACL token. This allows these containers to make HTTP API requests to the local Consul client for service registration and health syncing.

The following shows how to set the CONSUL_HTTP_TOKEN variable to the service token for the example-client-app service, if the token is stored in AWS Secrets Manager.

  1. {
  2. "containerDefinitions": [
  3. {
  4. "secrets": [
  5. {
  6. "name": "CONSUL_HTTP_TOKEN",
  7. "valueFrom": "arn:aws:secretsmanager:us-west-2:000000000000:secret:my-example-client-app-token"
  8. }
  9. ]
  10. },
  11. ...
  12. ],
  13. ...
  14. }