Skip to content

Commit

Permalink
feat: add dns response policy sub-module (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
maitreya-source authored Aug 21, 2023
1 parent f09dfac commit ce34fe5
Show file tree
Hide file tree
Showing 13 changed files with 1,574 additions and 0 deletions.
51 changes: 51 additions & 0 deletions examples/dns_response_policy/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* 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.
*/

module "dns_response_policy" {
source = "../../modules/dns_response_policy"
project_id = var.project_id
policy_name = "dns-response-policy-test"
network_self_links = [google_compute_network.this.self_link]
description = "Example DNS response policy created by terraform module."
rules = {
"override-google-com" = {
dns_name = "*.google.com."
rule_local_datas = {
"A" = { # Record type.
rrdatas = ["192.0.2.91"]
ttl = 300
},
"AAAA" = {
rrdatas = ["2001:db8::8bd:1002"]
ttl = 300
}
}
},
"override-withgoogle-com" = {
dns_name = "withgoogle.com."
rule_local_datas = {
"A" = {
rrdatas = ["193.0.2.93"]
ttl = 300
}
}
},
"bypass-google-account-domain" = {
dns_name = "account.google.com."
rule_behavior = "bypassResponsePolicy"
}
}
}
29 changes: 29 additions & 0 deletions examples/dns_response_policy/network.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* 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.
*/

resource "random_string" "suffix" {
length = 4
upper = "false"
lower = "true"
numeric = "false"
special = "false"
}

resource "google_compute_network" "this" {
name = "cft-cloud-dns-test-${random_string.suffix.result}"
auto_create_subnetworks = false
project = var.project_id
}
30 changes: 30 additions & 0 deletions examples/dns_response_policy/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* 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.
*/

output "project_id" {
description = "Project ID for the DNS response policy."
value = var.project_id
}

output "response_policy_id" {
description = "An identifier for the resource with format projects/{{project}}/responsePolicies/{{response_policy_name}}."
value = module.dns_response_policy.response_policy_id
}

output "response_policy_rule_ids" {
description = "List of response rules with format projects/{{project}}/responsePolicies/{{response_policy}}/rules/{{rule_name}}."
value = module.dns_response_policy.response_policy_rule_ids
}
20 changes: 20 additions & 0 deletions examples/dns_response_policy/variable.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* 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.
*/

variable "project_id" {
type = string
description = "The ID of the project in which the DNS response policy needs to be created."
}
29 changes: 29 additions & 0 deletions examples/dns_response_policy/version.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* 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.
*/

terraform {
required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
version = "~> 4.0"
}
google-beta = {
source = "hashicorp/google-beta"
version = "~> 4.0"
}
}
}
98 changes: 98 additions & 0 deletions modules/dns_response_policy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# gcp_dns_response_policy

This module is used to create DNS response policy and rules to the corresponding response policy.

Cloud DNS private zones let you create a single response policy per network that modifies resolver behavior according to the policy created.

You can create multiple rules within one response policy with following behaviors:

