feat(net): custom domain for the Fusion-facing API
Fusion couldn't resolve the default *.execute-api.amazonaws.com endpoint, so front the same HTTP API with hncb-deid.apim-apac-demo.com (ACM DNS-validated cert, apigatewayv2 REGIONAL custom domain, root api mapping, Route53 A ALIAS). Callers resolve our hostname straight to IPs and never touch an execute-api name; also survives API-id churn. Point POLICY_SETUP + README demo at the custom URLs. Verified live: resolves to IPs, 401 unauthenticated, tokenizes with the key. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
80
terraform/custom_domain.tf
Normal file
80
terraform/custom_domain.tf
Normal file
@@ -0,0 +1,80 @@
|
||||
# ---------------------------------------------------------------------------
|
||||
# Custom domain for the Fusion-facing API. Fusion couldn't resolve the default
|
||||
# *.execute-api.amazonaws.com hostname, so we front the same HTTP API with a
|
||||
# stable name in a zone we control and point it with a Route53 ALIAS (A record).
|
||||
# Callers resolve hncb-deid.apim-apac-demo.com -> IPs directly; they never have to
|
||||
# resolve an execute-api / amazonaws.com name. Also survives API-id churn.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
locals {
|
||||
api_fqdn = "hncb-deid.apim-apac-demo.com"
|
||||
}
|
||||
|
||||
data "aws_route53_zone" "api" {
|
||||
name = "apim-apac-demo.com"
|
||||
private_zone = false
|
||||
}
|
||||
|
||||
# Regional API Gateway custom domains need the ACM cert in the SAME region.
|
||||
resource "aws_acm_certificate" "api" {
|
||||
domain_name = local.api_fqdn
|
||||
validation_method = "DNS"
|
||||
tags = local.onprem_tag
|
||||
lifecycle {
|
||||
create_before_destroy = true
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_route53_record" "api_cert_validation" {
|
||||
for_each = {
|
||||
for dvo in aws_acm_certificate.api.domain_validation_options : dvo.domain_name => {
|
||||
name = dvo.resource_record_name
|
||||
type = dvo.resource_record_type
|
||||
record = dvo.resource_record_value
|
||||
}
|
||||
}
|
||||
zone_id = data.aws_route53_zone.api.zone_id
|
||||
name = each.value.name
|
||||
type = each.value.type
|
||||
records = [each.value.record]
|
||||
ttl = 60
|
||||
allow_overwrite = true
|
||||
}
|
||||
|
||||
resource "aws_acm_certificate_validation" "api" {
|
||||
certificate_arn = aws_acm_certificate.api.arn
|
||||
validation_record_fqdns = [for r in aws_route53_record.api_cert_validation : r.fqdn]
|
||||
}
|
||||
|
||||
resource "aws_apigatewayv2_domain_name" "api" {
|
||||
domain_name = local.api_fqdn
|
||||
domain_name_configuration {
|
||||
certificate_arn = aws_acm_certificate_validation.api.certificate_arn
|
||||
endpoint_type = "REGIONAL"
|
||||
security_policy = "TLS_1_2"
|
||||
}
|
||||
tags = local.onprem_tag
|
||||
}
|
||||
|
||||
# Map the custom domain at the root to the $default stage (routes: /tokenize, etc.)
|
||||
resource "aws_apigatewayv2_api_mapping" "api" {
|
||||
api_id = aws_apigatewayv2_api.gateway.id
|
||||
domain_name = aws_apigatewayv2_domain_name.api.id
|
||||
stage = aws_apigatewayv2_stage.default.id
|
||||
}
|
||||
|
||||
# ALIAS (IPv4) -> returns IPs directly, so Fusion never resolves an AWS hostname.
|
||||
resource "aws_route53_record" "api_alias" {
|
||||
zone_id = data.aws_route53_zone.api.zone_id
|
||||
name = local.api_fqdn
|
||||
type = "A"
|
||||
alias {
|
||||
name = aws_apigatewayv2_domain_name.api.domain_name_configuration[0].target_domain_name
|
||||
zone_id = aws_apigatewayv2_domain_name.api.domain_name_configuration[0].hosted_zone_id
|
||||
evaluate_target_health = false
|
||||
}
|
||||
}
|
||||
|
||||
output "tokenize_url_custom" { value = "https://${local.api_fqdn}/tokenize" }
|
||||
output "restore_url_custom" { value = "https://${local.api_fqdn}/restore" }
|
||||
output "demo_url_custom" { value = "https://${local.api_fqdn}/demo" }
|
||||
Reference in New Issue
Block a user