Ingress
This section contains example Resource Definitions for handling Kubernetes ingress traffic. Instead of the Driver type Ingress, we are using the Template Driver type, which allows us to render any Kubernetes YAML object.
ingress-traefik.yaml
: defines anIngressRoute
object for the Traefik Ingress Controller using the IngressRoute custom resource definition. This format is for use with the Humanitec CLIingress-traefik-multiple-routes.yaml
: defines anIngressRoute
object for the Traefik Ingress Controller using the IngressRoute custom resource definition. It dynamically extracts the routes from theroute
resource in the Resource Graph to provide multiple routes. This format is for use with the Humanitec CLIingress-ambassador.yaml
: defines aMapping
object for the Ambassador Ingress Controller using the Mapping custom resource definition. This format is for use with the Humanitec CLI
ingress-ambassador.yaml
(view on GitHub)
:
# This Resource Definition provisions an IngressRoute object for the Traefik Ingress Controller
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
id: ambassador-ingress
entity:
name: ambassador-ingress
type: ingress
driver_type: template
driver_inputs:
values:
templates:
init: |
name: {{ .id }}-ingress
secretname: ${resources.tls-cert.outputs.tls_secret_name}
host: ${resources.dns.outputs.host}
namespace: ${resources['k8s-namespace#k8s-namespace'].outputs.namespace}
manifests: |
ambassador-mapping.yaml:
data:
apiVersion: getambassador.io/v3alpha1
kind: Mapping
metadata:
name: {{ .init.name }}-mapping
spec:
host: {{ .init.host }}
prefix: /
service: my-service-name:8080
location: namespace
ambassador-tlscontext.yaml:
data:
apiVersion: getambassador.io/v3alpha1
kind: TLSContext
metadata:
name: {{ .init.name }}-tlscontext
spec:
hosts:
- {{ .init.host }}
secret: {{ .init.secretname }}
location: namespace
ingress-traefik-multiple-routes.yaml
(view on GitHub)
:
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
id: traefik-ingress-eg
entity:
name: traefik-ingress-eg
driver_type: humanitec/template
type: ingress
driver_inputs:
values:
# Find all the route resources that are dependent on any dns resources used in this workload.
# We extract arrays of their host, path, port, and service resource.
# These will become new entries in the .drivers.values table.
routeHosts: ${resources.dns<route.outputs.host}
routePaths: ${resources.dns<route.outputs.path}
routePorts: ${resources.dns<route.outputs.port}
routeServices: ${resources.dns<route.outputs.service}
templates:
# The init template gives us a place to precompute some fields that we'll use in the manifests template.
init: |
host: {{ .resource.host | quote }}
# ingress paths are added implicitely to our ingress resource based on the contents of our workload. These are an older
# alternative to route resources. Consider this deprecated in the future!
ingressPaths: {{ dig "rules" "http" (list) .resource | toRawJson }}
# The tls secret name could be generated by Humanitec or injected as an input parameter to our ingress.
tlsSecretName: {{ .driver.values.tls_secret_name | default .resource.tls_secret_name | default .driver.values.automatic_tls_secret_name | quote }}
{{- if eq (lower ( .driver.values.path_type | default "Prefix")) "exact" -}}
defaultMatchRule: Path
{{- else }}
defaultMatchRule: PathPrefix
{{- end }}
manifests: |
# Create our single manifest with many routes in it. Alternative configurations could create a manifest per route with unique file names if required.
ingressroute.yaml:
location: namespace
data:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
# id is the unique resource uuid for this ingress
name: {{ .id }}-ingressroute
annotations:
{{- range $k, $v := .driver.values.annotations }}
{{ $k | toRawJson }}: {{ $v | toRawJson }}
{{- end }}
labels:
{{- range $k, $v := .driver.values.labels }}
{{ $k | toRawJson }}: {{ $v | toRawJson }}
{{- end }}
spec:
entryPoints:
- websecure
routes:
# Add all the paths from the dependent route resources. Route resources can have different hostnames but will all obey the path type set out in the resource inputs.
{{- range $index, $path := .driver.values.routePaths }}
- match: Host(`{{ index $.driver.values.routeHosts $index }}`) && {{ $.init.defaultMatchRule }}(`{{ $path }}`)
kind: Rule
services:
- kind: Service
name: {{ index $.driver.values.routeServices $index | toRawJson }}
port: {{ index $.driver.values.routePorts $index }}
{{- end }}
# Add all the support ingress paths. The old style ingress rules use a single hostname coming from the resource configuration but support different path types per rule.
# As mentioned further up, consider these deprecated in the future!
{{- range $path, $rule := .init.ingressPaths }}
{{ $lcType := lower $rule.type -}}
{{- if eq $lcType "implementationspecific" -}}
- match: Host(`{{ $.init.host }}`) && Path(`{{ $path }}`)
{{- else if eq $lcType "exact" -}}
- match: Host(`{{ $.init.host }}`) && Path(`{{ $path }}`)
{{ else }}
- match: Host(`{{ $.init.host }}`) && PathPrefix(`{{ $path }}`)
{{- end }}
kind: Rule
services:
- kind: Service
name: {{ $rule.name | quote }}
port: {{ $rule.port }}
{{- end }}
{{- if not (or .driver.values.no_tls (eq .init.tlsSecretName "")) }}
tls:
secretName: {{ .init.tlsSecretName | toRawJson }}
{{- end }}
ingress-traefik.yaml
(view on GitHub)
:
# This Resource Definition provisions an IngressRoute object for the Traefik Ingress Controller
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
id: traefik-ingress
entity:
name: traefik-ingress
type: ingress
driver_type: template
driver_inputs:
values:
templates:
init: |
name: {{ .id }}-ir
secretname: ${resources.tls-cert.outputs.tls_secret_name}
host: ${resources.dns.outputs.host}
namespace: ${resources['k8s-namespace#k8s-namespace'].outputs.namespace}
manifests: |
traefik-ingressroute.yaml:
data:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: {{ .init.name }}
spec:
routes:
- match: Host(`{{ .init.host }}`) && PathPrefix(`/`)
kind: Rule
services:
- name: my-service-name
kind: Service
port: 8080
namespace: {{ .init.namespace }}
tls:
secretName: {{ .init.secretname }}
location: namespace
ingress-ambassador.tf
(view on GitHub)
:
resource "humanitec_resource_definition" "ambassador-ingress" {
driver_type = "template"
id = "ambassador-ingress"
name = "ambassador-ingress"
type = "ingress"
driver_inputs = {
values_string = jsonencode({
"templates" = {
"init" = <<END_OF_TEXT
name: {{ .id }}-ingress
secretname: $${resources.tls-cert.outputs.tls_secret_name}
host: $${resources.dns.outputs.host}
namespace: $${resources['k8s-namespace#k8s-namespace'].outputs.namespace}
END_OF_TEXT
"manifests" = <<END_OF_TEXT
ambassador-mapping.yaml:
data:
apiVersion: getambassador.io/v3alpha1
kind: Mapping
metadata:
name: {{ .init.name }}-mapping
spec:
host: {{ .init.host }}
prefix: /
service: my-service-name:8080
location: namespace
ambassador-tlscontext.yaml:
data:
apiVersion: getambassador.io/v3alpha1
kind: TLSContext
metadata:
name: {{ .init.name }}-tlscontext
spec:
hosts:
- {{ .init.host }}
secret: {{ .init.secretname }}
location: namespace
END_OF_TEXT
}
})
}
}
ingress-traefik-multiple-routes.tf
(view on GitHub)
:
resource "humanitec_resource_definition" "traefik-ingress-eg" {
driver_type = "humanitec/template"
id = "traefik-ingress-eg"
name = "traefik-ingress-eg"
type = "ingress"
driver_inputs = {
values_string = jsonencode({
"routeHosts" = "$${resources.dns<route.outputs.host}"
"routePaths" = "$${resources.dns<route.outputs.path}"
"routePorts" = "$${resources.dns<route.outputs.port}"
"routeServices" = "$${resources.dns<route.outputs.service}"
"templates" = {
"init" = <<END_OF_TEXT
host: {{ .resource.host | quote }}
# ingress paths are added implicitely to our ingress resource based on the contents of our workload. These are an older
# alternative to route resources. Consider this deprecated in the future!
ingressPaths: {{ dig "rules" "http" (list) .resource | toRawJson }}
# The tls secret name could be generated by Humanitec or injected as an input parameter to our ingress.
tlsSecretName: {{ .driver.values.tls_secret_name | default .resource.tls_secret_name | default .driver.values.automatic_tls_secret_name | quote }}
{{- if eq (lower ( .driver.values.path_type | default "Prefix")) "exact" -}}
defaultMatchRule: Path
{{- else }}
defaultMatchRule: PathPrefix
{{- end }}
END_OF_TEXT
"manifests" = <<END_OF_TEXT
# Create our single manifest with many routes in it. Alternative configurations could create a manifest per route with unique file names if required.
ingressroute.yaml:
location: namespace
data:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
# id is the unique resource uuid for this ingress
name: {{ .id }}-ingressroute
annotations:
{{- range $k, $v := .driver.values.annotations }}
{{ $k | toRawJson }}: {{ $v | toRawJson }}
{{- end }}
labels:
{{- range $k, $v := .driver.values.labels }}
{{ $k | toRawJson }}: {{ $v | toRawJson }}
{{- end }}
spec:
entryPoints:
- websecure
routes:
# Add all the paths from the dependent route resources. Route resources can have different hostnames but will all obey the path type set out in the resource inputs.
{{- range $index, $path := .driver.values.routePaths }}
- match: Host(`{{ index $.driver.values.routeHosts $index }}`) && {{ $.init.defaultMatchRule }}(`{{ $path }}`)
kind: Rule
services:
- kind: Service
name: {{ index $.driver.values.routeServices $index | toRawJson }}
port: {{ index $.driver.values.routePorts $index }}
{{- end }}
# Add all the support ingress paths. The old style ingress rules use a single hostname coming from the resource configuration but support different path types per rule.
# As mentioned further up, consider these deprecated in the future!
{{- range $path, $rule := .init.ingressPaths }}
{{ $lcType := lower $rule.type -}}
{{- if eq $lcType "implementationspecific" -}}
- match: Host(`{{ $.init.host }}`) && Path(`{{ $path }}`)
{{- else if eq $lcType "exact" -}}
- match: Host(`{{ $.init.host }}`) && Path(`{{ $path }}`)
{{ else }}
- match: Host(`{{ $.init.host }}`) && PathPrefix(`{{ $path }}`)
{{- end }}
kind: Rule
services:
- kind: Service
name: {{ $rule.name | quote }}
port: {{ $rule.port }}
{{- end }}
{{- if not (or .driver.values.no_tls (eq .init.tlsSecretName "")) }}
tls:
secretName: {{ .init.tlsSecretName | toRawJson }}
{{- end }}
END_OF_TEXT
}
})
}
}
ingress-traefik.tf
(view on GitHub)
:
resource "humanitec_resource_definition" "traefik-ingress" {
driver_type = "template"
id = "traefik-ingress"
name = "traefik-ingress"
type = "ingress"
driver_inputs = {
values_string = jsonencode({
"templates" = {
"init" = <<END_OF_TEXT
name: {{ .id }}-ir
secretname: $${resources.tls-cert.outputs.tls_secret_name}
host: $${resources.dns.outputs.host}
namespace: $${resources['k8s-namespace#k8s-namespace'].outputs.namespace}
END_OF_TEXT
"manifests" = <<END_OF_TEXT
traefik-ingressroute.yaml:
data:
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: {{ .init.name }}
spec:
routes:
- match: Host(`{{ .init.host }}`) && PathPrefix(`/`)
kind: Rule
services:
- name: my-service-name
kind: Service
port: 8080
namespace: {{ .init.namespace }}
tls:
secretName: {{ .init.secretname }}
location: namespace
END_OF_TEXT
}
})
}
}