- **Default / Unspecified**: Alter results for selected query names (including wildcards) by providing specific resource records.
- **Bypass**: Trigger [passthru](https://datatracker.ietf.org/doc/id/draft-vixie-dnsop-dns-rpz-00.html#rfc.section.3.3) behavior that bypasses the response policy, exempting names that would otherwise match.

Reference: https://cloud.google.com/dns/docs/zones/manage-response-policies

## Usage

Basic usage of this module for a DNS response policy is as follows:

```hcl
module "dns_response_policy" {
source = "terraform-google-modules/cloud-dns/google//modules/dns_response_policy"
project_id = "example-project-id"
policy_name = "example-policy-name"
network_self_links = ["projects/example-project-id/global/networks/default"]
description = "Example DNS response policy created by terraform module."
rules = {
"override-google-com" = {
dns_name = "*.google.com."
rule_local_datas = {
"A" = { # Record type.
rrdatas = ["192.0.2.91"]
ttl = 300
},
"AAAA" = {
rrdatas = ["2001:db8::8bd:1002"]
ttl = 300
}
}
},
"override-withgoogle-com" = {
dns_name = "withgoogle.com."
rule_local_datas = {
"A" = {
rrdatas = ["193.0.2.93"]
ttl = 300
}
}
},
"bypass-google-account-domain" = {
dns_name = "account.google.com."
rule_behavior = "bypassResponsePolicy"
}
}
}
```

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| description | The description of the response policy. | `string` | n/a | yes |
| network\_self\_links | The self links of the network to which the dns response policy needs to be applied. Note that only one response policy can be applied on a network. | `list(string)` | `[]` | no |
| policy\_name | Name of the DNS response policy. | `string` | n/a | yes |
| project\_id | The ID of the project in which the DNS response policy needs to be created. | `string` | n/a | yes |
| rules | A Response Policy Rule is a selector that applies its behavior to queries that match the selector.<br> Selectors are DNS names, which may be wildcards or exact matches.<br> Takes a map as input where the key is the name of the rule. The map contains following attributes:<br> Key - Name of the rule<br> Value - Object of following attributes:<br> * dns\_name - DNS name where policy will be applied.<br> * rule\_behavior - Whether to override or passthru. Use value bypassResponsePolicy for passthru rules and skip this key for overriding rules.<br> * rule\_local\_datas - When the rule behavior is override, policy will answer this matched DNS name directly with this DNS data. These resource record sets override any other DNS behavior for the matched name.<br> * Each local datas object can contain following attributes:<br> Key - One of the valid DNS resource type.<br> Value - Object of following attributes:<br> - ttl - Number of seconds that this ResourceRecordSet can be cached by resolvers.<br> - rrdatas - As defined in RFC 1035 (section 5) and RFC 1034 (section 3.6.1) | <pre>map(object({<br> dns_name = string<br> rule_behavior = optional(string)<br> rule_local_datas = optional(map(object({<br> ttl = string<br> rrdatas = list(string)<br> })))<br> }))</pre> | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| response\_policy\_id | An identifier for the resource with format projects/{{project}}/responsePolicies/{{response\_policy\_name}}. |
| response\_policy\_rule\_ids | List of response rules with format projects/{{project}}/responsePolicies/{{response\_policy}}/rules/{{rule\_name}}. |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13 |
| <a name="requirement_google-beta"></a> [google-beta](#requirement\_google-beta) | ~> 4.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_google-beta"></a> [google-beta](#provider\_google-beta) | ~> 4.0 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [google-beta_google_dns_response_policy.this](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/google_dns_response_policy) | resource |
| [google-beta_google_dns_response_policy_rule.this](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/google_dns_response_policy_rule) | resource |
60 changes: 60 additions & 0 deletions modules/dns_response_policy/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* 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.
*/

/**
Cloud DNS private zones let you create a single response policy per network that
modifies resolver behavior according to the policy created.
*/
resource "google_dns_response_policy" "this" {
project = var.project_id
response_policy_name = var.policy_name
description = var.description
dynamic "networks" {
for_each = var.network_self_links
content {
network_url = networks.value
}
}
}

/**
Response policy rules can be created under a response policy to alter results for
selected query names or trigger passthru behavior that bypasses the response policy.
*/
resource "google_dns_response_policy_rule" "this" {
for_each = toset(keys(var.rules))
provider = google-beta
project = var.project_id
rule_name = each.key
dns_name = lookup(var.rules[each.key], "dns_name")
response_policy = google_dns_response_policy.this.response_policy_name
behavior = lookup(var.rules[each.key], "rule_behavior", null)

dynamic "local_data" {
for_each = lookup(var.rules[each.key], "rule_behavior", "") == "bypassResponsePolicy" ? [] : [1]
content {
dynamic "local_datas" {
for_each = lookup(var.rules[each.key], "rule_local_datas")
content {
name = lookup(var.rules[each.key], "dns_name")
rrdatas = local_datas.value.rrdatas
ttl = local_datas.value.ttl
type = local_datas.key # Only one local data allowed for each type.
}
}
}
}
}
25 changes: 25 additions & 0 deletions modules/dns_response_policy/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* 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.
*/

output "response_policy_id" {
description = "An identifier for the resource with format projects/{{project}}/responsePolicies/{{response_policy_name}}."
value = google_dns_response_policy.this.id
}

output "response_policy_rule_ids" {
description = "List of response rules with format projects/{{project}}/responsePolicies/{{response_policy}}/rules/{{rule_name}}."
value = [for rule in google_dns_response_policy_rule.this : rule.id]
}
Loading

0 comments on commit ce34fe5

Please sign in to comment.