-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RE-344 Add files for multi node cluster
- Loading branch information
Showing
5 changed files
with
426 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Multi Node HA Cluster Example | ||
|
||
This directory shows an example Terraform configuration that uses all of the [modules](../../modules) to deploy NS1 in a more complex, multi-node pattern with 3 HA Data containers. This topology provides the foundation of a scalable, hub and spoke topology as well as high availability of the data nodes. The HA Data nodes are expected to be on 3 separate hosts, labeled `data01`, `data02` and `data03`. The "hub" is refered to in this configuration as the `control01` node and the "spoke" is refered to as the `edge01` node. | ||
|
||
In this example, the Docker images have already been loaded on the `control` node's Docker daemon, while the `edge` node will be download the images from a Docker registry. *Note* that in this example Docker Hub is used as the registry, but this cannot be used in production as the images are not publically available on Docker Hub. | ||
|
||
This example will also create dedicated `ns1` Docker networks on all of the `data` Docker hosts as well as the `control` and `edge` Docker hosts. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,262 @@ | ||
# --------------------------------------------------------------------------------------------------------------------- | ||
# DEPLOY NS1 eDDI CLUSTER ON MULTIPLE DOCKER HOSTS | ||
# This configuration deploys NS1 containers on two hosts. The Data cluster is deployed on 3 separate hosts. | ||
# The Core and XFR containers are deployed together on the "control" host, while the DHCP, DNS and Dist containers | ||
# are deployed on the "edge" host. In a "hub and spoke" pattern, "control" can be thought of as the hub, while "edge" | ||
# would be a sigle spoke. | ||
# --------------------------------------------------------------------------------------------------------------------- | ||
|
||
# ---------------------------------------------------------------------------------------------------------------------- | ||
# REQUIRE A SPECIFIC TERRAFORM VERSION OR HIGHER | ||
# This module has been updated with 0.12 syntax, which means it is no longer compatible with any versions below 0.12. | ||
# ---------------------------------------------------------------------------------------------------------------------- | ||
terraform { | ||
required_version = ">= 0.12" | ||
} | ||
|
||
# ---------------------------------------------------------------------------------------------------------------------- | ||
# DEPLOY DEDICATED NETWORKS ON DOCKER HOSTS | ||
# A dedicated Docker network should be deployed on both hosts for the NS1 containers to join. | ||
# ----------------------------------------------------------------------------------------------------------------------- | ||
|
||
provider "docker" { | ||
alias = "data01" | ||
host = "${var.docker_protocol}${var.data01_host}" | ||
} | ||
|
||
provider "docker" { | ||
alias = "data02" | ||
host = "${var.docker_protocol}${var.data02_host}" | ||
} | ||
|
||
provider "docker" { | ||
alias = "data03" | ||
host = "${var.docker_protocol}${var.data03_host}" | ||
} | ||
|
||
provider "docker" { | ||
alias = "control01" | ||
host = "${var.docker_protocol}${var.control01_host}" | ||
} | ||
|
||
provider "docker" { | ||
alias = "edge01" | ||
host = "${var.docker_protocol}${var.edge01_host}" | ||
} | ||
|
||
resource "docker_network" "data01" { | ||
provider = "docker.data01" | ||
name = "ns1" | ||
driver = "bridge" | ||
ipam_driver = "default" | ||
attachable = true | ||
|
||
ipam_config { | ||
subnet = "172.18.12.0/24" | ||
} | ||
} | ||
|
||
resource "docker_network" "data02" { | ||
provider = "docker.data02" | ||
name = "ns1" | ||
driver = "bridge" | ||
ipam_driver = "default" | ||
attachable = true | ||
|
||
ipam_config { | ||
subnet = "172.18.12.0/24" | ||
} | ||
} | ||
|
||
resource "docker_network" "data03" { | ||
provider = "docker.data03" | ||
name = "ns1" | ||
driver = "bridge" | ||
ipam_driver = "default" | ||
attachable = true | ||
|
||
ipam_config { | ||
subnet = "172.18.12.0/24" | ||
} | ||
} | ||
|
||
resource "docker_network" "control01" { | ||
provider = "docker.control01" | ||
name = "ns1" | ||
driver = "bridge" | ||
ipam_driver = "default" | ||
attachable = true | ||
|
||
ipam_config { | ||
subnet = "172.18.12.0/24" | ||
} | ||
} | ||
|
||
resource "docker_network" "edge01" { | ||
provider = "docker.edge01" | ||
name = "ns1" | ||
driver = "bridge" | ||
ipam_driver = "default" | ||
attachable = true | ||
|
||
ipam_config { | ||
subnet = "172.18.12.0/24" | ||
} | ||
} | ||
|
||
# --------------------------------------------------------------------------------------------------------------------- | ||
# DEPLOY THE CONTAINERS ON THE DATA HOSTS | ||
# This configuration assumes the containers have already been loaded on the Docker host. | ||
# If they have not been loaded, it will attempt to download them from Docker Hub and fail. | ||
# --------------------------------------------------------------------------------------------------------------------- | ||
|
||
module "data01" { | ||
source = "../../modules/data" | ||
docker_host = "${var.docker_protocol}${var.data01_host}" | ||
docker_network = docker_network.data01.name | ||
docker_image_username = var.docker_image_username | ||
docker_image_repository = "${var.docker_image_repository}_data" | ||
docker_image_tag = var.docker_image_tag | ||
docker_registry_address = var.docker_registry_address | ||
docker_registry_username = var.docker_registry_username | ||
docker_registry_password = var.docker_registry_password | ||
pop_id = var.data01_pop_id | ||
server_id = var.data01_host | ||
primary = false | ||
cluster_id = 1 | ||
cluster_size = 3 | ||
data_peers = [var.data02_host, var.data03_host] | ||
telegraf_output_elasticsearch_data_host = var.elasticsearch_data_host | ||
telegraf_output_elasticsearch_index = var.elasticsearch_index | ||
} | ||
|
||
module "data02" { | ||
source = "../../modules/data" | ||
docker_host = "${var.docker_protocol}${var.data02_host}" | ||
docker_network = docker_network.data02.name | ||
docker_image_username = var.docker_image_username | ||
docker_image_repository = "${var.docker_image_repository}_data" | ||
docker_image_tag = var.docker_image_tag | ||
docker_registry_address = var.docker_registry_address | ||
docker_registry_username = var.docker_registry_username | ||
docker_registry_password = var.docker_registry_password | ||
pop_id = var.data02_pop_id | ||
server_id = var.data02_host | ||
primary = false | ||
cluster_id = 2 | ||
cluster_size = 3 | ||
data_peers = [var.data01_host, var.data03_host] | ||
telegraf_output_elasticsearch_data_host = var.elasticsearch_data_host | ||
telegraf_output_elasticsearch_index = var.elasticsearch_index | ||
} | ||
|
||
module "data03" { | ||
source = "../../modules/data" | ||
docker_host = "${var.docker_protocol}${var.data03_host}" | ||
docker_network = docker_network.data03.name | ||
docker_image_username = var.docker_image_username | ||
docker_image_repository = "${var.docker_image_repository}_data" | ||
docker_image_tag = var.docker_image_tag | ||
docker_registry_address = var.docker_registry_address | ||
docker_registry_username = var.docker_registry_username | ||
docker_registry_password = var.docker_registry_password | ||
pop_id = var.data03_pop_id | ||
server_id = var.data03_host | ||
primary = false | ||
cluster_id = 3 | ||
cluster_size = 3 | ||
data_peers = [var.data01_host, var.data02_host] | ||
telegraf_output_elasticsearch_data_host = var.elasticsearch_data_host | ||
telegraf_output_elasticsearch_index = var.elasticsearch_index | ||
} | ||
|
||
# --------------------------------------------------------------------------------------------------------------------- | ||
# DEPLOY THE CONTAINERS ON THE CONTROL HOST | ||
# This configuration assumes the containers have already been loaded on the Docker host. | ||
# If they have not been loaded, it will attempt to download them from Docker Hub and fail. | ||
# --------------------------------------------------------------------------------------------------------------------- | ||
|
||
module "core" { | ||
source = "../../modules/core" | ||
docker_host = "${var.docker_protocol}${var.control01_host}" | ||
docker_network = docker_network.control01.name | ||
docker_image_username = var.docker_image_username | ||
docker_image_repository = "${var.docker_image_repository}_core" | ||
docker_image_tag = var.docker_image_tag | ||
docker_registry_address = var.docker_registry_address | ||
docker_registry_username = var.docker_registry_username | ||
docker_registry_password = var.docker_registry_password | ||
bootstrappable = false | ||
pop_id = var.control01_pop_id | ||
server_id = var.control01_host | ||
data_hosts = [var.data01_host,var.data02_host,var.data03_host] | ||
api_fqdn = var.api_fqdn | ||
portal_fqdn = var.portal_fqdn | ||
nameservers = var.nameservers | ||
hostmaster_email = var.hostmaster_email | ||
} | ||
|
||
module "xfr" { | ||
source = "../../modules/xfr" | ||
docker_host = "${var.docker_protocol}${var.control01_host}" | ||
docker_network = docker_network.control01.name | ||
docker_image_username = var.docker_image_username | ||
docker_image_repository = "${var.docker_image_repository}_xfr" | ||
docker_image_tag = var.docker_image_tag | ||
docker_registry_address = var.docker_registry_address | ||
docker_registry_username = var.docker_registry_username | ||
docker_registry_password = var.docker_registry_password | ||
pop_id = var.control01_pop_id | ||
server_id = var.control01_host | ||
} | ||
|
||
# --------------------------------------------------------------------------------------------------------------------- | ||
# DEPLOY THE CONTAINERS ON THE EDGE HOST | ||
# The configuration of these modules provides an example of using the moddules with a Docker registry. | ||
# The NS1 Docker containers should already be loaded into the registry at run time and the registry must be reachable | ||
# from the Docker host. | ||
# --------------------------------------------------------------------------------------------------------------------- | ||
module "dns" { | ||
source = "../../modules/dns" | ||
docker_host = "${var.docker_protocol}${var.edge01_host}" | ||
docker_network = docker_network.edge01.name | ||
docker_image_username = var.docker_image_username | ||
docker_image_repository = "${var.docker_image_repository}_dns" | ||
docker_image_tag = var.docker_image_tag | ||
docker_registry_address = var.docker_registry_address | ||
docker_registry_username = var.docker_registry_username | ||
docker_registry_password = var.docker_registry_password | ||
pop_id = var.edge01_pop_id | ||
server_id = var.edge01_host | ||
} | ||
|
||
module "dhcp" { | ||
source = "../../modules/dhcp" | ||
docker_host = "${var.docker_protocol}${var.edge01_host}" | ||
docker_network = docker_network.edge01.name | ||
docker_image_username = var.docker_image_username | ||
docker_image_repository = "${var.docker_image_repository}_dhcp" | ||
docker_image_tag = var.docker_image_tag | ||
docker_registry_address = var.docker_registry_address | ||
docker_registry_username = var.docker_registry_username | ||
docker_registry_password = var.docker_registry_password | ||
pop_id = var.edge01_pop_id | ||
server_id = var.edge01_host | ||
} | ||
|
||
module "dist" { | ||
source = "../../modules/dist" | ||
docker_host = "${var.docker_protocol}${var.edge01_host}" | ||
docker_network = docker_network.edge01.name | ||
docker_image_username = var.docker_image_username | ||
docker_image_repository = "${var.docker_image_repository}_dist" | ||
docker_image_tag = var.docker_image_tag | ||
docker_registry_address = var.docker_registry_address | ||
docker_registry_username = var.docker_registry_username | ||
docker_registry_password = var.docker_registry_password | ||
# This transforms the user defined URL defined for the control host into | ||
# a FQDN or IP, which is expected by the `core_hosts` argument | ||
core_hosts = [element(split("@", var.control01_host), 1)] | ||
pop_id = var.edge01_pop_id | ||
server_id = var.edge01_host | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
variable "docker_registry_username" { | ||
description = "Username for authentication to Docker registry." | ||
} | ||
|
||
variable "docker_registry_password" { | ||
description = "Password for authentication to Docker registry." | ||
} | ||
|
||
variable "docker_registry_address" { | ||
description = "The absolute URL of the Docker registry (i.e. 'https://registry.hub.docker.com') to pull the container images from." | ||
} | ||
|
||
variable "docker_image_tag" { | ||
default = "2.1.1" | ||
description = "The image tag of the Docker image. Defaults to the latest GA version number." | ||
} | ||
|
||
variable "docker_image_username" { | ||
default = "ns1inc" | ||
description = "The username used in the Docker image name. This should not need to be changed." | ||
} | ||
|
||
variable "docker_image_repository" { | ||
default = "privatedns_data" | ||
description = "The repository name used in the Docker image name. This should not need to be changed." | ||
} | ||
|
||
variable "docker_protocol" { | ||
default = "ssh://" | ||
description = "The protocol to use when connecting to the docker host" | ||
} | ||
|
||
variable "data01_host" { | ||
description = "The address of the Docker host to deploy the first Data container on (i.e. 'ssh://user@remote-host'). Both ssh:// and tcp:// are supported. See https://www.terraform.io/docs/providers/docker/index.html for more details" | ||
} | ||
|
||
variable "data02_host" { | ||
description = "The address of the Docker host to deploy the second Data container on (i.e. 'ssh://user@remote-host'). Both ssh:// and tcp:// are supported. See https://www.terraform.io/docs/providers/docker/index.html for more details" | ||
} | ||
|
||
variable "data03_host" { | ||
description = "The address of the Docker host to deploy the third Data container on (i.e. 'ssh://user@remote-host'). Both ssh:// and tcp:// are supported. See https://www.terraform.io/docs/providers/docker/index.html for more details" | ||
} | ||
|
||
variable "control01_host" { | ||
description = "The address of the Docker host to deploy the Data, Core and XFR containers on (i.e. 'ssh://user@remote-host'). Both ssh:// and tcp:// are supported. See https://www.terraform.io/docs/providers/docker/index.html for more details" | ||
} | ||
|
||
variable "edge01_host" { | ||
description = "The address of the Docker host to deploy the DHCP, DNS and Dist containers on (i.e. 'ssh://user@remote-host'). Both ssh:// and tcp:// are supported. See https://www.terraform.io/docs/providers/docker/index.html for more details" | ||
} | ||
|
||
variable "data01_pop_id" { | ||
description = "The pop id for data01" | ||
default = "dc1" | ||
} | ||
|
||
variable "data02_pop_id" { | ||
description = "The pop id for data02" | ||
default = "dc1" | ||
} | ||
|
||
variable "data03_pop_id" { | ||
description = "The pop id for data03" | ||
default = "dc1" | ||
} | ||
|
||
variable "control01_pop_id" { | ||
description = "The pop id for control01" | ||
default = "dc1" | ||
} | ||
|
||
variable "edge01_pop_id" { | ||
description = "The pop id for edge01" | ||
default = "dc2" | ||
} | ||
|
||
variable "elasticsearch_data_host" { | ||
default = null | ||
description = "The elasticsearch host to export metrics" | ||
} | ||
|
||
variable "elasticsearch_index" { | ||
default = null | ||
description = "The elasticsearch index to use when exporting metrics" | ||
} | ||
|
||
variable "api_fqdn" { | ||
default = "api.mycompany.net" | ||
description = "FQDN to use for the api and feed URLs" | ||
} | ||
|
||
variable "portal_fqdn" { | ||
default = "portal.mycompany.net" | ||
description = "FQDN to use for the portal URL" | ||
} | ||
|
||
variable "nameservers" { | ||
default = "ns1.mycompany.net" | ||
description = "Nameservers used in SOA records" | ||
} | ||
|
||
variable "hostmaster_email" { | ||
default = "hostmaster@mycompany.net" | ||
description = "Hostmaster email address used in SOA records" | ||
} |
Oops, something went wrong.