--- layout: docs page_title: Connecting Services Across Datacenters description: |- Connect services and secure inter-service communication across datacenters using Consul Connect and mesh gateways. --- ## Introduction Consul Connect is Consul’s service mesh offering, which allows users to observe and secure service-to-service communication. Because Connect implements mutual TLS between services, it also enabled us to build mesh gateways, which provide users with a way to help services in different datacenters communicate with each other. Mesh gateways take advantage of Server Name Indication (SNI), which is an extension to TLS that allows them to see the destination of inter-datacenter traffic without decrypting the message payload. Using mesh gateways for inter-datacenter communication can prevent each Connect proxy from needing an accessible IP address, and frees operators from worrying about IP address overlap between datacenters. In this guide, you will configure Consul Connect across multiple Consul datacenters and use mesh gateways to enable inter-service traffic between them. Specifically, you will: 1. Enable Connect in both datacenters 1. Deploy the two mesh gateways 1. Register services and Connect sidecar proxies 1. Configure intentions 1. Test that your services can communicate with each other For the remainder of this guide we will refer to mesh gateways as "gateways". Anywhere in this guide where you see the word gateway, assume it is specifically a mesh gateway (as opposed to an API or other type of gateway). ## Prerequisites To complete this guide you will need two wide area network (WAN) joined Consul datacenters with access control list (ACL) replication enabled. If you are starting from scratch, follow these guides to set up your datacenters, or use them to check that you have the proper configuration: - [Deployment Guide](/consul/datacenter-deploy/deployment-guide) - [Securing Consul with ACLs](/consul/security-networking/production-acls) - [Basic Federation with WAN Gossip](/consul/security-networking/datacenters) You will also need to enable ACL replication, which you can do by following the [ACL Replication for Multiple Datacenters](/consul/day-2-operations/acl-replication) guide with the following modification. When creating the [replication token for ACL management](/consul/day-2-operations/acl-replication#create-the-replication-token-for-acl-management), it will need the following policy: ```json { "acl": "write", "operator": "write", "service_prefix": { "": { "policy": "read" } } } ``` The replication token needs different permissions depending on what you want to accomplish. The above policy allows for ACL policy, role, and token replication with `acl:write`, CA replication with `operator:write` and intention and configuration entry replication with `service:*:read`. You will also need to install [Envoy](https://www.envoyproxy.io/) alongside your Consul clients. Both the gateway and sidecar proxies will need to get configuration and updates from a local Consul client. Lastly you should set [`enable_central_service_config = true`](/docs/agent/options#enable_central_service_config) on your Consul clients, which will allow them to centrally configrure the sidecar and mesh gateway proxies. ## Enable Connect in Both Datacenters Once you have your datacenters set up and ACL replication configured, it’s time to enable Connect in each of them sequentially. Connect’s certificate authority (which is distinct from the Consul certificate authority that you manage using the CLI) will automatically bootstrap as soon as a server with Connect enabled becomes the server cluster’s leader. You can also use [Vault as a Connect CA](/docs/connect/ca/vault). !> **Warning:** If you are using this guide as a production playbook, we strongly recommend that you enable Connect in each of your datacenters by following the [Connect in Production guide](/consul/developer-segmentation/connect-production), which includes production security recommendations. ### Enable Connect in the primary datacenter Enable Connect in the primary data center and bootstrap the Connect CA by adding the following snippet to the server configuration for each of your servers. ```json connect { "enabled": true } ``` Load the new configuration by restarting each server one at a time, making sure to maintain quorum. This will be a similar process to performing a [rolling restart during upgrades](/docs/upgrading#standard-upgrades). Stop the first server by running the following [leave command](/docs/commands/leave). ```shell-session $ consul leave ``` Once the server shuts down restart it and make sure that it is healthy and rejoins the other servers. Repeat this process until you've restarted all the servers with Connect enabled. ### Enable Connect in the secondary datacenter Once Connect is enabled in the primary datacenter, follow the same process to enable Connect in the secondary datacenter. Add the following configuration to the configuration for your servers, and restart them one at a time, making sure to maintain quorum. ```json connect { "enabled": true } ``` The `primary_datacenter` setting that was required in order to enable ACL replication between datacenters also specifies which datacenter will write intentions and act as the [root CA for Connect](/docs/connect/connect-internals#connections-across-datacenters). Intentions, which allow or deny inter-service communication, are automatically replicated to the secondary datacenter. ## Deploy Gateways Connect mesh gateways proxy requests from services in one datacenter to services in another, so you will need to deploy your gateways on nodes that can reach each other over the network. As we mentioned in the prerequisites, you will need to make sure that both Envoy and Consul are installed on the gateway nodes. You won’t want to run any services on these nodes other than Consul and Envoy because they necessarily will have access to the WAN. ### Generate Tokens for the Gateways You’ll need to [generate a token](/consul/security-networking/production-acls#apply-individual-tokens-to-the-services) for each gateway that gives it read access to the entire catalog. Create a file named `mesh-gateway-policy.json` containing the following content. ```json { "node_prefix": { "": { "policy": "read" } } } { "service_prefix": { "": { "policy": "read" } } } { "service": { "mesh-gateway": { "policy": "write" } } } ``` Next, create and name a new ACL policy using the file you just made. ```shell-session $ consul acl policy create \ -name mesh-gateway \ -rules @mesh-gateway-policy.json ``` Generate a token for each gateway from the new policy. ```shell-session $ consul acl token create -description "mesh-gateway primary datacenter token" \ -policy-name mesh-gateway ``` ```shell-session $ consul acl token create \ -description "mesh-gateway secondary datacenter token" \ -policy-name mesh-gateway ``` You’ll apply those tokens when you deploy the gateways. ### Deploy the Gateway for your primary datacenter Register and start the gateway in your primary datacenter with the following command. ```shell-session $ consul connect envoy -mesh-gateway -register \ -service-name "gateway-primary" -address "<your private address>" \ -wan-address "<your externally accessible address>"\ -token=<token for the primary dc gateway> ``` ### Deploy the Gateway for your Secondary Datacenter Register and start the gateway in your secondary datacenter with the following command. ```shell-session $ consul connect envoy -mesh-gateway -register \ -service-name "gateway-secondary" -address "<your private address>" \ -wan-address "<your externally accessible address>"\ -token=<token for the secondary dc gateway> ``` ### Configure Sidecar Proxies to use Gateways Next, create a [centralized configuration](/docs/agent/config_entries/proxy-defaults) file for all the sidecar proxies in both datacenters called `proxy-defaults.json`. This file will instruct the sidecar proxies to send all their inter-datacenter traffic through the gateways. It should contain the following: ```json { "Kind": "proxy-defaults", "Name": "global", "MeshGateway": "local" } ``` Write the centralized configuration you just created with the following command. ```shell-session $ consul config write proxy-defaults.json ``` Once this step is complete, you will have set up Consul Connect with gateways across multiple datacenters. Now you are ready to register the services that will use Connect. ## Register a Service in Each Datacenter to Use Connect You can register a service to use a sidecar proxy by including a sidecar proxy stanza in its registration file. For this guide, you can use socat to act as a backend service and register a dummy service called web to represent the client service. Those names are used in our examples. If you have services that you would like to connect, feel free to use those instead. ~> **Caution:** Connect takes its default intention policy from Consul’s default ACL policy. If you have set your default ACL policy to deny (as is recommended for secure operation) and are adding Connect to already registered services, those services may lose connection to each other until you set an intention between them to allow communication. ### Register a back end service in one datacenter In one datacenter register a backend service and add an Envoy sidecar proxy registration. To do this you will either create a new registration file or edit an existing one to include a sidecar proxy stanza. If you are using socat as your backend service, you will create a new file called `socat.json` that will contain the below snippet. Since you have ACLs enabled, you will have to [create a token for the service](/consul/security-networking/production-acls#apply-individual-tokens-to-the-services). ```json { "service": { "name": "socat", "port": 8181, "token": "<token here>", "connect": { "sidecar_service": {} } } } ``` Note the Connect stanza of the registration with the `sidecar_service` and `token` options. This is what you would add to an existing service registration if you are not using socat as an example. Reload the client with the new or modified registration. ```shell-session $ consul reload ``` Then start Envoy specifying which service it will proxy. ```shell-session $ consul connect envoy -sidecar-for socat ``` If you are using socat as your example, start it now on the port you specified in your registration by running the following command. ```shell-session $ socat -v tcp-l:8181,fork exec:"/bin/cat" ``` Check that the socat service is running by accessing it using netcat on the same node. It will echo back anything you type. ```shell-session $ nc 127.0.0.1 8181 hello hello echo echo ``` Stop the running netcat service by typing `ctrl + c`. ### Register a front end service in the other datacenter Now in your other datacenter, you will register a service (with a sidecar proxy) that calls your backend service. Your registration will need to list the backend service as your upstream. Like the backend service, you can use an example service, which will be called web, or append the connect stanza to an existing registration with some customization. To use web as your front end service, create a registration file called `web.json` that contains the following snippet. ```json { "service": { "name": "web", "port": 8080, "token": "<token here>", "connect": { "sidecar_service": { "proxy": { "upstreams": [ { "destination_name": "socat", "datacenter": "primary", "local_bind_port": 8181 } ] } } } } } ``` Note the Connect part of the registration, which specifies socat as an upstream. If you are using another service as a back end, replace `socat` with its name and the `8181` with its port. Reload the client with the new or modified registration. ```shell-session $ consul reload ``` Then start Envoy and specify which service it will proxy. ```shell-session $ consul connect envoy -sidecar-for web ``` ## Configure Intentions to Allow Communication Between Services Now that your services both use Connect, you will need to configure intentions in order for them to communicate with each other. Add an intention to allow the front end service to access the back end service. For web and socat the command would look like this. ```shell-session $ consul intention create web socat ``` Consul will automatically forward intentions initiated in the in the secondary datacenter to the primary datacenter, where the servers will write them. The servers in the primary datacenter will then automatically replicate the written intentions back to the secondary datacenter. ## Test the connection Now that you have services using Connect, verify that they can contact each other. If you have been using the example web and socat services, from the node and datacenter where you registered the web service, start netcat and type something for it to echo. ```shell-session $ nc 127.0.0.1 8181 hello hello echo echo ``` ## Summary In this guide you configured two WAN-joined datacenters to use Consul Connect, deployed gateways in each datacenter, and connected two services to each other across datacenters. Gateways know where to route traffic because of Server Name Indication (SNI) where the client service sends the destination as part of the TLS handshake. Because gateways rely on TLS to discover the traffic’s destination, they require Consul Connect to route traffic. ### Next Steps Now that you’ve seen how to deploy gateways to proxy inter-datacenter traffic, you can deploy multiple gateways for redundancy or availability. The gateways and proxies will automatically round-robin load balance traffic between the gateways. If you are using Kubernetes you can configure Connect and deploy gateways for your Kubernetes cluster using the Helm chart. Learn more in the [Consul’s Kubernetes documentation](/docs/platform/k8s/helm) Visit the Consul documentation for a full list of configurations for [Consul Connect](/docs/connect), including [mesh gateway configuration options](/docs/connect/mesh-gateway).