fix(nginx_gateway_fabric_aws): auto-issue ACM cert for base domain in acm_mode#376
Open
sanmesh-kakade wants to merge 1 commit into
Open
fix(nginx_gateway_fabric_aws): auto-issue ACM cert for base domain in acm_mode#376sanmesh-kakade wants to merge 1 commit into
sanmesh-kakade wants to merge 1 commit into
Conversation
… acm_mode In acm_mode (an ACM ARN is supplied as a domain's certificate_reference and no ACK ACM controller is present), TLS terminates at the NLB and cert-manager is disabled (external_tls_termination=true). The base domain carries no certificate_reference, so it contributed no ARN to the aws-load-balancer-ssl-cert annotation. Base-domain HTTPS then fell back to the NLB default certificate and failed hostname validation unless a user-supplied ACM cert happened to SAN it. Port the base-domain ACM handling from the capillary flavour: when acm_mode is active and the base domain is enabled on AWS, issue an ACM certificate covering base_domain + *.base_domain, DNS-validate it via the tooling-account Route53 zone, and append its validated ARN to local.acm_cert_arns so it always lands in the ssl-cert annotation. base_domain is computed in this wrapper from the same control-plane metadata the base module uses (data.external.cc_env), rather than the base module's output, to avoid a cycle (base_domain -> ssl-cert annotation -> base module input). Provider split matches capillary: the certificate is issued in the default aws provider (workload account/region, where the NLB lives) while its DNS validation records are written via aws3tooling (tooling-account Route53 zone). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
In acm_mode — an ACM ARN is supplied as a domain's
certificate_referenceand no ACK ACM controller is present — TLS terminates at the NLB and the wrapper setsexternal_tls_termination=true, which disables cert-manager in the base module.The base domain carries no
certificate_reference, so it contributed no ARN to theservice.beta.kubernetes.io/aws-load-balancer-ssl-certannotation. Result: base-domain HTTPS fell back to the NLB default certificate (first ARN in the list) and failed hostname validation unless a user-supplied ACM cert coincidentally SAN'd the base domain.Two independent code paths caused it:
certmanager_managed_domains = var.external_tls_termination ? {} : {...}(base module) → cert-manager issues nothing in acm_mode.acm_cert_arnsonly scannedspec.domains(user overrides). The base domain is injected inside the base module, so the wrapper never saw it.Fix
Port the base-domain ACM handling from the capillary flavour (
Facets-cloud/ingress-migration@init/nginx_gateway_fabric_capillary). Whenacm_modeis active and the base domain is enabled on AWS:base_domain+*.base_domain(DNS validation).local.acm_cert_arns→ always lands in thessl-certannotation.base_domainis derived in the wrapper from the same control-plane metadata the base module uses (data.external.cc_env), not the base module's output — this avoids a dependency cycle (base_domain→ ssl-cert annotation → base module input).Provider split (cross-account) — reviewer note
Matches capillary:
aws_acm_certificate/aws_acm_certificate_validation→ defaultawsprovider (workload account + region; an ACM cert attached to an NLB must be in the same account/region as the NLB).aws_route53_record(DNS validation) +data.aws_route53_zone→aws3tooling(tooling-account Route53 zone).Both providers are injected at deploy time by the iac-generator (same as
nginx_k8sand the base module) — norequired_providersin module source, per repo convention (facets_default_providers).Guards
acm_mode == true,disable_base_domain != true, andtenant_provider == "aws".acm_modeis false, the base domain keeps using cert-manager (unchanged).disable_base_domain = true→ zero base-ACM resources.Validation
terraform fmtclean.raptor ... --dry-runterraform initfails onaws3tooling— pre-existing and inherent to deploy-time provider injection; the pristine module fails identically (verified). Real validation happens on CP upload where providers are injected.ssl-certannotation shows ≥2 ARNs incl. base, andcurl https://<base_domain>returns a valid cert.Follow-up / maintenance note
base_domainderivation is now duplicated in the wrapper and the base module and must stay byte-for-byte in sync (flagged in a code comment). Worth considering a shared source later.🤖 Generated with Claude Code