AWS CDN for Kubernetes Ingresses
This module creates a CDN for a set of Kubernetes Ingresses by aggregating the cdn_origin_configs
output from instances of the kube_ingress
module and forwarding them to the aws_cdn module.
This module takes the same arguments as aws_cdn
, so see it's module documentation
for more information.
Limitations
-
The upstream ingresses for this module must all use the same set of domains. AWS Cloudfront provides no ability to perform routing based on domain names (only HTTP paths). If the ingresses you provide this module use different sets of domains, your routing will break in unexpected ways.
-
Changing the domains of your upstream ingresses will cause the Cloudfront distribution to re-provision its certificates causing a brief window of downtime (1-2 minutes).
-
You cannot use the same domain name on multiple CDNs. As a result, you can only create ONE
kube_aws_cdn
resource for all ingresses that use a particular domain name. -
For additional limitations, see the aws_cdn module docs.
Usage
terraform {
required_providers {
...
aws = {
source = "hashicorp/aws"
version = "5.70.0"
configuration_aliases = [aws.global]
}
...
}
}
module "ingress_1" {
source = "${var.pf_module_source}kube_ingress${var.pf_module_ref}"
namespace = local.namespace
name = "example1"
domains = ["example.com"]
...
# CDN mode MUST be enabled if you want to use a
# CDN in front of an ingress
cdn_mode_enabled = true
}
module "ingress_2" {
source = "../kube_ingress"
namespace = local.namespace
name = "example2"
domains = ["example.com"]
...
cdn_mode_enabled = true
ingress_configs = [{
path_prefix = "/test"
...
# You can configure CDN behavior on a per-ingress basis
# See the kube_ingress documentation for more information
cdn = {
default_cache_behavior = {
headers_in_cache_key = ["Authorization"]
}
}
}]
}
module "cdn" {
source = "${var.pf_module_source}kube_aws_cdn${var.pf_module_ref}"
# Since the CDN operates globally, you must use the global
# provider as follows:
providers = {
aws.global = aws.global
}
name = "example"
# Concatenate the CDN configs provided by each
# ingress module and pass them to the CDN module
origin_configs = concat(
module.ingress_1.cdn_origin_configs,
module.ingress_2.cdn_origin_configs
)
}
Providers
The following providers are needed by this module:
Required Inputs
The following input variables are required:
name
Description: The name of the CDN that will get created
Type: string
origin_configs
Description: A list of configuration settings for communicating with the upstream ingress resources. Do NOT set this manually. Use the outputs from kube_ingress.
Type:
list(object({
origin_id = optional(string) # A globally unique identifier for this origin (will be automatically computed if not provided)
origin_domain = string # The domain name of the ingress origin
domains = list(string) # The domains for this ingress
path_prefix = optional(string, "/") # Only traffic with this HTTP path prefix will be routed to the indicated origin
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)
}))
# 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")
})), {})
}))
Optional Inputs
The following input variables are optional (have default values):
cors_additional_allowed_origins
Description: Specifies which origins are allowed besides the domain name specified. Use '*' to allow any origin.
Type: list(string)
Default: []
cors_allowed_headers
Description: Specifies which headers are allowed for CORS requests.
Type: list(string)
Default:
[
"Content-Length"
]
cors_allowed_methods
Description: Specifies which methods are allowed. Can be GET, PUT, POST, DELETE or HEAD.
Type: list(string)
Default:
[
"GET",
"HEAD"
]
cors_enabled
Description: True if the CloudFront distribution should handle adding CORS headers instead of the origin.
Type: bool
Default: false
cors_max_age_seconds
Description: Time in seconds that the browser can cache the response for a preflight CORS request.
Type: number
Default: 3600
description
Description: A description for this CDN
Type: string
Default: null
geo_restriction_list
Description: A list of ISO 3166 country codes for the geographic restriction list (works for both whitelist and blacklist)
Type: list(string)
Default: []
geo_restriction_type
Description: What type of geographic restrictions to you want to apply to CDN clients
Type: string
Default: "none"
logging_cookies_enabled
Description: Whether cookies should be included in the request logs
Type: bool
Default: false
logging_enabled
Description: Whether request logging should be enabled for the CloudFront distribution
Type: bool
Default: false
logging_expire_after_days
Description: The number of days after which logs will be deleted. (0 to disable)
Type: number
Default: 0
origin_shield_enabled
Description: Whether origin shield should be enabled for the CloudFront distribution
Type: bool
Default: false
price_class
Description: The price class for the CDN
Type: string
Default: "PriceClass_100"
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: []
Outputs
The following outputs are exported:
distribution_id
Description: The ID of the CloudFront distribution
logging_bucket_name
Description: The name of the log bucket for CloudFront access logs
Maintainer Notes
No notes.