diff --git a/terraform/modules/acm_certificate/README.md b/terraform/modules/acm_certificate/README.md new file mode 100644 index 00000000..504a3d6b --- /dev/null +++ b/terraform/modules/acm_certificate/README.md @@ -0,0 +1,89 @@ + + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 5.0 | +| [tls](#provider\_tls) | >= 4.0 | + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.6.0 | +| [aws](#requirement\_aws) | >= 5.0 | +| [tls](#requirement\_tls) | >= 4.0 | + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [platform](#input\_platform) | Object representing the CDAP platform module. |
object({
app = string
env = string
primary_region = object({ name = string })
service = string
kms_alias_primary = object({
target_key_arn = string
})
})
| n/a | yes | +| [enable\_internal\_endpoint](#input\_enable\_internal\_endpoint) | Issue a PCA-backed certificate for the VPC-internal endpoint.
Domain: --.internal
Use for Lambda/ECS-to-ECS calls that do not need Zscaler or public access.
Route 53 is NOT managed here — DNS for .internal is handled by CMS. | `bool` | `false` | no | +| [enable\_zscaler\_endpoint](#input\_enable\_zscaler\_endpoint) | Issue a PCA-backed certificate for the Zscaler-accessible endpoint.
Domain: --.cmscloud.local
Route 53 is NOT managed here — DNS for cmscloud.local is handled by CMS.

-------------------------------------------------------------------------
CMS DOMAIN REGISTRATION — ACTION REQUIRED AFTER APPLY
-------------------------------------------------------------------------
After applying this module, submit a request to CMS to register:
--.cmscloud.local
and point it at the ALB DNS name from the alb module output.
Use the zscaler\_domain output from this module for the request.
------------------------------------------------------------------------- | `bool` | `false` | no | +| [pca\_ram\_resource\_share\_name](#input\_pca\_ram\_resource\_share\_name) | Name of the AWS RAM resource share providing access to the shared Private CA. Required when enable\_internal\_endpoint or enable\_zscaler\_endpoint is true. | `string` | `"pace-ca-g1"` | no | +| [public\_certificate](#input\_public\_certificate) | PEM-encoded CMS-signed public certificate. Include via SOPS if provided by CMS. Set null to defer import while awaiting CMS signing. | `string` | `null` | no | +| [public\_certificate\_chain](#input\_public\_certificate\_chain) | PEM-encoded certificate chain. Optional — include via SOPS if provided by CMS with the signed certificate. | `string` | `null` | no | +| [public\_certificate\_versions](#input\_public\_certificate\_versions) | Set of active certificate versions. Add a new version number to generate a new
key and CSR for renewal without deleting the previous version's parameters.
Example: [1] → initial; [1, 2] → renewal in progress; [2] → old version cleaned up. | `set(number)` |
[
1
]
| no | +| [public\_domain\_name](#input\_public\_domain\_name) | Domain name for the public endpoint. Must end in .cms.gov.
-------------------------------------------------------------------------
PUBLIC CERTIFICATE PROCESS — ACTION REQUIRED BEFORE CERT IS ACTIVE
-------------------------------------------------------------------------
1. Run this module once without public\_certificate or public\_private\_key defined.
2. Follow output instructions to provide CMS with CSR in a zip file.
3. Once returned from CMS signed, encrypt the certificate, private key, and chain via SOPS.
4. Pass the sensitive values via SOPS into public\_certificate, public\_private\_key,
and public\_certificate\_chain at module instantiation.
5. Re-apply — the module imports the cert into ACM automatically. | `string` | `null` | no | +| [public\_private\_key](#input\_public\_private\_key) | PEM-encoded private key for the public certificate. Include via SOPS if provided by CMS. Set null to defer. | `string` | `null` | no | + + +## Modules + +No modules. + + +## Resources + +| Name | Type | +|------|------| +| [aws_acm_certificate.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate) | resource | +| [aws_acm_certificate.public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate) | resource | +| [aws_acm_certificate_validation.private](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate_validation) | resource | +| [aws_ssm_parameter.csr](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter) | resource | +| [aws_ssm_parameter.private_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter) | resource | +| [tls_cert_request.this](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/cert_request) | resource | +| [tls_private_key.this](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/private_key) | resource | +| [aws_ram_resource_share.pace_ca](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ram_resource_share) | data source | +| [aws_route53_zone.internal](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source | +| [aws_route53_zone.zscaler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source | + + +## Outputs + +| Name | Description | +|------|-------------| +| [csr\_retrieval\_instructions](#output\_csr\_retrieval\_instructions) | Instructions for retrieving the latest CSR and submitting to CMS. | +| [internal\_domain](#output\_internal\_domain) | n/a | +| [private\_certificate\_arn](#output\_private\_certificate\_arn) | ARN of the PCA-issued certificate covering the internal and/or zscaler domains. Use as the primary cert on the ALB HTTPS listener. | +| [public\_certificate\_arn](#output\_public\_certificate\_arn) | ARN of the imported CMS-signed public certificate. Null if cert values have not yet been provided. | +| [zscaler\_domain](#output\_zscaler\_domain) | n/a | + \ No newline at end of file diff --git a/terraform/modules/acm_certificate/data.tf b/terraform/modules/acm_certificate/data.tf new file mode 100644 index 00000000..5c5e3ec3 --- /dev/null +++ b/terraform/modules/acm_certificate/data.tf @@ -0,0 +1,22 @@ +locals { + hosted_zone_base_internal = "${var.platform.env}.${var.platform.app}.cmscloud.internal" + hosted_zone_base_zscaler = "${var.platform.env}.${var.platform.app}.cmscloud.local" +} + +data "aws_ram_resource_share" "pace_ca" { + count = (var.enable_internal_endpoint || var.enable_zscaler_endpoint) ? 1 : 0 + resource_owner = "OTHER-ACCOUNTS" + name = var.pca_ram_resource_share_name +} + +data "aws_route53_zone" "internal" { + count = var.enable_internal_endpoint ? 1 : 0 + name = local.hosted_zone_base_internal + private_zone = true +} + +data "aws_route53_zone" "zscaler" { + count = var.enable_zscaler_endpoint ? 1 : 0 + name = local.hosted_zone_base_zscaler + private_zone = true +} diff --git a/terraform/modules/acm_certificate/main.tf b/terraform/modules/acm_certificate/main.tf new file mode 100644 index 00000000..aa6735d6 --- /dev/null +++ b/terraform/modules/acm_certificate/main.tf @@ -0,0 +1,116 @@ +locals { + internal_domain = var.enable_internal_endpoint ? "${var.platform.service}.${trimsuffix(data.aws_route53_zone.internal[0].name, ".")}" : null + zscaler_domain = var.enable_zscaler_endpoint ? "${var.platform.service}.${trimsuffix(data.aws_route53_zone.zscaler[0].name, ".")}" : null + + private_primary_domain = ( + var.enable_internal_endpoint ? local.internal_domain : + var.enable_zscaler_endpoint ? local.zscaler_domain : + null + ) + + private_subject_alternative_names = ( + var.enable_internal_endpoint && var.enable_zscaler_endpoint + ) ? [local.zscaler_domain] : [] +} + +# ------------------------------------------------------- +# PRIVATE: Issue from AWS Private CA +# ------------------------------------------------------- +resource "aws_acm_certificate" "private" { + count = (var.enable_internal_endpoint || var.enable_zscaler_endpoint) ? 1 : 0 + + certificate_authority_arn = one(data.aws_ram_resource_share.pace_ca[0].resource_arns) + domain_name = local.private_primary_domain + subject_alternative_names = local.private_subject_alternative_names + + tags = { Name = "${local.private_primary_domain}-private-cert" } + + lifecycle { + prevent_destroy = true + create_before_destroy = true + } +} + +# ------------------------------------------------------- +# PUBLIC PATH: Import CMS-signed cert (developer note: use SOPS encrypted values) +# ------------------------------------------------------- + +resource "tls_private_key" "this" { + for_each = var.public_domain_name != null ? toset([for v in var.public_certificate_versions : tostring(v)]) : toset([]) + algorithm = "RSA" + rsa_bits = 4096 +} + +resource "tls_cert_request" "this" { + for_each = var.public_domain_name != null ? toset([for v in var.public_certificate_versions : tostring(v)]) : toset([]) + private_key_pem = tls_private_key.this[each.key].private_key_pem + + subject { + country = "US" + province = "MD" + locality = "Rockville" + organization = "US Dept of Health and Human Services" + organizational_unit = "Centers for Medicare and Medicaid Services" + common_name = var.public_domain_name + } +} + +# ------------------------------------------------------- +# Store private key in SSM — encrypted with platform KMS key +# ------------------------------------------------------- + +resource "aws_ssm_parameter" "private_key" { + for_each = var.public_domain_name != null ? toset([for v in var.public_certificate_versions : tostring(v)]) : toset([]) + + name = "/${var.platform.app}/${var.platform.env}/${var.platform.service}/tls/v${each.key}/private-key" + type = "SecureString" + value = tls_private_key.this[each.key].private_key_pem + key_id = var.platform.kms_alias_primary.target_key_arn + + tags = { Name = "${var.public_domain_name}-private-key" } + + lifecycle { + # Prevent Terraform from overwriting the key if it already exists. + # The private key must remain stable — replacing it may invalidate signed certs. + ignore_changes = [value] + } +} + +# ------------------------------------------------------- +# Store CSR in SSM — plaintext is fine, CSRs are not sensitive +# Developers can retrieve this value and submit it to CMS for signing. +# ------------------------------------------------------- + +resource "aws_ssm_parameter" "csr" { + for_each = var.public_domain_name != null ? toset([for v in var.public_certificate_versions : tostring(v)]) : toset([]) + + name = "/${var.platform.app}/${var.platform.env}/${var.platform.service}/tls/v${each.key}/csr" + description = "Certificate Signing Request for ${var.public_domain_name}. Submit this to CMS for signing." + type = "String" + value = tls_cert_request.this[each.key].cert_request_pem + + lifecycle { + ignore_changes = [value] + } +} + + +# Once cert information is provided via SOPS path, this will be set +resource "aws_acm_certificate" "public" { + count = ( + var.public_domain_name != null && + var.public_certificate != null && + var.public_private_key != null + ) ? 1 : 0 + + certificate_body = var.public_certificate + private_key = var.public_private_key + certificate_chain = var.public_certificate_chain + + tags = { Name = var.public_domain_name } + + lifecycle { + prevent_destroy = true + create_before_destroy = true + } +} diff --git a/terraform/modules/acm_certificate/outputs.tf b/terraform/modules/acm_certificate/outputs.tf new file mode 100644 index 00000000..5e4d8a1b --- /dev/null +++ b/terraform/modules/acm_certificate/outputs.tf @@ -0,0 +1,44 @@ +locals { + _latest_cert_version = var.public_domain_name != null ? max(var.public_certificate_versions...) : null + + csr_instructions = var.public_domain_name != null ? join("\n", [ + "Latest CSR version: ${local._latest_cert_version}", + "", + "SSM path:", + " /${var.platform.app}/${var.platform.env}/${var.platform.service}/tls/v${local._latest_cert_version}/csr", + "", + "To retrieve and zip for CMS submission:", + " aws ssm get-parameter \\", + " --name \"/${var.platform.app}/${var.platform.env}/${var.platform.service}/tls/v${local._latest_cert_version}/csr\" \\", + " --query \"Parameter.Value\" \\", + " --output text > ${var.public_domain_name}.csr", + " zip ${var.public_domain_name}-v${local._latest_cert_version}-csr.zip ${var.public_domain_name}.csr", + "", + "After CMS signs the certificate, store the values via SOPS and re-apply.", + ]) : null +} + +output "private_certificate_arn" { + description = "ARN of the PCA-issued certificate covering the internal and/or zscaler domains. Use as the primary cert on the ALB HTTPS listener." + value = (var.enable_internal_endpoint || var.enable_zscaler_endpoint) ? aws_acm_certificate.private[0].arn : null + sensitive = true +} + +output "internal_domain" { + value = var.enable_internal_endpoint ? local.internal_domain : null +} + +output "zscaler_domain" { + value = var.enable_zscaler_endpoint ? local.zscaler_domain : null +} + +output "public_certificate_arn" { + description = "ARN of the imported CMS-signed public certificate. Null if cert values have not yet been provided." + value = (var.public_domain_name != null && var.public_certificate != null && var.public_private_key != null) ? aws_acm_certificate.public[0].arn : null + sensitive = true +} + +output "csr_retrieval_instructions" { + description = "Instructions for retrieving the latest CSR and submitting to CMS." + value = local.csr_instructions +} diff --git a/terraform/modules/acm_certificate/variables.tf b/terraform/modules/acm_certificate/variables.tf new file mode 100644 index 00000000..7a64f5d4 --- /dev/null +++ b/terraform/modules/acm_certificate/variables.tf @@ -0,0 +1,113 @@ +variable "platform" { + description = "Object representing the CDAP platform module." + type = object({ + app = string + env = string + primary_region = object({ name = string }) + service = string + kms_alias_primary = object({ + target_key_arn = string + }) + }) +} + +# ------------------------------------------------------- +# Internal endpoint (VPC-only, cmscloud.internal) +# ------------------------------------------------------- +variable "enable_internal_endpoint" { + type = bool + default = false + description = <<-EOT + Issue a PCA-backed certificate for the VPC-internal endpoint. + Domain: --.internal + Use for Lambda/ECS-to-ECS calls that do not need Zscaler or public access. + Route 53 is NOT managed here — DNS for .internal is handled by CMS. + EOT +} + +# ------------------------------------------------------- +# Zscaler endpoint (cmscloud.local) +# ------------------------------------------------------- +variable "enable_zscaler_endpoint" { + type = bool + default = false + description = <<-EOT + Issue a PCA-backed certificate for the Zscaler-accessible endpoint. + Domain: --.cmscloud.local + Route 53 is NOT managed here — DNS for cmscloud.local is handled by CMS. + + ------------------------------------------------------------------------- + CMS DOMAIN REGISTRATION — ACTION REQUIRED AFTER APPLY + ------------------------------------------------------------------------- + After applying this module, submit a request to CMS to register: + --.cmscloud.local + and point it at the ALB DNS name from the alb module output. + Use the zscaler_domain output from this module for the request. + ------------------------------------------------------------------------- + EOT +} + +# ------------------------------------------------------- +# Public endpoint (*.cms.gov) +# ------------------------------------------------------- + +variable "public_certificate_versions" { + type = set(number) + default = [1] + description = <<-EOT + Set of active certificate versions. Add a new version number to generate a new + key and CSR for renewal without deleting the previous version's parameters. + Example: [1] → initial; [1, 2] → renewal in progress; [2] → old version cleaned up. + EOT +} + +variable "public_domain_name" { + type = string + default = null + description = <<-EOT + Domain name for the public endpoint. Must end in .cms.gov. + ------------------------------------------------------------------------- + PUBLIC CERTIFICATE PROCESS — ACTION REQUIRED BEFORE CERT IS ACTIVE + ------------------------------------------------------------------------- + 1. Run this module once without public_certificate or public_private_key defined. + 2. Follow output instructions to provide CMS with CSR in a zip file. + 3. Once returned from CMS signed, encrypt the certificate, private key, and chain via SOPS. + 4. Pass the sensitive values via SOPS into public_certificate, public_private_key, + and public_certificate_chain at module instantiation. + 5. Re-apply — the module imports the cert into ACM automatically. + + EOT + validation { + condition = var.public_domain_name == null || endswith(var.public_domain_name, ".cms.gov") + error_message = "public_domain_name must end in .cms.gov." + } +} + +# Cert values passed in directly — populated from platform module SOPS outputs at instantiation. +# Set to null to defer cert creation while awaiting CMS issuance. +variable "public_certificate" { + type = string + default = null + sensitive = true + description = "PEM-encoded CMS-signed public certificate. Include via SOPS if provided by CMS. Set null to defer import while awaiting CMS signing." +} + +variable "public_private_key" { + type = string + default = null + sensitive = true + description = "PEM-encoded private key for the public certificate. Include via SOPS if provided by CMS. Set null to defer." +} + +variable "public_certificate_chain" { + type = string + default = null + sensitive = true + description = "PEM-encoded certificate chain. Optional — include via SOPS if provided by CMS with the signed certificate." +} + +variable "pca_ram_resource_share_name" { + type = string + default = "pace-ca-g1" + description = "Name of the AWS RAM resource share providing access to the shared Private CA. Required when enable_internal_endpoint or enable_zscaler_endpoint is true." +} diff --git a/terraform/modules/acm_certificate/versions.tf b/terraform/modules/acm_certificate/versions.tf new file mode 100644 index 00000000..0728cbb5 --- /dev/null +++ b/terraform/modules/acm_certificate/versions.tf @@ -0,0 +1,14 @@ +terraform { + required_version = ">= 1.6.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0" + } + tls = { + source = "hashicorp/tls" + version = ">= 4.0" + } + } +} diff --git a/terraform/modules/platform/variables.tf b/terraform/modules/platform/variables.tf index c1acd7f2..1f1f812d 100644 --- a/terraform/modules/platform/variables.tf +++ b/terraform/modules/platform/variables.tf @@ -2,7 +2,7 @@ variable "app" { description = "The short name for the delivery team or ADO." type = string validation { - condition = contains(["ab2d", "bcda", "dpc"], var.app) + condition = contains(["ab2d", "bcda", "dpc", "cdap"], var.app) error_message = "Invalid short var.app (application). Must be one of ab2d, bcda, or dpc." } } diff --git a/terraform/services/github-actions-role/main.tf b/terraform/services/github-actions-role/main.tf index 36c6b343..3ebbe950 100644 --- a/terraform/services/github-actions-role/main.tf +++ b/terraform/services/github-actions-role/main.tf @@ -431,7 +431,8 @@ data "aws_iam_policy_document" "github_actions_policy" { "route53:GetChange", "route53:GetHostedZone", "route53:ListHostedZones", - "route53:ListResourceRecordSets" + "route53:ListResourceRecordSets", + "route53:ListTagsForResource" ] resources = ["*"] } diff --git a/terraform/services/hosted_zones/README.md b/terraform/services/hosted_zones/README.md new file mode 100644 index 00000000..4fcb44e3 --- /dev/null +++ b/terraform/services/hosted_zones/README.md @@ -0,0 +1,73 @@ + + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | 5.100.0 | + + +## Requirements + +No requirements. + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [app](#input\_app) | The application name (ab2d, bcda, dpc, cdap) | `string` | n/a | yes | +| [env](#input\_env) | The application environment (dev, test, mgmt, sbx, sandbox, prod) | `string` | n/a | yes | + + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [platform](#module\_platform) | ../../modules/platform | n/a | + + +## Resources + +| Name | Type | +|------|------| +| [aws_route53_zone.internal](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone) | resource | +| [aws_route53_zone.zscaler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone) | resource | + + +## Outputs + +| Name | Description | +|------|-------------| +| [cms\_dns\_registration\_instructions](#output\_cms\_dns\_registration\_instructions) | Rendered instructions for registering this hosted zone with CMS DNS/networking. | +| [internal\_hosted\_zone\_id](#output\_internal\_hosted\_zone\_id) | The Route53 Hosted Zone ID that allows developer access. Provide this to CMS DNS/networking team for zone delegation or discovery registration. | +| [internal\_hosted\_zone\_name](#output\_internal\_hosted\_zone\_name) | The fully qualified domain name of the hosted zone accessible by VPC only. | +| [internal\_hosted\_zone\_name\_servers](#output\_internal\_hosted\_zone\_name\_servers) | Name servers assigned to this hosted zone by Route53. | +| [zscaler\_hosted\_zone\_id](#output\_zscaler\_hosted\_zone\_id) | The Route53 Hosted Zone ID that allows developer access. Provide this to CMS DNS/networking team for zone delegation or discovery registration. | +| [zscaler\_hosted\_zone\_name](#output\_zscaler\_hosted\_zone\_name) | The fully qualified domain name of the zscaler-friendly hosted zone. | +| [zscaler\_hosted\_zone\_name\_servers](#output\_zscaler\_hosted\_zone\_name\_servers) | Name servers assigned to this hosted zone by Route53. Required for public zone NS delegation — provide these to the CMS DNS team. | + \ No newline at end of file diff --git a/terraform/services/hosted_zones/conf.sh b/terraform/services/hosted_zones/conf.sh new file mode 100644 index 00000000..6e81d649 --- /dev/null +++ b/terraform/services/hosted_zones/conf.sh @@ -0,0 +1 @@ +TARGET_ENVS="cdap-test" diff --git a/terraform/services/hosted_zones/main.tf b/terraform/services/hosted_zones/main.tf new file mode 100644 index 00000000..7f892e6f --- /dev/null +++ b/terraform/services/hosted_zones/main.tf @@ -0,0 +1,25 @@ +module "platform" { + providers = { aws = aws, aws.secondary = aws.secondary } + + source = "../../modules/platform" + app = var.app + env = var.env + root_module = "https://github.com/CMSgov/cdap/tree/main/terraform/services/hosted-zones" + service = "hosted-zones" +} + +resource "aws_route53_zone" "internal" { + name = "${var.env}.${var.app}.cmscloud.internal" + + vpc { + vpc_id = module.platform.vpc_id + } +} + +resource "aws_route53_zone" "zscaler" { + name = "${var.env}.${var.app}.cmscloud.local" + + vpc { + vpc_id = module.platform.vpc_id + } +} diff --git a/terraform/services/hosted_zones/outputs.tf b/terraform/services/hosted_zones/outputs.tf new file mode 100644 index 00000000..ff63baa9 --- /dev/null +++ b/terraform/services/hosted_zones/outputs.tf @@ -0,0 +1,58 @@ +locals { + zscaler_hosted_zone_instructions = <<-EOT + ============================================================ + *** ACTION REQUIRED — CMS DNS Registration *** + ============================================================ + Zone Name : ${aws_route53_zone.zscaler.name} + Zone ID : ${aws_route53_zone.zscaler.zone_id} + Name Servers : ${join(", ", aws_route53_zone.zscaler.name_servers)} + ============================================================ + + For hosted zones that allow access via Zscaler, you must coordinate with the CMS DNS/networking + team to register this zone. Provide them with: + + 1. The information above + 2. The AWS Account ID and region where the zone is managed + 3. The intended use to be Zscaler resolution of internal endpoints. + + Upon completion, verify the Zscaler VPC association + has been completed on the hosted zone configuration and that the Zscaler team has validated DNS forwarding + for this zone's domain suffix. + ============================================================ + EOT +} + +output "zscaler_hosted_zone_id" { + description = "The Route53 Hosted Zone ID that allows developer access. Provide this to CMS DNS/networking team for zone delegation or discovery registration." + value = aws_route53_zone.zscaler.zone_id +} + +output "zscaler_hosted_zone_name" { + description = "The fully qualified domain name of the zscaler-friendly hosted zone." + value = aws_route53_zone.zscaler.name +} + +output "zscaler_hosted_zone_name_servers" { + description = "Name servers assigned to this hosted zone by Route53. Required for public zone NS delegation — provide these to the CMS DNS team." + value = aws_route53_zone.zscaler.name_servers +} + +output "cms_dns_registration_instructions" { + description = "Rendered instructions for registering this hosted zone with CMS DNS/networking." + value = local.zscaler_hosted_zone_instructions +} + +output "internal_hosted_zone_id" { + description = "The Route53 Hosted Zone ID that allows developer access. Provide this to CMS DNS/networking team for zone delegation or discovery registration." + value = aws_route53_zone.internal.zone_id +} + +output "internal_hosted_zone_name" { + description = "The fully qualified domain name of the hosted zone accessible by VPC only." + value = aws_route53_zone.internal.name +} + +output "internal_hosted_zone_name_servers" { + description = "Name servers assigned to this hosted zone by Route53." + value = aws_route53_zone.internal.name_servers +} diff --git a/terraform/services/hosted_zones/tofu.tf b/terraform/services/hosted_zones/tofu.tf new file mode 100644 index 00000000..087183da --- /dev/null +++ b/terraform/services/hosted_zones/tofu.tf @@ -0,0 +1,20 @@ +provider "aws" { + region = "us-east-1" + default_tags { + tags = module.platform.default_tags + } +} + +provider "aws" { + alias = "secondary" + region = "us-west-2" + default_tags { + tags = module.platform.default_tags + } +} + +terraform { + backend "s3" { + key = "hosted_zones/terraform.tfstate" + } +} diff --git a/terraform/services/hosted_zones/variables.tf b/terraform/services/hosted_zones/variables.tf new file mode 100644 index 00000000..336758ac --- /dev/null +++ b/terraform/services/hosted_zones/variables.tf @@ -0,0 +1,17 @@ +variable "app" { + description = "The application name (ab2d, bcda, dpc, cdap)" + type = string + validation { + condition = contains(["ab2d", "bcda", "dpc", "cdap"], var.app) + error_message = "Valid value for app is ab2d, bcda, dpc, or cdap." + } +} + +variable "env" { + description = "The application environment (dev, test, mgmt, sbx, sandbox, prod)" + type = string + validation { + condition = contains(["dev", "test", "mgmt", "sbx", "sandbox", "prod"], var.env) + error_message = "Valid value for env is dev, test, mgmt, sbx, sandbox, or prod." + } +} diff --git a/terraform/services/tftesting/acm_certificate/README.md b/terraform/services/tftesting/acm_certificate/README.md new file mode 100644 index 00000000..9237edfd --- /dev/null +++ b/terraform/services/tftesting/acm_certificate/README.md @@ -0,0 +1 @@ +This service is used when evaluating the acm_certificate module. Destroy all resources upon completion of relevant ticket. \ No newline at end of file diff --git a/terraform/services/tftesting/acm_certificate/main.tf b/terraform/services/tftesting/acm_certificate/main.tf new file mode 100644 index 00000000..4ad496eb --- /dev/null +++ b/terraform/services/tftesting/acm_certificate/main.tf @@ -0,0 +1,23 @@ +module "platform" { + providers = { aws = aws, aws.secondary = aws.secondary } + + source = "../../../modules/platform" + app = "cdap" + env = "test" + root_module = "https://github.com/CMSgov/cdap/tree/main/terraform/services/tftesting/acm_certificate" + service = "tf-test-acm-certificate" +} + +module "private_acm_certificate" { + source = "../../../modules/acm_certificate" + platform = module.platform + enable_internal_endpoint = true + enable_zscaler_endpoint = true +} + +module "public_acm_certificate" { + source = "../../../modules/acm_certificate" + platform = module.platform + public_domain_name = "tftesting-acm-certificate.cdap.cms.gov" +} + diff --git a/terraform/services/tftesting/acm_certificate/tofu.tf b/terraform/services/tftesting/acm_certificate/tofu.tf new file mode 100644 index 00000000..9834ea58 --- /dev/null +++ b/terraform/services/tftesting/acm_certificate/tofu.tf @@ -0,0 +1,20 @@ +provider "aws" { + region = "us-east-1" + default_tags { + tags = module.platform.default_tags + } +} + +provider "aws" { + alias = "secondary" + region = "us-west-2" + default_tags { + tags = module.platform.default_tags + } +} + +terraform { + backend "s3" { + key = "tftesting/acm_certificate/terraform.tfstate" + } +} diff --git a/terraform/services/tftesting/acm_certificate/variables.tf b/terraform/services/tftesting/acm_certificate/variables.tf new file mode 100644 index 00000000..e69de29b