diff --git a/README.md b/README.md
index ae1aa42..5db1f76 100644
--- a/README.md
+++ b/README.md
@@ -25,6 +25,32 @@ module "acm" {
}
```
+## Usage with external DNS validation (e.g. CloudFlare)
+
+```hcl
+module "acm" {
+ source = "terraform-aws-modules/acm/aws"
+ version = "~> 3.0"
+
+ domain_name = "weekly.tf"
+ zone_id = "b7d259641bf30b89887c943ffc9d2138"
+
+ subject_alternative_names = [
+ "*.weekly.tf",
+ ]
+
+ create_route53_records = false
+ validation_record_fqdns = [
+ "_689571ee9a5f9ec307c512c5d851e25a.weekly.tf",
+ ]
+
+ tags = {
+ Name = "weekly.tf"
+ }
+}
+
+```
+
## [Usage with CloudFront](https://aws.amazon.com/premiumsupport/knowledge-center/install-ssl-cloudfront/)
```hcl
@@ -56,6 +82,7 @@ module "acm" {
## Examples
- [Complete example with DNS validation (recommended)](https://github.com/terraform-aws-modules/terraform-aws-acm/tree/master/examples/complete-dns-validation)
+- [Complete example with DNS validation via external DNS provider (CloudFlare)](https://github.com/terraform-aws-modules/terraform-aws-acm/tree/master/examples/complete-dns-validation-with-cloudflare)
- [Complete example with EMAIL validation](https://github.com/terraform-aws-modules/terraform-aws-acm/tree/master/examples/complete-email-validation)
## Conditional creation and validation
@@ -92,7 +119,7 @@ module "acm" {
| Name | Version |
|------|---------|
-| [terraform](#requirement\_terraform) | >= 0.12.26 |
+| [terraform](#requirement\_terraform) | >= 0.13.1 |
| [aws](#requirement\_aws) | >= 2.53 |
## Providers
@@ -119,6 +146,7 @@ No modules.
|------|-------------|------|---------|:--------:|
| [certificate\_transparency\_logging\_preference](#input\_certificate\_transparency\_logging\_preference) | Specifies whether certificate details should be added to a certificate transparency log | `bool` | `true` | no |
| [create\_certificate](#input\_create\_certificate) | Whether to create ACM certificate | `bool` | `true` | no |
+| [create\_route53\_records](#input\_create\_route53\_records) | When validation is set to DNS, define whether to create the DNS records internally via Route53 or externally using any DNS provider | `bool` | `true` | no |
| [dns\_ttl](#input\_dns\_ttl) | The TTL of DNS recursive resolvers to cache information about this record. | `number` | `60` | no |
| [domain\_name](#input\_domain\_name) | A domain name for which the certificate should be issued | `string` | `""` | no |
| [subject\_alternative\_names](#input\_subject\_alternative\_names) | A list of domains that should be SANs in the issued certificate | `list(string)` | `[]` | no |
@@ -126,8 +154,9 @@ No modules.
| [validate\_certificate](#input\_validate\_certificate) | Whether to validate certificate by creating Route53 record | `bool` | `true` | no |
| [validation\_allow\_overwrite\_records](#input\_validation\_allow\_overwrite\_records) | Whether to allow overwrite of Route53 records | `bool` | `true` | no |
| [validation\_method](#input\_validation\_method) | Which method to use for validation. DNS or EMAIL are valid, NONE can be used for certificates that were imported into ACM and then into Terraform. | `string` | `"DNS"` | no |
+| [validation\_record\_fqdns](#input\_validation\_record\_fqdns) | When validation is set to DNS and the DNS validation records are set externally, provide the fqdns for the validation | `list(string)` | `[]` | no |
| [wait\_for\_validation](#input\_wait\_for\_validation) | Whether to wait for the validation to complete | `bool` | `true` | no |
-| [zone\_id](#input\_zone\_id) | The ID of the hosted zone to contain this record. | `string` | `""` | no |
+| [zone\_id](#input\_zone\_id) | The ID of the hosted zone to contain this record. Required when validating via Route53 | `string` | `""` | no |
## Outputs
diff --git a/examples/complete-dns-validation-with-cloudflare/README.md b/examples/complete-dns-validation-with-cloudflare/README.md
new file mode 100644
index 0000000..b4ad585
--- /dev/null
+++ b/examples/complete-dns-validation-with-cloudflare/README.md
@@ -0,0 +1,63 @@
+# Complete ACM example with external CloudFlare DNS validation
+
+Configuration in this directory creates an ACM certificate (valid for the domain name and wildcard) while the DNS validation is done via an external DNS provider.
+
+For this example CloudFlare DNS is used but any DNS provider could be used instead.
+
+This is a complete example which fits most of scenarios.
+
+## Usage
+
+To run this example you need to execute:
+
+```bash
+$ terraform init
+$ terraform plan
+$ terraform apply
+```
+
+Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.
+
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 0.13.1 |
+| [aws](#requirement\_aws) | >= 2.53 |
+| [cloudflare](#requirement\_cloudflare) | >= 3.4.0 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [cloudflare](#provider\_cloudflare) | >= 3.4.0 |
+
+## Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [acm](#module\_acm) | ../../ | n/a |
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [cloudflare_record.validation](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/record) | resource |
+| [cloudflare_zone.this](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/data-sources/zone) | data source |
+
+## Inputs
+
+No inputs.
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [acm\_certificate\_arn](#output\_acm\_certificate\_arn) | The ARN of the certificate |
+| [acm\_certificate\_domain\_validation\_options](#output\_acm\_certificate\_domain\_validation\_options) | A list of attributes to feed into other resources to complete certificate validation. Can have more than one element, e.g. if SANs are defined. Only set if DNS-validation was used. |
+| [acm\_certificate\_validation\_emails](#output\_acm\_certificate\_validation\_emails) | A list of addresses that received a validation E-Mail. Only set if EMAIL-validation was used. |
+| [distinct\_domain\_names](#output\_distinct\_domain\_names) | List of distinct domains names used for the validation. |
+| [validation\_domains](#output\_validation\_domains) | List of distinct domain validation options. This is useful if subject alternative names contain wildcards. |
+| [validation\_route53\_record\_fqdns](#output\_validation\_route53\_record\_fqdns) | List of FQDNs built using the zone domain and name. |
+
diff --git a/examples/complete-dns-validation-with-cloudflare/main.tf b/examples/complete-dns-validation-with-cloudflare/main.tf
new file mode 100644
index 0000000..f99a154
--- /dev/null
+++ b/examples/complete-dns-validation-with-cloudflare/main.tf
@@ -0,0 +1,44 @@
+locals {
+ domain = "terraform-aws-modules.modules.tf"
+
+ # Removing trailing dot from domain - just to be sure :)
+ domain_name = trimsuffix(local.domain, ".")
+}
+
+module "acm" {
+ source = "../../"
+
+ domain_name = local.domain_name
+ zone_id = data.cloudflare_zone.this.id
+
+ subject_alternative_names = [
+ "*.alerts.${local.domain_name}",
+ "new.sub.${local.domain_name}",
+ "*.${local.domain_name}",
+ "alerts.${local.domain_name}",
+ ]
+
+ create_route53_records = false
+ validation_record_fqdns = cloudflare_record.validation.*.hostname
+
+ tags = {
+ Name = local.domain_name
+ }
+}
+
+resource "cloudflare_record" "validation" {
+ count = length(module.acm.distinct_domain_names)
+
+ zone_id = data.cloudflare_zone.this.id
+ name = element(module.acm.validation_domains, count.index)["resource_record_name"]
+ type = element(module.acm.validation_domains, count.index)["resource_record_type"]
+ value = replace(element(module.acm.validation_domains, count.index)["resource_record_value"], "/.$/", "")
+ ttl = 60
+ proxied = false
+
+ allow_overwrite = true
+}
+
+data "cloudflare_zone" "this" {
+ name = local.domain_name
+}
diff --git a/examples/complete-dns-validation-with-cloudflare/outputs.tf b/examples/complete-dns-validation-with-cloudflare/outputs.tf
new file mode 100644
index 0000000..1eb07eb
--- /dev/null
+++ b/examples/complete-dns-validation-with-cloudflare/outputs.tf
@@ -0,0 +1,29 @@
+output "acm_certificate_arn" {
+ description = "The ARN of the certificate"
+ value = module.acm.acm_certificate_arn
+}
+
+output "acm_certificate_domain_validation_options" {
+ description = "A list of attributes to feed into other resources to complete certificate validation. Can have more than one element, e.g. if SANs are defined. Only set if DNS-validation was used."
+ value = module.acm.acm_certificate_domain_validation_options
+}
+
+output "acm_certificate_validation_emails" {
+ description = "A list of addresses that received a validation E-Mail. Only set if EMAIL-validation was used."
+ value = module.acm.acm_certificate_validation_emails
+}
+
+output "validation_route53_record_fqdns" {
+ description = "List of FQDNs built using the zone domain and name."
+ value = module.acm.validation_route53_record_fqdns
+}
+
+output "distinct_domain_names" {
+ description = "List of distinct domains names used for the validation."
+ value = module.acm.distinct_domain_names
+}
+
+output "validation_domains" {
+ description = "List of distinct domain validation options. This is useful if subject alternative names contain wildcards."
+ value = module.acm.validation_domains
+}
diff --git a/examples/complete-dns-validation-with-cloudflare/variables.tf b/examples/complete-dns-validation-with-cloudflare/variables.tf
new file mode 100644
index 0000000..e69de29
diff --git a/examples/complete-dns-validation-with-cloudflare/versions.tf b/examples/complete-dns-validation-with-cloudflare/versions.tf
new file mode 100644
index 0000000..ec2f77a
--- /dev/null
+++ b/examples/complete-dns-validation-with-cloudflare/versions.tf
@@ -0,0 +1,14 @@
+terraform {
+ required_version = ">= 0.13.1"
+
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 2.53"
+ }
+ cloudflare = {
+ source = "cloudflare/cloudflare"
+ version = ">= 3.4.0"
+ }
+ }
+}
diff --git a/examples/complete-dns-validation/README.md b/examples/complete-dns-validation/README.md
index 60c2eb3..2abeae3 100644
--- a/examples/complete-dns-validation/README.md
+++ b/examples/complete-dns-validation/README.md
@@ -23,7 +23,7 @@ Note that this example may create resources which cost money. Run `terraform des
| Name | Version |
|------|---------|
-| [terraform](#requirement\_terraform) | >= 0.12.26 |
+| [terraform](#requirement\_terraform) | >= 0.13.1 |
| [aws](#requirement\_aws) | >= 2.53 |
## Providers
diff --git a/examples/complete-dns-validation/versions.tf b/examples/complete-dns-validation/versions.tf
index 67d15ec..25f85e5 100644
--- a/examples/complete-dns-validation/versions.tf
+++ b/examples/complete-dns-validation/versions.tf
@@ -1,5 +1,5 @@
terraform {
- required_version = ">= 0.12.26"
+ required_version = ">= 0.13.1"
required_providers {
aws = {
diff --git a/examples/complete-email-validation/README.md b/examples/complete-email-validation/README.md
index ee9823c..2ae55d5 100644
--- a/examples/complete-email-validation/README.md
+++ b/examples/complete-email-validation/README.md
@@ -36,7 +36,7 @@ Note that this example may create resources which cost money. Run `terraform des
| Name | Version |
|------|---------|
-| [terraform](#requirement\_terraform) | >= 0.12.26 |
+| [terraform](#requirement\_terraform) | >= 0.13.1 |
| [aws](#requirement\_aws) | >= 2.53 |
## Providers
diff --git a/examples/complete-email-validation/versions.tf b/examples/complete-email-validation/versions.tf
index 67d15ec..25f85e5 100644
--- a/examples/complete-email-validation/versions.tf
+++ b/examples/complete-email-validation/versions.tf
@@ -1,5 +1,5 @@
terraform {
- required_version = ">= 0.12.26"
+ required_version = ">= 0.13.1"
required_providers {
aws = {
diff --git a/main.tf b/main.tf
index 0adc774..3cf045b 100644
--- a/main.tf
+++ b/main.tf
@@ -32,7 +32,7 @@ resource "aws_acm_certificate" "this" {
}
resource "aws_route53_record" "validation" {
- count = var.create_certificate && var.validation_method == "DNS" && var.validate_certificate ? length(local.distinct_domain_names) : 0
+ count = var.create_certificate && var.validation_method == "DNS" && var.create_route53_records && var.validate_certificate ? length(local.distinct_domain_names) : 0
zone_id = var.zone_id
name = element(local.validation_domains, count.index)["resource_record_name"]
@@ -53,5 +53,5 @@ resource "aws_acm_certificate_validation" "this" {
certificate_arn = aws_acm_certificate.this[0].arn
- validation_record_fqdns = aws_route53_record.validation.*.fqdn
+ validation_record_fqdns = flatten([aws_route53_record.validation.*.fqdn, var.validation_record_fqdns])
}
diff --git a/variables.tf b/variables.tf
index 4a5c670..42c149a 100644
--- a/variables.tf
+++ b/variables.tf
@@ -44,10 +44,27 @@ variable "validation_method" {
description = "Which method to use for validation. DNS or EMAIL are valid, NONE can be used for certificates that were imported into ACM and then into Terraform."
type = string
default = "DNS"
+
+ validation {
+ condition = contains(["DNS", "EMAIL", "NONE"], var.validation_method)
+ error_message = "Valid values are DNS, EMAIL or NONE."
+ }
+}
+
+variable "create_route53_records" {
+ description = "When validation is set to DNS, define whether to create the DNS records internally via Route53 or externally using any DNS provider"
+ type = bool
+ default = true
+}
+
+variable "validation_record_fqdns" {
+ description = "When validation is set to DNS and the DNS validation records are set externally, provide the fqdns for the validation"
+ type = list(string)
+ default = []
}
variable "zone_id" {
- description = "The ID of the hosted zone to contain this record."
+ description = "The ID of the hosted zone to contain this record. Required when validating via Route53"
type = string
default = ""
}
diff --git a/versions.tf b/versions.tf
index 67d15ec..25f85e5 100644
--- a/versions.tf
+++ b/versions.tf
@@ -1,5 +1,5 @@
terraform {
- required_version = ">= 0.12.26"
+ required_version = ">= 0.13.1"
required_providers {
aws = {