Kubernetes Ingress
Our standard module for creating Ingress resources in a Kubernetes cluster.
Usage
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
).
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,
OPTIONS
requests 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_enabled
totrue
. -
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. 1
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.
Providers
The following providers are needed by this module:
-
kubectl (2.0.4)
-
kubernetes (2.27.0)
-
pf (0.0.3)
-
random (3.6.0)
Required Inputs
The following input variables are required:
domains
Description: Which domains the generated ingresses will listen on
Type: list(string)
ingress_configs
Description: A list of ingress names to the configuration to use for the ingress
Type:
list(object({
# This ingress matches all incoming requests on the indicated domains that have the indicated path prefixes
path_prefix = optional(string, "/")
remove_prefix = optional(bool, false) # True iff the the path_prefix should be stripped before forwarding on to upstream service
# The backing Kubernetes service
service = string
service_port = number
# CDN Configuration
cdn = optional(object({
extra_origin_headers = optional(map(string), {}) # Headers sent from the CDN to the origin
# The default behavior of the CDN before routing requests to this ingress
default_cache_behavior = optional(object({
caching_enabled = optional(bool, true) # Whether the CDN should cache responses from the origin (overrides all other caching settings)
allowed_methods = optional(list(string), ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]) # What HTTP methods are allowed
cached_methods = optional(list(string), ["GET", "HEAD"]) # What HTTP methods will be cached
min_ttl = optional(number, 0) # Minimum cache time
default_ttl = optional(number, 86400) # Default cache time
max_ttl = optional(number, 31536000) # Maximum cache time
cookies_in_cache_key = optional(list(string), ["*"]) # Which cookies will be included in the cache key (Providing "*" means ALL cookies)
headers_in_cache_key = optional(list(string), [ # Which headers will be included in the cache key
"Authorization",
"Origin",
"x-http-method-override",
"x-http-method",
"x-method-override",
"x-forwarded-host",
"x-host",
"x-original-url",
"x-rewrite-url",
"forwarded"
])
query_strings_in_cache_key = optional(list(string), ["*"]) # Which query strings will be included in the cache key (Providing "*" means ALL query strings)
cookies_not_forwarded = optional(list(string), []) # Which cookies will NOT be forwarded to the ingress from the CDN
headers_not_forwarded = optional(list(string), []) # Which headers will NOT be forwarded to the ingress from CDN
query_strings_not_forwarded = optional(list(string), []) # Which query strings will NOT be forwarded to the ingress from the CDN
compression_enabled = optional(bool, true) # Whether the CDN performs compression on your assets
viewer_protocol_policy = optional(string, "redirect-to-https") # What should happen based on the client protocol (HTTP vs HTTPS). One of: allow-all, https-only, redirect-to-https
}))
# Similar to default_cache_behavior but allows you to specific specific rules for certain path patterns
# The keys for this map are the path patterns (e.g., "*.jpg")
# Path patterns will automatically be prefixed with the path_prefix value, so it can be omitted
path_match_behavior = optional(map(object({
caching_enabled = optional(bool, true) # Whether the CDN should cache responses from the origin (overrides all other caching settings)
allowed_methods = optional(list(string), ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"])
cached_methods = optional(list(string), ["GET", "HEAD"])
min_ttl = optional(number, 0)
default_ttl = optional(number, 86400)
max_ttl = optional(number, 31536000)
cookies_in_cache_key = optional(list(string), ["*"])
headers_in_cache_key = optional(list(string), [
"Authorization",
"Origin",
"x-http-method-override",
"x-http-method",
"x-method-override",
"x-forwarded-host",
"x-host",
"x-original-url",
"x-rewrite-url",
"forwarded"
])
query_strings_in_cache_key = optional(list(string), ["*"])
cookies_not_forwarded = optional(list(string), [])
headers_not_forwarded = optional(list(string), [])
query_strings_not_forwarded = optional(list(string), [])
compression_enabled = optional(bool, true)
viewer_protocol_policy = optional(string, "redirect-to-https")
})), {})
}))
}))
name
Description: The name of the ingresses that will get created
Type: string
namespace
Description: The namespace the ingress resource should be created
Type: string
Optional Inputs
The following input variables are optional (have default values):
cdn_mode_enabled
Description: Whether a CDN should be used in front of the ingresses
Type: bool
Default: false
cors_allow_credentials
Description: Whether to set the 'Access-Control-Allow-Credentials' header to 'true'
Type: bool
Default: true
cors_allowed_headers
Description: Extra headers to allow on CORS requests
Type: list(string)
Default:
[
"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"
]
cors_allowed_methods
Description: The methods to allow on CORS requests
Type: list(string)
Default:
[
"GET",
"HEAD",
"POST",
"OPTIONS",
"PUT",
"PATCH",
"DELETE"
]
cors_allowed_origins_any
Description: Whether to allow any origin on CORS requests
Type: bool
Default: false
cors_allowed_origins_self
Description: Whether the ingress domains should be allowed origins on CORS requests
Type: bool
Default: true
cors_allowed_origins_sibling_domains
Description: Whether sibling domains of the ingress domains should be allowed origins on CORS requests
Type: bool
Default: true
cors_allowed_origins_subdomains
Description: Whether subdomains of the ingress domains should be allowed origins on CORS requests
Type: bool
Default: true
cors_enabled
Description: Whether to enable CORS response handling in NGINX
Type: bool
Default: false
cors_exposed_headers
Description: The extra headers to expose in CORS responses
Type: list(string)
Default:
[
"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"
]
cors_extra_allowed_origins
Description: Extra origins allowed on CORS requests
Type: list(string)
Default: []
cors_max_age_seconds
Description: Controls how long the CORS preflight requests are allowed to be cached
Type: number
Default: 86400
cors_native_handling_enabled
Description: Whether to use the native NGINX-ingress annotations to handle cors rather than the Panfactum logic
Type: bool
Default: false
cross_origin_embedder_policy
Description: The value for the Cross-Origin-Embedder-Policy header
Type: string
Default: "require-corp"
cross_origin_isolation_enabled
Description: Whether to enable the Cross-Origin-Opener-Policy header
Type: bool
Default: false
cross_origin_opener_policy
Description: The value for the Cross-Origin-Opener-Policy header
Type: string
Default: "same-origin"
cross_origin_resource_policy
Description: The value for the Cross-Origin-Resource-Policy header
Type: string
Default: "same-site"
csp_base_uri
Description: The base-uri content security policy
Type: string
Default: null
csp_connect_src
Description: The connect-src content security policy
Type: string
Default: "'self' ws:"
csp_default_src
Description: The default-src content security policy
Type: string
Default: "'self'"
csp_enabled
Description: Whether the Content-Security-Policy header should be added to responses
Type: bool
Default: false
csp_fenced_frame_src
Description: The fenced-frame-src content security policy
Type: string
Default: null
csp_font_src
Description: The font-src content security policy
Type: string
Default: "'self' https: data:"
csp_form_action
Description: The form-action content security policy
Type: string
Default: null
csp_frame_ancestors
Description: The frame-ancestors content security policy
Type: string
Default: null
csp_frame_src
Description: The frame-src content security policy
Type: string
Default: null
csp_img_src
Description: The img-src content security policy
Type: string
Default: "'self' data:"
csp_manifest_src
Description: The manifest-src content security policy
Type: string
Default: null
csp_media_src
Description: The media-src content security policy
Type: string
Default: null
csp_non_html
Description: The full content security policy for non-HTML responses
Type: string
Default: "default-src 'none'; frame-ancestors 'none'; upgrade-insecure-requests"
csp_object_src
Description: The object-src content security policy
Type: string
Default: "'none'"
csp_override
Description: Whether to override the Content-Security-Response header if set from the upstream server
Type: bool
Default: false
csp_report_to
Description: The report-to content security policy
Type: string
Default: null
csp_report_uri
Description: The report-uri content security policy
Type: string
Default: null
csp_sandbox
Description: The sandbox content security policy
Type: string
Default: null
csp_script_src
Description: The script-src content security policy
Type: string
Default: null
csp_script_src_elem
Description: The script-src-elem content security policy
Type: string
Default: null
csp_style_src
Description: The style-src content security policy
Type: string
Default: "'self'"
csp_style_src_attr
Description: The style-src-attr content security policy
Type: string
Default: null
csp_style_src_elem
Description: The style-src-elem content security policy
Type: string
Default: null
csp_worker_src
Description: The worker-src content security policy
Type: string
Default: null
extra_annotations
Description: Extra annotations to add to the ingress objects
Type: map(string)
Default: {}
extra_configuration_snippet
Description: An extra NGINX configuration snippet to add to the route handlers
Type: string
Default: ""
extra_response_headers
Description: A key-value mapping of extra headers to add to every response
Type: map(string)
Default: {}
permissions_policy_accelerometer
Description: The permissions policy for the accelerometer directive
Type: string
Default: "()"
permissions_policy_ambient_light_sensor
Description: The permissions policy for the ambient-light-sensor directive
Type: string
Default: "()"
permissions_policy_autoplay
Description: The permissions policy for the autoplay directive
Type: string
Default: "()"
permissions_policy_battery
Description: The permissions policy for the battery directive
Type: string
Default: "()"
permissions_policy_bluetooth
Description: The permissions policy for the bluetooth directive
Type: string
Default: "()"
permissions_policy_camera
Description: The permissions policy for the camera directive
Type: string
Default: "()"
permissions_policy_display_capture
Description: The permissions policy for the display-capture directive
Type: string
Default: "()"
permissions_policy_document_domain
Description: The permissions policy for the document-domain directive
Type: string
Default: "(self)"
permissions_policy_enabled
Description: Whether to enable the Permissions-Policy header in HTML responses.
Type: bool
Default: false
permissions_policy_encrypted_media
Description: The permissions policy for the encrypted-media directive
Type: string
Default: "()"
permissions_policy_execution_while_not_rendered
Description: The permissions policy for the execution-while-not-rendered directive
Type: string
Default: "(self)"
permissions_policy_execution_while_out_of_viewport
Description: The permissions policy for the execution-while-out-of-viewport directive
Type: string
Default: "(self)"
permissions_policy_fullscreen
Description: The permissions policy for the fullscreen directive
Type: string
Default: "()"
permissions_policy_gamepad
Description: The permissions policy for the gamepad directive
Type: string
Default: "(self)"
permissions_policy_geolocation
Description: The permissions policy for the geolocation directive
Type: string
Default: "()"
permissions_policy_gyroscope
Description: The permissions policy for the gyroscope directive
Type: string
Default: "()"
permissions_policy_hid
Description: The permissions policy for the hid directive
Type: string
Default: "(self)"
permissions_policy_identity_credentials_get
Description: The permissions policy for the identity-credentials-get directive
Type: string
Default: "()"
permissions_policy_idle_detection
Description: The permissions policy for the idle-detection directive
Type: string
Default: "()"
permissions_policy_local_fonts
Description: The permissions policy for the local-fonts directive
Type: string
Default: "(self)"
permissions_policy_magnetometer
Description: The permissions policy for the magnetometer directive
Type: string
Default: "()"
permissions_policy_microphone
Description: The permissions policy for the microphone directive
Type: string
Default: "()"
permissions_policy_midi
Description: The permissions policy for the midi directive
Type: string
Default: "()"
permissions_policy_otp_credentials
Description: The permissions policy for the otp-credentials directive
Type: string
Default: "()"
permissions_policy_override
Description: Whether to override the Permissions-Policy header if set from the upstream server
Type: bool
Default: false
permissions_policy_payment
Description: The permissions policy for the payment directive
Type: string
Default: "()"
permissions_policy_picture_in_picture
Description: The permissions policy for the picture-in-picture directive
Type: string
Default: "(self)"
permissions_policy_publickey_credentials_create
Description: The permissions policy for the publickey-credentials-create directive
Type: string
Default: "()"
permissions_policy_publickey_credentials_get
Description: The permissions policy for the publickey-credentials-get directive
Type: string
Default: "()"
permissions_policy_screen_wake_lock
Description: The permissions policy for the screen-wake-lock directive
Type: string
Default: "()"
permissions_policy_serial
Description: The permissions policy for the serial directive
Type: string
Default: "()"
permissions_policy_speaker_selection
Description: The permissions policy for the speaker-selection directive
Type: string
Default: "()"
permissions_policy_storage_access
Description: The permissions policy for the storage-access directive
Type: string
Default: "()"
permissions_policy_usb
Description: The permissions policy for the usb directive
Type: string
Default: "()"
permissions_policy_web_share
Description: The permissions policy for the web-share directive
Type: string
Default: "()"
permissions_policy_window_management
Description: The permissions policy for the window-management directive
Type: string
Default: "()"
permissions_policy_xr_spatial_tracking
Description: The permissions policy for the xr-spatial-tracking directive
Type: string
Default: "()"
rate_limiting_enabled
Description: Whether to enable rate limiting
Type: bool
Default: true
redirect_rules
Description: A list of redirect rules that the ingress will match against before sending requests to the upstreams
Type:
list(object({
source = string # A regex string for matching the entire request url (^https://domain.com(/.*)?$)
target = string # The redirect target (can use numbered capture groups from the source - https://domain2.com/$1)
permanent = optional(bool, false) # If true will issue a 301 redirect; otherwise, will use 302
}))
Default: []
referrer_policy
Description: The value for Referrer-Policy header.
Type: string
Default: "no-referrer"
x_content_type_options_enabled
Description: Whether X-Content-Type-Options should be set to nosniff
Type: bool
Default: true
x_frame_options
Description: The value for the X-Frame-Options header.
Type: string
Default: "SAMEORIGIN"
x_xss_protection
Description: The value for the X-XSS-Protection header.
Type: string
Default: "1; mode=block"
Outputs
The following outputs are exported:
cdn_origin_configs
Description: Configuration to be passed to the kube_cdn module to configure the CDN
Maintainer Notes
No notes.
Footnotes
-
The default setting for
cross_origin_opener_policy
issame-origin
which 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-popups
to restore functionality. ↩