-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #48 from answerdigital/route53
Route53 module from our infra repo
- Loading branch information
Showing
12 changed files
with
414 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,22 @@ | ||
# terraform-modules | ||
The repo for AnswerDigital Terraform modules | ||
|
||
The repo for Answer Digital shared Terraform modules. | ||
|
||
## Using these modules | ||
|
||
You can use these modules in your own terraform projects as follows: | ||
|
||
```hcl | ||
module "ec2_setup" { | ||
source = "github.com/answerdigital/terraform-modules//modules/aws/ec2?ref=v2" | ||
} | ||
``` | ||
|
||
Notice the double `//` between the repository URL and the path to the module. | ||
For further information please see the [terraform documentation](https://developer.hashicorp.com/terraform/language/modules/sources#modules-in-package-sub-directories). | ||
|
||
Versions are shared across all modules. You can choose a specific tag (e.g. `?ref=v2.0.0`) or to get the latest changes within a major version, use `?ref=v2` which will get the latest v2.x.x release. | ||
|
||
## Documentation | ||
|
||
Further documentation can be found in the [wiki](https://github.com/answerdigital/terraform-modules/wiki). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
# Terraform Route53 Module | ||
|
||
This Terraform module manages a zone and multiple records in Route53. | ||
The module also simplifies a few boilerplate records at the apex for security purposes. | ||
|
||
<!-- BEGIN_TF_DOCS --> | ||
## Requirements | ||
|
||
| Name | Version | | ||
|------|---------| | ||
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 4.0 | | ||
|
||
## Providers | ||
|
||
| Name | Version | | ||
|------|---------| | ||
| <a name="provider_aws"></a> [aws](#provider\_aws) | ~> 4.0 | | ||
|
||
## Resources | ||
|
||
| Name | Type | | ||
|------|------| | ||
| [aws_route53_record.apex_txt](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | | ||
| [aws_route53_record.caa](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | | ||
| [aws_route53_record.dns_record](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | | ||
| [aws_route53_record.name_servers](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | | ||
| [aws_route53_record.redirect_record_apex](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | | ||
| [aws_route53_record.redirect_record_extra](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | | ||
| [aws_route53_record.redirect_record_mx](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | | ||
| [aws_route53_record.redirect_record_www](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource | | ||
| [aws_route53_zone.dns_zone](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone) | resource | | ||
| [aws_route53_zone.redirect_zone](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone) | resource | | ||
| [aws_s3_bucket.redirect](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | | ||
| [aws_s3_bucket_acl.redirect](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_acl) | resource | | ||
| [aws_s3_bucket_website_configuration.redirect](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_website_configuration) | resource | | ||
|
||
## Inputs | ||
|
||
| Name | Description | Type | Default | Required | | ||
|------|-------------|------|---------|:--------:| | ||
| <a name="input_alias_mx"></a> [alias\_mx](#input\_alias\_mx) | List of alias domains that should have the same MX records as the canonical domain. | `list(string)` | `[]` | no | | ||
| <a name="input_alias_records"></a> [alias\_records](#input\_alias\_records) | List of DNS records for alias domains. The top-level keys should match entries in the `aliases`<br> list. The second-level map should match the same structure as `records`. | <pre>map(map(object({<br> name = optional(string)<br> ttl = optional(string)<br> type = string<br> records = list(string)<br> })))</pre> | `{}` | no | | ||
| <a name="input_alias_redirect_protocol"></a> [alias\_redirect\_protocol](#input\_alias\_redirect\_protocol) | Protocol to use when redirecting to the canonical domain. Valid values: `http`, `https`. | `string` | `"https"` | no | | ||
| <a name="input_aliases"></a> [aliases](#input\_aliases) | List of alias domains that should redirect to the canonical domain. | `list(string)` | `[]` | no | | ||
| <a name="input_apex_txt"></a> [apex\_txt](#input\_apex\_txt) | List of TXT records to be added at the apex. | `list(string)` | `[]` | no | | ||
| <a name="input_caa_issuers"></a> [caa\_issuers](#input\_caa\_issuers) | List of CAs that can issue certificates. | `list(string)` | <pre>[<br> "amazon.com"<br>]</pre> | no | | ||
| <a name="input_canonical_mx_record"></a> [canonical\_mx\_record](#input\_canonical\_mx\_record) | The name of the MX record on the canonical domain. | `string` | `"apex_mx"` | no | | ||
| <a name="input_comment"></a> [comment](#input\_comment) | A comment for the hosted zone. Defaults to 'Managed by Terraform'. | `string` | `null` | no | | ||
| <a name="input_default_ttl"></a> [default\_ttl](#input\_default\_ttl) | Default TTL for DNS records. | `number` | `86400` | no | | ||
| <a name="input_domain"></a> [domain](#input\_domain) | The top-level domain name to hold the records. | `string` | n/a | yes | | ||
| <a name="input_records"></a> [records](#input\_records) | List of DNS records for the domain.<br><br> • `name` - (Optional) The name of the record. Defaults to the domain (i.e. an apex record).<br> • `ttl` - (Optional) The TTL of the record. Defaults to `default_ttl`.<br> • `type` - (Required) The record type.<br> • `records` - (Required) A string list of records. | <pre>map(object({<br> name = optional(string)<br> ttl = optional(string)<br> type = string<br> records = list(string)<br> }))</pre> | n/a | yes | | ||
| <a name="input_security_contact"></a> [security\_contact](#input\_security\_contact) | Security contact for the domain. Defaults to 'security@DOMAIN', where `DOMAIN` is the top-level domain name. | `string` | `null` | no | | ||
| <a name="input_spf"></a> [spf](#input\_spf) | List of SPF directives for the domain. | `list(string)` | `[]` | no | | ||
| <a name="input_tags"></a> [tags](#input\_tags) | Tags for the hosted zone. | `map(any)` | `{}` | no | | ||
|
||
## Outputs | ||
|
||
| Name | Description | | ||
|------|-------------| | ||
| <a name="output_zone_arn"></a> [zone\_arn](#output\_zone\_arn) | The Amazon Resource Name (ARN) of the Hosted Zone. | | ||
| <a name="output_zone_id"></a> [zone\_id](#output\_zone\_id) | The Hosted Zone ID. | | ||
<!-- END_TF_DOCS --> | ||
|
||
# Example Usage | ||
|
||
Below is a simple example for an example.com zone with a single subdomain record. | ||
|
||
```terraform | ||
module "example_com" { | ||
source = "github.com/answerdigital/terraform-modules//modules/aws/route53?ref=v2" | ||
domain = "example.com" | ||
records = { | ||
www = { | ||
name = "www" | ||
type = "A" | ||
records = ["1.2.3.4"] | ||
} | ||
} | ||
spf = [ | ||
"include:_spf.google.com" | ||
] | ||
} | ||
``` | ||
|
||
If the domain is a canonical domain with aliases (e.g. brand protection domains), alias | ||
domains can be added here. The alias domains are configured with an S3 bucket to redirect | ||
the bare domain and www subdomain to the canonical domain. | ||
|
||
|
||
```terraform | ||
module "example_com" { | ||
source = "github.com/answerdigital/terraform-modules//modules/aws/route53?ref=v2" | ||
domain = "example.com" | ||
aliases = [ | ||
"example.org" # example.org and www.example.org will redirect to example.com | ||
] | ||
alias_records = { | ||
"example.org" = { | ||
foo = { | ||
name = "foo" | ||
type = "A" | ||
records = ["8.7.6.5"] | ||
} | ||
} | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
resource "aws_s3_bucket" "redirect" { | ||
for_each = toset(concat(var.aliases, [for a in var.aliases : "www.${a}"])) | ||
bucket = each.key | ||
} | ||
|
||
resource "aws_s3_bucket_acl" "redirect" { | ||
for_each = toset(concat(var.aliases, [for a in var.aliases : "www.${a}"])) | ||
bucket = aws_s3_bucket.redirect[each.key].bucket | ||
acl = "private" | ||
} | ||
|
||
resource "aws_s3_bucket_website_configuration" "redirect" { | ||
for_each = toset(concat(var.aliases, [for a in var.aliases : "www.${a}"])) | ||
bucket = aws_s3_bucket.redirect[each.key].bucket | ||
|
||
redirect_all_requests_to { | ||
host_name = var.domain | ||
protocol = var.alias_redirect_protocol | ||
} | ||
} | ||
|
||
resource "aws_route53_zone" "redirect_zone" { | ||
for_each = toset(var.aliases) | ||
name = each.key | ||
tags = var.tags | ||
} | ||
|
||
resource "aws_route53_record" "redirect_record_apex" { | ||
for_each = toset(var.aliases) | ||
|
||
zone_id = aws_route53_zone.redirect_zone[each.key].zone_id | ||
name = each.key | ||
type = "A" | ||
allow_overwrite = true | ||
|
||
alias { | ||
zone_id = aws_s3_bucket.redirect[each.key].hosted_zone_id | ||
name = aws_s3_bucket_website_configuration.redirect[each.key].website_domain | ||
evaluate_target_health = false | ||
} | ||
} | ||
|
||
resource "aws_route53_record" "redirect_record_www" { | ||
for_each = toset(var.aliases) | ||
|
||
zone_id = aws_route53_zone.redirect_zone[each.key].zone_id | ||
name = "www" | ||
type = "A" | ||
allow_overwrite = true | ||
|
||
alias { | ||
zone_id = aws_s3_bucket.redirect["www.${each.key}"].hosted_zone_id | ||
name = aws_s3_bucket_website_configuration.redirect["www.${each.key}"].website_domain | ||
evaluate_target_health = false | ||
} | ||
} | ||
|
||
resource "aws_route53_record" "redirect_record_mx" { | ||
for_each = toset(var.alias_mx) | ||
|
||
zone_id = aws_route53_zone.redirect_zone[each.key].zone_id | ||
allow_overwrite = true | ||
name = each.key | ||
type = "MX" | ||
ttl = aws_route53_record.dns_record[var.canonical_mx_record].ttl | ||
records = aws_route53_record.dns_record[var.canonical_mx_record].records | ||
} | ||
|
||
resource "aws_route53_record" "redirect_record_extra" { | ||
for_each = { for r in local.alias_records_list : "${r.zone}_${r.key}" => r } | ||
|
||
zone_id = aws_route53_zone.redirect_zone[each.value.zone].zone_id | ||
allow_overwrite = true | ||
name = each.value.name | ||
type = each.value.type | ||
ttl = each.value.ttl | ||
records = each.value.records | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
resource "aws_route53_zone" "dns_zone" { | ||
name = var.domain | ||
comment = var.comment | ||
tags = var.tags | ||
} | ||
|
||
resource "aws_route53_record" "name_servers" { | ||
zone_id = aws_route53_zone.dns_zone.zone_id | ||
allow_overwrite = true | ||
name = var.domain | ||
ttl = var.default_ttl | ||
type = "NS" | ||
records = aws_route53_zone.dns_zone.name_servers | ||
} | ||
|
||
resource "aws_route53_record" "dns_record" { | ||
for_each = var.records | ||
|
||
zone_id = aws_route53_zone.dns_zone.zone_id | ||
allow_overwrite = true | ||
name = each.value.name != null ? each.value.name : var.domain | ||
ttl = each.value.ttl != null ? each.value.ttl : var.default_ttl | ||
type = each.value.type | ||
records = [ | ||
for r in each.value.records : length(r) > 255 ? join("\"\"", [ | ||
for c in chunklist(split("", r), 255) : join("", c) | ||
]) : r | ||
] | ||
} | ||
|
||
resource "aws_route53_record" "apex_txt" { | ||
zone_id = aws_route53_zone.dns_zone.zone_id | ||
name = var.domain | ||
ttl = var.default_ttl | ||
type = "TXT" | ||
records = concat(var.apex_txt, [ | ||
format("security_contact=mailto:%s", local.security_contact), | ||
replace("v=spf1 ${join(" ", var.spf)} -all", " ", " ") | ||
]) | ||
} | ||
|
||
resource "aws_route53_record" "caa" { | ||
zone_id = aws_route53_zone.dns_zone.zone_id | ||
name = var.domain | ||
ttl = var.default_ttl | ||
type = "CAA" | ||
records = flatten([ | ||
[for issuer in var.caa_issuers : format("0 issue \"%s\"", issuer)], | ||
format("0 iodef \"mailto:%s\"", local.security_contact) | ||
]) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
locals { | ||
security_contact = var.security_contact != null ? var.security_contact : format("security@%s", var.domain) | ||
|
||
alias_records_list = flatten([ | ||
for zone, records in var.alias_records : [ | ||
for key, record in records : { | ||
zone = zone | ||
key = key | ||
name = record.name != null ? record.name : zone | ||
ttl = record.ttl != null ? record.ttl : var.default_ttl | ||
type = record.type | ||
records = record.records | ||
} | ||
] | ||
]) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
output "zone_arn" { | ||
value = aws_route53_zone.dns_zone.arn | ||
description = "The Amazon Resource Name (ARN) of the Hosted Zone." | ||
} | ||
|
||
output "zone_id" { | ||
value = aws_route53_zone.dns_zone.zone_id | ||
description = "The Hosted Zone ID." | ||
} |
Oops, something went wrong.