Kubernetes Ingress
Our standard module for creating Ingress resources in a Kubernetes cluster.
Usage
Basics
This module provides the ability to create a set of routing rules for a given set of domains (var.domains) using Kubernetes Ingresses.
It works as follows:
For all domains in
domains, ensure that a DNS record is configured to point to the domain to this cluster’s NGINX ingress controller (via kube_external_dns) and provide the ingress controller a TLS certificate for the domains (via kube_cert_manager).When the ingress controller receives a request to a domain in
domains, first apply the rate limits and redirect rules.Next, the request’s path is compared to the
path_prefixin every config ofingress_configs. If the request path is prefixed withpath_prefix, use the settings in that config object. 1Apply CORS handling, rewrite rules, and any other request modification before forwarding the request to the Kubernetes service indicated by the config’s
serviceandservice_portvalues.When receiving a response form the upstream, perform any response modifications before forwarding the response to the initiating client.
TLS Certificates
kube_cert_issuers provides a global default cert for all covered domains and first-level subdomains (via wildcard SANs). This is stored at cert-manager/ingress-tls.
However, if you need coverage for second-level or greater subdomains on the ingresses for this module, you will need a dedicated TLS cert. To generate this cert, set generate_cert_enabled to true.
We use Let’s Encrypt as the CA for your certificate requests. They provide certificates for free, but also impose rate limits. If you need to raise your rate limits, you can submit a rate limits adjustment request.
CDN
If you want to provide a CDN in front of the created Ingresses for performance and security improvements, see the kube_aws_cdn module.
Additionally, this module must be deployed with cdn_mode_enabled set to true.
CDN configuration can be supplied via the cdn configuration field on each element of ingress_configs. The individual settings are described in more detail here.
Redirect Rules
You can use redirect_rules to perform pattern matching over the requested URLs to perform permanent or temporary HTTP redirects.
For example, if redirect_rules is set to the following
redirect_rules = [ { source = "^https://vault.prod.panfactum.com(/.*)?$" target = "https://vault.panfactum.com$1" permanent = false }]then a request to https://vault.prod.panfactum.com/some/path would receive a 302 HTTP redirect response to https://vault.panfactum.com/some/path.
Note that the source value can use regex capture groups (e.g., (/.*)) that can then be referenced in target (e.g., $1).
Rewrite Rules
You can use rewrite_rules in each ingress_config to rewrite the request’s path before forwarding to the request to the upstream service.
Rewrite rules work as follows:
The appropriate configuration from
ingress_configsis chosen based on itspath_prefix.Each rule in
rewrite_rulesis applied as follows. The request’s path without thepath_prefixis compared against thematchregex. Iff that regex matches, then the path after thepath_prefixis transformed torewrite. 2 3 Regex capture groups are allowed inmatchand can be used inrewrite.Iff
remove_prefixistrue, prefix is removed from the request.The request is then forwarded to the upstream service.
For example, consider a kube_ingress module with the following ingress_configs list:
ingress_configs = [ { path_prefix = "/a" remove_prefix = true rewrite_rules = [ { match = "(.*)" rewrite = "/1$1" } ] service = "foo" port = 80 }]If the ingress receives a request with path /a/b/c, then the path will be mutated to /1/b/c before being sent to foo:80. If remove_prefix were false, then the path would be mutated to /a/1/b/c before being forwarded.
Headers
CORS Headers
The NGINX instance can handle CORS response headers for the upstream server.
Set cors_enabled to true to begin CORS handling.
Variables prefixed with cors_ control the behavior.
A few important notes:
If cors handling is enabled,
OPTIONSrequests will not be forwarded to the upstream server.Our CORS handling this will overwrite any CORS headers returned from the upstream server.
Due to problems in the default NGINX ingress controller behavior, we implement our own CORS handling logic that fixes many issues in the default behavior. If you would rather use the default behavior, set
cors_native_handling_enabledtotrue.As a convenience, by default we allow the following popular headers in
Access-Control-Allow-Headers:DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Disposition,Content-Type,Range,Authorization,Cookies,Referrer,Accept,sec-ch-ua,sec-ch-ua-mobile,sec-ch-ua-platform,X-Suggested-File-Name,Cookie. You can change this viacors_allowed_headers.As a convenience, by default we expose the following popular headers in
Access-Control-Expose-Headers:Content-Encoding,Date,Location,X-Frame-Options,X-Content-Type-Options,Permissions-Policy,X-XSS-Protection,Vary,Cross-Origin-Response-Policy,Cross-Origin-Opener-Policy,Cross-Origin-Embedder-Policy,Content-Security-Policy,Referrer-Policy. You can change this viacors_exposed_headers.
Content-Security-Policy
Set csp_enabled to true to begin adding Content-Security-Policy headers to returned responses.
This is highly recommended to prevent XSS and packet sniffing attacks.
If the upstream server sets a Content-Security-Policy header, NGINX will not override it by default. To override the headers with the values from this module, set csp_override to true.
Variables prefixed with csp_ control the individual CSP directives.
These directives will only be set on HTML responses to prevent unnecessary bandwidth as browsers will only use the CSP from the main document. However, we provide the ability to specify the non-HTML CSP headers via csp_non_html which expects the full policy string. This can be useful for mitigating these attacks.
Permissions-Policy
The Permissions-Policy header instructs the browser which features the containing document is allowed to use.
Set permissions_policy_enabled to true to set the Permissions-Policy header on HTML responses.
If the upstream server sets a Permissions-Policy header, NGINX will not override it by default. To override the headers with the values from this module, set permissions_policy_override to true.
Variables prefixed with permissions_policy_ control the individual permissions policies. By default, they are all disabled.
Referrer-Policy
Set the Referrer-Policy via the referrer_policy variable. The default is no-referrer.
CORS
NGINX can be configured to handle CORS requests for the Ingress.
To enable this functionality, set cors_enabled to true.
To control the behavior of the CORS handling, see the variables prefixed with cors_.
Cross-Origin Isolation
See this guide for the benefits of enabled cross-origin isolation.
Set cross_origin_isolation_enabled to true to begin setting the Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers and enable the crossOriginIsolated state in the underlying webpages. 4
X-Content-Type-Options
We enforce browsers to respect the Content-Type header by setting X-Content-Type-Options to nosniff by default.
Disable this by setting x_content_type_options_enabled to false.
Legacy Headers
We set the following legacy headers to safe values by default, but they can be overridden:
- X-Frame-Options:
SAMEORIGIN - X-XSS-Protection:
1; mode=block
Extra Static Headers
You can specify extra static headers via the extra_response_headers input object.
Footnotes
If multiple path prefixes match, the longest
path_prefixvalue wins. ↩If multiple rewrite rules match, the one with the longest
matchregex applies. ↩Note that we do not allow transforming the entire path at this phase because that would impact which config from
ingress_configswould match. If you need that behavior, aredirect_rulewould be more appropriate than arewrite_rule. ↩The default setting for
cross_origin_opener_policyissame-originwhich will break sites loading SSO pop-ups from different origins as it may block communication between the two windows. Change the value tosame-origin-allow-popupsto restore functionality. ↩