DeployK8up installs the k8up backup operator and configures scheduled backups
(ctx *pulumi.Context, cluster *providers.ProviderInfo, environment string, storage *providers.BackupStorageInfo)
| 15 | |
| 16 | // DeployK8up installs the k8up backup operator and configures scheduled backups |
| 17 | func DeployK8up(ctx *pulumi.Context, cluster *providers.ProviderInfo, environment string, storage *providers.BackupStorageInfo) error { |
| 18 | if storage == nil { |
| 19 | ctx.Log.Info("No backup storage configured, skipping k8up deployment", nil) |
| 20 | return nil |
| 21 | } |
| 22 | |
| 23 | // Install the k8up CRDs before the helm chart |
| 24 | // Related: https://github.com/k8up-io/k8up/issues/1050 |
| 25 | k8upCRDs, err := yaml.NewConfigFile(ctx, "k8up-crds", &yaml.ConfigFileArgs{ |
| 26 | File: "https://github.com/k8up-io/k8up/releases/download/k8up-4.8.4/k8up-crd.yaml", |
| 27 | }, pulumi.Provider(cluster.Provider)) |
| 28 | if err != nil { |
| 29 | return fmt.Errorf("failed to install k8up CRDs: %w", err) |
| 30 | } |
| 31 | |
| 32 | // Install k8up operator |
| 33 | k8upValues := pulumi.Map{ |
| 34 | "k8up": pulumi.Map{ |
| 35 | "backupCommandAnnotation": pulumi.String("k8up.io/backup-command"), |
| 36 | "fileExtensionAnnotation": pulumi.String("k8up.io/file-extension"), |
| 37 | }, |
| 38 | } |
| 39 | |
| 40 | k8up, err := helm.NewChart(ctx, "k8up", helm.ChartArgs{ |
| 41 | Chart: pulumi.String("k8up"), |
| 42 | Version: pulumi.String("4.8.4"), |
| 43 | FetchArgs: helm.FetchArgs{ |
| 44 | Repo: pulumi.String("https://k8up-io.github.io/k8up"), |
| 45 | }, |
| 46 | Values: k8upValues, |
| 47 | }, pulumi.Provider(cluster.Provider), pulumi.DependsOn([]pulumi.Resource{k8upCRDs})) |
| 48 | if err != nil { |
| 49 | return fmt.Errorf("failed to install k8up: %w", err) |
| 50 | } |
| 51 | |
| 52 | // Create restic repository password secret |
| 53 | repoPassword, err := corev1.NewSecret(ctx, "k8up-repo-password", &corev1.SecretArgs{ |
| 54 | Metadata: &metav1.ObjectMetaArgs{ |
| 55 | Name: pulumi.String("k8up-repo-password"), |
| 56 | Namespace: pulumi.String("default"), |
| 57 | Labels: pulumi.StringMap{ |
| 58 | "k8up.io/backup": pulumi.String("true"), |
| 59 | }, |
| 60 | }, |
| 61 | Type: pulumi.String("Opaque"), |
| 62 | StringData: pulumi.StringMap{ |
| 63 | "password": pulumi.String("password"), // In production we use GCS, which is already encrypted |
| 64 | }, |
| 65 | }, pulumi.Provider(cluster.Provider)) |
| 66 | if err != nil { |
| 67 | return fmt.Errorf("failed to create repository password secret: %w", err) |
| 68 | } |
| 69 | |
| 70 | // Determine schedule based on environment |
| 71 | backupSchedule := "46 4 * * *" // Daily at 4:46 AM |
| 72 | pruneSchedule := "46 5 * * *" // Daily at 5:46 AM |
| 73 | keepDaily := 28 // Keep daily backups for 28 days |
| 74 |