Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DNS Response Policy module #1276

Merged
merged 3 commits into from Mar 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -30,7 +30,7 @@ The current list of modules supports most of the core foundational and networkin
Currently available modules:

- **foundational** - [billing budget](./modules/billing-budget), [Cloud Identity group](./modules/cloud-identity-group/), [folder](./modules/folder), [service accounts](./modules/iam-service-account), [logging bucket](./modules/logging-bucket), [organization](./modules/organization), [project](./modules/project), [projects-data-source](./modules/projects-data-source)
- **networking** - [DNS](./modules/dns), [Cloud Endpoints](./modules/endpoints), [address reservation](./modules/net-address), [NAT](./modules/net-cloudnat), [Global Load Balancer (classic)](./modules/net-glb/), [L4 ILB](./modules/net-ilb), [L7 ILB](./modules/net-ilb-l7), [VPC](./modules/net-vpc), [VPC firewall](./modules/net-vpc-firewall), [VPC firewall policy](./modules/net-vpc-firewall-policy), [VPC peering](./modules/net-vpc-peering), [VPN dynamic](./modules/net-vpn-dynamic), [HA VPN](./modules/net-vpn-ha), [VPN static](./modules/net-vpn-static), [Service Directory](./modules/service-directory)
- **networking** - [DNS](./modules/dns), [DNS Response Policy](./modules/dns-response-policy/), [Cloud Endpoints](./modules/endpoints), [address reservation](./modules/net-address), [NAT](./modules/net-cloudnat), [Global Load Balancer (classic)](./modules/net-glb/), [L4 ILB](./modules/net-ilb), [L7 ILB](./modules/net-ilb-l7), [VPC](./modules/net-vpc), [VPC firewall](./modules/net-vpc-firewall), [VPC firewall policy](./modules/net-vpc-firewall-policy), [VPC peering](./modules/net-vpc-peering), [VPN dynamic](./modules/net-vpn-dynamic), [HA VPN](./modules/net-vpn-ha), [VPN static](./modules/net-vpn-static), [Service Directory](./modules/service-directory)
ludoo marked this conversation as resolved.
Show resolved Hide resolved
- **compute** - [VM/VM group](./modules/compute-vm), [MIG](./modules/compute-mig), [COS container](./modules/cloud-config-container/cos-generic-metadata/) (coredns, mysql, onprem, squid), [GKE cluster](./modules/gke-cluster), [GKE hub](./modules/gke-hub), [GKE nodepool](./modules/gke-nodepool)
- **data** - [BigQuery dataset](./modules/bigquery-dataset), [Bigtable instance](./modules/bigtable-instance), [Cloud SQL instance](./modules/cloudsql-instance), [Data Catalog Policy Tag](./modules/data-catalog-policy-tag), [Datafusion](./modules/datafusion), [Dataproc](./modules/dataproc), [GCS](./modules/gcs), [Pub/Sub](./modules/pubsub)
- **development** - [API Gateway](./modules/api-gateway), [Apigee](./modules/apigee), [Artifact Registry](./modules/artifact-registry), [Container Registry](./modules/container-registry), [Cloud Source Repository](./modules/source-repository)
Expand Down
13 changes: 7 additions & 6 deletions modules/README.md
Expand Up @@ -41,21 +41,22 @@ These modules are used in the examples included in this repository. If you are u

## Networking modules

- [DNS](./dns)
- [Address reservation](./net-address)
- [Cloud Endpoints](./endpoints)
- [address reservation](./net-address)
- [NAT](./net-cloudnat)
- [DNS](./dns)
- [DNS Response Policy](./dns-response-policy/)
- [Global Load Balancer (classic)](./net-glb/)
- [L4 ILB](./net-ilb)
- [L7 ILB](./net-ilb-l7)
- [NAT](./net-cloudnat)
- [Service Directory](./service-directory)
- [VPC](./net-vpc)
- [VPC firewall](./net-vpc-firewall)
- [VPC firewall policy](./net-vpc-firewall-policy)
- [VPC peering](./net-vpc-peering)
- [VPN dynamic](./net-vpn-dynamic)
- [HA VPN](./net-vpn-ha)
- [VPC peering](./net-vpc-peering)
- [VPN HA](./net-vpn-ha)
- [VPN static](./net-vpn-static)
- [Service Directory](./service-directory)

