HashiCorp’s Network Infrastructure Automation Integration Program allows your network administrators to build integrations that automatically apply network and security infrastructure changes reacting to changes in the Consul service catalog.
Network Infrastructure Automation is carried out by Consul-Terraform-Sync, a multi-platform tool, that is able to connect to Consul catalog and monitor changes in the services' state and health. The tool leverages Terraform as the underlying automation tool, and utilizes the Terraform provider ecosystem to drive relevant change to your network infrastructure.
Consul-Terraform-Sync can be configured to execute one or more automation tasks that use variables based on the content of the Consul service catalog. Each task consists of a runbook automation written as a compatible Terraform module using resources and data sources for the underlying network infrastructure.
In this tutorial you will learn how to install Consul-Terraform-Sync on a node and to configure it to communicate with your Consul datacenter, to react to service changes, and execute an example task.
»Prerequisites
A Consul datacenter with two registered services,
web
andapi
. You can follow the Deployment Guide for guidance on installing Consul.The Consul-Terraform-Sync binary
Terraform 0.13.0+ binary (will be automatically installed if not present)
For this tutorial, you will be using the Consul Print Module to configure Consul-Terraform-Sync. This Terraform module creates text files on your local machine containing Consul service information. It is a useful module to use to familiarize yourself with Consul Terraform Sync, without requiring deployed infrastructure and credentials.
NOTE: An interactive hands-on lab is also available if you do not have a Consul environment to perform the steps described in this tutorial. Click the Show Tutorial button to launch the lab experience.
»Automatic Terraform installation
As mentioned in the prerequisites section, Consul-Terraform-Sync requires
Terraform 0.13+
to operate. You can either install Terraform before starting
the Consul-Terraform-Sync or let the Consul-Terraform-Sync daemon install a
compatible Terraform version for you.
You can discover Terraform installation information In the Consul-Terraform-Sync daemon output. If Terraform is not present, the output will indicate the installation location and if it was successfully installed.
[INFO] (driver.terraform) installing terraform to path '/root'
[DEBUG] (driver.terraform) successfully installed terraform 0.14.6: /root/terraform
[INFO] (driver.terraform) successfully installed terraform
In case Terraform is already present on the system or was installed from a previous run, Consul-Terraform-Sync will be able to detect it and skip the installation.
[INFO] (driver.terraform) skipping install, terraform 0.14.6 already exists at path /root/terraform
Note: The example above and the other output examples in the tutorial use
/root
as the working directory and do no specify an installation path for
Terraform binary. This means Consul-Terraform-Sync will look for, and install,
Terraform in the working directory. In your environment you can specify any
directory the user running Consul-Terraform-Sync has permissions for.
»Install Consul-Terraform-Sync
You can install Consul-Terraform-Sync manually either by using a pre-compiled binary or by building it yourself from source.
To install Consul-Terraform-Sync, find the appropriate package
for your system and download it as a zip archive. Unzip the package to extract
the binary named consul-terraform-sync
.
Move the consul-terraform-sync
binary to a location available on your PATH
.
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
The output is a list of locations separated by colons. You can make
Consul-Terraform-Sync available by moving the binary to one of the listed
locations, or by adding Consul-Terraform-Sync's location to your PATH
.
$ mv ./consul-terraform-sync /usr/local/bin/consul-terraform-sync
Tip (Linux-based or Mac): Permanently add a new location to your path by
editing your shell's settings file (usually called something like ~/.bashrc
,
where the part of the file name after the .
and before rc
is the name of
your shell). In that file you will see a line that starts with export PATH=
,
followed by a colon-separated list of locations. Add the location of the Consul
binary to that list and save the file. Then reload your shell's configuration
with the command source ~/.bashrc
, replacing bash
with the name of your
shell.
Tip (Windows): Add a location to your path via the GUI by navigating to
Environment Variables
in your system settings, and looking for the variable
called PATH
. You will see a semicolon-separated list of locations. Add the
Consul binary's location to that list and then launch a new console window.
Once installed, verify the installation works by prompting the help option.
$ consul-terraform-sync -h
Usage of consul-terraform-sync:
-config-dir
A directory to load files for configuring Sync. Configuration files require an .hcl or .json file extention in order to specify their format. This option can be specified multiple times to load different directories.
-config-file
A file to load for configuring Sync. Configuration file requires an .hcl or .json extension in order to specify their format. This option can be specified multiple times to load different configuration files.
-inspect false
Run Sync in Inspect mode to print the proposed state changes for all tasks, and then exits. No changes are applied in this mode.
-inspect-task
Run Sync in Inspect mode to print the proposed state changes for the task, and then exits. No changes are applied in this mode.
-once false
Render templates and run tasks once. Does not run the process as a daemon and disables buffer periods.
-version false
Print the version of this daemon.
»Configure Consul-Terraform-Sync
The Consul-Terraform-Sync daemon is configured using configuration files and supports HashiCorp Configuration Language (HCL) and JSON file formats.
A configuration file for Consul-Terraform-Sync is composed by several blocks, this section will guide you through the different blocks and provide you with example values. For the full list of available options check the documentation.
»Global configs
Top level options are reserved for configuring the Consul-Terraform-Sync daemon.
log_level = "INFO"
port = 8558
syslog {}
buffer_period {
enabled = true
min = "5s"
max = "20s"
}
In this section you can configure the log level to use for Consul-Terraform-Sync logging as well as the port used by the demon to offer the API interface.
Other notable sections are:
buffer_period
: configures the default buffer period for all tasks to mitigate the affects of flapping services to downstream network devices.syslog
: specifies the syslog server for logging. This section can be useful when Consul-Terraform-Sync is configured as a daemon, for example in Linux using systemd.
»Consul block
The consul block is used to configure Consul-Terraform-Sync connection with a Consul agent to perform queries to the Consul catalog and Consul KV pertaining to task execution.
consul {
address = "localhost:8500"
}
You can use this block to configure connection parameters, such as the Consul address, and security parameters, like TLS certificates or ACL token, to secure the connection with Consul and make sure you provide the Consul-Terraform-Sync daemon with the right privileges to perform the required operations.
Note: In a fully secured environment, with mTLS and ACLs enabled, you
can use this section to include the certificates and token required by
Consul-Terraform-Sync to securely communicate with Consul. The same information
can also be provided using environment variables, such as CONSUL_HTTP_TOKEN
for the ACL token, to avoid having sensitive data in your configuration file.
Performance considerations: As shown in the architectural diagram above it is recommended to run Consul-Terraform-Sync on a dedicated node running a Consul agent. This permits to have dedicated resources for network automation and to fine tune security and privilege separation between the network administrators and the other Consul agents.
»Driver “terraform” block
The driver block configures the subprocess used by Consul-Terraform-Sync to propagate infrastructure change. The Terraform driver is a required configuration for Consul-Terraform-Sync to relay provider discovery and installation information to Terraform.
driver "terraform" {
# version = "0.14.0"
# path = ""
log = false
persist_log = false
working_dir = ""
backend "consul" {
gzip = true
}
}
Using this section you can define the version of Terraform you want to use, in case you want to define strict requirements for it, the path where to find/install the Terraform binary or if you want the logs for Terraform to be included in the Consul-Terraform-Sync logs or persisted on disk. Finally, you can also define the working directory for Terraform to operate in.
Terraform state: By default, Consul-Terraform-Sync uses Consul to store
Terraform state files.
If no options are specified the same Consul instance configured in the consul
block is used. In case you want to use a different backend for Terraform or to
specify a different Consul datacenter as backend, you can use the backend
section of the configuration to define it. All standard backends supported by
Terraform are supported by Consul-Terraform-Sync. Check Terraform backend documentation to learn about available options.
»Task block
A task is executed when any change of information for services the task is configured for is detected from the Consul catalog. Execution could include one or more changes to service values, like IP address, added or removed service instance, or tags.
task {
name = "learn-cts-example"
description = "Example task with two services"
source = "findkim/print/cts"
version = "0.1.0"
services = ["web", "api"]
}
You can check the full list of values that would cause a task to run in the Task Execution documentation.
Consul-Terraform-Sync will attempt to execute each task once upon startup to synchronize infrastructure with the current state of Consul. The daemon will stop and exit if any error occurs while preparing the automation environment or executing a task for the first time.
A task block configures which task to run as automation for the defined services. The list of services can include services explicitly defined by a service block or implicitly declared by the service name.
You can specify multiple task blocks in case you need to configure multiple tasks.
For example, in the code snippet above, you are defining a task block that will
monitor and react to changes on web
and api
services and run the module
defined in the source
parameter when any change is detected.
»Service block
A service
block is an optional block to explicitly define configuration of
services that Consul-Terraform-Sync monitors. A service
block is only necessary
for services that have non-default values (e.g. custom tags).
service {
name = "api"
tag = "cts"
# namespace = "my-team"
# datacenter = "dc1"
description = "Match only services with a specific tag"
}
Services that do not have a service block configured will assume default values.
To configure multiple services, you can specify multiple service
blocks.
For example, in the code snippet above, you are defining a service block
matching instances of the api
service that also have cts
as a tag.
»Start Consul-Terraform-Sync
Once the configuration file is created it is possible to start
Consul-Terraform-Sync using the consul-terraform-sync
binary. The binary
requires the configuration to be passed either using the -config-file
or
-config-dir
.
Consul-Terraform-Sync provides different running modes, including some that can be useful to safely test your configuration and the changes that are going to be applied.
The default mode is named daemon mode, in this mode Consul-Terraform-Sync passes through a once-mode phase, in which it will try to run all the tasks once, and then turns into a long running process. During the once-mode phase, the daemon will exit with a non-zero status if it encounters an error. After successfully passing through once-mode phase, errors will be logged and the process is not expected to exit.
$ consul-terraform-sync -config-file cts-config.hcl
[INFO] v0.1.0 (354ce7a)
[INFO] (driver.terraform) installing terraform to path '/root'
[INFO] (driver.terraform) successfully installed terraform
[INFO] (cli) setting up controller: readwrite
[INFO] (ctrl) initializing Consul client and testing connection
[INFO] (cli) initializing controller
[INFO] (ctrl) initializing driver
[INFO] (ctrl) initializing all tasks
[INFO] (client.terraformcli) Terraform output is muted
[INFO] (driver.terraform) retrieved 0 Terraform handlers for task 'learn-cts-example'
[INFO] (ctrl) driver initialized
[INFO] (ctrl) executing all tasks once through
[INFO] (ctrl) executing task learn-cts-example
[INFO] (ctrl) task completed learn-cts-example
[INFO] (ctrl) all tasks completed once
[INFO] (cli) running controller in daemon mode
[INFO] (api) starting server at '8558'
Note: when running in daemon mode Consul-Terraform-Sync will keep running in the foreground and prevent you from performing other operations in the same terminal. Also it will get terminated in case the terminal session is closed. Please consider configuring it as a service and to run it at system startup to be able to survive machine reboots.
»Review files created by Consul-Terraform-Sync daemon
After startup, Consul-Terraform-Sync will run Terraform inside the
working_directory
defined in the configuration. If no directory is defined, it
creates a folder, named sync-tasks
, in the directory from which the binary is
started.
Inside that folder, Terraform will create a workspace for each task defined in the configuration.
$ tree sync-tasks/
sync-tasks/
└── learn-cts-example
├── main.tf
├── terraform.tfvars
├── terraform.tfvars.tmpl
├── variables.tf
└── web.txt
main.tf
: contains the terraform block, provider blocks, and a module block calling the module configured for the task.variables.tf
: contains the services input variable which determines module compatibility with Consul-Terraform Sync and optionally the intermediate variables used to dynamically configure providers.terraform.tfvars
: is where the services input variable is assigned values from the Consul catalog. It is periodically updated to reflect the current state of the configured set of services for the task.terraform.tfvars.tmpl
: is used to template the information retrieved from Consul catalog into theterraform.tfvars
file.
For example, running Consul-Terraform-Sync against a Consul datacenter with a
web
service matching the task configuration will produce the following
terraform.tfvars
:
# This file is generated by Consul Terraform Sync.
#
# The HCL blocks, arguments, variables, and values are derived from the
# operator configuration for Sync. Any manual changes to this file
# may not be preserved and could be overwritten by a subsequent update.
services = {
"web.service-2.dc1" : {
id = "web"
name = "web"
address = "172.19.0.5"
port = 9002
meta = {}
tags = []
namespace = null
status = "passing"
node = "service-2"
node_id = "fe3d73af-e099-941c-acfb-93ef5596e01f"
node_address = "172.19.0.5"
node_datacenter = "dc1"
node_tagged_addresses = {
lan = "172.19.0.5"
lan_ipv4 = "172.19.0.5"
wan = "172.19.0.5"
wan_ipv4 = "172.19.0.5"
}
node_meta = {
consul-network-segment = ""
}
}
}
Note: Generated template and Terraform configuration files are crucial to the automation of tasks. Any manual changes to the files may not be preserved and could be overwritten by a subsequent update.
In this example the module used prints the addresses of the matched services
into one file for each service matched. In the above example you can see one of
those files called web.txt
that refers to the web
service.
In a real life scenario your module will react on service changes to trigger Terraform runs and deploy changes to your network infrastructure.
»Next Steps
In this tutorial you learned the basics of Network Infrastructure Automation with Consul-Terraform-Sync. You got an architectural overview of all the logical blocks involved in the process and what are the advantages of automating Day-2 operations for network administrative tasks. Finally, you tried first hand the Consul-Terraform-Sync binary with an example module that retrieved information from Consul service catalog and printed it on a text file in your working directory.
Specifically you:
- Installed Consul-Terraform-Sync
- Created a working configuration file for the binary
- Started Consul-Terraform-Sync
- Checked the files and data pulled from Consul-Terraform-Sync into the Terraform workspace
In the next tutorial you will learn the different run modes for Consul-Terraform-Sync and how to inspect task status using the REST API, and Terraform state when using Consul as backend for Terraform.
To learn more about Network Infrastructure Automation with Consul-Terraform-Sync check the full documentation for it on the Consul website.
If you need guidance on how to deploy your services to Consul service mesh, refer to our Connect services with Consul Service Mesh tutorial.
To learn even more about operating, observing, and monitoring your Consul service mesh, check out the following tutorials and collections.