Resource Definitions

Driver

Capability

Resource Type

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-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
      }
    })
  }
}


Top