Panfactum LogoPanfactum
Infrastructure ModulesSubmodulesKuberneteskube_ingress
kube_ingress
Stable
Submodule
Source Code Link

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 to true.

  • 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 via cors_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 via cors_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:

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

  1. The default setting for cross_origin_opener_policy is same-origin which will break sites loading SSO pop-ups from different origins as it may block communication between the two windows. Change the value to same-origin-allow-popups to restore functionality.