From a7a08ef9f33ad9ce4370759dc01ed0380639d949 Mon Sep 17 00:00:00 2001 From: alexlebens Date: Sat, 13 Apr 2024 02:06:02 -0600 Subject: [PATCH] change chart to align with cnpg's chart --- charts/postgres-cluster/Chart.yaml | 2 +- charts/postgres-cluster/templates/_backup.tpl | 30 +++ .../postgres-cluster/templates/_boostrap.tpl | 61 ++++++ .../postgres-cluster/templates/_helpers.tpl | 71 +++++++ .../postgres-cluster/templates/cluster.yaml | 52 +++++ .../templates/postgresql-cluster.yaml | 81 -------- .../templates/prometheus-rule.yaml | 30 +++ .../templates/scheduled-backup.yaml | 16 +- charts/postgres-cluster/values.yaml | 186 +++++++++++++++--- 9 files changed, 408 insertions(+), 121 deletions(-) create mode 100644 charts/postgres-cluster/templates/_backup.tpl create mode 100644 charts/postgres-cluster/templates/_boostrap.tpl create mode 100644 charts/postgres-cluster/templates/_helpers.tpl create mode 100644 charts/postgres-cluster/templates/cluster.yaml delete mode 100644 charts/postgres-cluster/templates/postgresql-cluster.yaml create mode 100644 charts/postgres-cluster/templates/prometheus-rule.yaml diff --git a/charts/postgres-cluster/Chart.yaml b/charts/postgres-cluster/Chart.yaml index 41119ec..2b4fcce 100644 --- a/charts/postgres-cluster/Chart.yaml +++ b/charts/postgres-cluster/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: postgres-cluster -version: 0.3.0 +version: 1.0.0 description: Chart for cloudnative-pg cluster keywords: - database diff --git a/charts/postgres-cluster/templates/_backup.tpl b/charts/postgres-cluster/templates/_backup.tpl new file mode 100644 index 0000000..5bac7cb --- /dev/null +++ b/charts/postgres-cluster/templates/_backup.tpl @@ -0,0 +1,30 @@ +{{- define "cluster.backup" -}} +{{- if .Values.backup.enabled }} +backup: + retentionPolicy: {{ .Values.backup.retentionPolicy }} + barmanObjectStore: + destinationPath: "s3://{{ .Values.backup.endpointBucket }}/{{ .Values.kubernetesClusterName }}/postgresql/{{ .Release.Name }}" + endpointURL: {{ .Values.backup.endpointURL }} + {{- if .Values.backup.endpointCA }} + endpointCA: + name: {{ .Values.backup.endpointCA }} + key: ca-bundle.crt + {{- end }} + serverName: "postgresql-{{ .Release.Name }}-cluster-backup-index-{{ .Values.backup.backupIndex }}" + s3Credentials: + accessKeyId: + name: {{ include "cluster.backup.credentials" . }} + key: ACCESS_KEY_ID + secretAccessKey: + name: {{ include "cluster.backup.credentials" . }} + key: ACCESS_SECRET_KEY + wal: + compression: {{ .Values.backup.wal.compression }} + encryption: {{ .Values.backup.wal.encryption }} + maxParallel: {{ .Values.backup.wal.maxParallel }} + data: + compression: {{ .Values.backup.data.compression }} + encryption: {{ .Values.backup.data.encryption }} + jobs: {{ .Values.backup.data.jobs }} +{{- end }} +{{- end }} diff --git a/charts/postgres-cluster/templates/_boostrap.tpl b/charts/postgres-cluster/templates/_boostrap.tpl new file mode 100644 index 0000000..8ab054f --- /dev/null +++ b/charts/postgres-cluster/templates/_boostrap.tpl @@ -0,0 +1,61 @@ +{{- define "cluster.bootstrap" -}} +bootstrap: +{{- if eq .Values.mode "standalone" }} + initdb: + {{- with .Values.cluster.initdb }} + {{- with (omit . "postInitApplicationSQL") }} + {{- . | toYaml | nindent 4 }} + {{- end }} + {{- end }} + postInitApplicationSQL: + {{- if eq .Values.type "postgis" }} + - CREATE EXTENSION IF NOT EXISTS postgis; + - CREATE EXTENSION IF NOT EXISTS postgis_topology; + - CREATE EXTENSION IF NOT EXISTS fuzzystrmatch; + - CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder; + {{- else if eq .Values.type "timescaledb" }} + - CREATE EXTENSION IF NOT EXISTS timescaledb; + {{- end }} + {{- with .Values.cluster.initdb }} + {{- range .postInitApplicationSQL }} + {{- printf "- %s" . | nindent 6 }} + {{- end -}} + {{- end -}} +{{- else if eq .Values.mode "recovery" }} + recovery: + {{- with .Values.recovery.pitrTarget.time }} + recoveryTarget: + targetTime: {{ . }} + {{- end }} + source: "postgresql-{{ .Release.Name }}-cluster-backup-index-{{ .Values.recovery.recoveryIndex }}" +externalClusters: + - name: "postgresql-{{ .Release.Name }}-cluster-backup-index-{{ .Values.recovery.recoveryIndex }}" + barmanObjectStore: + serverName: "postgresql-{{ .Release.Name }}-cluster-backup-index-{{ .Values.recovery.recoveryIndex }}" + destinationPath: "s3://{{ .Values.recovery.endpointBucket }}/{{ .Values.kubernetesClusterName }}/postgresql/{{ .Release.Name }}" + endpointURL: {{ .Values.recovery.endpointURL }} + {{- with .Values.recovery.endpointCA }} + endpointCA: + name: {{ . }} + key: ca-bundle.crt + {{- end }} + serverName: "postgresql-{{ .Release.Name }}-cluster-backup-index-{{ .Values.recovery.recoveryIndex }}" + s3Credentials: + accessKeyId: + name: {{ include "cluster.recovery.credentials" . }} + key: ACCESS_KEY_ID + secretAccessKey: + name: {{ include "cluster.recovery.credentials" . }} + key: ACCESS_SECRET_KEY + wal: + compression: {{ .Values.recovery.wal.compression }} + encryption: {{ .Values.recovery.wal.encryption }} + maxParallel: {{ .Values.recovery.wal.maxParallel }} + data: + compression: {{ .Values.recovery.data.compression }} + encryption: {{ .Values.recovery.data.encryption }} + jobs: {{ .Values.recovery.data.jobs }} +{{- else }} + {{ fail "Invalid cluster mode!" }} +{{- end }} +{{- end }} diff --git a/charts/postgres-cluster/templates/_helpers.tpl b/charts/postgres-cluster/templates/_helpers.tpl new file mode 100644 index 0000000..06d0012 --- /dev/null +++ b/charts/postgres-cluster/templates/_helpers.tpl @@ -0,0 +1,71 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "cluster.name" -}} + {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "cluster.fullname" -}} +{{- if .Values.fullnameOverride }} + {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} + {{- $name := default .Chart.Name .Values.nameOverride }} + {{- if contains $name .Release.Name }} + {{- .Release.Name | trunc 63 | trimSuffix "-" }} + {{- else }} + {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} + {{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "cluster.chart" -}} + {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "cluster.labels" -}} +helm.sh/chart: {{ include "cluster.chart" . }} +{{ include "cluster.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "cluster.selectorLabels" -}} +app.kubernetes.io/name: {{ include "cluster.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/part-of: cloudnative-pg +{{- end }} + +{{/* +Generate name for object store credentials +*/}} +{{- define "cluster.recovery.credentials" -}} + {{- if .Values.recovery.endpointCredentials -}} + {{- .Values.recovery.endpointCredentials -}} + {{- else -}} + {{- printf "postgresql-%s-cluster-backup-secret" .Release.Name | trunc 63 | trimSuffix "-" -}} + {{- end }} +{{- end -}} + +{{- define "cluster.backup.credentials" -}} + {{- if .Values.backup.endpointCredentials -}} + {{- .Values.backup.endpointCredentials -}} + {{- else -}} + {{- printf "postgresql-%s-cluster-backup-secret" .Release.Name | trunc 63 | trimSuffix "-" -}} + {{- end }} +{{- end -}} diff --git a/charts/postgres-cluster/templates/cluster.yaml b/charts/postgres-cluster/templates/cluster.yaml new file mode 100644 index 0000000..b5c8f4e --- /dev/null +++ b/charts/postgres-cluster/templates/cluster.yaml @@ -0,0 +1,52 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: "postgresql-{{ include "cluster.fullname" . }}-cluster" + namespace: {{ .Release.Namespace }} + {{- with .Values.cluster.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "cluster.labels" . | nindent 4 }} + {{- with .Values.cluster.additionalLabels }} + {{ toYaml . | nindent 4 }} + {{- end }} +spec: + instances: {{ .Values.cluster.instances }} + imageName: "{{ .Values.cluster.image.repository }}:{{ .Values.cluster.image.tag }}" + imagePullPolicy: {{ .Values.cluster.image.pullPolicy }} + postgresUID: {{ .Values.cluster.postgresUID }} + postgresGID: {{ .Values.cluster.postgresGID }} + walStorage: + size: {{ .Values.cluster.walStorage.size }} + storageClass: {{ .Values.cluster.walStorage.storageClass }} + storage: + size: {{ .Values.cluster.storage.size }} + storageClass: {{ .Values.cluster.storage.storageClass }} + {{- with .Values.cluster.resources }} + resources: + {{- toYaml . | nindent 4 }} + {{ end }} + {{- with .Values.cluster.affinity }} + affinity: + {{- toYaml . | nindent 4 }} + {{- end }} + priorityClassName: {{ .Values.cluster.priorityClassName }} + primaryUpdateMethod: {{ .Values.cluster.primaryUpdateMethod }} + primaryUpdateStrategy: {{ .Values.cluster.primaryUpdateStrategy }} + logLevel: {{ .Values.cluster.logLevel }} + postgresql: + shared_preload_libraries: + {{- if eq .Values.type "timescaledb" }} + - timescaledb + {{- end }} + {{- with .Values.cluster.postgresql.parameters }} + parameters: + {{- toYaml . | nindent 6 }} + {{ end }} + monitoring: + enablePodMonitor: {{ and .Values.cluster.monitoring.enabled .Values.cluster.monitoring.podMonitor.enabled }} + + {{ include "cluster.bootstrap" . | nindent 2 }} + {{ include "cluster.backup" . | nindent 2 }} diff --git a/charts/postgres-cluster/templates/postgresql-cluster.yaml b/charts/postgres-cluster/templates/postgresql-cluster.yaml deleted file mode 100644 index 071e548..0000000 --- a/charts/postgres-cluster/templates/postgresql-cluster.yaml +++ /dev/null @@ -1,81 +0,0 @@ -apiVersion: postgresql.cnpg.io/v1 -kind: Cluster -metadata: - name: "postgresql-{{ .Release.Name }}-cluster" - namespace: {{ .Release.Namespace }} - labels: - app.kubernetes.io/name: postgresql - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/version: {{ .Chart.AppVersion }} - app.kubernetes.io/component: database - app.kubernetes.io/part-of: {{ .Release.Name }} -spec: - imageName: "{{ .Values.cluster.image.repository }}:{{ .Values.cluster.image.tag }}" - instances: {{ .Values.cluster.instances }} - replicationSlots: - highAvailability: - enabled: true - affinity: - enablePodAntiAffinity: true - topologyKey: kubernetes.io/hostname - postgresql: - parameters: - {{- toYaml .Values.cluster.parameters | nindent 6 }} - resources: - {{- toYaml .Values.cluster.resources | nindent 4 }} - storage: - storageClass: {{ .Values.cluster.storage.data.storageClass }} - size: {{ .Values.cluster.storage.data.size }} - walStorage: - storageClass: {{ .Values.cluster.storage.wal.storageClass }} - size: {{ .Values.cluster.storage.wal.size }} - monitoring: - enablePodMonitor: true - - {{- if .Values.bootstrap.initdbEnabled }} - bootstrap: - initdb: - {{- toYaml .Values.bootstrap.initdb | nindent 6 }} - {{- end }} - - {{- if .Values.bootstrap.recoveryEnabled }} - bootstrap: - recovery: - source: "postgresql-{{ .Release.Name }}-cluster-backup-index-{{ .Values.bootstrap.recoveryIndex }}" - externalClusters: - - name: "postgresql-{{ .Release.Name }}-cluster-backup-index-{{ .Values.bootstrap.recoveryIndex }}" - barmanObjectStore: - endpointURL: {{ .Values.bootstrap.endpointURL }} - destinationPath: "s3://{{ .Values.bootstrap.bucket }}/{{ .Values.cluster.name }}/postgresql/{{ .Release.Name }}-cluster" - s3Credentials: - accessKeyId: - name: "postgresql-{{ .Release.Name }}-cluster-backup-secret" - key: ACCESS_KEY_ID - secretAccessKey: - name: "postgresql-{{ .Release.Name }}-cluster-backup-secret" - key: ACCESS_SECRET_KEY - data: - compression: {{ .Values.cluster.compression }} - wal: - compression: {{ .Values.cluster.compression }} - {{- end }} - - {{- if .Values.backup.backupEnabled }} - backup: - retentionPolicy: "{{ .Values.backup.retentionPolicy }}" - barmanObjectStore: - destinationPath: "s3://{{ .Values.backup.bucket }}/{{ .Values.cluster.name }}/postgresql/{{ .Release.Name }}-cluster" - endpointURL: {{ .Values.backup.endpointURL }} - serverName: "postgresql-{{ .Release.Name }}-cluster-backup-index-{{ .Values.backup.backupIndex }}" - s3Credentials: - accessKeyId: - name: "postgresql-{{ .Release.Name }}-cluster-backup-secret" - key: ACCESS_KEY_ID - secretAccessKey: - name: "postgresql-{{ .Release.Name }}-cluster-backup-secret" - key: ACCESS_SECRET_KEY - data: - compression: {{ .Values.cluster.compression }} - wal: - compression: {{ .Values.cluster.compression }} - {{- end }} diff --git a/charts/postgres-cluster/templates/prometheus-rule.yaml b/charts/postgres-cluster/templates/prometheus-rule.yaml new file mode 100644 index 0000000..9c6b15c --- /dev/null +++ b/charts/postgres-cluster/templates/prometheus-rule.yaml @@ -0,0 +1,30 @@ +{{- if and .Values.cluster.monitoring.enabled .Values.cluster.monitoring.prometheusRule.enabled -}} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: "postgresql-{{ include "cluster.fullname" . }}-alert-rules" + namespace: {{ .Release.Namespace }} + labels: + {{- include "cluster.labels" . | nindent 4 }} + {{- with .Values.cluster.additionalLabels }} + {{ toYaml . | nindent 4 }} + {{- end }} +spec: + groups: + - name: cloudnative-pg/{{ include "cluster.fullname" . }} + rules: + {{- $dict := dict "excludeRules" .Values.cluster.monitoring.prometheusRule.excludeRules -}} + {{- $_ := set $dict "value" "{{ $value }}" -}} + {{- $_ := set $dict "namespace" .Release.Namespace -}} + {{- $_ := set $dict "cluster" (include "cluster.fullname" .) -}} + {{- $_ := set $dict "labels" (dict "job" "{{ $labels.job }}" "node" "{{ $labels.node }}" "pod" "{{ $labels.pod }}") -}} + {{- $_ := set $dict "podSelector" (printf "%s-([1-9][0-9]*)$" (include "cluster.fullname" .)) -}} + {{- $_ := set $dict "Values" .Values -}} + {{- $_ := set $dict "Template" .Template -}} + {{- range $path, $_ := .Files.Glob "prometheus_rules/**.yaml" }} + {{- $tpl := tpl ($.Files.Get $path) $dict | nindent 10 | trim -}} + {{- with $tpl }} + - {{ $tpl }} + {{- end -}} + {{- end -}} +{{ end }} diff --git a/charts/postgres-cluster/templates/scheduled-backup.yaml b/charts/postgres-cluster/templates/scheduled-backup.yaml index 1ec8706..d13e542 100644 --- a/charts/postgres-cluster/templates/scheduled-backup.yaml +++ b/charts/postgres-cluster/templates/scheduled-backup.yaml @@ -1,16 +1,18 @@ +{{ if .Values.backup.enabled }} apiVersion: postgresql.cnpg.io/v1 kind: ScheduledBackup metadata: - name: "postgresql-{{ .Release.Name }}-cluster-backup" + name: "postgresql-{{ include "cluster.fullname" . }}-cluster-scheduled-backup" namespace: {{ .Release.Namespace }} labels: - app.kubernetes.io/name: postgresql - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/version: {{ .Chart.AppVersion }} - app.kubernetes.io/component: database - app.kubernetes.io/part-of: {{ .Release.Name }} + {{- include "cluster.labels" . | nindent 4 }} + {{- with .Values.cluster.additionalLabels }} + {{ toYaml . | nindent 4 }} + {{- end }} spec: + immediate: true schedule: {{ .Values.backup.schedule }} backupOwnerReference: self cluster: - name: "postgresql-{{ .Release.Name }}-cluster" + name: "postgresql-{{ include "cluster.fullname" . }}-cluster" +{{ end }} diff --git a/charts/postgres-cluster/values.yaml b/charts/postgres-cluster/values.yaml index 3dcdd64..76a838b 100644 --- a/charts/postgres-cluster/values.yaml +++ b/charts/postgres-cluster/values.yaml @@ -1,42 +1,164 @@ +# -- Override the name of the chart +nameOverride: "" +# -- Override the full name of the chart +fullnameOverride: "" + +### +# -- Type of the CNPG database. Available types: +# * `postgresql` +# * `postgis` +# * `timescaledb` +type: postgresql + +### +# Cluster mode of operation. Available modes: +# * `standalone` - default mode. Creates new or updates an existing CNPG cluster. +# * `recovery` - Same as standalone but creates a cluster from a backup, object store or via pg_basebackup +mode: standalone + +# Generates bucket name and path for recovery and backup, creates: //postgresql/{{ .Release.Name }} +kubernetesClusterName: "" + cluster: - name: + instances: 3 + image: repository: ghcr.io/cloudnative-pg/postgresql tag: 16.2 - instances: 3 - parameters: - shared_buffers: 128MB - max_slot_wal_keep_size: 2000MB - hot_standby_feedback: "on" - compression: snappy + pullPolicy: IfNotPresent + + # The UID and GID of the postgres user inside the image + postgresUID: 26 + postgresGID: 26 + + walStorage: + size: 2Gi + storageClass: "" + storage: + size: 10Gi + storageClass: "" + resources: requests: - memory: 512Mi - cpu: 100m + memory: 256Mi + cpu: 10m limits: - memory: 2Gi - cpu: 1500m - hugepages-2Mi: 512Mi - storage: - data: - storageClass: - size: 10Gi - wal: - storageClass: - size: 2Gi -bootstrap: - recoveryEnabled: false + memory: 1Gi + cpu: 100m + hugepages-2Mi: 256Mi + + # See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-AffinityConfiguration + affinity: + enablePodAntiAffinity: true + topologyKey: kubernetes.io/hostname + + additionalLabels: {} + annotations: {} + + priorityClassName: "" + + # Method to follow to upgrade the primary server during a rolling update procedure, after all replicas have been + # successfully updated. It can be switchover (default) or in-place (restart). + primaryUpdateMethod: switchover + + # Strategy to follow to upgrade the primary server during a rolling update procedure, after all replicas have been + # successfully updated: it can be automated (unsupervised - default) or manual (supervised) + primaryUpdateStrategy: unsupervised + + logLevel: "info" + + monitoring: + enabled: false + podMonitor: + enabled: true + prometheusRule: + enabled: true + excludeRules: [] + + # See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-PostgresConfiguration + postgresql: + parameters: + shared_buffers: 128MB + max_slot_wal_keep_size: 2000MB + hot_standby_feedback: "on" + + # BootstrapInitDB is the configuration of the bootstrap process when initdb is used. + # See: https://cloudnative-pg.io/documentation/current/bootstrap/ + # See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-bootstrapinitdb + initdb: {} + # database: app + # owner: app + # secret: "" # Name of the secret containing the initial credentials for the owner of the user database. If empty a new secret will be created from scratch + # postInitApplicationSQL: + # - CREATE TABLE IF NOT EXISTS example; + +recovery: + # Point in time recovery target in RFC3339 format + pitrTarget: + time: "" + + # Overrides the provider specific default endpoint. Defaults to: + # S3: https://s3..amazonaws.com" + endpointURL: "" + endpointBucket: "" + + # Specifies secret that contains a CA bundle to validate a privately signed certificate, should contain the key ca-bundle.crt + endpointCA: "" + + # Specifies secret that contains S3 credentials, should contain the keys ACCESS_KEY_ID and ACCESS_SECRET_KEY + endpointCredentials: "" + + # Generate external cluster name, uses: postgresql-{{ .Release.Name }}-cluster-backup-index-{{ .Values.recovery.recoveryIndex }}" recoveryIndex: 1 - endpointURL: - bucket: - initdbEnabled: false - initdb: - database: app - owner: app + + wal: + # WAL compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. + compression: snappy + # Whether to instruct the storage provider to encrypt WAL files. One of `` (use the storage container default), `AES256` or `aws:kms`. + encryption: "" + # Number of WAL files to be archived or restored in parallel. + maxParallel: 2 + data: + # Data compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. + compression: snappy + # Whether to instruct the storage provider to encrypt data files. One of `` (use the storage container default), `AES256` or `aws:kms`. + encryption: "" + # Number of data files to be archived or restored in parallel. + jobs: 2 + backup: - backupEnabled: true - schedule: "0 0 0 * * *" - retentionPolicy: 14d + enabled: false + + # Overrides the provider specific default endpoint + endpointURL: "" + endpointBucket: "" + + # Specifies secret that contains a CA bundle to validate a privately signed certificate, should contain the key ca-bundle.crt + endpointCA: "" + + # Specifies secret that contains S3 credentials, should contain the keys ACCESS_KEY_ID and ACCESS_SECRET_KEY + endpointCredentials: "" + + # Generate external cluster name, creates: postgresql-{{ .Release.Name }}-cluster-backup-index-{{ .Values.backups.backupIndex }}" backupIndex: 1 - endpointURL: - bucket: + + wal: + # WAL compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. + compression: snappy + # Whether to instruct the storage provider to encrypt WAL files. One of `` (use the storage container default), `AES256` or `aws:kms`. + encryption: "" + # Number of WAL files to be archived or restored in parallel. + maxParallel: 2 + data: + # Data compression method. One of `` (for no compression), `gzip`, `bzip2` or `snappy`. + compression: snappy + # Whether to instruct the storage provider to encrypt data files. One of `` (use the storage container default), `AES256` or `aws:kms`. + encryption: "" + # Number of data files to be archived or restored in parallel. + jobs: 2 + + # Retention policy for backups + retentionPolicy: "30d" + + # Scheduled backup in cron format + schedule: "0 0 0 * * *"