EKS collector custom domain - Snowplow-managed DNS, imported certificate
Last updated: September 3, 2026
Snowplow owns the Route53 record. The customer supplies the certificate.
Start at EKS collector custom domains overview if you are not sure this is the right path.
Use this when the zone is delegated to the customer's Snowplow AWS account, but the customer insists on their own certificate — for example a wildcard from their corporate CA, or a Cloudflare Origin certificate.
The certificate is held by a separate k8s_certificate stack deployment, one per certificate. The collector then references that deployment by its environment name.
Consul keys
customer/<client>/aws_rt_pipeline_<env>/input/collector/dns/delegated_imported_cert_mapBoth are a JSON object mapping domain to k8s_certificate environment name. Default is {}.
{"collector.acme.com": "cert1"}Key | Effect |
|---|---|
| Same, and points the Route53 record at the NLB IPs. |
Steps
1. Get the certificate from the customer
Ask for the full certificate chain and the private key, in PEM format. The certificate must cover the collector domain, either exactly or by a wildcard. Take it through an approved secure channel.
2. Deploy a k8s_certificate stack
Pick a short environment name for this certificate, for example cert1. Use a new name for each distinct certificate; reuse the name when the customer sends a renewal.
Store the material in Vault at:
secret/customer/<client>/k8s_certificate_<cert_env>
with fields cert (the full chain) and key (the private key).
Set the Consul inputs under customer/<client>/k8s_certificate_<cert_env>/input/:
Key | Value |
|---|---|
| The |
| The certificate subject, for identification. For example |
Deploy the k8s_certificate stack with the stacks/deploy handler, using workspace<client>-<cert_env>. This creates the TLS secret in the namespace.
3. Reference it from the pipeline
Add an entry to collector/dns/delegated_imported_cert_map mapping the domain to <cert_env>, then apply aws_rt_pipeline.
{"t.acme.com": "cer1", "d.example.com": "cert2"}The apply attaches the secret to the Traefik ingress and writes the Route53 A record pointing at the NLB IPs, with a 60 second TTL.
Renewals
An imported certificate does not renew itself. Track the expiry, which the k8s_certificate stack publishes as cert_expiry. When the customer sends a replacement, create a brand new k8s_certificate environment. Once created you will update the existing domain in collector/dns/delegated_imported_cert_map
Example is updating "t.acme.com" to use a new certificate
{"t.acme.com": "cer1", "d.example.com": "cert2"}
becomes
{"t.acme.com": "cert20", "d.example.com": "cert2"}The reason we don't replace the existing k8s_certificate is for rollback purposes. If there's an issue with new certificate we can always repoint back to the previous k8s_certificate ENV for that domain
Verify
dig +short <domain>
curl -sI https://<domain>/health
aws/collector/validate_eks_collector 0.1.0 prints the certificate actually served, including its serial, subject, issuer and validity dates. Use it to confirm the imported certificate is in use and not a stale one.
Common failures
Message contains | Cause |
|---|---|
| The value is not valid JSON. It must be an object, not a list or a bare string. |
| The |
| The domain is also in an ACM key. Pick one certificate source. |
| The domain is also in a cert-manager key. The imported secret wins and the cert-manager entry is ignored, so remove it. |
| The domain is also in |