diff --git a/helm/cluster-issuer/chart/templates/_helpers.tpl b/helm/cluster-issuer/chart/templates/_helpers.tpl deleted file mode 100644 index dd5ba3b..0000000 --- a/helm/cluster-issuer/chart/templates/_helpers.tpl +++ /dev/null @@ -1,62 +0,0 @@ -{{/* -Expand the name of the chart. -*/}} -{{- define "cluster-issuer.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "cluster-issuer.fullname" -}} -{{- if .Values.fullnameOverride }} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- $name := default .Chart.Name .Values.nameOverride }} -{{- if contains $name .Release.Name }} -{{- .Release.Name | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} -{{- end }} -{{- end }} -{{- end }} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "cluster-issuer.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Common labels -*/}} -{{- define "cluster-issuer.labels" -}} -helm.sh/chart: {{ include "cluster-issuer.chart" . }} -{{ include "cluster-issuer.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "cluster-issuer.selectorLabels" -}} -app.kubernetes.io/name: {{ include "cluster-issuer.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - -{{/* -Create the name of the service account to use -*/}} -{{- define "cluster-issuer.serviceAccountName" -}} -{{- if .Values.serviceAccount.create }} -{{- default (include "cluster-issuer.fullname" .) .Values.serviceAccount.name }} -{{- else }} -{{- default "default" .Values.serviceAccount.name }} -{{- end }} -{{- end }} diff --git a/helm/wildcard-certificate/chart/.helmignore b/helm/dns01-certificate/chart/.helmignore similarity index 100% rename from helm/wildcard-certificate/chart/.helmignore rename to helm/dns01-certificate/chart/.helmignore diff --git a/helm/wildcard-certificate/chart/Chart.yaml b/helm/dns01-certificate/chart/Chart.yaml similarity index 94% rename from helm/wildcard-certificate/chart/Chart.yaml rename to helm/dns01-certificate/chart/Chart.yaml index 4a65d0b..2bd9388 100644 --- a/helm/wildcard-certificate/chart/Chart.yaml +++ b/helm/dns01-certificate/chart/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 -name: wildcard-certificate -description: Wildcard Certificate +name: dns01-certificate +description: DNS01 Certificate # A chart can be either an 'application' or a 'library' chart. # diff --git a/helm/wildcard-certificate/chart/templates/wildcard-certificate.yaml b/helm/dns01-certificate/chart/templates/dns01-certificate.yaml similarity index 87% rename from helm/wildcard-certificate/chart/templates/wildcard-certificate.yaml rename to helm/dns01-certificate/chart/templates/dns01-certificate.yaml index 0e512a1..c0c6501 100644 --- a/helm/wildcard-certificate/chart/templates/wildcard-certificate.yaml +++ b/helm/dns01-certificate/chart/templates/dns01-certificate.yaml @@ -10,8 +10,9 @@ spec: kind: ClusterIssuer commonName: {{ .Values.domain }} dnsNames: - - {{ .Values.domain }} - - "*.{{ .Values.domain }}" + {{- range .Values.dnsNameTemplates }} + - {{ tpl . $ | quote }} + {{- end }} secretTemplate: annotations: {{- if .Values.reflectNamespaces }} diff --git a/helm/wildcard-certificate/chart/values.yaml b/helm/dns01-certificate/chart/values.yaml similarity index 100% rename from helm/wildcard-certificate/chart/values.yaml rename to helm/dns01-certificate/chart/values.yaml diff --git a/helm/gateway-config/chart/.helmignore b/helm/gateway-config/chart/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/helm/gateway-config/chart/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/gateway-config/chart/Chart.yaml b/helm/gateway-config/chart/Chart.yaml new file mode 100644 index 0000000..4ae4216 --- /dev/null +++ b/helm/gateway-config/chart/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: gateway-config +description: Gateway Configuration + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/helm/gateway-config/chart/templates/gateway-class.yaml b/helm/gateway-config/chart/templates/gateway-class.yaml new file mode 100644 index 0000000..21ad2ef --- /dev/null +++ b/helm/gateway-config/chart/templates/gateway-class.yaml @@ -0,0 +1,6 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: GatewayClass +metadata: + name: envoy +spec: + controllerName: gateway.envoyproxy.io/gatewayclass-controller \ No newline at end of file diff --git a/helm/gateway-config/chart/templates/gateway.yaml b/helm/gateway-config/chart/templates/gateway.yaml new file mode 100644 index 0000000..77a67fe --- /dev/null +++ b/helm/gateway-config/chart/templates/gateway.yaml @@ -0,0 +1,27 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: {{ .Values.name }} + namespace: {{ .Release.Namespace }} +spec: + gatewayClassName: envoy + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All + + - name: https + protocol: HTTPS + port: 443 + tls: + mode: Terminate + certificateRefs: + - kind: Secret + group: "" + name: {{ .Values.certificateName }} + allowedRoutes: + namespaces: + from: All \ No newline at end of file diff --git a/helm/gateway-config/chart/templates/http-to-https.yaml b/helm/gateway-config/chart/templates/http-to-https.yaml new file mode 100644 index 0000000..3495fc0 --- /dev/null +++ b/helm/gateway-config/chart/templates/http-to-https.yaml @@ -0,0 +1,15 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: http-to-https + namespace: {{ .Release.Namespace }} +spec: + parentRefs: + - name: {{ .Values.name }} + sectionName: http + rules: + - filters: + - type: RequestRedirect + requestRedirect: + scheme: https + statusCode: 308 diff --git a/helm/gateway-config/chart/values.yaml b/helm/gateway-config/chart/values.yaml new file mode 100644 index 0000000..1f607ed --- /dev/null +++ b/helm/gateway-config/chart/values.yaml @@ -0,0 +1,2 @@ +name: gateway +certificateName: wildcard-certificate \ No newline at end of file diff --git a/helm/gitlab/values.yaml b/helm/gitlab/values.yaml index 3826ded..6e09f2c 100644 --- a/helm/gitlab/values.yaml +++ b/helm/gitlab/values.yaml @@ -14,14 +14,18 @@ global: name: ${registry_host}.${domain} pages: name: ${pages_host}.${domain} - https: false - ingress: + gatewayApi: + enabled: true + installEnvoy: false configureCertmanager: false - class: nginx - tls: - enabled: true - secretName: "wildcard-certificate" + gatewayClass: envoy + gateway: + name: gateway + namespace: envoy-gateway-system + + ingress: + enabled: false psql: host: ${postgres_host} diff --git a/helm/kube-prometheus-stack/values.yaml b/helm/kube-prometheus-stack/values.yaml index 04d422e..0fd3d6f 100644 --- a/helm/kube-prometheus-stack/values.yaml +++ b/helm/kube-prometheus-stack/values.yaml @@ -1,12 +1,14 @@ grafana: ingress: - enabled: true - hosts: - - ${grafana_host}.${domain} - tls: - - secretName: wildcard-certificate - hosts: - - ${grafana_host}.${domain} + enabled: false + route: + main: + enabled: true + hostnames: + - ${grafana_host}.${domain} + parentRefs: + - name: gateway + namespace: envoy-gateway-system prometheus: prometheusSpec: diff --git a/helm/wildcard-certificate/chart/templates/_helpers.tpl b/helm/wildcard-certificate/chart/templates/_helpers.tpl deleted file mode 100644 index 82469f0..0000000 --- a/helm/wildcard-certificate/chart/templates/_helpers.tpl +++ /dev/null @@ -1,62 +0,0 @@ -{{/* -Expand the name of the chart. -*/}} -{{- define "wildcard-certificate.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "wildcard-certificate.fullname" -}} -{{- if .Values.fullnameOverride }} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- $name := default .Chart.Name .Values.nameOverride }} -{{- if contains $name .Release.Name }} -{{- .Release.Name | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} -{{- end }} -{{- end }} -{{- end }} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "wildcard-certificate.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Common labels -*/}} -{{- define "wildcard-certificate.labels" -}} -helm.sh/chart: {{ include "wildcard-certificate.chart" . }} -{{ include "wildcard-certificate.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "wildcard-certificate.selectorLabels" -}} -app.kubernetes.io/name: {{ include "wildcard-certificate.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - -{{/* -Create the name of the service account to use -*/}} -{{- define "wildcard-certificate.serviceAccountName" -}} -{{- if .Values.serviceAccount.create }} -{{- default (include "wildcard-certificate.fullname" .) .Values.serviceAccount.name }} -{{- else }} -{{- default "default" .Values.serviceAccount.name }} -{{- end }} -{{- end }} diff --git a/helm/wildcard-certificate/values.yaml b/helm/wildcard-certificate/values.yaml deleted file mode 100644 index 4edfcdf..0000000 --- a/helm/wildcard-certificate/values.yaml +++ /dev/null @@ -1,2 +0,0 @@ -domain: ${domain} -reflectNamespaces: "${reflectNamespaces}" \ No newline at end of file diff --git a/terraform/dns.tf b/terraform/dns.tf index 77e7a6f..0a0fc79 100644 --- a/terraform/dns.tf +++ b/terraform/dns.tf @@ -1,5 +1,5 @@ locals { - lb_ip = try(data.kubernetes_service_v1.ingress_nginx.status[0].load_balancer[0].ingress[0].ip, null) + lb_ip = try(data.kubernetes_service_v1.envoy_gateway.status[0].load_balancer[0].ingress[0].ip, null) records = toset([ var.gitlab_host, var.registry_host, "*.${var.pages_host}", var.grafana_host ]) diff --git a/terraform/helm.tf b/terraform/helm.tf index 2de9c37..297b907 100644 --- a/terraform/helm.tf +++ b/terraform/helm.tf @@ -50,15 +50,19 @@ resource "helm_release" "cluster_issuer" { depends_on = [helm_release.cert_manager] } -resource "helm_release" "wildcard_certificate" { - name = "wildcard-certificate" - namespace = kubernetes_namespace_v1.cert_manager.metadata[0].name - chart = "${path.module}/../helm/wildcard-certificate/chart" +resource "helm_release" "dns01_certificate" { + name = "dns01-certificate" + namespace = kubernetes_namespace_v1.envoy_gateway_system.metadata[0].name + chart = "${path.module}/../helm/dns01-certificate/chart" values = [ - templatefile("${path.module}/../helm/wildcard-certificate/values.yaml", - { + yamlencode({ domain = var.domain_name + dnsNameTemplates = [ + "{{ .Values.domain }}", + "*.{{ .Values.domain }}", + "*.pages.{{ .Values.domain }}" + ] reflectNamespaces = "${kubernetes_namespace_v1.gitlab.metadata[0].name},${kubernetes_namespace_v1.monitoring.metadata[0].name}" }) ] @@ -66,6 +70,24 @@ resource "helm_release" "wildcard_certificate" { depends_on = [helm_release.cert_manager, helm_release.cluster_issuer, helm_release.reflector] } +resource "helm_release" "envoy_gateway" { + name = "eg" + namespace = kubernetes_namespace_v1.envoy_gateway_system.metadata[0].name + chart = "${path.module}/../helm/gateway-config/chart" + + wait = true + + depends_on = [ helm_release.cert_manager, helm_release.dns01_certificate ] +} + +resource "helm_release" "gateway_config" { + name = "gateway-config" + namespace = kubernetes_namespace_v1.envoy_gateway_system.metadata[0].name + repository = "oci://docker.io/envoyproxy/gateway-helm" + chart = "gateway-helm" + version = "1.7.2" +} + resource "helm_release" "ingress_nginx" { name = "ingress-nginx" namespace = kubernetes_namespace_v1.ingress_nginx.metadata[0].name @@ -113,10 +135,12 @@ resource "helm_release" "gitlab" { digitalocean_database_connection_pool.main, digitalocean_database_cluster.valkey, helm_release.cert_manager, - helm_release.wildcard_certificate, + helm_release.dns01_certificate, helm_release.reflector, helm_release.cluster_issuer, helm_release.ingress_nginx, + helm_release.envoy_gateway, + helm_release.gateway_config, digitalocean_record.main, kubernetes_secret_v1.gitlab_initial_root_password, kubernetes_secret_v1.gitlab_postgres, @@ -140,4 +164,6 @@ resource "helm_release" "kube_prometheus_stack" { domain = var.domain_name }) ] + + depends_on = [ helm_release.envoy_gateway ] } \ No newline at end of file diff --git a/terraform/kubernetes.tf b/terraform/kubernetes.tf index fbfc969..b74e352 100644 --- a/terraform/kubernetes.tf +++ b/terraform/kubernetes.tf @@ -6,17 +6,25 @@ # depends_on = [ digitalocean_kubernetes_cluster.main ] # } -resource "kubernetes_namespace_v1" "ingress_nginx" { +resource "kubernetes_namespace_v1" "cert_manager" { metadata { - name = "ingress-nginx" + name = "cert-manager" } depends_on = [ digitalocean_kubernetes_cluster.main ] } -resource "kubernetes_namespace_v1" "cert_manager" { +resource "kubernetes_namespace_v1" "envoy_gateway_system" { metadata { - name = "cert-manager" + name = "envoy-gateway-system" + } + + depends_on = [ digitalocean_kubernetes_cluster.main ] +} + +resource "kubernetes_namespace_v1" "ingress_nginx" { + metadata { + name = "ingress-nginx" } depends_on = [ digitalocean_kubernetes_cluster.main ] @@ -167,14 +175,14 @@ resource "kubernetes_secret_v1" "gitlab_sendgrid_secret" { } resource "time_sleep" "wait_for_lb" { - depends_on = [ helm_release.ingress_nginx ] + depends_on = [ helm_release.envoy_gateway ] create_duration = "120s" } -data "kubernetes_service_v1" "ingress_nginx" { +data "kubernetes_service_v1" "envoy_gateway" { metadata { - name = "ingress-nginx-controller" - namespace = kubernetes_namespace_v1.ingress_nginx.metadata[0].name + name = "envoy-gateway" + namespace = kubernetes_namespace_v1.envoy_gateway_system.metadata[0].name } depends_on = [ time_sleep.wait_for_lb ]