Skip to content

Commit d230695

Browse files
committed
[feature] aws-acm-certificate module compatible with TF AWS Provider >3.0
1 parent 781e2bc commit d230695

File tree

7 files changed

+217
-0
lines changed

7 files changed

+217
-0
lines changed

aws-acm-cert/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# AWS ACM Cert
22

3+
**_DEPRECATED: Use aws-acm-certificate if using Terraform AWS Provider >3.0._**
4+
35
Will create and attempt to validate an certificate in the [AWS ACM service](https://aws.amazon.com/certificate-manager/). This module uses DNS verification so the principal running this needs to be able to write to the supplied Route53 zone.
46

57
NOTE: if you intend to use this certificate in a cloudfront distribution it must be created in `us-east-1` region.

aws-acm-certificate/README.md

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# AWS ACM Certificate
2+
3+
Will create and attempt to validate an certificate in the [AWS ACM service](https://aws.amazon.com/certificate-manager/). This module uses DNS verification so the principal running this needs to be able to write to the supplied Route53 zone.
4+
5+
NOTE: if you intend to use this certificate in a cloudfront distribution it must be created in `us-east-1` region.
6+
7+
## Example
8+
9+
```hcl
10+
module "cert" {
11+
source = "github.com/chanzuckerberg/cztack//aws-acm-certificate?ref=v0.40.0"
12+
13+
# the cert domain name
14+
cert_domain_name = "..."
15+
16+
# the route53 zone for validating the `cert_domain_name`
17+
aws_route53_zone_id = "..."
18+
19+
# an optional map of alternative : route53_zone_id
20+
cert_subject_alternative_names = {"foobar.com" = data.aws_route53_zone.foo.id}
21+
22+
# optional variable for tags
23+
tags = {
24+
project = "...",
25+
env = "...",
26+
service = "...",
27+
owner = "..."
28+
}
29+
}
30+
```
31+
32+
<!-- START -->
33+
## Requirements
34+
35+
| Name | Version |
36+
|------|---------|
37+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.0.0 |
38+
39+
## Providers
40+
41+
| Name | Version |
42+
|------|---------|
43+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.0.0 |
44+
45+
## Modules
46+
47+
No modules.
48+
49+
## Resources
50+
51+
| Name | Type |
52+
|------|------|
53+
| [aws_acm_certificate.cert](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate) | resource |
54+
| [aws_acm_certificate_validation.cert](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate_validation) | resource |
55+
| [aws_route53_record.cert_validation](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
56+
57+
## Inputs
58+
59+
| Name | Description | Type | Default | Required |
60+
|------|-------------|------|---------|:--------:|
61+
| <a name="input_aws_route53_zone_id"></a> [aws\_route53\_zone\_id](#input\_aws\_route53\_zone\_id) | n/a | `string` | n/a | yes |
62+
| <a name="input_cert_domain_name"></a> [cert\_domain\_name](#input\_cert\_domain\_name) | Like www.foo.bar.com or *.foo.bar.com | `string` | n/a | yes |
63+
| <a name="input_cert_subject_alternative_names"></a> [cert\_subject\_alternative\_names](#input\_cert\_subject\_alternative\_names) | A map of <alternative\_domain:route53\_zone\_id> | `map(string)` | `{}` | no |
64+
| <a name="input_tags"></a> [tags](#input\_tags) | Tags to apply to certificate | `map(string)` | `{}` | no |
65+
| <a name="input_validation_record_ttl"></a> [validation\_record\_ttl](#input\_validation\_record\_ttl) | n/a | `string` | `60` | no |
66+
67+
## Outputs
68+
69+
| Name | Description |
70+
|------|-------------|
71+
| <a name="output_arn"></a> [arn](#output\_arn) | n/a |
72+
| <a name="output_id"></a> [id](#output\_id) | n/a |
73+
<!-- END -->

aws-acm-certificate/main.tf

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
resource "aws_acm_certificate" "cert" {
2+
domain_name = var.cert_domain_name
3+
subject_alternative_names = keys(var.cert_subject_alternative_names)
4+
validation_method = "DNS"
5+
tags = var.tags
6+
7+
lifecycle {
8+
create_before_destroy = true
9+
}
10+
}
11+
12+
resource "aws_route53_record" "cert_validation" {
13+
for_each = {
14+
for dvo in aws_acm_certificate.cert.domain_validation_options : dvo.domain_name => {
15+
name = dvo.resource_record_name
16+
record = dvo.resource_record_value
17+
type = dvo.resource_record_type
18+
}
19+
}
20+
21+
name = each.value.name
22+
type = each.value.type
23+
zone_id = lookup(var.cert_subject_alternative_names, each.key, var.aws_route53_zone_id)
24+
records = [each.value.record]
25+
ttl = var.validation_record_ttl
26+
27+
allow_overwrite = true # Needed if making cert in multiple regions, and for AWS Provider 3.0 conversion
28+
}
29+
30+
resource "aws_acm_certificate_validation" "cert" {
31+
certificate_arn = aws_acm_certificate.cert.arn
32+
validation_record_fqdns = [for record in aws_route53_record.cert_validation : record.fqdn]
33+
}

aws-acm-certificate/module_test.go

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/chanzuckerberg/go-misc/tftest"
8+
"github.com/gruntwork-io/terratest/modules/terraform"
9+
)
10+
11+
func TestAWSACMCertificateInit(t *testing.T) {
12+
options := &terraform.Options{
13+
TerraformDir: ".",
14+
}
15+
terraform.Init(t, options)
16+
}
17+
18+
func TestAWSACMCertificateDefaults(t *testing.T) {
19+
t.Parallel()
20+
21+
test := tftest.Test{
22+
Setup: func(t *testing.T) *terraform.Options {
23+
certDomainName := fmt.Sprintf(
24+
"%s.%s",
25+
tftest.UniqueID(),
26+
tftest.EnvVar(tftest.EnvRoute53ZoneName))
27+
28+
alternativeDomainName := fmt.Sprintf(
29+
"%s.%s",
30+
tftest.UniqueID(),
31+
tftest.EnvVar(tftest.EnvRoute53ZoneName))
32+
33+
route53ZoneID := tftest.EnvVar(tftest.EnvRoute53ZoneID)
34+
35+
alternativeNames := map[string]string{
36+
alternativeDomainName: route53ZoneID,
37+
}
38+
39+
tags := map[string]string{
40+
"project": tftest.UniqueID(),
41+
"env": tftest.UniqueID(),
42+
"service": tftest.UniqueID(),
43+
"owner": tftest.UniqueID(),
44+
"managedBy": "terraform",
45+
}
46+
47+
vars := map[string]interface{}{
48+
"cert_domain_name": certDomainName,
49+
"aws_route53_zone_id": route53ZoneID,
50+
"validation_record_ttl": 5,
51+
"cert_subject_alternative_names": alternativeNames,
52+
"tags": tags,
53+
}
54+
55+
options := &terraform.Options{
56+
TerraformDir: ".",
57+
58+
EnvVars: map[string]string{
59+
"AWS_DEFAULT_REGION": tftest.DefaultRegion,
60+
},
61+
62+
Vars: vars,
63+
}
64+
65+
return options
66+
},
67+
Validate: func(t *testing.T, options *terraform.Options) {},
68+
}
69+
70+
test.Run(t)
71+
}

aws-acm-certificate/outputs.tf

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
output "arn" {
2+
value = aws_acm_certificate.cert.arn
3+
}
4+
5+
output "id" {
6+
value = aws_acm_certificate.cert.id
7+
}

aws-acm-certificate/terraform.tf

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
terraform {
2+
required_providers {
3+
# aws_acm_certificate changed API in 3.0.0
4+
aws = ">= 3.0.0"
5+
}
6+
}

aws-acm-certificate/variables.tf

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
variable "cert_domain_name" {
2+
type = string
3+
description = "Like www.foo.bar.com or *.foo.bar.com"
4+
}
5+
6+
variable "cert_subject_alternative_names" {
7+
type = map(string)
8+
description = "A map of <alternative_domain:route53_zone_id>"
9+
default = {}
10+
}
11+
12+
variable "aws_route53_zone_id" {
13+
type = string
14+
}
15+
16+
variable "validation_record_ttl" {
17+
type = string
18+
default = 60
19+
}
20+
21+
variable tags {
22+
type = map(string)
23+
description = "Tags to apply to certificate"
24+
default = {}
25+
}

0 commit comments

Comments
 (0)