Appearance
Custom Domains & WAF
Custom domains
A custom domain needs a hosted zone, a certificate, and DNS records pointing to the load balancer. Set domain.dns according to where the hosted zone is managed.
| Mode | The zone | What Keel does | Manual steps |
|---|---|---|---|
route53 (default) | Already exists in this AWS account | Writes validation + alias records; the apply waits for the certificate | None |
route53-managed | Keel creates it | Everything, once you set the nameservers at your registrar | Set 4 nameservers |
external | Stays where it is (Cloudflare, another account, corporate DNS) | Issues the certificate; prints the records; writes none | Create the records, then keel domains verify |
bash
keel domains add app.example.com # looks the zone up once and records the mode
keel domains add app.example.com --dns route53-managed
keel domains add app.example.com --dns external
keel domains status # live state: zone, delegation, certificate, what's left (--json)
keel domains records # the records to create by hand, in provider-form shape
keel domains verify # recheck; for external, records an issued certificate (--wait, --timeout 15m)
keel domains remove app.example.comdomains add supports --zone, --zone-id, --dns, repeatable --alias, --certificate-arn, and --no-force-https. It updates the target environment in keel.yml; run keel up to apply the change in AWS.
Declared in keel.yml:
yaml
domain:
name: app.example.com
zone: example.com # required for the route53 modes; ignored for external
# dns: route53 # route53 | route53-managed | external
# aliases:
# - www.app.example.com
# - "*.app.example.com" # on the certificate, deliberately not routed
# certificate_arn: arn:aws:acm:... # bring your own; Keel then issues nothing
# certificate_issued: true # external only — written by 'keel domains verify'
# force_https: true # takes effect only once a certificate exists
# validation_timeout: 20mHTTPS activation
While a certificate is pending, port 80 continues to serve the application. force_https defaults to true and starts redirecting only after the certificate is issued and attached.
Delegation checks
keel domains status queries public DNS instead of relying only on Route 53, so it can detect a registrar that still delegates to another provider. It reports the next required step in order: zone, delegation, certificate, then attachment. For apex domains it also notes that DNS providers must use ALIAS or ANAME records rather than CNAME.
Retained managed zones
Keel retains hosted zones created with route53-managed when you run domains remove or keel destroy. Recreating a zone assigns different nameservers and would invalidate registrar delegation and remove records Keel may not manage. Delete a retained zone manually in AWS when it is no longer needed; AWS charges $0.50 per month for it.
External DNS takes two applies
With dns: external, run keel up to provision HTTP and print the validation records. Add those records at your DNS provider, run keel domains verify --wait, then run keel up again to attach HTTPS. Static sites use the same sequence with keel sites verify.
WAF
Keel supports AWS WAF with managed rule sets to protect your ALB. WAF requires load_balancer.enabled: true — and therefore at least one service; a sites-only app has no ALB to attach it to.
yaml
waf:
enabled: true
managed_rules:
- AWSManagedRulesCommonRuleSetbash
keel waf enable # default rule set: AWSManagedRulesCommonRuleSet
keel waf enable --rules AWSManagedRulesCommonRuleSet,AWSManagedRulesSQLiRuleSet
keel waf status
keel waf disableChanges are applied on the next keel up.