## Compute/Container

Expand Down
92 changes: 92 additions & 0 deletions modules/dns-response-policy/README.md
@@ -0,0 +1,92 @@
# Google Cloud DNS Response Policy

This module allows management of a [Google Cloud DNS policy and its rules](https://cloud.google.com/dns/docs/zones/manage-response-policies). The policy can be already existing and passed in via its id.
ludoo marked this conversation as resolved.
Show resolved Hide resolved

## Examples

### Manage policy and override resolution for specific names

This example shows how to create a policy with a single rule, that directs a specific Google API name to the restricted VIP addresses.

```hcl
module "dns-policy" {
source = "./fabric/modules/dns-response-policy"
project_id = "myproject"
name = "googleapis"
networks = {
landing = var.vpc.self_link
}
rules = {
pubsub = {
dns_name = "pubsub.googleapis.com."
local_data = {
A = {
rrdatas = ["199.36.153.4", "199.36.153.5"]
}
}
}
}
}
# tftest modules=1 resources=2 inventory=simple.yaml
```

### Use existing policy and override resolution via wildcard with exceptions

This example shows how to create a policy with a single rule, that directs all Google API names except specific ones to the restricted VIP addresses.

```hcl
module "dns-policy" {
source = "./fabric/modules/dns-response-policy"
project_id = "myproject"
name = "googleapis"
policy_create = false
networks = {
landing = var.vpc.self_link
}
rules = {
default = {
dns_name = "*.googleapis.com."
local_data = {
CNAME = {
rrdatas = ["restricted.googleapis.com."]
}
}
}
pubsub = {
dns_name = "pubsub.googleapis.com."
}
restricted = {
dns_name = "restricted.googleapis.com."
local_data = {
A = {
rrdatas = ["199.36.153.4", "199.36.153.5"]
}
}
}
}
}
# tftest modules=1 resources=3 inventory=nocreate.yaml
```
<!-- BEGIN TFDOC -->

## Variables

| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [name](variables.tf#L30) | Zone name, must be unique within the project. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L49) | Project id for the zone. | <code>string</code> | ✓ | |
| [clusters](variables.tf#L17) | Map of GKE clusters to which this policy is applied in name => id format. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [description](variables.tf#L24) | Policy description. | <code>string</code> | | <code>&#34;Terraform managed.&#34;</code> |
| [networks](variables.tf#L35) | Map of VPC self links to which this policy is applied in name => self link format. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [policy_create](variables.tf#L42) | Set to false to use the existing policy matching name and only manage rules. | <code>bool</code> | | <code>true</code> |
| [rules](variables.tf#L54) | Map of policy rules in name => rule format. Local data takes precedence over behavior and is in the form record type => attributes. | <code title="map&#40;object&#40;&#123;&#10; dns_name &#61; string&#10; behavior &#61; optional&#40;string, &#34;bypassResponsePolicy&#34;&#41;&#10; local_data &#61; optional&#40;map&#40;object&#40;&#123;&#10; ttl &#61; optional&#40;number&#41;&#10; rrdatas &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |

## Outputs

| name | description | sensitive |
|---|---|:---:|
| [id](outputs.tf#L17) | Policy id. | |
| [name](outputs.tf#L22) | Policy name. | |
| [policy](outputs.tf#L27) | Policy resource. | |

<!-- END TFDOC -->
73 changes: 73 additions & 0 deletions modules/dns-response-policy/main.tf
@@ -0,0 +1,73 @@
/**
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

locals {
policy_name = (
var.policy_create
? google_dns_response_policy.default.0.response_policy_name
: var.name
)
}

resource "google_dns_response_policy" "default" {
provider = google-beta
count = var.policy_create ? 1 : 0
project = var.project_id
response_policy_name = var.name
dynamic "networks" {
for_each = var.networks
content {
network_url = networks.value
}
}
dynamic "gke_clusters" {
for_each = var.clusters
content {
gke_cluster_name = gke_clusters.value
}
}
}

resource "google_dns_response_policy_rule" "default" {
provider = google-beta
for_each = var.rules
project = var.project_id
response_policy = local.policy_name
rule_name = each.key
dns_name = each.value.dns_name
behavior = (
length(each.value.local_data) == 0 ? each.value.behavior : null
)
dynamic "local_data" {
for_each = length(each.value.local_data) == 0 ? [] : [""]
content {
dynamic "local_datas" {
for_each = each.value.local_data
iterator = data
content {
# setting name to something different seems to have no effect
# so we comply with the console UI and set it to the rule dns name
# name = split(" ", data.key)[1]
# type = split(" ", data.key)[0]
name = each.value.dns_name
type = data.key
ttl = data.value.ttl
rrdatas = data.value.rrdatas
}
}
}
}
}
30 changes: 30 additions & 0 deletions modules/dns-response-policy/outputs.tf
@@ -0,0 +1,30 @@
/**
* Copyright 2022 Google LLC
ludoo marked this conversation as resolved.
Show resolved Hide resolved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

output "id" {
description = "Policy id."
value = try(google_dns_response_policy.default.0.id, null)
}

output "name" {
description = "Policy name."
value = local.policy_name
}

output "policy" {
description = "Policy resource."
value = try(google_dns_response_policy.default.0, null)
}
66 changes: 66 additions & 0 deletions modules/dns-response-policy/variables.tf
@@ -0,0 +1,66 @@
/**
* Copyright 2022 Google LLC
ludoo marked this conversation as resolved.
Show resolved Hide resolved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

variable "clusters" {
description = "Map of GKE clusters to which this policy is applied in name => id format."
type = map(string)
default = {}
nullable = false
}

variable "description" {
description = "Policy description."
type = string
default = "Terraform managed."
}

variable "name" {
description = "Zone name, must be unique within the project."
ludoo marked this conversation as resolved.
Show resolved Hide resolved
type = string
}

variable "networks" {
description = "Map of VPC self links to which this policy is applied in name => self link format."
type = map(string)
default = {}
nullable = false
}

variable "policy_create" {
description = "Set to false to use the existing policy matching name and only manage rules."
type = bool
default = true
nullable = false
}

variable "project_id" {
description = "Project id for the zone."
type = string
}

variable "rules" {
description = "Map of policy rules in name => rule format. Local data takes precedence over behavior and is in the form record type => attributes."
type = map(object({
dns_name = string
behavior = optional(string, "bypassResponsePolicy")
local_data = optional(map(object({
ttl = optional(number)
rrdatas = optional(list(string), [])
})), {})
}))
default = {}
nullable = false
}
33 changes: 33 additions & 0 deletions modules/dns-response-policy/versions.tf
@@ -0,0 +1,33 @@
# Copyright 2022 Google LLC
ludoo marked this conversation as resolved.
Show resolved Hide resolved
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

terraform {
required_version = ">= 1.3.1"
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.55.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.55.0" # tftest
}
local = {
ludoo marked this conversation as resolved.
Show resolved Hide resolved
source = "hashicorp/local"
version = "2.2.3"
}
}
}


52 changes: 52 additions & 0 deletions tests/modules/dns_response_policy/examples/nocreate.yaml
@@ -0,0 +1,52 @@
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

values:
module.dns-policy.google_dns_response_policy_rule.default["default"]:
behavior: null
dns_name: '*.googleapis.com.'
local_data:
- local_datas:
- name: '*.googleapis.com.'
rrdatas:
- restricted.googleapis.com.
ttl: null
type: CNAME
project: myproject
response_policy: googleapis
rule_name: default
module.dns-policy.google_dns_response_policy_rule.default["pubsub"]:
behavior: bypassResponsePolicy
dns_name: pubsub.googleapis.com.
local_data: []
project: myproject
response_policy: googleapis
rule_name: pubsub
module.dns-policy.google_dns_response_policy_rule.default["restricted"]:
behavior: null
dns_name: restricted.googleapis.com.
local_data:
- local_datas:
- name: restricted.googleapis.com.
rrdatas:
- 199.36.153.4
- 199.36.153.5
ttl: null
type: A
project: myproject
response_policy: googleapis
rule_name: restricted

counts:
google_dns_response_policy_rule: 3