Skip to content

Commit 6e9c840

Browse files
authored
Merge pull request #21 from infraspecdev/feature/route53-cross-account-access
feat: Add provision to use cross-account route53 for acm dns validation
2 parents 4727f2e + 1f608b0 commit 6e9c840

File tree

13 files changed

+108
-13
lines changed

13 files changed

+108
-13
lines changed

.github/workflows/terraform-docs.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
- name: Checkout repository
1414
uses: actions/checkout@v4
1515
with:
16-
ref: ${{ github.ref }}
16+
ref: ${{ github.event.pull_request.head.ref }}
1717

1818
- name: Render and Push terraform docs for main module
1919
uses: terraform-docs/gh-actions@main

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ repos:
44
hooks:
55
- id: terraform_fmt
66
- id: terraform_validate
7+
exclude: '^[^/]+\.tf$|^modules/acm/.*'
78
- id: terraform_tflint
89
args:
910
- '--args=--only=terraform_deprecated_interpolation'

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ Terraform module to deploy production-ready applications and services on an exis
1212
| Name | Version |
1313
|------|---------|
1414
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.6.0 |
15-
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 5.0 |
15+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 6.0 |
1616

1717
## Providers
1818

1919
| Name | Version |
2020
|------|---------|
21-
| <a name="provider_aws"></a> [aws](#provider\_aws) | ~> 5.0 |
21+
| <a name="provider_aws"></a> [aws](#provider\_aws) | ~> 6.0 |
2222

2323
## Modules
2424

@@ -51,6 +51,8 @@ Terraform module to deploy production-ready applications and services on an exis
5151
| <a name="input_create_s3_bucket_for_alb_logging"></a> [create\_s3\_bucket\_for\_alb\_logging](#input\_create\_s3\_bucket\_for\_alb\_logging) | (Optional) Creates S3 bucket for storing ALB Access and Connection Logs. | `bool` | `true` | no |
5252
| <a name="input_default_capacity_providers_strategies"></a> [default\_capacity\_providers\_strategies](#input\_default\_capacity\_providers\_strategies) | (Optional) Set of capacity provider strategies to use by default for the cluster. | `any` | `[]` | no |
5353
| <a name="input_load_balancer"></a> [load\_balancer](#input\_load\_balancer) | Configuration for the Application Load Balancer. | <pre>object({<br/> name = optional(string)<br/> internal = optional(bool, false)<br/> subnets_ids = optional(list(string), [])<br/> security_groups_ids = optional(list(string), [])<br/> preserve_host_header = optional(bool)<br/> enable_deletion_protection = optional(bool, false)<br/> access_logs = optional(any, null)<br/> connection_logs = optional(any, null)<br/> target_groups = optional(any, {})<br/> listeners = optional(any, {})<br/> listener_rules = optional(any, {})<br/> tags = optional(map(string), {})<br/> })</pre> | `{}` | no |
54+
| <a name="input_region"></a> [region](#input\_region) | (Optional) AWS region to create resources in. | `string` | `null` | no |
55+
| <a name="input_route53_assume_role_arn"></a> [route53\_assume\_role\_arn](#input\_route53\_assume\_role\_arn) | (Optional) ARN of the role to assume for Route53 operations. | `string` | `null` | no |
5456
| <a name="input_s3_bucket_force_destroy"></a> [s3\_bucket\_force\_destroy](#input\_s3\_bucket\_force\_destroy) | (Optional, Default:false) Boolean that indicates all objects (including any locked objects) should be deleted from the bucket when the bucket is destroyed so that the bucket can be destroyed without error. | `bool` | `false` | no |
5557
| <a name="input_s3_bucket_name"></a> [s3\_bucket\_name](#input\_s3\_bucket\_name) | (Optional, Forces new resource) Name of the bucket. | `string` | `null` | no |
5658
| <a name="input_s3_bucket_policy_id_prefix"></a> [s3\_bucket\_policy\_id\_prefix](#input\_s3\_bucket\_policy\_id\_prefix) | (Optional) - Prefix of the ID for the policy document. | `string` | `"ecs-deployment-alb-"` | no |

examples/complete/main.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ module "ecs_deployment" {
9393
record_zone_id = data.aws_route53_zone.base_domain.zone_id
9494
}
9595
}
96+
region = var.region
97+
# Cross-account role that ACM module will use for Route53 DNS record creation
98+
route53_assume_role_arn = var.route53_assume_role_arn
9699

97100
# Application Load Balancer
98101
load_balancer = {

examples/complete/variables.tf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,13 @@ variable "domain_name" {
132132
description = "Domain name for ACM"
133133
type = string
134134
}
135+
136+
variable "region" {
137+
description = "AWS region to deploy resources"
138+
type = string
139+
}
140+
141+
variable "route53_assume_role_arn" {
142+
description = "ARN of the cross-account role for Route53 DNS record creation"
143+
type = string
144+
}

main.tf

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,12 +243,33 @@ resource "aws_ecs_task_definition" "this" {
243243
################################################################################
244244
# Amazon Certificates Manager Sub-module
245245
################################################################################
246+
provider "aws" {
247+
region = var.region
248+
}
249+
250+
# Cross-account provider for Route53
251+
provider "aws" {
252+
alias = "cross_account_provider"
253+
region = var.region
254+
255+
dynamic "assume_role" {
256+
for_each = var.route53_assume_role_arn != null ? [1] : []
257+
content {
258+
role_arn = var.route53_assume_role_arn
259+
}
260+
}
261+
}
246262

247263
module "acm" {
248264
source = "./modules/acm"
249265

250-
for_each = var.create_acm ? var.acm_certificates : {}
266+
providers = {
267+
aws = aws
268+
aws.cross_account_provider = aws.cross_account_provider
269+
}
270+
route53_assume_role_arn = var.route53_assume_role_arn
251271

272+
for_each = var.create_acm ? var.acm_certificates : {}
252273
# ACM Certificate
253274
certificate_domain_name = each.value.domain_name
254275
certificate_subject_alternative_names = try(each.value.subject_alternative_names, null)
@@ -259,8 +280,7 @@ module "acm" {
259280
# Route53 Record
260281
record_zone_id = try(each.value.record_zone_id, null)
261282
record_allow_overwrite = try(each.value.record_allow_overwrite, null)
262-
263-
tags = try(each.value.tags, {})
283+
tags = try(each.value.tags, {})
264284
}
265285

266286
################################################################################

modules/acm/README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ This sub-module creates the Amazon-issued certificate for a given domain with `v
2424
| Name | Version |
2525
|------|---------|
2626
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.6.0 |
27+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | ~> 6.0 |
2728

2829
## Providers
2930

3031
| Name | Version |
3132
|------|---------|
32-
| <a name="provider_aws"></a> [aws](#provider\_aws) | n/a |
33+
| <a name="provider_aws"></a> [aws](#provider\_aws) | ~> 6.0 |
34+
| <a name="provider_aws.cross_account_provider"></a> [aws.cross\_account\_provider](#provider\_aws.cross\_account\_provider) | ~> 6.0 |
3335

3436
## Modules
3537

@@ -41,6 +43,7 @@ No modules.
4143
|------|------|
4244
| [aws_acm_certificate.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate) | resource |
4345
| [aws_acm_certificate_validation.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate_validation) | resource |
46+
| [aws_route53_record.cross_account](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
4447
| [aws_route53_record.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
4548

4649
## Inputs
@@ -54,6 +57,7 @@ No modules.
5457
| <a name="input_certificate_validation_option"></a> [certificate\_validation\_option](#input\_certificate\_validation\_option) | (Optional) Configuration block used to specify information about the initial validation of each domain name. | <pre>object({<br/> domain_name = string<br/> validation_domain = string<br/> })</pre> | `null` | no |
5558
| <a name="input_record_allow_overwrite"></a> [record\_allow\_overwrite](#input\_record\_allow\_overwrite) | (Optional) Allow creation of this record in Terraform to overwrite an existing record, if any. | `bool` | `true` | no |
5659
| <a name="input_record_zone_id"></a> [record\_zone\_id](#input\_record\_zone\_id) | (Required) Hosted zone ID for a CloudFront distribution, S3 bucket, ELB, or Route 53 hosted zone. | `string` | n/a | yes |
60+
| <a name="input_route53_assume_role_arn"></a> [route53\_assume\_role\_arn](#input\_route53\_assume\_role\_arn) | (Optional) IAM role ARN to assume for Route53 operations | `string` | `null` | no |
5761
| <a name="input_tags"></a> [tags](#input\_tags) | (Optional) Map of tags to assign to the resource. | `map(string)` | `{}` | no |
5862

5963
## Outputs
@@ -63,5 +67,5 @@ No modules.
6367
| <a name="output_acm_certificate_arn"></a> [acm\_certificate\_arn](#output\_acm\_certificate\_arn) | ARN of the ACM certificate. |
6468
| <a name="output_acm_certificate_id"></a> [acm\_certificate\_id](#output\_acm\_certificate\_id) | ARN of the ACM certificate. |
6569
| <a name="output_acm_certificate_validation_id"></a> [acm\_certificate\_validation\_id](#output\_acm\_certificate\_validation\_id) | Identifier of the ACM certificate validation resource. |
66-
| <a name="output_route53_record_id"></a> [route53\_record\_id](#output\_route53\_record\_id) | Identifier of the Route53 Record for validation of the ACM certificate. |
70+
| <a name="output_route53_record_id"></a> [route53\_record\_id](#output\_route53\_record\_id) | Identifier of the Route53 Record (supports same & cross-account). |
6771
<!-- END_TF_DOCS -->

modules/acm/main.tf

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,21 @@ resource "aws_acm_certificate" "this" {
3838
################################################################################
3939

4040
resource "aws_route53_record" "this" {
41+
count = var.route53_assume_role_arn == null ? 1 : 0
42+
43+
zone_id = var.record_zone_id
44+
name = local.acm_certificate_validation_record.name
45+
type = local.acm_certificate_validation_record.type
46+
records = [local.acm_certificate_validation_record.value]
47+
ttl = 60
48+
allow_overwrite = var.record_allow_overwrite
49+
}
50+
51+
resource "aws_route53_record" "cross_account" {
52+
count = var.route53_assume_role_arn != null ? 1 : 0
53+
provider = aws.cross_account_provider
54+
55+
4156
zone_id = var.record_zone_id
4257
name = local.acm_certificate_validation_record.name
4358
type = local.acm_certificate_validation_record.type
@@ -47,6 +62,11 @@ resource "aws_route53_record" "this" {
4762
}
4863

4964
resource "aws_acm_certificate_validation" "this" {
50-
certificate_arn = aws_acm_certificate.this.arn
51-
validation_record_fqdns = [aws_route53_record.this.fqdn]
65+
certificate_arn = aws_acm_certificate.this.arn
66+
67+
validation_record_fqdns = [
68+
var.route53_assume_role_arn == null ?
69+
aws_route53_record.this[0].fqdn :
70+
aws_route53_record.cross_account[0].fqdn
71+
]
5272
}

modules/acm/outputs.tf

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,15 @@ output "acm_certificate_arn" {
1717
################################################################################
1818

1919
output "route53_record_id" {
20-
description = "Identifier of the Route53 Record for validation of the ACM certificate."
21-
value = aws_route53_record.this.id
20+
description = "Identifier of the Route53 Record (supports same & cross-account)."
21+
value = (
22+
var.route53_assume_role_arn == null
23+
? aws_route53_record.this[0].id
24+
: aws_route53_record.cross_account[0].id
25+
)
2226
}
2327

28+
2429
################################################################################
2530
# ACM Certificate Validation
2631
################################################################################

modules/acm/providers.tf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
terraform {
2+
required_providers {
3+
aws = {
4+
source = "hashicorp/aws"
5+
version = "~> 6.0"
6+
configuration_aliases = [
7+
aws,
8+
aws.cross_account_provider
9+
]
10+
}
11+
}
12+
}

0 commit comments

Comments
 (0)