Add support for DNS routing policies
This commit is contained in:
parent
c4d599f321
commit
8bacd8f5d5
|
@ -53,25 +53,59 @@ module "private-dns" {
|
||||||
}
|
}
|
||||||
# tftest modules=1 resources=1
|
# tftest modules=1 resources=1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Routing Policies
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
module "private-dns" {
|
||||||
|
source = "./fabric/modules/dns"
|
||||||
|
project_id = "myproject"
|
||||||
|
type = "private"
|
||||||
|
name = "test-example"
|
||||||
|
domain = "test.example."
|
||||||
|
client_networks = [var.vpc.self_link]
|
||||||
|
recordsets = {
|
||||||
|
"A regular" = { records = ["10.20.0.1"] }
|
||||||
|
"A geo" = {
|
||||||
|
geo_routing = [
|
||||||
|
{ location = "europe-west1", records = ["10.0.0.1"] },
|
||||||
|
{ location = "europe-west2", records = ["10.0.0.2"] },
|
||||||
|
{ location = "europe-west3", records = ["10.0.0.3"] }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
"A wrr" = {
|
||||||
|
ttl = 600
|
||||||
|
wrr_routing = [
|
||||||
|
{ weight = 0.6, records = ["10.10.0.1"] },
|
||||||
|
{ weight = 0.2, records = ["10.10.0.2"] },
|
||||||
|
{ weight = 0.2, records = ["10.10.0.3"] }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# tftest modules=1 resources=4
|
||||||
|
```
|
||||||
|
|
||||||
<!-- BEGIN TFDOC -->
|
<!-- BEGIN TFDOC -->
|
||||||
|
|
||||||
## Variables
|
## Variables
|
||||||
|
|
||||||
| name | description | type | required | default |
|
| name | description | type | required | default |
|
||||||
|---|---|:---:|:---:|:---:|
|
|---|---|:---:|:---:|:---:|
|
||||||
| [domain](variables.tf#L51) | Zone domain, must end with a period. | <code>string</code> | ✓ | |
|
| [domain](variables.tf#L53) | Zone domain, must end with a period. | <code>string</code> | ✓ | |
|
||||||
| [name](variables.tf#L69) | Zone name, must be unique within the project. | <code>string</code> | ✓ | |
|
| [name](variables.tf#L71) | Zone name, must be unique within the project. | <code>string</code> | ✓ | |
|
||||||
| [project_id](variables.tf#L80) | Project id for the zone. | <code>string</code> | ✓ | |
|
| [project_id](variables.tf#L82) | Project id for the zone. | <code>string</code> | ✓ | |
|
||||||
| [client_networks](variables.tf#L21) | List of VPC self links that can see this zone. | <code>list(string)</code> | | <code>[]</code> |
|
| [client_networks](variables.tf#L21) | List of VPC self links that can see this zone. | <code>list(string)</code> | | <code>[]</code> |
|
||||||
| [description](variables.tf#L28) | Domain description. | <code>string</code> | | <code>"Terraform managed."</code> |
|
| [description](variables.tf#L28) | Domain description. | <code>string</code> | | <code>"Terraform managed."</code> |
|
||||||
| [dnssec_config](variables.tf#L34) | DNSSEC configuration for this zone. | <code title="object({ non_existence = optional(string, "nsec3") state = string key_signing_key = optional(object( { algorithm = string, key_length = number }), { algorithm = "rsasha256", key_length = 2048 } ) zone_signing_key = optional(object( { algorithm = string, key_length = number }), { algorithm = "rsasha256", key_length = 1024 } ) })">object({…})</code> | | <code>null</code> |
|
| [dnssec_config](variables.tf#L34) | DNSSEC configuration for this zone. | <code title="object({ non_existence = optional(string, "nsec3") state = string key_signing_key = optional(object( { algorithm = string, key_length = number }), { algorithm = "rsasha256", key_length = 2048 } ) zone_signing_key = optional(object( { algorithm = string, key_length = number }), { algorithm = "rsasha256", key_length = 1024 } ) })">object({…})</code> | | <code title="{ state = "off" }">{…}</code> |
|
||||||
| [enable_logging](variables.tf#L62) | Enable query logging for this zone. Only valid for public zones. | <code>bool</code> | | <code>false</code> |
|
| [enable_logging](variables.tf#L64) | Enable query logging for this zone. Only valid for public zones. | <code>bool</code> | | <code>false</code> |
|
||||||
| [forwarders](variables.tf#L56) | Map of {IPV4_ADDRESS => FORWARDING_PATH} for 'forwarding' zone types. Path can be 'default', 'private', or null for provider default. | <code>map(string)</code> | | <code>{}</code> |
|
| [forwarders](variables.tf#L58) | Map of {IPV4_ADDRESS => FORWARDING_PATH} for 'forwarding' zone types. Path can be 'default', 'private', or null for provider default. | <code>map(string)</code> | | <code>{}</code> |
|
||||||
| [peer_network](variables.tf#L74) | Peering network self link, only valid for 'peering' zone types. | <code>string</code> | | <code>null</code> |
|
| [peer_network](variables.tf#L76) | Peering network self link, only valid for 'peering' zone types. | <code>string</code> | | <code>null</code> |
|
||||||
| [recordsets](variables.tf#L85) | Map of DNS recordsets in \"type name\" => {ttl, [records]} format. | <code title="map(object({ ttl = optional(number, 300) records = list(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
| [recordsets](variables.tf#L87) | Map of DNS recordsets in \"type name\" => {ttl, [records]} format. | <code title="map(object({ ttl = optional(number, 300) records = optional(list(string)) geo_routing = optional(list(object({ location = string records = list(string) }))) wrr_routing = optional(list(object({ weight = number records = list(string) }))) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||||
| [service_directory_namespace](variables.tf#L102) | Service directory namespace id (URL), only valid for 'service-directory' zone types. | <code>string</code> | | <code>null</code> |
|
| [service_directory_namespace](variables.tf#L122) | Service directory namespace id (URL), only valid for 'service-directory' zone types. | <code>string</code> | | <code>null</code> |
|
||||||
| [type](variables.tf#L108) | Type of zone to create, valid values are 'public', 'private', 'forwarding', 'peering', 'service-directory'. | <code>string</code> | | <code>"private"</code> |
|
| [type](variables.tf#L128) | Type of zone to create, valid values are 'public', 'private', 'forwarding', 'peering', 'service-directory'. | <code>string</code> | | <code>"private"</code> |
|
||||||
| [zone_create](variables.tf#L118) | Create zone. When set to false, uses a data source to reference existing zone. | <code>bool</code> | | <code>true</code> |
|
| [zone_create](variables.tf#L138) | Create zone. When set to false, uses a data source to reference existing zone. | <code>bool</code> | | <code>true</code> |
|
||||||
|
|
||||||
## Outputs
|
## Outputs
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,25 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
locals {
|
locals {
|
||||||
recordsets = {
|
_recordsets = {
|
||||||
for key, attrs in var.recordsets :
|
for key, attrs in var.recordsets :
|
||||||
key => merge(attrs, zipmap(["type", "name"], split(" ", key)))
|
key => merge(attrs, zipmap(["type", "name"], split(" ", key)))
|
||||||
}
|
}
|
||||||
|
geo_recordsets = {
|
||||||
|
for k, v in local._recordsets :
|
||||||
|
k => v
|
||||||
|
if v.geo_routing != null
|
||||||
|
}
|
||||||
|
recordsets = {
|
||||||
|
for k, v in local._recordsets :
|
||||||
|
k => v
|
||||||
|
if v.records != null
|
||||||
|
}
|
||||||
|
wrr_recordsets = {
|
||||||
|
for k, v in local._recordsets :
|
||||||
|
k => v
|
||||||
|
if v.wrr_routing != null
|
||||||
|
}
|
||||||
zone = (
|
zone = (
|
||||||
var.zone_create
|
var.zone_create
|
||||||
? try(
|
? try(
|
||||||
|
@ -166,6 +181,87 @@ resource "google_dns_record_set" "cloud-static-records" {
|
||||||
type = each.value.type
|
type = each.value.type
|
||||||
ttl = each.value.ttl
|
ttl = each.value.ttl
|
||||||
rrdatas = each.value.records
|
rrdatas = each.value.records
|
||||||
|
|
||||||
|
depends_on = [
|
||||||
|
google_dns_managed_zone.non-public, google_dns_managed_zone.public
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_dns_record_set" "cloud-geo-records" {
|
||||||
|
for_each = (
|
||||||
|
var.type == "public" || var.type == "private"
|
||||||
|
? local.geo_recordsets
|
||||||
|
: {}
|
||||||
|
)
|
||||||
|
project = var.project_id
|
||||||
|
managed_zone = var.name
|
||||||
|
name = (
|
||||||
|
each.value.name == ""
|
||||||
|
? var.domain
|
||||||
|
: (
|
||||||
|
substr(each.value.name, -1, 1) == "."
|
||||||
|
? each.value.name
|
||||||
|
: "${each.value.name}.${var.domain}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
type = each.value.type
|
||||||
|
ttl = each.value.ttl
|
||||||
|
|
||||||
|
dynamic "routing_policy" {
|
||||||
|
for_each = each.value.geo_routing != null ? [1] : [0]
|
||||||
|
iterator = unused
|
||||||
|
content {
|
||||||
|
dynamic "geo" {
|
||||||
|
for_each = each.value.geo_routing
|
||||||
|
iterator = policy
|
||||||
|
content {
|
||||||
|
location = policy.value.location
|
||||||
|
rrdatas = policy.value.records
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
depends_on = [
|
||||||
|
google_dns_managed_zone.non-public, google_dns_managed_zone.public
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_dns_record_set" "cloud-wrr-records" {
|
||||||
|
for_each = (
|
||||||
|
var.type == "public" || var.type == "private"
|
||||||
|
? local.wrr_recordsets
|
||||||
|
: {}
|
||||||
|
)
|
||||||
|
project = var.project_id
|
||||||
|
managed_zone = var.name
|
||||||
|
name = (
|
||||||
|
each.value.name == ""
|
||||||
|
? var.domain
|
||||||
|
: (
|
||||||
|
substr(each.value.name, -1, 1) == "."
|
||||||
|
? each.value.name
|
||||||
|
: "${each.value.name}.${var.domain}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
type = each.value.type
|
||||||
|
ttl = each.value.ttl
|
||||||
|
|
||||||
|
dynamic "routing_policy" {
|
||||||
|
for_each = each.value.wrr_routing != null ? [1] : [0]
|
||||||
|
iterator = unused
|
||||||
|
content {
|
||||||
|
dynamic "wrr" {
|
||||||
|
for_each = each.value.wrr_routing
|
||||||
|
iterator = policy
|
||||||
|
content {
|
||||||
|
weight = policy.value.weight
|
||||||
|
rrdatas = policy.value.records
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
depends_on = [
|
depends_on = [
|
||||||
google_dns_managed_zone.non-public, google_dns_managed_zone.public
|
google_dns_managed_zone.non-public, google_dns_managed_zone.public
|
||||||
]
|
]
|
||||||
|
|
|
@ -45,7 +45,9 @@ variable "dnssec_config" {
|
||||||
{ algorithm = "rsasha256", key_length = 1024 }
|
{ algorithm = "rsasha256", key_length = 1024 }
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
default = null
|
default = {
|
||||||
|
state = "off"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "domain" {
|
variable "domain" {
|
||||||
|
@ -86,17 +88,35 @@ variable "recordsets" {
|
||||||
description = "Map of DNS recordsets in \"type name\" => {ttl, [records]} format."
|
description = "Map of DNS recordsets in \"type name\" => {ttl, [records]} format."
|
||||||
type = map(object({
|
type = map(object({
|
||||||
ttl = optional(number, 300)
|
ttl = optional(number, 300)
|
||||||
records = list(string)
|
records = optional(list(string))
|
||||||
|
geo_routing = optional(list(object({
|
||||||
|
location = string
|
||||||
|
records = list(string)
|
||||||
|
})))
|
||||||
|
wrr_routing = optional(list(object({
|
||||||
|
weight = number
|
||||||
|
records = list(string)
|
||||||
|
})))
|
||||||
}))
|
}))
|
||||||
default = {}
|
default = {}
|
||||||
nullable = false
|
nullable = false
|
||||||
validation {
|
validation {
|
||||||
condition = alltrue([
|
condition = alltrue([
|
||||||
for k, v in var.recordsets == null ? {} : var.recordsets :
|
for k, v in coalesce(var.recordsets, {}) :
|
||||||
length(split(" ", k)) == 2
|
length(split(" ", k)) == 2
|
||||||
])
|
])
|
||||||
error_message = "Recordsets must have keys in the format \"type name\"."
|
error_message = "Recordsets must have keys in the format \"type name\"."
|
||||||
}
|
}
|
||||||
|
validation {
|
||||||
|
condition = alltrue([
|
||||||
|
for k, v in coalesce(var.recordsets, {}) : (
|
||||||
|
(v.records != null && v.wrr_routing == null && v.geo_routing == null) ||
|
||||||
|
(v.records == null && v.wrr_routing != null && v.geo_routing == null) ||
|
||||||
|
(v.records == null && v.wrr_routing == null && v.geo_routing != null)
|
||||||
|
)
|
||||||
|
])
|
||||||
|
error_message = "Only one of records, wrr_routing or geo_routing can be defined for each recordset."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "service_directory_namespace" {
|
variable "service_directory_namespace" {
|
||||||
|
|
Loading…
Reference in New Issue