Set up Consul multi-datacenter replication with ACL token replication

Advanced 45 min Apr 24, 2026 136 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Configure Consul WAN federation across multiple datacenters with secure ACL token replication. Enable automatic token synchronization, gossip encryption, and cross-datacenter service discovery for distributed infrastructure.

Prerequisites

  • At least 6 servers (3 per datacenter)
  • Network connectivity between datacenters on ports 8300-8302
  • Root or sudo access on all servers
  • Basic understanding of Consul architecture

What this solves

Consul multi-datacenter replication allows you to federate multiple Consul clusters across different geographic locations or network segments. This setup enables global service discovery, configuration sharing, and ACL token synchronization between datacenters while maintaining network segmentation and local performance.

Step-by-step configuration

Install Consul on all nodes

Install Consul on servers in both datacenters using the HashiCorp repository.

curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update
sudo apt install -y consul
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo dnf install -y consul

Generate encryption keys

Create a gossip encryption key and bootstrap ACL token that will be shared across all datacenters.

consul keygen
consul keygen
Note: Save both keys securely. The first will be used for gossip encryption, the second for initial ACL bootstrap. All servers in both datacenters need these same keys.

Configure primary datacenter (dc1)

Set up the primary datacenter configuration with ACL system enabled.

datacenter = "dc1"
data_dir = "/opt/consul"
log_level = "INFO"
server = true
bootstrap_expect = 3
bind_addr = "203.0.113.10"
client_addr = "0.0.0.0"
retry_join = ["203.0.113.11", "203.0.113.12"]
ui_config {
  enabled = true
}
connect {
  enabled = true
}
encrypt = "your-gossip-encryption-key-here"
acl = {
  enabled = true
  default_policy = "deny"
  enable_token_persistence = true
  enable_token_replication = true
}
ports {
  grpc = 8502
}

Configure secondary datacenter (dc2)

Set up the secondary datacenter to replicate from the primary datacenter.

datacenter = "dc2"
data_dir = "/opt/consul"
log_level = "INFO"
server = true
bootstrap_expect = 3
bind_addr = "198.51.100.10"
client_addr = "0.0.0.0"
retry_join = ["198.51.100.11", "198.51.100.12"]
retry_join_wan = ["203.0.113.10", "203.0.113.11", "203.0.113.12"]
ui_config {
  enabled = true
}
connect {
  enabled = true
}
encrypt = "your-gossip-encryption-key-here"
acl = {
  enabled = true
  default_policy = "deny"
  enable_token_persistence = true
  enable_token_replication = true
  tokens {
    replication = "your-replication-token-here"
  }
}
ports {
  grpc = 8502
}
primary_datacenter = "dc1"

Create systemd service

Configure Consul to run as a system service with proper user permissions.

sudo useradd --system --home /etc/consul.d --shell /bin/false consul
sudo mkdir -p /opt/consul
sudo chown -R consul:consul /opt/consul /etc/consul.d
sudo chmod 640 /etc/consul.d/consul.hcl
[Unit]
Description=Consul
Documentation=https://www.consul.io/
Requires=network-online.target
After=network-online.target
ConditionFileNotEmpty=/etc/consul.d/consul.hcl

[Service]
Type=notify
User=consul
Group=consul
ExecStart=/usr/bin/consul agent -config-dir=/etc/consul.d/
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

Start Consul clusters

Enable and start Consul on all servers in the primary datacenter first.

sudo systemctl daemon-reload
sudo systemctl enable consul
sudo systemctl start consul
sudo systemctl status consul
Note: Start all three servers in dc1 before proceeding to dc2. Wait for the cluster to elect a leader before continuing.

Bootstrap ACL system in primary datacenter

Initialize the ACL system and create the bootstrap token on the leader server in dc1.

consul acl bootstrap
Note: Save the SecretID from the bootstrap output. This is your initial management token.

Create replication token

Create a dedicated token for ACL replication with the necessary permissions.

export CONSUL_HTTP_TOKEN="your-bootstrap-token-here"
consul acl policy create \
  -name "replication-policy" \
  -description "ACL replication policy" \
  -rules @- << 'EOF'
acl = "write"
operator = "write"
service_prefix "" {
  policy = "read"
  intentions = "read"
}
EOF
consul acl token create \
  -description "ACL replication token" \
  -policy-name "replication-policy"

Update secondary datacenter configuration

Add the replication token to the secondary datacenter configuration.

