Skip to content

Commit d2fc084

Browse files
KNFSD DNS Round Robin module
This Terraform module configures Cloud DNS to use DNS Round Robin for a KNFSD proxy cluster. This offers an alternative to using the load balancer. Change-Id: Iffd3b8c52ab239e9a643749dfc661d1a0949cdf2
1 parent 9aea5a9 commit d2fc084

11 files changed

Lines changed: 381 additions & 30 deletions

File tree

deployment/README.md

Lines changed: 30 additions & 20 deletions
Large diffs are not rendered by default.

deployment/terraform-module-knfsd/loadbalancer.tf

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
resource "google_compute_address" "nfsproxy_static" {
2424
# This module will be made optional later, set the count to 1 so that the
2525
# correct refactoring can be created and tested.
26-
count = 1
26+
count = var.TRAFFIC_DISTRIBUTION_MODE == "loadbalancer" ? 1 : 0
2727

2828
project = var.PROJECT
2929
region = var.REGION
@@ -41,11 +41,10 @@ resource "google_compute_address" "nfsproxy_static" {
4141
}
4242
}
4343

44-
4544
module "loadbalancer" {
4645
# This module will be made optional later, set the count to 1 so that the
4746
# correct refactoring can be created and tested.
48-
count = 1
47+
count = var.TRAFFIC_DISTRIBUTION_MODE == "loadbalancer" ? 1 : 0
4948
source = "./modules/loadbalancer"
5049

5150
PROJECT = var.PROJECT
@@ -60,6 +59,31 @@ module "loadbalancer" {
6059
INSTANCE_GROUP = google_compute_instance_group_manager.proxy-group.instance_group
6160
}
6261

62+
resource "null_resource" "dns_round_robin" {
63+
count = var.TRAFFIC_DISTRIBUTION_MODE == "dns_round_robin" ? 1 : 0
64+
lifecycle {
65+
precondition {
66+
condition = var.ASSIGN_STATIC_IPS
67+
error_message = "ASSIGN_STATIC_IPS must be enabled when using DNS round robin."
68+
}
69+
70+
precondition {
71+
condition = !var.ENABLE_KNFSD_AUTOSCALING
72+
error_message = "ENABLE_KNFSD_AUTOSCALING cannot be enabled when using DNS round robin."
73+
}
74+
}
75+
}
76+
77+
module "dns_round_robin" {
78+
count = var.TRAFFIC_DISTRIBUTION_MODE == "dns_round_robin" ? 1 : 0
79+
source = "./modules/dns_round_robin"
80+
project = var.PROJECT
81+
instance_group = google_compute_instance_group_manager.proxy-group.instance_group
82+
proxy_basename = var.PROXY_BASENAME
83+
dns_name = var.DNS_NAME
84+
knfsd_nodes = var.KNFSD_NODES
85+
}
86+
6387
moved {
6488
from = google_compute_address.nfsproxy_static
6589
to = google_compute_address.nfsproxy_static[0]
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# KNFSD DNS Round Robin Module
2+
3+
This Terraform module configures Cloud DNS to use DNS Round Robin for a KNFSD proxy cluster. This offers an alternative to using the load balancer.
4+
5+
This module is not generally intended to be used directly, and is included by the main KNFSD proxy module when `TRAFFIC_DISTRIBUTION_MODE = "dns_round_robin"`.
6+
7+
## Prerequisites
8+
9+
To use DNS Round Robin the KNFSD proxy cluster must be configured with:
10+
11+
* `ENABLE_KNFSD_AUTOSCALING = false`
12+
* `ASSIGN_STATIC_IPS = true`
13+
14+
## Inputs
15+
16+
* `project` - (optional) The ID of the project in which the resource belongs. If it is not provided, the provider project is used.
17+
18+
* `networks` - (optional) Set of networks to attach Cloud DNS to. These should be formatted like `projects/{project}/global/networks/{network}` or `https://www.googleapis.com/compute/v1/projects/{project}/global/networks/{network}`. This defaults to the same network as the KNFSD proxy cluster.
19+
20+
* `instance_group` - The full URL (self link) of the KNFSD proxy instance group.
21+
22+
* `proxy_basename` - The proxy basename of the KNFSD proxy cluster.
23+
24+
* `dns_name` - (optional) The fully qualified domain name (FQDN) to assign the KNFSD proxy cluster. This defaults to `{proxy_basename}.knfsd.internal.`.
25+
26+
* `knfsd_nodes` - The number of instances (size) of the KNFSD instance group.
27+
28+
## Outputs
29+
30+
* `dns_name` - The DNS name that was created for the KNFSD proxy cluster.
31+
32+
**NOTE:** `dns_name` is useful if you're creating other resources in the same Terraform configuration that depend on the DNS entry to create a dependency between the DNS entry and the other resources.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright 2020 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
terraform {
18+
required_version = ">=1.2.0"
19+
}
20+
21+
data "google_compute_instance_group" "proxy" {
22+
project = var.project
23+
self_link = var.instance_group
24+
25+
lifecycle {
26+
postcondition {
27+
condition = self.instances != null
28+
error_message = "No compute instances found for instance group \"${var.instance_group}\"."
29+
}
30+
31+
postcondition {
32+
condition = length(self.instances) == var.knfsd_nodes
33+
error_message = "Incorrect number of compute instances found, expected ${var.knfsd_nodes} but was ${length(self.instances)}."
34+
}
35+
}
36+
}
37+
38+
data "google_compute_instance" "proxy" {
39+
count = var.knfsd_nodes
40+
self_link = local.instances[count.index]
41+
}
42+
43+
locals {
44+
instances = tolist(data.google_compute_instance_group.proxy.instances)
45+
46+
ip_addresses = toset([
47+
for vm in data.google_compute_instance.proxy :
48+
vm.network_interface[0].network_ip
49+
])
50+
}
51+
52+
resource "google_dns_managed_zone" "proxy" {
53+
project = var.project
54+
name = var.proxy_basename
55+
dns_name = coalesce(var.dns_name, "${var.proxy_basename}.knfsd.internal.")
56+
description = "Internal DNS for KNFSD proxies"
57+
visibility = "private"
58+
59+
private_visibility_config {
60+
dynamic "networks" {
61+
for_each = coalesce(var.networks, [data.google_compute_instance_group.proxy.network])
62+
content {
63+
network_url = networks.value
64+
}
65+
}
66+
}
67+
}
68+
69+
resource "google_dns_record_set" "proxy" {
70+
project = var.project
71+
managed_zone = google_dns_managed_zone.proxy.name
72+
73+
name = google_dns_managed_zone.proxy.dns_name
74+
type = "A"
75+
ttl = 300
76+
77+
routing_policy {
78+
dynamic "wrr" {
79+
for_each = local.ip_addresses
80+
iterator = ip
81+
82+
content {
83+
weight = 1
84+
rrdatas = [ip.value]
85+
}
86+
}
87+
}
88+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright 2020 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
output "dns_name" {
18+
# Even though this effectively just echoes back var.dns_name this is still
19+
# useful as it allows other resources to depend upon the A record having been
20+
# created.
21+
value = google_dns_record_set.proxy.name
22+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2020 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
variable "project" {
18+
type = string
19+
default = ""
20+
}
21+
22+
variable "networks" {
23+
type = set(string)
24+
default = null
25+
}
26+
27+
variable "instance_group" {
28+
type = string
29+
}
30+
31+
variable "proxy_basename" {
32+
type = string
33+
}
34+
35+
variable "dns_name" {
36+
type = string
37+
}
38+
39+
variable "knfsd_nodes" {
40+
type = number
41+
}

deployment/terraform-module-knfsd/modules/loadbalancer/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
This module supports deploying an Internal TCP Load Balancer TCP (and optionally UDP) for the KNFSD proxy cluster.
44

5-
This module is not generally intended to be used directly, and is included by the main KNFSD proxy module when `LOADBALANCING_MODE = "loadbalancer"`.
5+
This module is not generally intended to be used directly, and is included by the main KNFSD proxy module when `TRAFFIC_DISTRIBUTION_MODE = "loadbalancer"`.
66

77
## Prerequisites
88

deployment/terraform-module-knfsd/outputs.tf

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,32 @@
1414
* limitations under the License.
1515
*/
1616

17-
// The IP Address of the Internal Load Balancer
1817
output "nfsproxy_loadbalancer_ipaddress" {
19-
description = "The internal ip address for the nfsProxy load balancer:"
18+
description = "The internal IP address of the load balancer."
2019
value = one(google_compute_address.nfsproxy_static.*.address)
2120
}
2221

23-
# The Internal DNS name of the Internal Load Balancer
2422
output "nfsproxy_loadbalancer_dnsaddress" {
25-
description = "The internal dns entry address for the nfsProxy load balancer:"
23+
description = "The internal DNS name of the load balancer."
2624
value = one(module.loadbalancer.*.dns_name)
2725
}
2826

27+
output "dns_name" {
28+
description = "The internal DNS name of the KNFSD proxy instance group."
29+
value = (
30+
var.TRAFFIC_DISTRIBUTION_MODE == "loadbalancer" ? one(module.loadbalancer.*.dns_name) :
31+
var.TRAFFIC_DISTRIBUTION_MODE == "dns_round_robin" ? one(module.dns_round_robin.*.dns_name) :
32+
null
33+
)
34+
}
35+
2936
output "instance_group" {
30-
description = "Full URL of the KNFSD proxy instance group."
37+
description = "Full URL (self link) of the KNFSD proxy instance group."
3138
value = google_compute_instance_group_manager.proxy-group.instance_group
3239
}
3340

3441
output "instance_group_manager" {
35-
description = "Full URL of the KNFSD proxy instance group manager."
42+
description = "Full URL (self link) of the KNFSD proxy instance group manager."
3643
value = google_compute_instance_group_manager.proxy-group.self_link
3744
}
3845

deployment/terraform-module-knfsd/variables.tf

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,29 @@ variable "AUTO_CREATE_FIREWALL_RULES" {
100100
type = bool
101101
}
102102

103+
variable "TRAFFIC_DISTRIBUTION_MODE" {
104+
type = string
105+
validation {
106+
condition = contains(["dns_round_robin", "loadbalancer", "none"], var.TRAFFIC_DISTRIBUTION_MODE)
107+
error_message = "Valid values for TRAFFIC_DISTRIBUTION_MODE are 'dns_round_robin', 'loadbalancer', and 'none'."
108+
}
109+
}
110+
103111
variable "LOADBALANCER_IP" {
104112
default = null
105113
type = string
106114
}
107115

116+
variable "DNS_NAME" {
117+
default = ""
118+
type = string
119+
120+
validation {
121+
condition = var.DNS_NAME == "" || endswith(var.DNS_NAME, ".")
122+
error_message = "DNS_NAME must end with tailing dot, for example \"knfsd.example.\" (note the tailing dot)."
123+
}
124+
}
125+
108126
variable "SERVICE_LABEL" {
109127
default = "dns"
110128
type = string

0 commit comments

Comments
 (0)