charts
diff --git a/charts/ingress-nginx/templates/NOTES.txt b/charts/ingress-nginx/templates/NOTES.txt
new file mode 100644
index 0000000..03ece9c
--- /dev/null
+++ b/charts/ingress-nginx/templates/NOTES.txt
@@ -0,0 +1,71 @@
+The ingress-nginx controller has been installed.
+
+{{- if contains "NodePort" .Values.controller.service.type }}
+Get the application URL by running these commands:
+
+{{- if (not (empty .Values.controller.service.nodePorts.http)) }}
+  export HTTP_NODE_PORT={{ .Values.controller.service.nodePorts.http }}
+{{- else }}
+  export HTTP_NODE_PORT=$(kubectl --namespace {{ .Release.Namespace }} get services -o jsonpath="{.spec.ports[0].nodePort}" {{ include "ingress-nginx.controller.fullname" . }})
+{{- end }}
+{{- if (not (empty .Values.controller.service.nodePorts.https)) }}
+  export HTTPS_NODE_PORT={{ .Values.controller.service.nodePorts.https }}
+{{- else }}
+  export HTTPS_NODE_PORT=$(kubectl --namespace {{ .Release.Namespace }} get services -o jsonpath="{.spec.ports[1].nodePort}" {{ include "ingress-nginx.controller.fullname" . }})
+{{- end }}
+  export NODE_IP=$(kubectl --namespace {{ .Release.Namespace }} get nodes -o jsonpath="{.items[0].status.addresses[1].address}")
+
+  echo "Visit http://$NODE_IP:$HTTP_NODE_PORT to access your application via HTTP."
+  echo "Visit https://$NODE_IP:$HTTPS_NODE_PORT to access your application via HTTPS."
+{{- else if contains "LoadBalancer" .Values.controller.service.type }}
+It may take a few minutes for the LoadBalancer IP to be available.
+You can watch the status by running 'kubectl --namespace {{ .Release.Namespace }} get services -o wide -w {{ include "ingress-nginx.controller.fullname" . }}'
+{{- else if contains "ClusterIP"  .Values.controller.service.type }}
+Get the application URL by running these commands:
+  export POD_NAME=$(kubectl --namespace {{ .Release.Namespace }} get pods -o jsonpath="{.items[0].metadata.name}" -l "app={{ template "ingress-nginx.name" . }},component={{ .Values.controller.name }},release={{ .Release.Name }}")
+  kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80
+  echo "Visit http://127.0.0.1:8080 to access your application."
+{{- end }}
+
+An example Ingress that makes use of the controller:
+
+  apiVersion: networking.k8s.io/v1
+  kind: Ingress
+  metadata:
+    annotations:
+      kubernetes.io/ingress.class: {{ .Values.controller.ingressClassResource.name }}
+    name: example
+    namespace: foo
+  spec:
+    rules:
+      - host: www.example.com
+        http:
+          paths:
+            - backend:
+                serviceName: exampleService
+                servicePort: 80
+              path: /
+    # This section is only required if TLS is to be enabled for the Ingress
+    tls:
+        - hosts:
+            - www.example.com
+          secretName: example-tls
+
+If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided:
+
+  apiVersion: v1
+  kind: Secret
+  metadata:
+    name: example-tls
+    namespace: foo
+  data:
+    tls.crt: <base64 encoded cert>
+    tls.key: <base64 encoded key>
+  type: kubernetes.io/tls
+
+{{- if .Values.controller.headers }}
+#################################################################################
+######   WARNING: `controller.headers` has been deprecated!                 #####
+######            It has been renamed to `controller.proxySetHeaders`.      #####
+#################################################################################
+{{- end }}
diff --git a/charts/ingress-nginx/templates/_helpers.tpl b/charts/ingress-nginx/templates/_helpers.tpl
new file mode 100644
index 0000000..8b1fd09
--- /dev/null
+++ b/charts/ingress-nginx/templates/_helpers.tpl
@@ -0,0 +1,134 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "ingress-nginx.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "ingress-nginx.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | 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).
+*/}}
+{{- define "ingress-nginx.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 a default fully qualified controller name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+*/}}
+{{- define "ingress-nginx.controller.fullname" -}}
+{{- printf "%s-%s" (include "ingress-nginx.fullname" .) .Values.controller.name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Construct the path for the publish-service.
+
+By convention this will simply use the <namespace>/<controller-name> to match the name of the
+service generated.
+
+Users can provide an override for an explicit service they want bound via `.Values.controller.publishService.pathOverride`
+
+*/}}
+{{- define "ingress-nginx.controller.publishServicePath" -}}
+{{- $defServiceName := printf "%s/%s" "$(POD_NAMESPACE)" (include "ingress-nginx.controller.fullname" .) -}}
+{{- $servicePath := default $defServiceName .Values.controller.publishService.pathOverride }}
+{{- print $servicePath | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified default backend name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+*/}}
+{{- define "ingress-nginx.defaultBackend.fullname" -}}
+{{- printf "%s-%s" (include "ingress-nginx.fullname" .) .Values.defaultBackend.name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "ingress-nginx.labels" -}}
+helm.sh/chart: {{ include "ingress-nginx.chart" . }}
+{{ include "ingress-nginx.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Selector labels
+*/}}
+{{- define "ingress-nginx.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "ingress-nginx.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end -}}
+
+{{/*
+Create the name of the controller service account to use
+*/}}
+{{- define "ingress-nginx.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+    {{ default (include "ingress-nginx.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+    {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create the name of the backend service account to use - only used when podsecuritypolicy is also enabled
+*/}}
+{{- define "ingress-nginx.defaultBackend.serviceAccountName" -}}
+{{- if .Values.defaultBackend.serviceAccount.create -}}
+    {{ default (printf "%s-backend" (include "ingress-nginx.fullname" .)) .Values.defaultBackend.serviceAccount.name }}
+{{- else -}}
+    {{ default "default-backend" .Values.defaultBackend.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Return the appropriate apiGroup for PodSecurityPolicy.
+*/}}
+{{- define "podSecurityPolicy.apiGroup" -}}
+{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
+{{- print "policy" -}}
+{{- else -}}
+{{- print "extensions" -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Check the ingress controller version tag is at most three versions behind the last release
+*/}}
+{{- define "isControllerTagValid" -}}
+{{- if not (semverCompare ">=0.27.0-0" .Values.controller.image.tag) -}}
+{{- fail "Controller container image tag should be 0.27.0 or higher" -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+IngressClass parameters.
+*/}}
+{{- define "ingressClass.parameters" -}}
+  {{- if .Values.controller.ingressClassResource.parameters -}}
+          parameters:
+{{ toYaml .Values.controller.ingressClassResource.parameters | indent 4}}
+  {{ end }}
+{{- end -}}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml
new file mode 100644
index 0000000..fd762f9
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml
@@ -0,0 +1,31 @@
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: {{ include "ingress-nginx.fullname" . }}-admission
+  annotations:
+    "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
+    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+rules:
+  - apiGroups:
+      - admissionregistration.k8s.io
+    resources:
+      - validatingwebhookconfigurations
+    verbs:
+      - get
+      - update
+{{- if .Values.podSecurityPolicy.enabled }}
+  - apiGroups: ['extensions']
+    resources: ['podsecuritypolicies']
+    verbs:     ['use']
+    resourceNames:
+    {{- with .Values.controller.admissionWebhooks.existingPsp }}
+    - {{ . }}
+    {{- else }}
+    - {{ include "ingress-nginx.fullname" . }}-admission
+    {{- end }}
+{{- end }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml
new file mode 100644
index 0000000..4990fb1
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml
@@ -0,0 +1,20 @@
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name:  {{ include "ingress-nginx.fullname" . }}-admission
+  annotations:
+    "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
+    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: {{ include "ingress-nginx.fullname" . }}-admission
+subjects:
+  - kind: ServiceAccount
+    name: {{ include "ingress-nginx.fullname" . }}-admission
+    namespace: {{ .Release.Namespace | quote }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml
new file mode 100644
index 0000000..1f58bdc
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml
@@ -0,0 +1,64 @@
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: {{ include "ingress-nginx.fullname" . }}-admission-create
+  namespace: {{ .Release.Namespace }}
+  annotations:
+    "helm.sh/hook": pre-install,pre-upgrade
+    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+spec:
+{{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }}
+  # Alpha feature since k8s 1.12
+  ttlSecondsAfterFinished: 0
+{{- end }}
+  template:
+    metadata:
+      name: {{ include "ingress-nginx.fullname" . }}-admission-create
+    {{- if .Values.controller.admissionWebhooks.patch.podAnnotations }}
+      annotations: {{ toYaml .Values.controller.admissionWebhooks.patch.podAnnotations | nindent 8 }}
+    {{- end }}
+      labels:
+        {{- include "ingress-nginx.labels" . | nindent 8 }}
+        app.kubernetes.io/component: admission-webhook
+    spec:
+    {{- if .Values.controller.admissionWebhooks.patch.priorityClassName }}
+      priorityClassName: {{ .Values.controller.admissionWebhooks.patch.priorityClassName }}
+    {{- end }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }}
+    {{- end }}
+      containers:
+        - name: create
+          {{- with .Values.controller.admissionWebhooks.patch.image }}
+          image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ .image }}{{- end -}}:{{ .tag }}{{- if (.digest) -}} @{{.digest}} {{- end -}}"
+          {{- end }}
+          imagePullPolicy: {{ .Values.controller.admissionWebhooks.patch.image.pullPolicy }}
+          args:
+            - create
+            - --host={{ include "ingress-nginx.controller.fullname" . }}-admission,{{ include "ingress-nginx.controller.fullname" . }}-admission.$(POD_NAMESPACE).svc
+            - --namespace=$(POD_NAMESPACE)
+            - --secret-name={{ include "ingress-nginx.fullname" . }}-admission
+          env:
+            - name: POD_NAMESPACE
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.namespace
+          {{- if .Values.controller.admissionWebhooks.createSecretJob.resources }}
+          resources: {{ toYaml .Values.controller.admissionWebhooks.createSecretJob.resources | nindent 12 }}
+          {{- end }}
+      restartPolicy: OnFailure
+      serviceAccountName: {{ include "ingress-nginx.fullname" . }}-admission
+    {{- if .Values.controller.admissionWebhooks.patch.nodeSelector }}
+      nodeSelector: {{ toYaml .Values.controller.admissionWebhooks.patch.nodeSelector | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.admissionWebhooks.patch.tolerations }}
+      tolerations: {{ toYaml .Values.controller.admissionWebhooks.patch.tolerations | nindent 8 }}
+    {{- end }}
+      securityContext:
+        runAsNonRoot: true
+        runAsUser: {{ .Values.controller.admissionWebhooks.patch.runAsUser }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml
new file mode 100644
index 0000000..6d01ad2
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml
@@ -0,0 +1,66 @@
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: {{ include "ingress-nginx.fullname" . }}-admission-patch
+  namespace: {{ .Release.Namespace }}
+  annotations:
+    "helm.sh/hook": post-install,post-upgrade
+    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+spec:
+{{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }}
+  # Alpha feature since k8s 1.12
+  ttlSecondsAfterFinished: 0
+{{- end }}
+  template:
+    metadata:
+      name: {{ include "ingress-nginx.fullname" . }}-admission-patch
+    {{- if .Values.controller.admissionWebhooks.patch.podAnnotations }}
+      annotations: {{ toYaml .Values.controller.admissionWebhooks.patch.podAnnotations | nindent 8 }}
+    {{- end }}
+      labels:
+        {{- include "ingress-nginx.labels" . | nindent 8 }}
+        app.kubernetes.io/component: admission-webhook
+    spec:
+    {{- if .Values.controller.admissionWebhooks.patch.priorityClassName }}
+      priorityClassName: {{ .Values.controller.admissionWebhooks.patch.priorityClassName }}
+    {{- end }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }}
+    {{- end }}
+      containers:
+        - name: patch
+          {{- with .Values.controller.admissionWebhooks.patch.image }}
+          image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ .image }}{{- end -}}:{{ .tag }}{{- if (.digest) -}} @{{.digest}} {{- end -}}"
+          {{- end }}
+          imagePullPolicy: {{ .Values.controller.admissionWebhooks.patch.image.pullPolicy }}
+          args:
+            - patch
+            - --webhook-name={{ include "ingress-nginx.fullname" . }}-admission
+            - --namespace=$(POD_NAMESPACE)
+            - --patch-mutating=false
+            - --secret-name={{ include "ingress-nginx.fullname" . }}-admission
+            - --patch-failure-policy={{ .Values.controller.admissionWebhooks.failurePolicy }}
+          env:
+            - name: POD_NAMESPACE
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.namespace
+          {{- if .Values.controller.admissionWebhooks.patchWebhookJob.resources }}
+          resources: {{ toYaml .Values.controller.admissionWebhooks.patchWebhookJob.resources | nindent 12 }}
+          {{- end }}
+      restartPolicy: OnFailure
+      serviceAccountName: {{ include "ingress-nginx.fullname" . }}-admission
+    {{- if .Values.controller.admissionWebhooks.patch.nodeSelector }}
+      nodeSelector: {{ toYaml .Values.controller.admissionWebhooks.patch.nodeSelector | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.admissionWebhooks.patch.tolerations }}
+      tolerations: {{ toYaml .Values.controller.admissionWebhooks.patch.tolerations | nindent 8 }}
+    {{- end }}
+      securityContext:
+        runAsNonRoot: true
+        runAsUser: {{ .Values.controller.admissionWebhooks.patch.runAsUser }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/psp.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/psp.yaml
new file mode 100644
index 0000000..d2c7de6
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/psp.yaml
@@ -0,0 +1,36 @@
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled .Values.podSecurityPolicy.enabled (empty .Values.controller.admissionWebhooks.existingPsp) -}}
+apiVersion: policy/v1beta1
+kind: PodSecurityPolicy
+metadata:
+  name: {{ include "ingress-nginx.fullname" . }}-admission
+  annotations:
+    "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
+    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+spec:
+  allowPrivilegeEscalation: false
+  fsGroup:
+    ranges:
+    - max: 65535
+      min: 1
+    rule: MustRunAs
+  requiredDropCapabilities:
+  - ALL
+  runAsUser:
+    rule: MustRunAsNonRoot
+  seLinux:
+    rule: RunAsAny
+  supplementalGroups:
+    ranges:
+    - max: 65535
+      min: 1
+    rule: MustRunAs
+  volumes:
+  - configMap
+  - emptyDir
+  - projected
+  - secret
+  - downwardAPI
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/role.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/role.yaml
new file mode 100644
index 0000000..9b083ee
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/role.yaml
@@ -0,0 +1,21 @@
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name:  {{ include "ingress-nginx.fullname" . }}-admission
+  namespace: {{ .Release.Namespace }}
+  annotations:
+    "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
+    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - secrets
+    verbs:
+      - get
+      - create
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml
new file mode 100644
index 0000000..edda07f
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml
@@ -0,0 +1,21 @@
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: {{ include "ingress-nginx.fullname" . }}-admission
+  namespace: {{ .Release.Namespace }}
+  annotations:
+    "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
+    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: {{ include "ingress-nginx.fullname" . }}-admission
+subjects:
+  - kind: ServiceAccount
+    name: {{ include "ingress-nginx.fullname" . }}-admission
+    namespace: {{ .Release.Namespace | quote }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml
new file mode 100644
index 0000000..1ff0f7f
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml
@@ -0,0 +1,13 @@
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ include "ingress-nginx.fullname" . }}-admission
+  namespace: {{ .Release.Namespace }}
+  annotations:
+    "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
+    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml b/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml
new file mode 100644
index 0000000..712f74f
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml
@@ -0,0 +1,45 @@
+{{- if .Values.controller.admissionWebhooks.enabled -}}
+# before changing this value, check the required kubernetes version
+# https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#prerequisites
+apiVersion: admissionregistration.k8s.io/v1
+kind: ValidatingWebhookConfiguration
+metadata:
+  {{- if .Values.controller.admissionWebhooks.annotations }}
+  annotations: {{ toYaml .Values.controller.admissionWebhooks.annotations | nindent 4 }}
+  {{- end }}
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+  name: {{ include "ingress-nginx.fullname" . }}-admission
+webhooks:
+  - name: validate.nginx.ingress.kubernetes.io
+    matchPolicy: Equivalent
+    rules:
+      - apiGroups:
+          - networking.k8s.io
+        apiVersions:
+          - v1
+        operations:
+          - CREATE
+          - UPDATE
+        resources:
+          - ingresses
+    failurePolicy: {{ .Values.controller.admissionWebhooks.failurePolicy | default "Fail" }}
+    sideEffects: None
+    admissionReviewVersions:
+      - v1
+    clientConfig:
+      service:
+        namespace: {{ .Release.Namespace | quote }}
+        name: {{ include "ingress-nginx.controller.fullname" . }}-admission
+        path: /networking/v1/ingresses
+    {{- if .Values.controller.admissionWebhooks.timeoutSeconds }}
+    timeoutSeconds: {{ .Values.controller.admissionWebhooks.timeoutSeconds }}
+    {{- end }}
+    {{- if .Values.controller.admissionWebhooks.namespaceSelector }}
+    namespaceSelector: {{ toYaml .Values.controller.admissionWebhooks.namespaceSelector | nindent 6 }}
+    {{- end }}
+    {{- if .Values.controller.admissionWebhooks.objectSelector }}
+    objectSelector: {{ toYaml .Values.controller.admissionWebhooks.objectSelector | nindent 6 }}
+    {{- end }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/clusterrole.yaml b/charts/ingress-nginx/templates/clusterrole.yaml
new file mode 100644
index 0000000..c1f901d
--- /dev/null
+++ b/charts/ingress-nginx/templates/clusterrole.yaml
@@ -0,0 +1,81 @@
+{{- if .Values.rbac.create }}
+
+{{- if and .Values.rbac.scope (not .Values.controller.scope.enabled) -}}
+  {{ required "Invalid configuration: 'rbac.scope' should be equal to 'controller.scope.enabled' (true/false)." (index (dict) ".") }}
+{{- end }}
+
+{{- if not .Values.rbac.scope -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+  name: {{ include "ingress-nginx.fullname" . }}
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - configmaps
+      - endpoints
+      - nodes
+      - pods
+      - secrets
+    verbs:
+      - list
+      - watch
+{{- if and .Values.controller.scope.enabled .Values.controller.scope.namespace }}
+  - apiGroups:
+      - ""
+    resources:
+      - namespaces
+    resourceNames:
+      - "{{ .Values.controller.scope.namespace }}"
+    verbs:
+      - get
+{{- end }}
+  - apiGroups:
+      - ""
+    resources:
+      - nodes
+    verbs:
+      - get
+  - apiGroups:
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+      - networking.k8s.io
+    resources:
+      - ingresses
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+      - networking.k8s.io
+    resources:
+      - ingresses/status
+    verbs:
+      - update
+  - apiGroups:
+      - networking.k8s.io
+    resources:
+      - ingressclasses
+    verbs:
+      - get
+      - list
+      - watch
+{{- end }}
+
+{{- end }}
diff --git a/charts/ingress-nginx/templates/clusterrolebinding.yaml b/charts/ingress-nginx/templates/clusterrolebinding.yaml
new file mode 100644
index 0000000..81be52b
--- /dev/null
+++ b/charts/ingress-nginx/templates/clusterrolebinding.yaml
@@ -0,0 +1,16 @@
+{{- if and .Values.rbac.create (not .Values.rbac.scope) -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+  name: {{ include "ingress-nginx.fullname" . }}
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: {{ include "ingress-nginx.fullname" . }}
+subjects:
+  - kind: ServiceAccount
+    name: {{ template "ingress-nginx.serviceAccountName" . }}
+    namespace: {{ .Release.Namespace | quote }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-configmap-addheaders.yaml b/charts/ingress-nginx/templates/controller-configmap-addheaders.yaml
new file mode 100644
index 0000000..e0b7a0f
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-configmap-addheaders.yaml
@@ -0,0 +1,11 @@
+{{- if .Values.controller.addHeaders -}}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+  name: {{ include "ingress-nginx.fullname" . }}-custom-add-headers
+  namespace: {{ .Release.Namespace }}
+data: {{ toYaml .Values.controller.addHeaders | nindent 2 }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-configmap-proxyheaders.yaml b/charts/ingress-nginx/templates/controller-configmap-proxyheaders.yaml
new file mode 100644
index 0000000..91f22f0
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-configmap-proxyheaders.yaml
@@ -0,0 +1,16 @@
+{{- if or .Values.controller.proxySetHeaders .Values.controller.headers -}}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+  name: {{ include "ingress-nginx.fullname" . }}-custom-proxy-headers
+  namespace: {{ .Release.Namespace }}
+data:
+{{- if .Values.controller.proxySetHeaders }}
+{{ toYaml .Values.controller.proxySetHeaders | indent 2 }}
+{{ else if and .Values.controller.headers (not .Values.controller.proxySetHeaders) }}
+{{ toYaml .Values.controller.headers | indent 2 }}
+{{- end }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-configmap-tcp.yaml b/charts/ingress-nginx/templates/controller-configmap-tcp.yaml
new file mode 100644
index 0000000..aaf336f
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-configmap-tcp.yaml
@@ -0,0 +1,14 @@
+{{- if .Values.tcp -}}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+{{- if .Values.controller.tcp.annotations }}
+  annotations: {{ toYaml .Values.controller.tcp.annotations | nindent 4 }}
+{{- end }}
+  name: {{ include "ingress-nginx.fullname" . }}-tcp
+  namespace: {{ .Release.Namespace }}
+data: {{ tpl (toYaml .Values.tcp) . | nindent 2 }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-configmap-udp.yaml b/charts/ingress-nginx/templates/controller-configmap-udp.yaml
new file mode 100644
index 0000000..7f46791
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-configmap-udp.yaml
@@ -0,0 +1,14 @@
+{{- if .Values.udp -}}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+{{- if .Values.controller.udp.annotations }}
+  annotations: {{ toYaml .Values.controller.udp.annotations | nindent 4 }}
+{{- end }}
+  name: {{ include "ingress-nginx.fullname" . }}-udp
+  namespace: {{ .Release.Namespace }}
+data: {{ tpl (toYaml .Values.udp) . | nindent 2 }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-configmap.yaml b/charts/ingress-nginx/templates/controller-configmap.yaml
new file mode 100644
index 0000000..6973892
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-configmap.yaml
@@ -0,0 +1,26 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+{{- if .Values.controller.configAnnotations }}
+  annotations: {{ toYaml .Values.controller.configAnnotations | nindent 4 }}
+{{- end }}
+  name: {{ include "ingress-nginx.controller.fullname" . }}
+  namespace: {{ .Release.Namespace }}
+data:
+  allow-snippet-annotations: "{{ .Values.controller.allowSnippetAnnotations }}"
+{{- if .Values.controller.addHeaders }}
+  add-headers: {{ .Release.Namespace }}/{{ include "ingress-nginx.fullname" . }}-custom-add-headers
+{{- end }}
+{{- if or .Values.controller.proxySetHeaders .Values.controller.headers }}
+  proxy-set-headers: {{ .Release.Namespace }}/{{ include "ingress-nginx.fullname" . }}-custom-proxy-headers
+{{- end }}
+{{- if .Values.dhParam }}
+  ssl-dh-param: {{ printf "%s/%s" .Release.Namespace (include "ingress-nginx.controller.fullname" .) }}
+{{- end }}
+{{- range $key, $value := .Values.controller.config }}
+    {{ $key | nindent 2 }}: {{ $value | quote }}
+{{- end }}
+
diff --git a/charts/ingress-nginx/templates/controller-daemonset.yaml b/charts/ingress-nginx/templates/controller-daemonset.yaml
new file mode 100644
index 0000000..68291ed
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-daemonset.yaml
@@ -0,0 +1,256 @@
+{{- if or (eq .Values.controller.kind "DaemonSet") (eq .Values.controller.kind "Both") -}}
+{{- include  "isControllerTagValid" . -}}
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
+  name: {{ include "ingress-nginx.controller.fullname" . }}
+  namespace: {{ .Release.Namespace }}
+  {{- if .Values.controller.annotations }}
+  annotations: {{ toYaml .Values.controller.annotations | nindent 4 }}
+  {{- end }}
+spec:
+  selector:
+    matchLabels:
+      {{- include "ingress-nginx.selectorLabels" . | nindent 6 }}
+      app.kubernetes.io/component: controller
+  revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
+  {{- if .Values.controller.updateStrategy }}
+  updateStrategy: {{ toYaml .Values.controller.updateStrategy | nindent 4 }}
+  {{- end }}
+  minReadySeconds: {{ .Values.controller.minReadySeconds }}
+  template:
+    metadata:
+    {{- if .Values.controller.podAnnotations }}
+      annotations:
+      {{- range $key, $value := .Values.controller.podAnnotations }}
+        {{ $key }}: {{ $value | quote }}
+      {{- end }}
+    {{- end }}
+      labels:
+        {{- include "ingress-nginx.selectorLabels" . | nindent 8 }}
+        app.kubernetes.io/component: controller
+      {{- if .Values.controller.podLabels }}
+        {{- toYaml .Values.controller.podLabels | nindent 8 }}
+      {{- end }}
+    spec:
+    {{- if .Values.controller.dnsConfig }}
+      dnsConfig: {{ toYaml .Values.controller.dnsConfig | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.hostname }}
+      hostname: {{ toYaml .Values.controller.hostname | nindent 8 }}
+    {{- end }}
+      dnsPolicy: {{ .Values.controller.dnsPolicy }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.priorityClassName }}
+      priorityClassName: {{ .Values.controller.priorityClassName }}
+    {{- end }}
+    {{- if or .Values.controller.podSecurityContext .Values.controller.sysctls }}
+      securityContext:
+    {{- end }}
+    {{- if .Values.controller.podSecurityContext  }}
+        {{- toYaml .Values.controller.podSecurityContext | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.sysctls }}
+        sysctls:
+    {{- range $sysctl, $value := .Values.controller.sysctls }}
+        - name: {{ $sysctl | quote }}
+          value: {{ $value | quote }}
+    {{- end }}
+    {{- end }}
+      containers:
+        - name: {{ .Values.controller.containerName }}
+          {{- with .Values.controller.image }}
+          image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ .image }}{{- end -}}:{{ .tag }}{{- if (.digest) -}} @{{.digest}} {{- end -}}"
+          {{- end }}
+          imagePullPolicy: {{ .Values.controller.image.pullPolicy }}
+        {{- if .Values.controller.lifecycle }}
+          lifecycle: {{ toYaml .Values.controller.lifecycle | nindent 12 }}
+        {{- end }}
+          args:
+            - /nginx-ingress-controller
+          {{- if .Values.defaultBackend.enabled }}
+            - --default-backend-service=$(POD_NAMESPACE)/{{ include "ingress-nginx.defaultBackend.fullname" . }}
+          {{- end }}
+          {{- if .Values.controller.publishService.enabled }}
+            - --publish-service={{ template "ingress-nginx.controller.publishServicePath" . }}
+          {{- end }}
+            - --election-id={{ .Values.controller.electionID }}
+            - --controller-class={{ .Values.controller.ingressClassResource.controllerValue }}
+            - --configmap={{ default "$(POD_NAMESPACE)" .Values.controller.configMapNamespace }}/{{ include "ingress-nginx.controller.fullname" . }}
+          {{- if .Values.tcp }}
+            - --tcp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.tcp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-tcp
+          {{- end }}
+          {{- if .Values.udp }}
+            - --udp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.udp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-udp
+          {{- end }}
+          {{- if .Values.controller.scope.enabled }}
+            - --watch-namespace={{ default "$(POD_NAMESPACE)" .Values.controller.scope.namespace }}
+          {{- end }}
+          {{- if and .Values.controller.reportNodeInternalIp .Values.controller.hostNetwork }}
+            - --report-node-internal-ip-address={{ .Values.controller.reportNodeInternalIp }}
+          {{- end }}
+          {{- if .Values.controller.admissionWebhooks.enabled }}
+            - --validating-webhook=:{{ .Values.controller.admissionWebhooks.port }}
+            - --validating-webhook-certificate={{ .Values.controller.admissionWebhooks.certificate }}
+            - --validating-webhook-key={{ .Values.controller.admissionWebhooks.key }}
+          {{- end }}
+          {{- if .Values.controller.maxmindMirror }}
+            - --maxmind-mirror={{ .Values.controller.maxmindMirror }}
+          {{- end}}
+          {{- if .Values.controller.maxmindLicenseKey }}
+            - --maxmind-license-key={{ .Values.controller.maxmindLicenseKey }}
+          {{- end }}
+          {{- if not (eq .Values.controller.healthCheckPath "/healthz") }}
+            - --health-check-path={{ .Values.controller.healthCheckPath }}
+          {{- end }}
+          {{- if .Values.controller.healthCheckHost }}
+            - --healthz-host={{ .Values.controller.healthCheckHost }}
+          {{- end }}
+          {{- if .Values.controller.ingressClassByName }}
+            - --ingress-class-by-name=true
+          {{- end }}
+          {{- if .Values.controller.watchIngressWithoutClass }}
+            - --watch-ingress-without-class=true
+          {{- end }}
+          {{- range $key, $value := .Values.controller.extraArgs }}
+            {{- /* Accept keys without values or with false as value */}}
+            {{- if eq ($value | quote | len) 2 }}
+            - --{{ $key }}
+            {{- else }}
+            - --{{ $key }}={{ $value }}
+            {{- end }}
+          {{- end }}
+          securityContext:
+            capabilities:
+                drop:
+                - ALL
+                add:
+                - NET_BIND_SERVICE
+            runAsUser: {{ .Values.controller.image.runAsUser }}
+            allowPrivilegeEscalation: {{ .Values.controller.image.allowPrivilegeEscalation }}
+          env:
+            - name: POD_NAME
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.name
+            - name: POD_NAMESPACE
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.namespace
+          {{- if .Values.controller.enableMimalloc }}
+            - name: LD_PRELOAD
+              value: /usr/local/lib/libmimalloc.so
+          {{- end }}
+          {{- if .Values.controller.extraEnvs }}
+            {{- toYaml .Values.controller.extraEnvs | nindent 12 }}
+          {{- end }}
+          {{- if .Values.controller.startupProbe }}
+          startupProbe: {{ toYaml .Values.controller.startupProbe | nindent 12 }}
+          {{- end }}
+          livenessProbe: {{ toYaml .Values.controller.livenessProbe | nindent 12 }}
+          readinessProbe: {{ toYaml .Values.controller.readinessProbe | nindent 12 }}
+          ports:
+          {{- range $key, $value := .Values.controller.containerPort }}
+            - name: {{ $key }}
+              containerPort: {{ $value }}
+              protocol: TCP
+              {{- if $.Values.controller.hostPort.enabled }}
+              hostPort: {{ index $.Values.controller.hostPort.ports $key | default $value }}
+              {{- end }}
+          {{- end }}
+          {{- if .Values.controller.metrics.enabled }}
+            - name: metrics
+              containerPort: {{ .Values.controller.metrics.port }}
+              protocol: TCP
+          {{- end }}
+          {{- if .Values.controller.admissionWebhooks.enabled }}
+            - name: webhook
+              containerPort: {{ .Values.controller.admissionWebhooks.port }}
+              protocol: TCP
+          {{- end }}
+          {{- range $key, $value := .Values.tcp }}
+            - name: {{ $key }}-tcp
+              containerPort: {{ $key }}
+              protocol: TCP
+              {{- if $.Values.controller.hostPort.enabled }}
+              hostPort: {{ $key }}
+              {{- end }}
+          {{- end }}
+          {{- range $key, $value := .Values.udp }}
+            - name: {{ $key }}-udp
+              containerPort: {{ $key }}
+              protocol: UDP
+              {{- if $.Values.controller.hostPort.enabled }}
+              hostPort: {{ $key }}
+              {{- end }}
+          {{- end }}
+        {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled) }}
+          volumeMounts:
+          {{- if .Values.controller.customTemplate.configMapName }}
+            - mountPath: /etc/nginx/template
+              name: nginx-template-volume
+              readOnly: true
+          {{- end }}
+          {{- if .Values.controller.admissionWebhooks.enabled }}
+            - name: webhook-cert
+              mountPath: /usr/local/certificates/
+              readOnly: true
+          {{- end }}
+          {{- if .Values.controller.extraVolumeMounts }}
+            {{- toYaml .Values.controller.extraVolumeMounts | nindent 12 }}
+          {{- end }}
+        {{- end }}
+        {{- if .Values.controller.resources }}
+          resources: {{ toYaml .Values.controller.resources | nindent 12 }}
+        {{- end }}
+      {{- if .Values.controller.extraContainers }}
+        {{ toYaml .Values.controller.extraContainers | nindent 8 }}
+      {{- end }}
+    {{- if .Values.controller.extraInitContainers }}
+      initContainers: {{ toYaml .Values.controller.extraInitContainers | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.hostNetwork }}
+      hostNetwork: {{ .Values.controller.hostNetwork }}
+    {{- end }}
+    {{- if .Values.controller.nodeSelector }}
+      nodeSelector: {{ toYaml .Values.controller.nodeSelector | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.tolerations }}
+      tolerations: {{ toYaml .Values.controller.tolerations | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.affinity }}
+      affinity: {{ toYaml .Values.controller.affinity | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.topologySpreadConstraints }}
+      topologySpreadConstraints: {{ toYaml .Values.controller.topologySpreadConstraints | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "ingress-nginx.serviceAccountName" . }}
+      terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }}
+    {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraVolumes) }}
+      volumes:
+      {{- if .Values.controller.customTemplate.configMapName }}
+        - name: nginx-template-volume
+          configMap:
+            name: {{ .Values.controller.customTemplate.configMapName }}
+            items:
+            - key: {{ .Values.controller.customTemplate.configMapKey }}
+              path: nginx.tmpl
+      {{- end }}
+      {{- if .Values.controller.admissionWebhooks.enabled }}
+        - name: webhook-cert
+          secret:
+            secretName: {{ include "ingress-nginx.fullname" . }}-admission
+      {{- end }}
+      {{- if .Values.controller.extraVolumes }}
+        {{ toYaml .Values.controller.extraVolumes | nindent 8 }}
+      {{- end }}
+    {{- end }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-deployment.yaml b/charts/ingress-nginx/templates/controller-deployment.yaml
new file mode 100644
index 0000000..24714a5
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-deployment.yaml
@@ -0,0 +1,257 @@
+{{- if or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both") -}}
+{{- include  "isControllerTagValid" . -}}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
+  name: {{ include "ingress-nginx.controller.fullname" . }}
+  namespace: {{ .Release.Namespace }}
+  {{- if .Values.controller.annotations }}
+  annotations: {{ toYaml .Values.controller.annotations | nindent 4 }}
+  {{- end }}
+spec:
+  selector:
+    matchLabels:
+      {{- include "ingress-nginx.selectorLabels" . | nindent 6 }}
+      app.kubernetes.io/component: controller
+  {{- if not .Values.controller.autoscaling.enabled }}
+  replicas: {{ .Values.controller.replicaCount }}
+  {{- end }}
+  revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
+  {{- if .Values.controller.updateStrategy }}
+  strategy:
+    {{ toYaml .Values.controller.updateStrategy | nindent 4 }}
+  {{- end }}
+  minReadySeconds: {{ .Values.controller.minReadySeconds }}
+  template:
+    metadata:
+    {{- if .Values.controller.podAnnotations }}
+      annotations:
+      {{- range $key, $value := .Values.controller.podAnnotations }}
+        {{ $key }}: {{ $value | quote }}
+      {{- end }}
+    {{- end }}
+      labels:
+        {{- include "ingress-nginx.selectorLabels" . | nindent 8 }}
+        app.kubernetes.io/component: controller
+      {{- if .Values.controller.podLabels }}
+        {{- toYaml .Values.controller.podLabels | nindent 8 }}
+      {{- end }}
+    spec:
+    {{- if .Values.controller.dnsConfig }}
+      dnsConfig: {{ toYaml .Values.controller.dnsConfig | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.hostname }}
+      hostname: {{ toYaml .Values.controller.hostname | nindent 8 }}
+    {{- end }}
+      dnsPolicy: {{ .Values.controller.dnsPolicy }}
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.priorityClassName }}
+      priorityClassName: {{ .Values.controller.priorityClassName }}
+    {{- end }}
+    {{- if or .Values.controller.podSecurityContext .Values.controller.sysctls }}
+      securityContext:
+    {{- end }}
+    {{- if .Values.controller.podSecurityContext }}
+        {{- toYaml .Values.controller.podSecurityContext | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.sysctls }}
+        sysctls:
+    {{- range $sysctl, $value := .Values.controller.sysctls }}
+        - name: {{ $sysctl | quote }}
+          value: {{ $value | quote }}
+    {{- end }}
+    {{- end }}
+      containers:
+        - name: {{ .Values.controller.containerName }}
+          {{- with .Values.controller.image }}
+          image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ .image }}{{- end -}}:{{ .tag }}{{- if (.digest) -}} @{{.digest}} {{- end -}}"
+          {{- end }}
+          imagePullPolicy: {{ .Values.controller.image.pullPolicy }}
+        {{- if .Values.controller.lifecycle }}
+          lifecycle: {{ toYaml .Values.controller.lifecycle | nindent 12 }}
+        {{- end }}
+          args:
+            - /nginx-ingress-controller
+          {{- if .Values.defaultBackend.enabled }}
+            - --default-backend-service=$(POD_NAMESPACE)/{{ include "ingress-nginx.defaultBackend.fullname" . }}
+          {{- end }}
+          {{- if .Values.controller.publishService.enabled }}
+            - --publish-service={{ template "ingress-nginx.controller.publishServicePath" . }}
+          {{- end }}
+            - --election-id={{ .Values.controller.electionID }}
+            - --controller-class={{ .Values.controller.ingressClassResource.controllerValue }}
+            - --configmap={{ default "$(POD_NAMESPACE)" .Values.controller.configMapNamespace }}/{{ include "ingress-nginx.controller.fullname" . }}
+          {{- if .Values.tcp }}
+            - --tcp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.tcp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-tcp
+          {{- end }}
+          {{- if .Values.udp }}
+            - --udp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.udp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-udp
+          {{- end }}
+          {{- if .Values.controller.scope.enabled }}
+            - --watch-namespace={{ default "$(POD_NAMESPACE)" .Values.controller.scope.namespace }}
+          {{- end }}
+          {{- if and .Values.controller.reportNodeInternalIp .Values.controller.hostNetwork }}
+            - --report-node-internal-ip-address={{ .Values.controller.reportNodeInternalIp }}
+          {{- end }}
+          {{- if .Values.controller.admissionWebhooks.enabled }}
+            - --validating-webhook=:{{ .Values.controller.admissionWebhooks.port }}
+            - --validating-webhook-certificate={{ .Values.controller.admissionWebhooks.certificate }}
+            - --validating-webhook-key={{ .Values.controller.admissionWebhooks.key }}
+          {{- end }}
+          {{- if .Values.controller.maxmindLicenseKey }}
+            - --maxmind-license-key={{ .Values.controller.maxmindLicenseKey }}
+          {{- end }}
+          {{- if .Values.controller.healthCheckHost }}
+            - --healthz-host={{ .Values.controller.healthCheckHost }}
+          {{- end }}
+          {{- if not (eq .Values.controller.healthCheckPath "/healthz") }}
+            - --health-check-path={{ .Values.controller.healthCheckPath }}
+          {{- end }}
+          {{- if .Values.controller.ingressClassByName }}
+            - --ingress-class-by-name=true
+          {{- end }}
+          {{- if .Values.controller.watchIngressWithoutClass }}
+            - --watch-ingress-without-class=true
+          {{- end }}
+          {{- range $key, $value := .Values.controller.extraArgs }}
+            {{- /* Accept keys without values or with false as value */}}
+            {{- if eq ($value | quote | len) 2 }}
+            - --{{ $key }}
+            {{- else }}
+            - --{{ $key }}={{ $value }}
+            {{- end }}
+          {{- end }}
+          securityContext:
+            capabilities:
+                drop:
+                - ALL
+                add:
+                - NET_BIND_SERVICE
+            runAsUser: {{ .Values.controller.image.runAsUser }}
+            allowPrivilegeEscalation: {{ .Values.controller.image.allowPrivilegeEscalation }}
+          env:
+            - name: POD_NAME
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.name
+            - name: POD_NAMESPACE
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.namespace
+          {{- if .Values.controller.enableMimalloc }}
+            - name: LD_PRELOAD
+              value: /usr/local/lib/libmimalloc.so
+          {{- end }}
+          {{- if .Values.controller.extraEnvs }}
+            {{- toYaml .Values.controller.extraEnvs | nindent 12 }}
+          {{- end }}
+          {{- if .Values.controller.startupProbe }}
+          startupProbe: {{ toYaml .Values.controller.startupProbe | nindent 12 }}
+          {{- end }}
+          livenessProbe: {{ toYaml .Values.controller.livenessProbe | nindent 12 }}
+          readinessProbe: {{ toYaml .Values.controller.readinessProbe | nindent 12 }}
+          ports:
+          {{- range $key, $value := .Values.controller.containerPort }}
+            - name: {{ $key }}
+              containerPort: {{ $value }}
+              protocol: TCP
+              {{- if $.Values.controller.hostPort.enabled }}
+              hostPort: {{ index $.Values.controller.hostPort.ports $key | default $value }}
+              {{- end }}
+          {{- end }}
+          {{- if .Values.controller.metrics.enabled }}
+            - name: metrics
+              containerPort: {{ .Values.controller.metrics.port }}
+              protocol: TCP
+          {{- end }}
+          {{- if .Values.controller.admissionWebhooks.enabled }}
+            - name: webhook
+              containerPort: {{ .Values.controller.admissionWebhooks.port }}
+              protocol: TCP
+          {{- end }}
+          {{- range $key, $value := .Values.tcp }}
+            - name: {{ $key }}-tcp
+              containerPort: {{ $key }}
+              protocol: TCP
+              {{- if $.Values.controller.hostPort.enabled }}
+              hostPort: {{ $key }}
+              {{- end }}
+          {{- end }}
+          {{- range $key, $value := .Values.udp }}
+            - name: {{ $key }}-udp
+              containerPort: {{ $key }}
+              protocol: UDP
+              {{- if $.Values.controller.hostPort.enabled }}
+              hostPort: {{ $key }}
+              {{- end }}
+          {{- end }}
+        {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled) }}
+          volumeMounts:
+          {{- if .Values.controller.customTemplate.configMapName }}
+            - mountPath: /etc/nginx/template
+              name: nginx-template-volume
+              readOnly: true
+          {{- end }}
+          {{- if .Values.controller.admissionWebhooks.enabled }}
+            - name: webhook-cert
+              mountPath: /usr/local/certificates/
+              readOnly: true
+          {{- end }}
+          {{- if .Values.controller.extraVolumeMounts }}
+            {{- toYaml .Values.controller.extraVolumeMounts | nindent 12 }}
+          {{- end }}
+        {{- end }}
+        {{- if .Values.controller.resources }}
+          resources: {{ toYaml .Values.controller.resources | nindent 12 }}
+        {{- end }}
+      {{- if .Values.controller.extraContainers }}
+        {{ toYaml .Values.controller.extraContainers | nindent 8 }}
+      {{- end }}
+    {{- if .Values.controller.extraInitContainers }}
+      initContainers: {{ toYaml .Values.controller.extraInitContainers | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.hostNetwork }}
+      hostNetwork: {{ .Values.controller.hostNetwork }}
+    {{- end }}
+    {{- if .Values.controller.nodeSelector }}
+      nodeSelector: {{ toYaml .Values.controller.nodeSelector | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.tolerations }}
+      tolerations: {{ toYaml .Values.controller.tolerations | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.affinity }}
+      affinity: {{ toYaml .Values.controller.affinity | nindent 8 }}
+    {{- end }}
+    {{- if .Values.controller.topologySpreadConstraints }}
+      topologySpreadConstraints: {{ toYaml .Values.controller.topologySpreadConstraints | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "ingress-nginx.serviceAccountName" . }}
+      terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }}
+    {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraVolumes) }}
+      volumes:
+      {{- if .Values.controller.customTemplate.configMapName }}
+        - name: nginx-template-volume
+          configMap:
+            name: {{ .Values.controller.customTemplate.configMapName }}
+            items:
+            - key: {{ .Values.controller.customTemplate.configMapKey }}
+              path: nginx.tmpl
+      {{- end }}
+      {{- if .Values.controller.admissionWebhooks.enabled }}
+        - name: webhook-cert
+          secret:
+            secretName: {{ include "ingress-nginx.fullname" . }}-admission
+      {{- end }}
+      {{- if .Values.controller.extraVolumes }}
+        {{ toYaml .Values.controller.extraVolumes | nindent 8 }}
+      {{- end }}
+    {{- end }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-hpa.yaml b/charts/ingress-nginx/templates/controller-hpa.yaml
new file mode 100644
index 0000000..876315f
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-hpa.yaml
@@ -0,0 +1,49 @@
+{{- if and .Values.controller.autoscaling.enabled (or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both")) -}}
+{{- if not .Values.controller.keda.enabled }}
+
+apiVersion: autoscaling/v2beta2
+kind: HorizontalPodAutoscaler
+metadata:
+  annotations:
+  {{- with .Values.controller.autoscaling.annotations }}
+  {{- toYaml . | trimSuffix "\n" | nindent 4 }}
+  {{- end }}
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+  name: {{ include "ingress-nginx.controller.fullname" . }}
+  namespace: {{ .Release.Namespace }}
+spec:
+  scaleTargetRef:
+    apiVersion: apps/v1
+    kind: Deployment
+    name: {{ include "ingress-nginx.controller.fullname" . }}
+  minReplicas: {{ .Values.controller.autoscaling.minReplicas }}
+  maxReplicas: {{ .Values.controller.autoscaling.maxReplicas }}
+  metrics:
+  {{- with .Values.controller.autoscaling.targetMemoryUtilizationPercentage }}
+  - type: Resource
+    resource:
+      name: memory
+      target:
+        type: Utilization
+        averageUtilization: {{ . }}
+  {{- end }}
+  {{- with .Values.controller.autoscaling.targetCPUUtilizationPercentage }}
+  - type: Resource
+    resource:
+      name: cpu
+      target:
+        type: Utilization
+        averageUtilization: {{ . }}
+  {{- end }}
+  {{- with .Values.controller.autoscalingTemplate }}
+  {{- toYaml . | nindent 2 }}
+  {{- end }}
+  {{- with .Values.controller.autoscaling.behavior }}
+  behavior:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+{{- end }}
+{{- end }}
+
diff --git a/charts/ingress-nginx/templates/controller-ingressclass.yaml b/charts/ingress-nginx/templates/controller-ingressclass.yaml
new file mode 100644
index 0000000..9492784
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-ingressclass.yaml
@@ -0,0 +1,21 @@
+{{- if .Values.controller.ingressClassResource.enabled -}}
+# We don't support namespaced ingressClass yet
+# So a ClusterRole and a ClusterRoleBinding is required
+apiVersion: networking.k8s.io/v1
+kind: IngressClass
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
+  name: {{ .Values.controller.ingressClassResource.name }}
+{{- if .Values.controller.ingressClassResource.default }}
+  annotations:
+    ingressclass.kubernetes.io/is-default-class: "true"
+{{- end }}
+spec:
+  controller: {{ .Values.controller.ingressClassResource.controllerValue }}
+  {{ template "ingressClass.parameters" . }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-keda.yaml b/charts/ingress-nginx/templates/controller-keda.yaml
new file mode 100644
index 0000000..c7eebf5
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-keda.yaml
@@ -0,0 +1,39 @@
+{{- if and .Values.controller.keda.enabled (or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both")) -}}
+# https://keda.sh/docs/
+
+apiVersion: {{ .Values.controller.keda.apiVersion }}
+kind: ScaledObject
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+  name: {{ include "ingress-nginx.controller.fullname" . }}
+  {{- if .Values.controller.keda.scaledObject.annotations }}
+  annotations: {{ toYaml .Values.controller.keda.scaledObject.annotations | nindent 4 }}
+  {{- end }}
+spec:
+  scaleTargetRef:
+{{- if eq .Values.controller.keda.apiVersion "keda.k8s.io/v1alpha1" }}
+    deploymentName: {{ include "ingress-nginx.controller.fullname" . }}
+{{- else if eq .Values.controller.keda.apiVersion "keda.sh/v1alpha1" }}
+    name: {{ include "ingress-nginx.controller.fullname" . }}
+{{- end }}
+  pollingInterval: {{ .Values.controller.keda.pollingInterval }}
+  cooldownPeriod: {{ .Values.controller.keda.cooldownPeriod }}
+  minReplicaCount: {{ .Values.controller.keda.minReplicas }}
+  maxReplicaCount: {{ .Values.controller.keda.maxReplicas }}
+  triggers:
+{{- with .Values.controller.keda.triggers }}
+{{ toYaml . | indent 2 }}
+{{ end }}
+  advanced:
+    restoreToOriginalReplicaCount: {{ .Values.controller.keda.restoreToOriginalReplicaCount }}
+{{- if .Values.controller.keda.behavior }}
+    horizontalPodAutoscalerConfig:
+      behavior:
+{{ with .Values.controller.keda.behavior -}}
+{{ toYaml . | indent 8 }}
+{{ end }}
+
+{{- end }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-poddisruptionbudget.yaml b/charts/ingress-nginx/templates/controller-poddisruptionbudget.yaml
new file mode 100644
index 0000000..9556f58
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-poddisruptionbudget.yaml
@@ -0,0 +1,16 @@
+{{- if or (and .Values.controller.autoscaling.enabled (gt (.Values.controller.autoscaling.minReplicas | int) 1)) (and (not .Values.controller.autoscaling.enabled) (gt (.Values.controller.replicaCount | int) 1)) }}
+apiVersion: {{ ternary "policy/v1" "policy/v1beta1" (semverCompare ">=1.21.0-0" .Capabilities.KubeVersion.Version) }}
+kind: PodDisruptionBudget
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+  name: {{ include "ingress-nginx.controller.fullname" . }}
+  namespace: {{ .Release.Namespace }}
+spec:
+  selector:
+    matchLabels:
+      {{- include "ingress-nginx.selectorLabels" . | nindent 6 }}
+      app.kubernetes.io/component: controller
+  minAvailable: {{ .Values.controller.minAvailable }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-prometheusrules.yaml b/charts/ingress-nginx/templates/controller-prometheusrules.yaml
new file mode 100644
index 0000000..ca54275
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-prometheusrules.yaml
@@ -0,0 +1,21 @@
+{{- if and .Values.controller.metrics.enabled .Values.controller.metrics.prometheusRule.enabled -}}
+apiVersion: monitoring.coreos.com/v1
+kind: PrometheusRule
+metadata:
+  name: {{ include "ingress-nginx.controller.fullname" . }}
+{{- if .Values.controller.metrics.prometheusRule.namespace }}
+  namespace: {{ .Values.controller.metrics.prometheusRule.namespace | quote }}
+{{- end }}
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+  {{- if .Values.controller.metrics.prometheusRule.additionalLabels }}
+    {{- toYaml .Values.controller.metrics.prometheusRule.additionalLabels | nindent 4 }}
+  {{- end }}
+spec:
+{{- if .Values.controller.metrics.prometheusRule.rules }}
+  groups:
+  - name: {{ template "ingress-nginx.name" . }}
+    rules: {{- toYaml .Values.controller.metrics.prometheusRule.rules | nindent 4 }}
+{{- end }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-psp.yaml b/charts/ingress-nginx/templates/controller-psp.yaml
new file mode 100644
index 0000000..bdb8563
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-psp.yaml
@@ -0,0 +1,86 @@
+{{- if and .Values.podSecurityPolicy.enabled (empty .Values.controller.existingPsp) -}}
+apiVersion: policy/v1beta1
+kind: PodSecurityPolicy
+metadata:
+  name: {{ include "ingress-nginx.fullname" . }}
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+spec:
+  allowedCapabilities:
+    - NET_BIND_SERVICE
+{{- if .Values.controller.sysctls }}
+  allowedUnsafeSysctls:
+  {{- range $sysctl, $value := .Values.controller.sysctls }}
+  - {{ $sysctl }}
+  {{- end }}
+{{- end }}
+  privileged: false
+  allowPrivilegeEscalation: true
+  # Allow core volume types.
+  volumes:
+    - 'configMap'
+    - 'emptyDir'
+    #- 'projected'
+    - 'secret'
+    #- 'downwardAPI'
+{{- if .Values.controller.hostNetwork }}
+  hostNetwork: {{ .Values.controller.hostNetwork }}
+{{- end }}
+{{- if or .Values.controller.hostNetwork .Values.controller.hostPort.enabled }}
+  hostPorts:
+{{- if .Values.controller.hostNetwork }}
+{{- range $key, $value := .Values.controller.containerPort }}
+  # {{ $key }}
+  - min: {{ $value }}
+    max: {{ $value }}
+{{- end }}
+{{- else if .Values.controller.hostPort.enabled }}
+{{- range $key, $value := .Values.controller.hostPort.ports }}
+  # {{ $key }}
+  - min: {{ $value }}
+    max: {{ $value }}
+{{- end }}
+{{- end }}
+{{- if .Values.controller.metrics.enabled }}
+  # metrics
+  - min: {{ .Values.controller.metrics.port }}
+    max: {{ .Values.controller.metrics.port }}
+{{- end }}
+{{- if .Values.controller.admissionWebhooks.enabled }}
+  # admission webhooks
+  - min: {{ .Values.controller.admissionWebhooks.port }}
+    max: {{ .Values.controller.admissionWebhooks.port }}
+{{- end }}
+{{- range $key, $value := .Values.tcp }}
+  # {{ $key }}-tcp
+  - min: {{ $key }}
+    max: {{ $key }}
+{{- end }}
+{{- range $key, $value := .Values.udp }}
+  # {{ $key }}-udp
+  - min: {{ $key }}
+    max: {{ $key }}
+{{- end }}
+{{- end }}
+  hostIPC: false
+  hostPID: false
+  runAsUser:
+    # Require the container to run without root privileges.
+    rule: 'MustRunAsNonRoot'
+  supplementalGroups:
+    rule: 'MustRunAs'
+    ranges:
+      # Forbid adding the root group.
+      - min: 1
+        max: 65535
+  fsGroup:
+    rule: 'MustRunAs'
+    ranges:
+      # Forbid adding the root group.
+      - min: 1
+        max: 65535
+  readOnlyRootFilesystem: false
+  seLinux:
+    rule: 'RunAsAny'
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-role.yaml b/charts/ingress-nginx/templates/controller-role.yaml
new file mode 100644
index 0000000..97c627d
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-role.yaml
@@ -0,0 +1,90 @@
+{{- if .Values.rbac.create -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+  name: {{ include "ingress-nginx.fullname" . }}
+  namespace: {{ .Release.Namespace }}
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - namespaces
+    verbs:
+      - get
+  - apiGroups:
+      - ""
+    resources:
+      - configmaps
+      - pods
+      - secrets
+      - endpoints
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+      - networking.k8s.io
+    resources:
+      - ingresses
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+      - networking.k8s.io
+    resources:
+      - ingresses/status
+    verbs:
+      - update
+  - apiGroups:
+      - networking.k8s.io
+    resources:
+      - ingressclasses
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+      - ""
+    resources:
+      - configmaps
+    resourceNames:
+      - {{ .Values.controller.electionID }}
+    verbs:
+      - get
+      - update
+  - apiGroups:
+      - ""
+    resources:
+      - configmaps
+    verbs:
+      - create
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+{{- if .Values.podSecurityPolicy.enabled }}
+  - apiGroups:      [{{ template "podSecurityPolicy.apiGroup" . }}]
+    resources:      ['podsecuritypolicies']
+    verbs:          ['use']
+    {{- with .Values.controller.existingPsp }}
+    resourceNames:  [{{ . }}]
+    {{- else }}
+    resourceNames:  [{{ include "ingress-nginx.fullname" . }}]
+    {{- end }}
+{{- end }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-rolebinding.yaml b/charts/ingress-nginx/templates/controller-rolebinding.yaml
new file mode 100644
index 0000000..5ec3bc7
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-rolebinding.yaml
@@ -0,0 +1,18 @@
+{{- if .Values.rbac.create -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+  name: {{ include "ingress-nginx.fullname" . }}
+  namespace: {{ .Release.Namespace }}
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: {{ include "ingress-nginx.fullname" . }}
+subjects:
+  - kind: ServiceAccount
+    name: {{ template "ingress-nginx.serviceAccountName" . }}
+    namespace: {{ .Release.Namespace | quote }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-service-internal.yaml b/charts/ingress-nginx/templates/controller-service-internal.yaml
new file mode 100644
index 0000000..5994498
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-service-internal.yaml
@@ -0,0 +1,79 @@
+{{- if and .Values.controller.service.enabled .Values.controller.service.internal.enabled .Values.controller.service.internal.annotations}}
+apiVersion: v1
+kind: Service
+metadata:
+  annotations:
+  {{- range $key, $value := .Values.controller.service.internal.annotations }}
+    {{ $key }}: {{ $value | quote }}
+  {{- end }}
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+  {{- if .Values.controller.service.labels }}
+    {{- toYaml .Values.controller.service.labels | nindent 4 }}
+  {{- end }}
+  name: {{ include "ingress-nginx.controller.fullname" . }}-internal
+  namespace: {{ .Release.Namespace }}
+spec:
+  type: "{{ .Values.controller.service.type }}"
+{{- if .Values.controller.service.internal.loadBalancerIP }}
+  loadBalancerIP: {{ .Values.controller.service.internal.loadBalancerIP }}
+{{- end }}
+{{- if .Values.controller.service.internal.loadBalancerSourceRanges }}
+  loadBalancerSourceRanges: {{ toYaml .Values.controller.service.internal.loadBalancerSourceRanges | nindent 4 }}
+{{- end }}
+{{- if .Values.controller.service.internal.externalTrafficPolicy }}
+  externalTrafficPolicy: {{ .Values.controller.service.internal.externalTrafficPolicy }}
+{{- end }}
+  ports:
+  {{- $setNodePorts := (or (eq .Values.controller.service.type "NodePort") (eq .Values.controller.service.type "LoadBalancer")) }}
+  {{- if .Values.controller.service.enableHttp }}
+    - name: http
+      port: {{ .Values.controller.service.ports.http }}
+      protocol: TCP
+      targetPort: {{ .Values.controller.service.targetPorts.http }}
+    {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }}
+      appProtocol: http
+    {{- end }}
+    {{- if (and $setNodePorts (not (empty .Values.controller.service.nodePorts.http))) }}
+      nodePort: {{ .Values.controller.service.nodePorts.http }}
+    {{- end }}
+  {{- end }}
+  {{- if .Values.controller.service.enableHttps }}
+    - name: https
+      port: {{ .Values.controller.service.ports.https }}
+      protocol: TCP
+      targetPort: {{ .Values.controller.service.targetPorts.https }}
+    {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }}
+      appProtocol: https
+    {{- end }}
+    {{- if (and $setNodePorts (not (empty .Values.controller.service.nodePorts.https))) }}
+      nodePort: {{ .Values.controller.service.nodePorts.https }}
+    {{- end }}
+  {{- end }}
+  {{- range $key, $value := .Values.tcp }}
+    - name: {{ $key }}-tcp
+      port: {{ $key }}
+      protocol: TCP
+      targetPort: {{ $key }}-tcp
+    {{- if $.Values.controller.service.nodePorts.tcp }}
+    {{- if index $.Values.controller.service.nodePorts.tcp $key }}
+      nodePort: {{ index $.Values.controller.service.nodePorts.tcp $key }}
+    {{- end }}
+    {{- end }}
+  {{- end }}
+  {{- range $key, $value := .Values.udp }}
+    - name: {{ $key }}-udp
+      port: {{ $key }}
+      protocol: UDP
+      targetPort: {{ $key }}-udp
+    {{- if $.Values.controller.service.nodePorts.udp }}
+    {{- if index $.Values.controller.service.nodePorts.udp $key }}
+      nodePort: {{ index $.Values.controller.service.nodePorts.udp $key }}
+    {{- end }}
+    {{- end }}
+  {{- end }}
+  selector:
+    {{- include "ingress-nginx.selectorLabels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-service-metrics.yaml b/charts/ingress-nginx/templates/controller-service-metrics.yaml
new file mode 100644
index 0000000..1b69019
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-service-metrics.yaml
@@ -0,0 +1,44 @@
+{{- if .Values.controller.metrics.enabled -}}
+apiVersion: v1
+kind: Service
+metadata:
+{{- if .Values.controller.metrics.service.annotations }}
+  annotations: {{ toYaml .Values.controller.metrics.service.annotations | nindent 4 }}
+{{- end }}
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+  {{- if .Values.controller.metrics.service.labels }}
+    {{- toYaml .Values.controller.metrics.service.labels | nindent 4 }}
+  {{- end }}
+  name: {{ include "ingress-nginx.controller.fullname" . }}-metrics
+  namespace: {{ .Release.Namespace }}
+spec:
+  type: {{ .Values.controller.metrics.service.type }}
+{{- if .Values.controller.metrics.service.clusterIP }}
+  clusterIP: {{ .Values.controller.metrics.service.clusterIP }}
+{{- end }}
+{{- if .Values.controller.metrics.service.externalIPs }}
+  externalIPs: {{ toYaml .Values.controller.metrics.service.externalIPs | nindent 4 }}
+{{- end }}
+{{- if .Values.controller.metrics.service.loadBalancerIP }}
+  loadBalancerIP: {{ .Values.controller.metrics.service.loadBalancerIP }}
+{{- end }}
+{{- if .Values.controller.metrics.service.loadBalancerSourceRanges }}
+  loadBalancerSourceRanges: {{ toYaml .Values.controller.metrics.service.loadBalancerSourceRanges | nindent 4 }}
+{{- end }}
+{{- if .Values.controller.metrics.service.externalTrafficPolicy }}
+  externalTrafficPolicy: {{ .Values.controller.metrics.service.externalTrafficPolicy }}
+{{- end }}
+  ports:
+    - name: metrics
+      port: {{ .Values.controller.metrics.service.servicePort }}
+      targetPort: metrics
+    {{- $setNodePorts := (or (eq .Values.controller.metrics.service.type "NodePort") (eq .Values.controller.metrics.service.type "LoadBalancer")) }}
+    {{- if (and $setNodePorts (not (empty .Values.controller.metrics.service.nodePort))) }}
+      nodePort: {{ .Values.controller.metrics.service.nodePort }}
+    {{- end }}
+  selector:
+    {{- include "ingress-nginx.selectorLabels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-service-webhook.yaml b/charts/ingress-nginx/templates/controller-service-webhook.yaml
new file mode 100644
index 0000000..ae3b1fc
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-service-webhook.yaml
@@ -0,0 +1,37 @@
+{{- if .Values.controller.admissionWebhooks.enabled -}}
+apiVersion: v1
+kind: Service
+metadata:
+{{- if .Values.controller.admissionWebhooks.service.annotations }}
+  annotations: {{ toYaml .Values.controller.admissionWebhooks.service.annotations | nindent 4 }}
+{{- end }}
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+  name: {{ include "ingress-nginx.controller.fullname" . }}-admission
+  namespace: {{ .Release.Namespace }}
+spec:
+  type: {{ .Values.controller.admissionWebhooks.service.type }}
+{{- if .Values.controller.admissionWebhooks.service.clusterIP }}
+  clusterIP: {{ .Values.controller.admissionWebhooks.service.clusterIP }}
+{{- end }}
+{{- if .Values.controller.admissionWebhooks.service.externalIPs }}
+  externalIPs: {{ toYaml .Values.controller.admissionWebhooks.service.externalIPs | nindent 4 }}
+{{- end }}
+{{- if .Values.controller.admissionWebhooks.service.loadBalancerIP }}
+  loadBalancerIP: {{ .Values.controller.admissionWebhooks.service.loadBalancerIP }}
+{{- end }}
+{{- if .Values.controller.admissionWebhooks.service.loadBalancerSourceRanges }}
+  loadBalancerSourceRanges: {{ toYaml .Values.controller.admissionWebhooks.service.loadBalancerSourceRanges | nindent 4 }}
+{{- end }}
+  ports:
+    - name: https-webhook
+      port: 443
+      targetPort: webhook
+    {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }}
+      appProtocol: https
+    {{- end }}
+  selector:
+    {{- include "ingress-nginx.selectorLabels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-service.yaml b/charts/ingress-nginx/templates/controller-service.yaml
new file mode 100644
index 0000000..9248818
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-service.yaml
@@ -0,0 +1,91 @@
+{{- if .Values.controller.service.enabled -}}
+apiVersion: v1
+kind: Service
+metadata:
+  annotations:
+  {{- range $key, $value := .Values.controller.service.annotations }}
+    {{ $key }}: {{ $value | quote }}
+  {{- end }}
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+  {{- if .Values.controller.service.labels }}
+    {{- toYaml .Values.controller.service.labels | nindent 4 }}
+  {{- end }}
+  name: {{ include "ingress-nginx.controller.fullname" . }}
+  namespace: {{ .Release.Namespace }}
+spec:
+  type: {{ .Values.controller.service.type }}
+{{- if .Values.controller.service.clusterIP }}
+  clusterIP: {{ .Values.controller.service.clusterIP }}
+{{- end }}
+{{- if .Values.controller.service.externalIPs }}
+  externalIPs: {{ toYaml .Values.controller.service.externalIPs | nindent 4 }}
+{{- end }}
+{{- if .Values.controller.service.loadBalancerIP }}
+  loadBalancerIP: {{ .Values.controller.service.loadBalancerIP }}
+{{- end }}
+{{- if .Values.controller.service.loadBalancerSourceRanges }}
+  loadBalancerSourceRanges: {{ toYaml .Values.controller.service.loadBalancerSourceRanges | nindent 4 }}
+{{- end }}
+{{- if .Values.controller.service.externalTrafficPolicy }}
+  externalTrafficPolicy: {{ .Values.controller.service.externalTrafficPolicy }}
+{{- end }}
+{{- if .Values.controller.service.sessionAffinity }}
+  sessionAffinity: {{ .Values.controller.service.sessionAffinity }}
+{{- end }}
+{{- if .Values.controller.service.healthCheckNodePort }}
+  healthCheckNodePort: {{ .Values.controller.service.healthCheckNodePort }}
+{{- end }}
+  ports:
+  {{- $setNodePorts := (or (eq .Values.controller.service.type "NodePort") (eq .Values.controller.service.type "LoadBalancer")) }}
+  {{- if .Values.controller.service.enableHttp }}
+    - name: http
+      port: {{ .Values.controller.service.ports.http }}
+      protocol: TCP
+      targetPort: {{ .Values.controller.service.targetPorts.http }}
+    {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }}
+      appProtocol: http
+    {{- end }}
+    {{- if (and $setNodePorts (not (empty .Values.controller.service.nodePorts.http))) }}
+      nodePort: {{ .Values.controller.service.nodePorts.http }}
+    {{- end }}
+  {{- end }}
+  {{- if .Values.controller.service.enableHttps }}
+    - name: https
+      port: {{ .Values.controller.service.ports.https }}
+      protocol: TCP
+      targetPort: {{ .Values.controller.service.targetPorts.https }}
+    {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }}
+      appProtocol: https
+    {{- end }}
+    {{- if (and $setNodePorts (not (empty .Values.controller.service.nodePorts.https))) }}
+      nodePort: {{ .Values.controller.service.nodePorts.https }}
+    {{- end }}
+  {{- end }}
+  {{- range $key, $value := .Values.tcp }}
+    - name: {{ $key }}-tcp
+      port: {{ $key }}
+      protocol: TCP
+      targetPort: {{ $key }}-tcp
+    {{- if $.Values.controller.service.nodePorts.tcp }}
+    {{- if index $.Values.controller.service.nodePorts.tcp $key }}
+      nodePort: {{ index $.Values.controller.service.nodePorts.tcp $key }}
+    {{- end }}
+    {{- end }}
+  {{- end }}
+  {{- range $key, $value := .Values.udp }}
+    - name: {{ $key }}-udp
+      port: {{ $key }}
+      protocol: UDP
+      targetPort: {{ $key }}-udp
+    {{- if $.Values.controller.service.nodePorts.udp }}
+    {{- if index $.Values.controller.service.nodePorts.udp $key }}
+      nodePort: {{ index $.Values.controller.service.nodePorts.udp $key }}
+    {{- end }}
+    {{- end }}
+  {{- end }}
+  selector:
+    {{- include "ingress-nginx.selectorLabels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-serviceaccount.yaml b/charts/ingress-nginx/templates/controller-serviceaccount.yaml
new file mode 100644
index 0000000..50a718d
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-serviceaccount.yaml
@@ -0,0 +1,11 @@
+{{- if or .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+  name: {{ template "ingress-nginx.serviceAccountName" . }}
+  namespace: {{ .Release.Namespace }}
+automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-servicemonitor.yaml b/charts/ingress-nginx/templates/controller-servicemonitor.yaml
new file mode 100644
index 0000000..17894c8
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-servicemonitor.yaml
@@ -0,0 +1,45 @@
+{{- if and ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) .Values.controller.metrics.enabled .Values.controller.metrics.serviceMonitor.enabled -}}
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+  name: {{ include "ingress-nginx.controller.fullname" . }}
+{{- if .Values.controller.metrics.serviceMonitor.namespace }}
+  namespace: {{ .Values.controller.metrics.serviceMonitor.namespace | quote }}
+{{- end }}
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+  {{- if .Values.controller.metrics.serviceMonitor.additionalLabels }}
+    {{- toYaml .Values.controller.metrics.serviceMonitor.additionalLabels | nindent 4 }}
+  {{- end }}
+spec:
+  endpoints:
+    - port: metrics
+      interval: {{ .Values.controller.metrics.serviceMonitor.scrapeInterval }}
+    {{- if .Values.controller.metrics.serviceMonitor.honorLabels }}
+      honorLabels: true
+    {{- end }}
+    {{- if .Values.controller.metrics.serviceMonitor.metricRelabelings }}
+      metricRelabelings: {{ toYaml .Values.controller.metrics.serviceMonitor.metricRelabelings | nindent 8 }}
+    {{- end }}
+{{- if .Values.controller.metrics.serviceMonitor.jobLabel }}
+  jobLabel: {{ .Values.controller.metrics.serviceMonitor.jobLabel | quote }}
+{{- end }}
+{{- if .Values.controller.metrics.serviceMonitor.namespaceSelector }}
+  namespaceSelector: {{ toYaml .Values.controller.metrics.serviceMonitor.namespaceSelector | nindent 4 }}
+{{ else }}
+  namespaceSelector:
+    matchNames:
+      - {{ .Release.Namespace }}
+{{- end }}
+{{- if .Values.controller.metrics.serviceMonitor.targetLabels }}
+  targetLabels:
+  {{- range .Values.controller.metrics.serviceMonitor.targetLabels }}
+    - {{ . }}
+  {{- end }}
+{{- end }}
+  selector:
+    matchLabels:
+      {{- include "ingress-nginx.selectorLabels" . | nindent 6 }}
+      app.kubernetes.io/component: controller
+{{- end }}
diff --git a/charts/ingress-nginx/templates/default-backend-deployment.yaml b/charts/ingress-nginx/templates/default-backend-deployment.yaml
new file mode 100644
index 0000000..9934526
--- /dev/null
+++ b/charts/ingress-nginx/templates/default-backend-deployment.yaml
@@ -0,0 +1,112 @@
+{{- if .Values.defaultBackend.enabled -}}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: default-backend
+  name: {{ include "ingress-nginx.defaultBackend.fullname" . }}
+  namespace: {{ .Release.Namespace }}
+spec:
+  selector:
+    matchLabels:
+      {{- include "ingress-nginx.selectorLabels" . | nindent 6 }}
+      app.kubernetes.io/component: default-backend
+{{- if not .Values.defaultBackend.autoscaling.enabled }}
+  replicas: {{ .Values.defaultBackend.replicaCount }}
+{{- end }}
+  revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
+  template:
+    metadata:
+    {{- if .Values.defaultBackend.podAnnotations }}
+      annotations: {{ toYaml .Values.defaultBackend.podAnnotations | nindent 8 }}
+    {{- end }}
+      labels:
+        {{- include "ingress-nginx.selectorLabels" . | nindent 8 }}
+        app.kubernetes.io/component: default-backend
+      {{- if .Values.defaultBackend.podLabels }}
+        {{- toYaml .Values.defaultBackend.podLabels | nindent 8 }}
+      {{- end }}
+    spec:
+    {{- if .Values.imagePullSecrets }}
+      imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }}
+    {{- end }}
+    {{- if .Values.defaultBackend.priorityClassName }}
+      priorityClassName: {{ .Values.defaultBackend.priorityClassName }}
+    {{- end }}
+    {{- if .Values.defaultBackend.podSecurityContext }}
+      securityContext: {{ toYaml .Values.defaultBackend.podSecurityContext | nindent 8 }}
+    {{- end }}
+      containers:
+        - name: {{ template "ingress-nginx.name" . }}-default-backend
+          {{- with .Values.defaultBackend.image }}
+          image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ .image }}{{- end -}}:{{ .tag }}{{- if (.digest) -}} @{{.digest}} {{- end -}}"
+          {{- end }}
+          imagePullPolicy: {{ .Values.defaultBackend.image.pullPolicy }}
+        {{- if .Values.defaultBackend.extraArgs }}
+          args:
+          {{- range $key, $value := .Values.defaultBackend.extraArgs }}
+            {{- /* Accept keys without values or with false as value */}}
+            {{- if eq ($value | quote | len) 2 }}
+            - --{{ $key }}
+            {{- else }}
+            - --{{ $key }}={{ $value }}
+            {{- end }}
+          {{- end }}
+        {{- end }}
+          securityContext:
+            capabilities:
+              drop:
+              - ALL
+            runAsUser: {{ .Values.defaultBackend.image.runAsUser }}
+            runAsNonRoot: {{ .Values.defaultBackend.image.runAsNonRoot }}
+            allowPrivilegeEscalation: {{ .Values.defaultBackend.image.allowPrivilegeEscalation }}
+            readOnlyRootFilesystem: {{ .Values.defaultBackend.image.readOnlyRootFilesystem}}
+        {{- if .Values.defaultBackend.extraEnvs }}
+          env: {{ toYaml .Values.defaultBackend.extraEnvs | nindent 12 }}
+        {{- end }}
+          livenessProbe:
+            httpGet:
+              path: /healthz
+              port: {{ .Values.defaultBackend.port }}
+              scheme: HTTP
+            initialDelaySeconds: {{ .Values.defaultBackend.livenessProbe.initialDelaySeconds }}
+            periodSeconds: {{ .Values.defaultBackend.livenessProbe.periodSeconds }}
+            timeoutSeconds: {{ .Values.defaultBackend.livenessProbe.timeoutSeconds }}
+            successThreshold: {{ .Values.defaultBackend.livenessProbe.successThreshold }}
+            failureThreshold: {{ .Values.defaultBackend.livenessProbe.failureThreshold }}
+          readinessProbe:
+            httpGet:
+              path: /healthz
+              port: {{ .Values.defaultBackend.port }}
+              scheme: HTTP
+            initialDelaySeconds: {{ .Values.defaultBackend.readinessProbe.initialDelaySeconds }}
+            periodSeconds: {{ .Values.defaultBackend.readinessProbe.periodSeconds }}
+            timeoutSeconds: {{ .Values.defaultBackend.readinessProbe.timeoutSeconds }}
+            successThreshold: {{ .Values.defaultBackend.readinessProbe.successThreshold }}
+            failureThreshold: {{ .Values.defaultBackend.readinessProbe.failureThreshold }}
+          ports:
+            - name: http
+              containerPort: {{ .Values.defaultBackend.port }}
+              protocol: TCP
+        {{- if .Values.defaultBackend.extraVolumeMounts }}
+          volumeMounts: {{- toYaml .Values.defaultBackend.extraVolumeMounts | nindent 12 }}
+        {{- end }}
+        {{- if .Values.defaultBackend.resources }}
+          resources: {{ toYaml .Values.defaultBackend.resources | nindent 12 }}
+        {{- end }}
+    {{- if .Values.defaultBackend.nodeSelector }}
+      nodeSelector: {{ toYaml .Values.defaultBackend.nodeSelector | nindent 8 }}
+    {{- end }}
+      serviceAccountName: {{ template "ingress-nginx.defaultBackend.serviceAccountName" . }}
+    {{- if .Values.defaultBackend.tolerations }}
+      tolerations: {{ toYaml .Values.defaultBackend.tolerations | nindent 8 }}
+    {{- end }}
+    {{- if .Values.defaultBackend.affinity }}
+      affinity: {{ toYaml .Values.defaultBackend.affinity | nindent 8 }}
+    {{- end }}
+      terminationGracePeriodSeconds: 60
+    {{- if .Values.defaultBackend.extraVolumes }}
+      volumes: {{ toYaml .Values.defaultBackend.extraVolumes | nindent 8 }}
+    {{- end }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/default-backend-hpa.yaml b/charts/ingress-nginx/templates/default-backend-hpa.yaml
new file mode 100644
index 0000000..e31fda3
--- /dev/null
+++ b/charts/ingress-nginx/templates/default-backend-hpa.yaml
@@ -0,0 +1,30 @@
+{{- if and .Values.defaultBackend.enabled .Values.defaultBackend.autoscaling.enabled }}
+apiVersion: autoscaling/v2beta1
+kind: HorizontalPodAutoscaler
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: default-backend
+  name: {{ template "ingress-nginx.defaultBackend.fullname" . }}
+  namespace: {{ .Release.Namespace }}
+spec:
+  scaleTargetRef:
+    apiVersion: apps/v1
+    kind: Deployment
+    name: {{ template "ingress-nginx.defaultBackend.fullname" . }}
+  minReplicas: {{ .Values.defaultBackend.autoscaling.minReplicas }}
+  maxReplicas: {{ .Values.defaultBackend.autoscaling.maxReplicas }}
+  metrics:
+{{- with .Values.defaultBackend.autoscaling.targetCPUUtilizationPercentage }}
+    - type: Resource
+      resource:
+        name: cpu
+        targetAverageUtilization: {{ . }}
+{{- end }}
+{{- with .Values.defaultBackend.autoscaling.targetMemoryUtilizationPercentage }}
+    - type: Resource
+      resource:
+        name: memory
+        targetAverageUtilization: {{ . }}
+{{- end }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/default-backend-poddisruptionbudget.yaml b/charts/ingress-nginx/templates/default-backend-poddisruptionbudget.yaml
new file mode 100644
index 0000000..9e586aa
--- /dev/null
+++ b/charts/ingress-nginx/templates/default-backend-poddisruptionbudget.yaml
@@ -0,0 +1,16 @@
+{{- if or (gt (.Values.defaultBackend.replicaCount | int) 1) (gt (.Values.defaultBackend.autoscaling.minReplicas | int) 1) }}
+apiVersion: {{ ternary "policy/v1" "policy/v1beta1" (semverCompare ">=1.21.0-0" .Capabilities.KubeVersion.Version) }}
+kind: PodDisruptionBudget
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: default-backend
+  name: {{ include "ingress-nginx.defaultBackend.fullname" . }}
+  namespace: {{ .Release.Namespace }}
+spec:
+  selector:
+    matchLabels:
+      {{- include "ingress-nginx.selectorLabels" . | nindent 6 }}
+      app.kubernetes.io/component: default-backend
+  minAvailable: {{ .Values.defaultBackend.minAvailable }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/default-backend-psp.yaml b/charts/ingress-nginx/templates/default-backend-psp.yaml
new file mode 100644
index 0000000..716dbf1
--- /dev/null
+++ b/charts/ingress-nginx/templates/default-backend-psp.yaml
@@ -0,0 +1,33 @@
+{{- if and .Values.podSecurityPolicy.enabled .Values.defaultBackend.enabled (empty .Values.defaultBackend.existingPsp) -}}
+apiVersion: policy/v1beta1
+kind: PodSecurityPolicy
+metadata:
+  name: {{ include "ingress-nginx.fullname" . }}-backend
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: default-backend
+spec:
+  allowPrivilegeEscalation: false
+  fsGroup:
+    ranges:
+    - max: 65535
+      min: 1
+    rule: MustRunAs
+  requiredDropCapabilities:
+  - ALL
+  runAsUser:
+    rule: MustRunAsNonRoot
+  seLinux:
+    rule: RunAsAny
+  supplementalGroups:
+    ranges:
+    - max: 65535
+      min: 1
+    rule: MustRunAs
+  volumes:
+  - configMap
+  - emptyDir
+  - projected
+  - secret
+  - downwardAPI
+{{- end }}
diff --git a/charts/ingress-nginx/templates/default-backend-role.yaml b/charts/ingress-nginx/templates/default-backend-role.yaml
new file mode 100644
index 0000000..5d29a2d
--- /dev/null
+++ b/charts/ingress-nginx/templates/default-backend-role.yaml
@@ -0,0 +1,19 @@
+{{- if and .Values.rbac.create .Values.podSecurityPolicy.enabled .Values.defaultBackend.enabled -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: default-backend
+  name: {{ include "ingress-nginx.fullname" . }}-backend
+  namespace: {{ .Release.Namespace }}
+rules:
+  - apiGroups:      [{{ template "podSecurityPolicy.apiGroup" . }}]
+    resources:      ['podsecuritypolicies']
+    verbs:          ['use']
+    {{- with .Values.defaultBackend.existingPsp }}
+    resourceNames:  [{{ . }}]
+    {{- else }}
+    resourceNames:  [{{ include "ingress-nginx.fullname" . }}-backend]
+    {{- end }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/default-backend-rolebinding.yaml b/charts/ingress-nginx/templates/default-backend-rolebinding.yaml
new file mode 100644
index 0000000..4a9cb92
--- /dev/null
+++ b/charts/ingress-nginx/templates/default-backend-rolebinding.yaml
@@ -0,0 +1,18 @@
+{{- if and .Values.rbac.create .Values.podSecurityPolicy.enabled .Values.defaultBackend.enabled -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: default-backend
+  name: {{ include "ingress-nginx.fullname" . }}-backend
+  namespace: {{ .Release.Namespace }}
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: {{ include "ingress-nginx.fullname" . }}-backend
+subjects:
+  - kind: ServiceAccount
+    name: {{ template "ingress-nginx.defaultBackend.serviceAccountName" . }}
+    namespace: {{ .Release.Namespace | quote }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/default-backend-service.yaml b/charts/ingress-nginx/templates/default-backend-service.yaml
new file mode 100644
index 0000000..f59eb1e
--- /dev/null
+++ b/charts/ingress-nginx/templates/default-backend-service.yaml
@@ -0,0 +1,38 @@
+{{- if .Values.defaultBackend.enabled -}}
+apiVersion: v1
+kind: Service
+metadata:
+{{- if .Values.defaultBackend.service.annotations }}
+  annotations: {{ toYaml .Values.defaultBackend.service.annotations | nindent 4 }}
+{{- end }}
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: default-backend
+  name: {{ include "ingress-nginx.defaultBackend.fullname" . }}
+  namespace: {{ .Release.Namespace }}
+spec:
+  type: {{ .Values.defaultBackend.service.type }}
+{{- if .Values.defaultBackend.service.clusterIP }}
+  clusterIP: {{ .Values.defaultBackend.service.clusterIP }}
+{{- end }}
+{{- if .Values.defaultBackend.service.externalIPs }}
+  externalIPs: {{ toYaml .Values.defaultBackend.service.externalIPs | nindent 4 }}
+{{- end }}
+{{- if .Values.defaultBackend.service.loadBalancerIP }}
+  loadBalancerIP: {{ .Values.defaultBackend.service.loadBalancerIP }}
+{{- end }}
+{{- if .Values.defaultBackend.service.loadBalancerSourceRanges }}
+  loadBalancerSourceRanges: {{ toYaml .Values.defaultBackend.service.loadBalancerSourceRanges | nindent 4 }}
+{{- end }}
+  ports:
+    - name: http
+      port: {{ .Values.defaultBackend.service.servicePort }}
+      protocol: TCP
+      targetPort: http
+    {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }}
+      appProtocol: http
+    {{- end }}
+  selector:
+    {{- include "ingress-nginx.selectorLabels" . | nindent 4 }}
+    app.kubernetes.io/component: default-backend
+{{- end }}
diff --git a/charts/ingress-nginx/templates/default-backend-serviceaccount.yaml b/charts/ingress-nginx/templates/default-backend-serviceaccount.yaml
new file mode 100644
index 0000000..0c00e93
--- /dev/null
+++ b/charts/ingress-nginx/templates/default-backend-serviceaccount.yaml
@@ -0,0 +1,11 @@
+{{- if and .Values.defaultBackend.enabled  .Values.defaultBackend.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: default-backend
+  name: {{ template "ingress-nginx.defaultBackend.serviceAccountName" . }}
+  namespace: {{ .Release.Namespace }}
+automountServiceAccountToken: {{ .Values.defaultBackend.serviceAccount.automountServiceAccountToken }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/dh-param-secret.yaml b/charts/ingress-nginx/templates/dh-param-secret.yaml
new file mode 100644
index 0000000..12e7a4f
--- /dev/null
+++ b/charts/ingress-nginx/templates/dh-param-secret.yaml
@@ -0,0 +1,10 @@
+{{- with .Values.dhParam -}}
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ include "ingress-nginx.controller.fullname" $ }}
+  labels:
+    {{- include "ingress-nginx.labels" $ | nindent 4 }}
+data:
+  dhparam.pem: {{ . }}
+{{- end }}