datacenter = "dc2"
data_dir = "/opt/consul"
log_level = "INFO"
server = true
bootstrap_expect = 3
bind_addr = "198.51.100.10"
client_addr = "0.0.0.0"
retry_join = ["198.51.100.11", "198.51.100.12"]
retry_join_wan = ["203.0.113.10", "203.0.113.11", "203.0.113.12"]
ui_config {
  enabled = true
}
connect {
  enabled = true
}
encrypt = "your-gossip-encryption-key-here"
acl = {
  enabled = true
  default_policy = "deny"
  enable_token_persistence = true
  enable_token_replication = true
  tokens {
    replication = "your-actual-replication-token-secretid"
  }
}
ports {
  grpc = 8502
}
primary_datacenter = "dc1"

Start secondary datacenter

Start all servers in the secondary datacenter to join the WAN federation.

sudo systemctl reload consul
sudo systemctl start consul
sudo systemctl status consul

Configure firewall rules

Open the necessary ports for Consul federation between datacenters.

sudo ufw allow 8300/tcp comment "Consul server RPC"
sudo ufw allow 8301/tcp comment "Consul LAN gossip"
sudo ufw allow 8301/udp comment "Consul LAN gossip"
sudo ufw allow 8302/tcp comment "Consul WAN gossip"
sudo ufw allow 8302/udp comment "Consul WAN gossip"
sudo ufw allow 8500/tcp comment "Consul HTTP API"
sudo ufw allow 8502/tcp comment "Consul gRPC API"
sudo ufw reload
sudo firewall-cmd --permanent --add-port=8300/tcp --add-port=8301/tcp --add-port=8301/udp
sudo firewall-cmd --permanent --add-port=8302/tcp --add-port=8302/udp
sudo firewall-cmd --permanent --add-port=8500/tcp --add-port=8502/tcp
sudo firewall-cmd --reload

Create service tokens for applications

Create tokens for services that need to register across datacenters.

consul acl policy create \
  -name "service-policy" \
  -description "Policy for service registration" \
  -rules @- << 'EOF'
service_prefix "" {
  policy = "write"
}
node_prefix "" {
  policy = "read"
}
EOF

consul acl token create \
  -description "Service registration token" \
  -policy-name "service-policy"

Verify multi-datacenter setup

export CONSUL_HTTP_TOKEN="your-bootstrap-token-here"
consul members -wan
consul catalog datacenters
consul acl token list

Test cross-datacenter service discovery:

consul catalog services -datacenter=dc1
consul catalog services -datacenter=dc2
consul catalog nodes -datacenter=dc1
consul catalog nodes -datacenter=dc2

Configure ACL token replication monitoring

Monitor the replication status and configure alerts for replication failures.

consul acl replication-status
curl -H "X-Consul-Token: your-token" http://localhost:8500/v1/acl/replication

Check replication lag and last success time:

consul operator raft list-peers
consul info | grep replication

Common issues

SymptomCauseFix
Replication not workingWrong replication tokenVerify token has acl:write and operator:write permissions
WAN federation failsFirewall blocking port 8302Open UDP/TCP 8302 between datacenters
Services not visible across DCsACL policy too restrictiveGrant service:read permissions to query token
Bootstrap token not workingACL system not properly initializedRun consul acl bootstrap on cluster leader
Secondary DC won't joinGossip key mismatchEnsure same encrypt key on all nodes
Replication lag increasingNetwork issues or high loadCheck network connectivity and server resources

Monitor and troubleshoot federation

Set up monitoring for federation health and ACL replication status. You can integrate this with Consul monitoring using Prometheus and Grafana for comprehensive observability.

consul monitor -log-level=DEBUG | grep -i replication
consul debug -duration=30s -output=/tmp/consul-debug

Monitor federation metrics:

curl http://localhost:8500/v1/status/leader
curl http://localhost:8500/v1/catalog/datacenters
curl -H "X-Consul-Token: your-token" http://localhost:8500/v1/acl/replication

Backup and disaster recovery

Implement automated backup strategies for your federated Consul clusters. Consider setting up Consul backup and disaster recovery procedures to protect your federation configuration.

consul snapshot save backup-$(date +%Y%m%d-%H%M%S).snap
consul snapshot inspect backup-*.snap

Next steps

Running this in production?

Want this handled for you? Running this at scale adds a second layer of work: capacity planning, failover drills, cost control, and on-call. See how we run infrastructure like this for European teams.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle managed devops services for businesses that depend on uptime. From initial setup to ongoing operations.