Skip to content

Commit a5701bb

Browse files
committed
initial commit
1 parent 06694c7 commit a5701bb

File tree

6 files changed

+212
-9
lines changed

6 files changed

+212
-9
lines changed

README.md

+27-5
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,47 @@ The `terraform-docs` utility is used to generate this README. Follow the below s
3434
|------|---------|
3535
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0.7 |
3636
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.0.0 |
37-
| <a name="requirement_awscc"></a> [awscc](#requirement\_awscc) | >= 0.24.0 |
3837

3938
## Providers
4039

41-
No providers.
40+
| Name | Version |
41+
|------|---------|
42+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.0.0 |
4243

4344
## Modules
4445

4546
No modules.
4647

4748
## Resources
4849

49-
No resources.
50+
| Name | Type |
51+
|------|------|
52+
| [aws_ram_principal_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ram_principal_association) | resource |
53+
| [aws_ram_resource_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ram_resource_association) | resource |
54+
| [aws_ram_resource_share.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ram_resource_share) | resource |
55+
| [aws_route53_resolver_endpoint.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_resolver_endpoint) | resource |
56+
| [aws_route53_resolver_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_resolver_rule) | resource |
57+
| [aws_route53_zone_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone_association) | resource |
58+
| [aws_security_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
5059

5160
## Inputs
5261

53-
No inputs.
62+
| Name | Description | Type | Default | Required |
63+
|------|-------------|------|---------|:--------:|
64+
| <a name="input_resolver_name"></a> [resolver\_name](#input\_resolver\_name) | Name of the Route53 resolver endpoint | `string` | n/a | yes |
65+
| <a name="input_resolver_subnet_ids"></a> [resolver\_subnet\_ids](#input\_resolver\_subnet\_ids) | List of subnet IDs in which to create the Route53 Outbound Resolver | `list(string)` | n/a | yes |
66+
| <a name="input_resolver_vpc_id"></a> [resolver\_vpc\_id](#input\_resolver\_vpc\_id) | The ID of the VPC in which to create the Route53 Outbound Resolver | `string` | n/a | yes |
67+
| <a name="input_resolver_endpoint_type"></a> [resolver\_endpoint\_type](#input\_resolver\_endpoint\_type) | The Route 53 Resolver endpoint IP address type. Valid values: IPV4, IPV6, DUALSTACK. | `string` | `"IPV4"` | no |
68+
| <a name="input_resolver_protocols"></a> [resolver\_protocols](#input\_resolver\_protocols) | List of protocols that the Route53 Outbound Resolver should support | `list(string)` | <pre>[<br> "Do53"<br>]</pre> | no |
69+
| <a name="input_resolver_rule_groups"></a> [resolver\_rule\_groups](#input\_resolver\_rule\_groups) | Map of Route53 Resolver Rules by group. Every rule in each group can be shared with principals via AWS RAM. | <pre>map(object({<br> name = optional(string)<br> ram_principals = optional(list(string), [])<br><br> rules = list(object({<br> domain = string<br> targets = list(string)<br> name = optional(string)<br> rule_type = optional(string, "FORWARD")<br> }))<br> }))</pre> | `{}` | no |
70+
| <a name="input_route53_zone_ids"></a> [route53\_zone\_ids](#input\_route53\_zone\_ids) | List of Route53 Zone IDs to be associated with the resolver VPC. | `list(string)` | `[]` | no |
71+
| <a name="input_tags"></a> [tags](#input\_tags) | Map of tags to apply to resources created by this module | `map(string)` | `{}` | no |
5472

5573
## Outputs
5674

57-
No outputs.
75+
| Name | Description |
76+
|------|-------------|
77+
| <a name="output_endpoint"></a> [endpoint](#output\_endpoint) | Details of the Route53 Outbound Resolver endpoint. |
78+
| <a name="output_resource_shares"></a> [resource\_shares](#output\_resource\_shares) | Map of AWS RAM Shares by group. |
79+
| <a name="output_rules"></a> [rules](#output\_rules) | Map of resolver rules by group. |
5880
<!-- END_TF_DOCS -->

locals.tf

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
locals {
2+
replace_regex = "/[\\._\\s]/"
3+
4+
normalised_rule_groups = {
5+
for group, config in var.resolver_rule_groups :
6+
group => merge(config, {
7+
name = replace(coalesce(config.name, group), local.replace_regex, "-")
8+
rules = [
9+
for rule in config.rules : merge(rule, {
10+
name = replace(coalesce(rule.name, rule.domain), local.replace_regex, "-")
11+
})
12+
]
13+
})
14+
}
15+
16+
normalised_rules = merge([
17+
for group, config in local.normalised_rule_groups : {
18+
for rule in config.rules :
19+
join("-", [config.name, rule.name]) => merge(rule, {
20+
group = group
21+
})
22+
}
23+
]...)
24+
}

main.tf

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
resource "aws_security_group" "this" {
2+
name = "${var.resolver_name}-sg"
3+
description = "Security group for the ${var.resolver_name} resolver endpoint"
4+
vpc_id = var.resolver_vpc_id
5+
6+
tags = merge(var.tags, {
7+
Name = var.resolver_name
8+
})
9+
}
10+
11+
resource "aws_route53_resolver_endpoint" "this" {
12+
name = var.resolver_name
13+
resolver_endpoint_type = var.resolver_endpoint_type
14+
protocols = var.resolver_protocols
15+
direction = "OUTBOUND"
16+
17+
security_group_ids = [
18+
aws_security_group.this.id,
19+
]
20+
21+
dynamic "ip_address" {
22+
for_each = toset(var.resolver_subnet_ids)
23+
24+
content {
25+
subnet_id = ip_address.value
26+
}
27+
}
28+
}
29+
30+
resource "aws_route53_resolver_rule" "this" {
31+
for_each = local.normalised_rules
32+
33+
name = each.value.name
34+
domain_name = each.value.domain
35+
rule_type = "FORWARD"
36+
37+
resolver_endpoint_id = aws_route53_resolver_endpoint.this.id
38+
39+
dynamic "target_ip" {
40+
for_each = each.value.targets
41+
42+
content {
43+
ip = target_ip.value
44+
}
45+
}
46+
47+
tags = merge(var.tags, {
48+
Name = var.resolver_name
49+
})
50+
}
51+
52+
resource "aws_route53_zone_association" "this" {
53+
for_each = toset(var.route53_zone_ids)
54+
55+
vpc_id = var.resolver_vpc_id
56+
zone_id = each.value
57+
}
58+
59+
resource "aws_ram_resource_share" "this" {
60+
for_each = local.normalised_rule_groups
61+
62+
name = format("%s-resolver", each.value.name)
63+
allow_external_principals = false
64+
65+
tags = merge(var.tags, {
66+
Name = each.value.name
67+
})
68+
}
69+
70+
resource "aws_ram_resource_association" "this" {
71+
for_each = local.normalised_rules
72+
73+
resource_arn = aws_route53_resolver_rule.this[each.key].arn
74+
resource_share_arn = aws_ram_resource_share.this[each.value.group].arn
75+
}
76+
77+
resource "aws_ram_principal_association" "this" {
78+
for_each = merge([
79+
for k, v in local.normalised_rule_groups : {
80+
for p in v.ram_principals :
81+
join("-", [k, p]) => {
82+
group = k
83+
principal = p
84+
}
85+
}
86+
]...)
87+
88+
principal = each.value.principal
89+
resource_share_arn = aws_ram_resource_share.this[each.value.group].arn
90+
}

outputs.tf

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
output "endpoint" {
2+
value = aws_route53_resolver_endpoint.this
3+
description = "Details of the Route53 Outbound Resolver endpoint."
4+
}
5+
6+
output "rules" {
7+
value = aws_route53_resolver_rule.this
8+
description = "Map of resolver rules by group."
9+
}
10+
11+
output "resource_shares" {
12+
value = aws_ram_resource_share.this
13+
description = "Map of AWS RAM Shares by group."
14+
}

terraform.tf

-4
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,5 @@ terraform {
77
source = "hashicorp/aws"
88
version = ">= 5.0.0"
99
}
10-
awscc = {
11-
source = "hashicorp/awscc"
12-
version = ">= 0.24.0"
13-
}
1410
}
1511
}

variables.tf

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
variable "resolver_name" {
2+
type = string
3+
description = "Name of the Route53 resolver endpoint"
4+
}
5+
6+
variable "resolver_vpc_id" {
7+
type = string
8+
description = "The ID of the VPC in which to create the Route53 Outbound Resolver"
9+
}
10+
11+
variable "resolver_subnet_ids" {
12+
type = list(string)
13+
description = "List of subnet IDs in which to create the Route53 Outbound Resolver"
14+
}
15+
16+
variable "resolver_protocols" {
17+
type = list(string)
18+
default = [
19+
"Do53",
20+
]
21+
description = "List of protocols that the Route53 Outbound Resolver should support"
22+
}
23+
24+
variable "resolver_endpoint_type" {
25+
type = string
26+
default = "IPV4"
27+
description = "The Route 53 Resolver endpoint IP address type. Valid values: IPV4, IPV6, DUALSTACK."
28+
}
29+
30+
variable "resolver_rule_groups" {
31+
type = map(object({
32+
name = optional(string)
33+
ram_principals = optional(list(string), [])
34+
35+
rules = list(object({
36+
domain = string
37+
targets = list(string)
38+
name = optional(string)
39+
rule_type = optional(string, "FORWARD")
40+
}))
41+
}))
42+
43+
default = {}
44+
description = "Map of Route53 Resolver Rules by group. Every rule in each group can be shared with principals via AWS RAM."
45+
}
46+
47+
variable "route53_zone_ids" {
48+
type = list(string)
49+
default = []
50+
description = "List of Route53 Zone IDs to be associated with the resolver VPC."
51+
}
52+
53+
variable "tags" {
54+
type = map(string)
55+
default = {}
56+
description = "Map of tags to apply to resources created by this module"
57+
}

0 commit comments

Comments
 (0)