diff --git a/charts/nautobot/Chart.lock b/charts/nautobot/Chart.lock index 4f5a28e7..b6627387 100644 --- a/charts/nautobot/Chart.lock +++ b/charts/nautobot/Chart.lock @@ -16,6 +16,6 @@ dependencies: version: 12.15.0 - name: common repository: oci://registry-1.docker.io/bitnamicharts - version: 2.26.0 -digest: sha256:b3fa151d1762cb262367a8fcbdc36adb0a1b583602e7cbee71675e2a74d92293 -generated: "2024-10-18T09:06:48.023158023+03:00" + version: 2.27.0 +digest: sha256:3b3d075f4c99531c211670fe76b74b1e2ee53a896e6b0cea38241cb21a7b3cd8 +generated: "2024-11-14T13:38:07.814675+01:00" diff --git a/charts/nautobot/README.md b/charts/nautobot/README.md index 1746d482..75529d55 100644 --- a/charts/nautobot/README.md +++ b/charts/nautobot/README.md @@ -162,6 +162,12 @@ See [Uninstall](https://docs.nautobot.com/projects/helm-charts/en/stable/operati |-----|------|---------|-------------| | [commonAnnotations](https://github.com/nautobot/helm-charts/blob/main/charts/nautobot/values.yaml#L3) | map[string]string | `{}` | Annotations to be applied to ALL resources created by this chart | +## ExtraObjects Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| [extraObjects](https://github.com/nautobot/helm-charts/blob/main/charts/nautobot/values.yaml#L1228) | list | `[]` | Deploy additional Kubernetes manifests | + ## Ingress Values | Key | Type | Default | Description | diff --git a/charts/nautobot/charts/common-2.26.0.tgz b/charts/nautobot/charts/common-2.26.0.tgz deleted file mode 100644 index 8d2a6c55..00000000 Binary files a/charts/nautobot/charts/common-2.26.0.tgz and /dev/null differ diff --git a/charts/nautobot/charts/common-2.27.0.tgz b/charts/nautobot/charts/common-2.27.0.tgz new file mode 100644 index 00000000..297fe4f2 Binary files /dev/null and b/charts/nautobot/charts/common-2.27.0.tgz differ diff --git a/charts/nautobot/templates/extra-objects.yaml b/charts/nautobot/templates/extra-objects.yaml new file mode 100644 index 00000000..f1e2a43e --- /dev/null +++ b/charts/nautobot/templates/extra-objects.yaml @@ -0,0 +1,8 @@ +{{- range .Values.extraObjects }} +--- + {{- if typeIs "string" . }} + {{- tpl . $ }} + {{- else }} + {{- tpl (. | toYaml | nindent 0) $ }} + {{- end }} +{{- end }} diff --git a/charts/nautobot/values.schema.json b/charts/nautobot/values.schema.json index 5e5138d6..0b8d228e 100644 --- a/charts/nautobot/values.schema.json +++ b/charts/nautobot/values.schema.json @@ -1197,6 +1197,20 @@ } }, "description": "List of Nautobot objects (matching the Nautobot spec) to create deployments for" + }, + "extraObjects": { + "type": "array", + "description": "A property where you can define additional Kubernetes manifests that are deployed along the other Kubernetes manifests generated by this Helm Chart.", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + } } } } diff --git a/charts/nautobot/values.yaml b/charts/nautobot/values.yaml index 21c25df5..4cd47e11 100644 --- a/charts/nautobot/values.yaml +++ b/charts/nautobot/values.yaml @@ -1223,3 +1223,6 @@ postgresqlha: rabbitmq: # -- Enable deployment of the [Bitnami RabbitMQ](https://github.com/bitnami/charts/tree/main/bitnami/rabbitmq) chart, all other `rabbitmq.*` parameters will be passed directly to that chart enabled: false + +# -- Deploy additional Kubernetes manifests +extraObjects: [] diff --git a/docs/advanced-features/extra-objects.md b/docs/advanced-features/extra-objects.md new file mode 100644 index 00000000..6f2a66f9 --- /dev/null +++ b/docs/advanced-features/extra-objects.md @@ -0,0 +1,216 @@ +# Applying Extra Kubernetes Objects + +Certain deployments require additional Kubernetes objects that are not deployed +as a part of this Helm Chart. + +The following are some of the use cases: + +- Admin credentials are generated and stored in a secret manager such as + HashiCorp Vault or AWS Secrets Manager. These credentials must be injected + to Pods as a Kubernetes secret. +- Additional Ingresses must be deployed to expose Nautobot on a different hostname. +- Additional Kubernetes Jobs must be executed to perform additional checks or + to provision certain aspects of Nautobot deployment. + +Let's focus on the use case for admin credentials. Once the credentials are +stored in HashiCorp Vault, for example, you can use the ExternalSecrets +operator to fetch those credentials and create the Kubernetes Secret object. +The following snippet shows an example: + +```yaml +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: my-secret + namespace: nautobot +spec: + data: + - remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: secrets/nautobot/superuser + metadataPolicy: None + property: SUPERUSER_PASSWORD + secretKey: SUPERUSER_PASSWORD + - remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: secrets/nautobot/superuser + metadataPolicy: None + property: API_TOKEN + secretKey: API_TOKEN + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + creationPolicy: Owner + deletionPolicy: Retain + name: my-secret + template: + data: + NAUTOBOT_SUPERUSER_PASSWORD: "{{ `{{ .SUPERUSER_PASSWORD | toString }}` }}" + NAUTOBOT_SUPERUSER_API_TOKEN: "{{ `{{ .API_TOKEN | toString }}` }}" + engineVersion: v2 + mergePolicy: Replace +``` + +The operator will fetch credentials from Vault and it will create a Kubernetes +Secret, after this object is deployed. The Helm Chart values will then specify +the existing secret name such as this: + +```yaml +nautobot: + superUser: + existingSecret: "my-secret" +``` + +To apply additional Kubernetes objects, such as the one above, you +must use an external tool, such as FluxCD, ArgoCD, Ansible, or something else. + +To simplify this process, the Nautobot Helm Chart supports an additional +property called `extraObjects`. This property is a list of Kubernetes manifests +that must be deployed along to Nautobot objects generated from this Helm Chart. +This allows you to omit using external tools to deploy any extra Kubernetes +objects. + +The following snippet shows how the Helm Chart values would look in this +case: + +```yaml +--- +nautobot: + superUser: + existingSecret: "my-secret" + +extraObjects: + - | + apiVersion: external-secrets.io/v1beta1 + kind: ExternalSecret + metadata: + name: my-secret + namespace: nautobot + spec: + data: + - remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: secrets/nautobot/superuser + metadataPolicy: None + property: SUPERUSER_PASSWORD + secretKey: SUPERUSER_PASSWORD + - remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: secrets/nautobot/superuser + metadataPolicy: None + property: API_TOKEN + secretKey: API_TOKEN + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + creationPolicy: Owner + deletionPolicy: Retain + name: my-secret + template: + data: + NAUTOBOT_SUPERUSER_PASSWORD: "{{ `{{ .SUPERUSER_PASSWORD | toString }}` }}" + NAUTOBOT_SUPERUSER_API_TOKEN: "{{ `{{ .API_TOKEN | toString }}` }}" + engineVersion: v2 + mergePolicy: Replace +``` + +Helm will also deploy the `ExternalSecret` object when the release with these +values is deployed. The Nautobot Pods require the `my-secret` Secret, +so they will not start until the ExternalSecrets operator creates the Secret. + +You must be aware that these manifests are deployed in order defined by Helm. +So, there is no guarantee, that certain manifests will be deployed before others. +In cases where you need certain manifests (such as a Job for example), you +will still need a third-party tool. + +The manifests can be defined as a string or as a dictionary, as shown in the +following example: + +```yaml +extraObjects: + - apiVersion: v1 + kind: ConfigMap + metadata: + name: database-host + namespace: nautobot + data: + DATABASE_HOST: database.example.com + - | + apiVersion: v1 + kind: ConfigMap + metadata: + name: database-user + namespace: nautobot + data: + DATABASE_USER: db-admin +``` + +You can also use Go templating language to define certain parts of a manifest. +All variables from the Helm Chart values file are available. You can also +use functions that are available in Go templating language. + +The following example shows how you can specify namespace dynamically, and +how to define the secret name on a single place. + +```yaml +--- +nautobot: + superUser: + existingSecret: "my-secret" + +extraObjects: + - | + apiVersion: external-secrets.io/v1beta1 + kind: ExternalSecret + metadata: + name: {{ .Values.nautobot.superUser.existingSecret }} + namespace: {{ .Release.Namespace }} + spec: + data: + - remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: secrets/nautobot/superuser + metadataPolicy: None + property: SUPERUSER_PASSWORD + secretKey: SUPERUSER_PASSWORD + - remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: secrets/nautobot/superuser + metadataPolicy: None + property: API_TOKEN + secretKey: API_TOKEN + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault + target: + creationPolicy: Owner + deletionPolicy: Retain + name: {{ .Values.nautobot.superUser.existingSecret }} + template: + data: + NAUTOBOT_SUPERUSER_PASSWORD: "{{ `{{ .SUPERUSER_PASSWORD | toString }}` }}" + NAUTOBOT_SUPERUSER_API_TOKEN: "{{ `{{ .API_TOKEN | toString }}` }}" + engineVersion: v2 + mergePolicy: Replace +``` + +Please note that these objects are processed in a template. So make sure that +you don't use the same syntax as used for Go templating. You can use back quotes +to "escape" strings in those cases. The following is an example: + +```yaml +NAUTOBOT_SUPERUSER_PASSWORD: "{{ `{{ .SUPERUSER_PASSWORD | toString }}` }}" +``` + +The resulting manifest will be: `NAUTOBOT_SUPERUSER_PASSWORD: {{ .SUPERUSER_PASSWORD | toString }}` diff --git a/docs/configuration/reference.md b/docs/configuration/reference.md index 566ff6d1..9b548cf5 100644 --- a/docs/configuration/reference.md +++ b/docs/configuration/reference.md @@ -68,6 +68,12 @@ hide: |-----|------|---------|-------------| | [commonAnnotations](https://github.com/nautobot/helm-charts/blob/main/charts/nautobot/values.yaml#L3) | map[string]string | `{}` | Annotations to be applied to ALL resources created by this chart | +## ExtraObjects Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| [extraObjects](https://github.com/nautobot/helm-charts/blob/main/charts/nautobot/values.yaml#L1228) | list | `[]` | Deploy additional Kubernetes manifests | + ## Ingress Values | Key | Type | Default | Description | diff --git a/mkdocs.yml b/mkdocs.yml index 5bc357a9..8751ef28 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -79,6 +79,7 @@ nav: - Existing Secrets: "advanced-features/existing-secrets.md" - External Database: "advanced-features/external-database.md" - External Redis: "advanced-features/external-redis.md" + - Extra Objects: "advanced-features/extra-objects.md" - Initialization Job: "advanced-features/init-hook.md" - Ingress: "advanced-features/ingress.md" - MySQL Support: "advanced-features/mysql.md"