Skip to content

Commit

Permalink
[feature] aws-acm-certificate module compatible with TF AWS Provider …
Browse files Browse the repository at this point in the history
…>3.0
  • Loading branch information
mbarrien committed Jul 6, 2021
1 parent 781e2bc commit d230695
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 0 deletions.
2 changes: 2 additions & 0 deletions aws-acm-cert/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# AWS ACM Cert

**_DEPRECATED: Use aws-acm-certificate if using Terraform AWS Provider >3.0._**

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.

NOTE: if you intend to use this certificate in a cloudfront distribution it must be created in `us-east-1` region.
Expand Down
73 changes: 73 additions & 0 deletions aws-acm-certificate/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# AWS ACM Certificate

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.

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

## Example

```hcl
module "cert" {
source = "github.com/chanzuckerberg/cztack//aws-acm-certificate?ref=v0.40.0"
# the cert domain name
cert_domain_name = "..."
# the route53 zone for validating the `cert_domain_name`
aws_route53_zone_id = "..."
# an optional map of alternative : route53_zone_id
cert_subject_alternative_names = {"foobar.com" = data.aws_route53_zone.foo.id}
# optional variable for tags
tags = {
project = "...",
env = "...",
service = "...",
owner = "..."
}
}
```

<!-- START -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.0.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.0.0 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [aws_acm_certificate.cert](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate) | resource |
| [aws_acm_certificate_validation.cert](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate_validation) | resource |
| [aws_route53_record.cert_validation](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_aws_route53_zone_id"></a> [aws\_route53\_zone\_id](#input\_aws\_route53\_zone\_id) | n/a | `string` | n/a | yes |
| <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 |
| <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 |
| <a name="input_tags"></a> [tags](#input\_tags) | Tags to apply to certificate | `map(string)` | `{}` | no |
| <a name="input_validation_record_ttl"></a> [validation\_record\_ttl](#input\_validation\_record\_ttl) | n/a | `string` | `60` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_arn"></a> [arn](#output\_arn) | n/a |
| <a name="output_id"></a> [id](#output\_id) | n/a |
<!-- END -->
33 changes: 33 additions & 0 deletions aws-acm-certificate/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
resource "aws_acm_certificate" "cert" {
domain_name = var.cert_domain_name
subject_alternative_names = keys(var.cert_subject_alternative_names)
validation_method = "DNS"
tags = var.tags

lifecycle {
create_before_destroy = true
}
}

resource "aws_route53_record" "cert_validation" {
for_each = {
for dvo in aws_acm_certificate.cert.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}

name = each.value.name
type = each.value.type
zone_id = lookup(var.cert_subject_alternative_names, each.key, var.aws_route53_zone_id)
records = [each.value.record]
ttl = var.validation_record_ttl

allow_overwrite = true # Needed if making cert in multiple regions, and for AWS Provider 3.0 conversion
}

resource "aws_acm_certificate_validation" "cert" {
certificate_arn = aws_acm_certificate.cert.arn
validation_record_fqdns = [for record in aws_route53_record.cert_validation : record.fqdn]
}
71 changes: 71 additions & 0 deletions aws-acm-certificate/module_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package test

import (
"fmt"
"testing"

"github.com/chanzuckerberg/go-misc/tftest"
"github.com/gruntwork-io/terratest/modules/terraform"
)

func TestAWSACMCertificateInit(t *testing.T) {
options := &terraform.Options{
TerraformDir: ".",
}
terraform.Init(t, options)
}

func TestAWSACMCertificateDefaults(t *testing.T) {
t.Parallel()

test := tftest.Test{
Setup: func(t *testing.T) *terraform.Options {
certDomainName := fmt.Sprintf(
"%s.%s",
tftest.UniqueID(),
tftest.EnvVar(tftest.EnvRoute53ZoneName))

alternativeDomainName := fmt.Sprintf(
"%s.%s",
tftest.UniqueID(),
tftest.EnvVar(tftest.EnvRoute53ZoneName))

route53ZoneID := tftest.EnvVar(tftest.EnvRoute53ZoneID)

alternativeNames := map[string]string{
alternativeDomainName: route53ZoneID,
}

tags := map[string]string{
"project": tftest.UniqueID(),
"env": tftest.UniqueID(),
"service": tftest.UniqueID(),
"owner": tftest.UniqueID(),
"managedBy": "terraform",
}

vars := map[string]interface{}{
"cert_domain_name": certDomainName,
"aws_route53_zone_id": route53ZoneID,
"validation_record_ttl": 5,
"cert_subject_alternative_names": alternativeNames,
"tags": tags,
}

options := &terraform.Options{
TerraformDir: ".",

EnvVars: map[string]string{
"AWS_DEFAULT_REGION": tftest.DefaultRegion,
},

Vars: vars,
}

return options
},
Validate: func(t *testing.T, options *terraform.Options) {},
}

test.Run(t)
}
7 changes: 7 additions & 0 deletions aws-acm-certificate/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
output "arn" {
value = aws_acm_certificate.cert.arn
}

output "id" {
value = aws_acm_certificate.cert.id
}
6 changes: 6 additions & 0 deletions aws-acm-certificate/terraform.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
terraform {
required_providers {
# aws_acm_certificate changed API in 3.0.0
aws = ">= 3.0.0"
}
}
25 changes: 25 additions & 0 deletions aws-acm-certificate/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
variable "cert_domain_name" {
type = string
description = "Like www.foo.bar.com or *.foo.bar.com"
}

variable "cert_subject_alternative_names" {
type = map(string)
description = "A map of <alternative_domain:route53_zone_id>"
default = {}
}

variable "aws_route53_zone_id" {
type = string
}

variable "validation_record_ttl" {
type = string
default = 60
}

variable tags {
type = map(string)
description = "Tags to apply to certificate"
default = {}
}

0 comments on commit d230695

Please sign in to comment.