mirror of
https://github.com/immich-app/devtools.git
synced 2026-09-30 13:23:00 +08:00
chore: adapt volsync template to use new r2 bucket module secret (#818)
This commit is contained in:
@@ -49,4 +49,6 @@ spec:
|
|||||||
APP: *app
|
APP: *app
|
||||||
VOLSYNC_CAPACITY: 20Gi
|
VOLSYNC_CAPACITY: 20Gi
|
||||||
VOLSYNC_SCHEDULE: "0 17 * * *"
|
VOLSYNC_SCHEDULE: "0 17 * * *"
|
||||||
VOLSYNC_REPO_SECRET: mich-cloudflare-r2-outline-volsync-backup
|
VOLSYNC_SECRET_STORE: 1p-tf
|
||||||
|
VOLSYNC_RESTIC_PASSWORD_SECRET: OUTLINE_VOLSYNC_BACKUPS_RESTIC_SECRET
|
||||||
|
VOLSYNC_BUCKET_SECRET: OUTLINE_VOLSYNC_BACKUPS_BUCKET
|
||||||
|
|||||||
@@ -43,9 +43,6 @@ resources:
|
|||||||
|
|
||||||
- `APP`: The application name
|
- `APP`: The application name
|
||||||
- `VOLSYNC_CAPACITY`: The PVC size
|
- `VOLSYNC_CAPACITY`: The PVC size
|
||||||
- `VOLSYNC_REPO_SECRET`
|
- `VOLSYNC_SECRET_STORE`: The name of the ClusterSecretStore to use
|
||||||
The name of the 1password entry holding the appropriate secret values:
|
- `VOLSYNC_RESTIC_PASSWORD_SECRET`: The name of the 1password entry holding the restic password
|
||||||
- `RESTIC_REPOSITORY`
|
- `VOLSYNC_BUCKET_SECRET`: The name of the 1password entry holding the bucket credentials
|
||||||
- `RESTIC_PASSWORD`
|
|
||||||
- `AWS_ACCESS_KEY_ID`
|
|
||||||
- `AWS_SECRET_ACCESS_KEY`
|
|
||||||
|
|||||||
@@ -1,6 +1,37 @@
|
|||||||
apiVersion: onepassword.com/v1
|
apiVersion: external-secrets.io/v1
|
||||||
kind: OnePasswordItem
|
kind: ExternalSecret
|
||||||
metadata:
|
metadata:
|
||||||
name: "${VOLSYNC_REPO_SECRET}"
|
name: ${APP}-volsync-repo
|
||||||
spec:
|
spec:
|
||||||
itemPath: "vaults/Kubernetes/items/${VOLSYNC_REPO_SECRET}"
|
secretStoreRef:
|
||||||
|
kind: ClusterSecretStore
|
||||||
|
name: ${VOLSYNC_SECRET_STORE}
|
||||||
|
refreshInterval: "20s"
|
||||||
|
target:
|
||||||
|
template:
|
||||||
|
engineVersion: v2
|
||||||
|
data:
|
||||||
|
RESTIC_PASSWORD: "{{ .restic_password }}"
|
||||||
|
RESTIC_REPOSITORY: "s3:{{ .endpoint }}/{{ .bucket_name }}"
|
||||||
|
AWS_ACCESS_KEY_ID: "{{ .access_key_id }}"
|
||||||
|
AWS_SECRET_ACCESS_KEY: "{{ .secret_access_key }}"
|
||||||
|
data:
|
||||||
|
- secretKey: restic_password
|
||||||
|
remoteRef:
|
||||||
|
key: ${VOLSYNC_RESTIC_PASSWORD_SECRET}
|
||||||
|
- secretKey: access_key_id
|
||||||
|
remoteRef:
|
||||||
|
key: ${VOLSYNC_BUCKET_SECRET}
|
||||||
|
property: access_key_id
|
||||||
|
- secretKey: secret_access_key
|
||||||
|
remoteRef:
|
||||||
|
key: ${VOLSYNC_BUCKET_SECRET}
|
||||||
|
property: secret_access_key
|
||||||
|
- secretKey: bucket_name
|
||||||
|
remoteRef:
|
||||||
|
key: ${VOLSYNC_BUCKET_SECRET}
|
||||||
|
property: bucket_name
|
||||||
|
- secretKey: endpoint
|
||||||
|
remoteRef:
|
||||||
|
key: ${VOLSYNC_BUCKET_SECRET}
|
||||||
|
property: endpoint
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ spec:
|
|||||||
manual: restore-once
|
manual: restore-once
|
||||||
restic:
|
restic:
|
||||||
copyMethod: Snapshot
|
copyMethod: Snapshot
|
||||||
repository: "${VOLSYNC_REPO_SECRET}"
|
repository: "${APP}-volsync-repo"
|
||||||
cacheStorageClassName: "zfs"
|
cacheStorageClassName: "zfs"
|
||||||
cacheCapacity: "${VOLSYNC_CACHE_CAPACITY:-1Gi}"
|
cacheCapacity: "${VOLSYNC_CACHE_CAPACITY:-1Gi}"
|
||||||
storageClassName: "zfs"
|
storageClassName: "zfs"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ spec:
|
|||||||
schedule: "${VOLSYNC_SCHEDULE:-0 4 * * *}"
|
schedule: "${VOLSYNC_SCHEDULE:-0 4 * * *}"
|
||||||
restic:
|
restic:
|
||||||
copyMethod: Clone
|
copyMethod: Clone
|
||||||
repository: "${VOLSYNC_REPO_SECRET}"
|
repository: "${APP}-volsync-repo"
|
||||||
cacheStorageClassName: "zfs"
|
cacheStorageClassName: "zfs"
|
||||||
cacheCapacity: "${VOLSYNC_CACHE_CAPACITY:-1Gi}"
|
cacheCapacity: "${VOLSYNC_CACHE_CAPACITY:-1Gi}"
|
||||||
storageClassName: "zfs"
|
storageClassName: "zfs"
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ module "generated-secrets" {
|
|||||||
{ name = "PREVIEWS_GITHUB_WEBHOOK_SECRET" },
|
{ name = "PREVIEWS_GITHUB_WEBHOOK_SECRET" },
|
||||||
{ name = "AUTH_ZITADEL_MASTER_KEY", length = 32 },
|
{ name = "AUTH_ZITADEL_MASTER_KEY", length = 32 },
|
||||||
{ name = "OUTLINE_SECRET_KEY", length = 64, type = "numeric" },
|
{ name = "OUTLINE_SECRET_KEY", length = 64, type = "numeric" },
|
||||||
{ name = "OUTLINE_UTILS_SECRET" }
|
{ name = "OUTLINE_UTILS_SECRET" },
|
||||||
|
{ name = "OUTLINE_VOLSYNC_BACKUPS_RESTIC_SECRET" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,45 +95,6 @@ resource "onepassword_item" "mich_cloudflare_r2_data_pipeline_vmetrics_backups_b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "random_password" "outline_backups_restic_secret" {
|
|
||||||
length = 40
|
|
||||||
special = true
|
|
||||||
override_special = "!@#$%^&*()_+"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "onepassword_item" "mich_cloudflare_r2_outline_volsync_backup" {
|
|
||||||
vault = data.onepassword_vault.kubernetes.uuid
|
|
||||||
title = "mich-cloudflare-r2-outline-volsync-backup"
|
|
||||||
category = "secure_note"
|
|
||||||
section {
|
|
||||||
label = "Cloudflare R2 Bucket"
|
|
||||||
|
|
||||||
field {
|
|
||||||
label = "RESTIC_REPOSITORY"
|
|
||||||
type = "STRING"
|
|
||||||
value = "s3:https://${cloudflare_r2_bucket.outline_volsync_backups.account_id}.r2.cloudflarestorage.com/${cloudflare_r2_bucket.outline_volsync_backups.name}"
|
|
||||||
}
|
|
||||||
|
|
||||||
field {
|
|
||||||
label = "RESTIC_PASSWORD"
|
|
||||||
type = "CONCEALED"
|
|
||||||
value = random_password.outline_backups_restic_secret.result
|
|
||||||
}
|
|
||||||
|
|
||||||
field {
|
|
||||||
label = "AWS_ACCESS_KEY_ID"
|
|
||||||
type = "CONCEALED"
|
|
||||||
value = data.terraform_remote_state.api_keys_state.outputs.mich_cloudflare_r2_token_id
|
|
||||||
}
|
|
||||||
|
|
||||||
field {
|
|
||||||
label = "AWS_SECRET_ACCESS_KEY"
|
|
||||||
type = "CONCEALED"
|
|
||||||
value = sha256(data.terraform_remote_state.api_keys_state.outputs.mich_cloudflare_r2_token_value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "onepassword_item" "mich_cloudflare_r2_outline_database_backups_bucket" {
|
resource "onepassword_item" "mich_cloudflare_r2_outline_database_backups_bucket" {
|
||||||
vault = data.onepassword_vault.kubernetes.uuid
|
vault = data.onepassword_vault.kubernetes.uuid
|
||||||
title = "mich-cloudflare-r2-outline-database-backup-bucket"
|
title = "mich-cloudflare-r2-outline-database-backup-bucket"
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
data "onepassword_vault" "tf" {
|
||||||
|
name = "tf"
|
||||||
|
}
|
||||||
|
|
||||||
resource "cloudflare_r2_bucket" "tf_state_database_backups" {
|
resource "cloudflare_r2_bucket" "tf_state_database_backups" {
|
||||||
account_id = var.cloudflare_account_id
|
account_id = var.cloudflare_account_id
|
||||||
name = "tf-state-database-backups"
|
name = "tf-state-database-backups"
|
||||||
@@ -22,10 +26,19 @@ resource "cloudflare_r2_bucket" "outline_database_backups" {
|
|||||||
location = "WEUR"
|
location = "WEUR"
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "cloudflare_r2_bucket" "outline_volsync_backups" {
|
moved {
|
||||||
account_id = var.cloudflare_account_id
|
from = cloudflare_r2_bucket.outline_volsync_backups
|
||||||
name = "outline-volsync-backups"
|
to = module.outline_volsync_backups.cloudflare_r2_bucket.bucket
|
||||||
location = "WEUR"
|
}
|
||||||
|
|
||||||
|
module "outline_volsync_backups" {
|
||||||
|
source = "./shared/modules/cloudflare-r2-bucket"
|
||||||
|
|
||||||
|
bucket_name = "outline-volsync-backups"
|
||||||
|
cloudflare_account_id = var.cloudflare_account_id
|
||||||
|
onepassword_vault_id = data.onepassword_vault.tf.uuid
|
||||||
|
item_name = "OUTLINE_VOLSYNC_BACKUPS_BUCKET"
|
||||||
|
allowed_ips = [local.mich_ip]
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "cloudflare_r2_bucket" "static" {
|
resource "cloudflare_r2_bucket" "static" {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
terraform {
|
terraform {
|
||||||
source = "."
|
source = "../../../../../"
|
||||||
|
|
||||||
extra_arguments custom_vars {
|
extra_arguments custom_vars {
|
||||||
commands = get_terraform_commands_that_need_vars()
|
commands = get_terraform_commands_that_need_vars()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ terraform {
|
|||||||
|
|
||||||
required_providers {
|
required_providers {
|
||||||
cloudflare = {
|
cloudflare = {
|
||||||
source = "cloudflare/cloudflare"
|
source = "cloudflare/cloudflare"
|
||||||
version = "~>4.46"
|
version = "~>4.46"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
locals {
|
locals {
|
||||||
app_name = replace(var.app_name, "/[^a-zA-Z\\d]/", "-")
|
app_name = replace(var.app_name, "/[^a-zA-Z\\d]/", "-")
|
||||||
dashed_domain = replace(var.domain, "/[^a-zA-Z\\d]/", "-")
|
dashed_domain = replace(var.domain, "/[^a-zA-Z\\d]/", "-")
|
||||||
sanitised_project_name = "${local.app_name}-${local.dashed_domain}-${var.env}"
|
sanitised_project_name = "${local.app_name}-${local.dashed_domain}-${var.env}"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ terraform {
|
|||||||
|
|
||||||
required_providers {
|
required_providers {
|
||||||
cloudflare = {
|
cloudflare = {
|
||||||
source = "cloudflare/cloudflare"
|
source = "cloudflare/cloudflare"
|
||||||
version = "~>4.46"
|
version = "~>4.46"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ module "domain" {
|
|||||||
source = "../domain"
|
source = "../domain"
|
||||||
|
|
||||||
app_name = var.app_name
|
app_name = var.app_name
|
||||||
stage = var.stage
|
stage = var.stage
|
||||||
env = var.env
|
env = var.env
|
||||||
}
|
}
|
||||||
|
|
||||||
data "cloudflare_zone" "domain" {
|
data "cloudflare_zone" "domain" {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ locals {
|
|||||||
// This determines whether the deployment is production or staging
|
// This determines whether the deployment is production or staging
|
||||||
// In our case we deploy to the "prod" production branch only for production environment with no stage
|
// In our case we deploy to the "prod" production branch only for production environment with no stage
|
||||||
// This automatically resolves if we combine stage and env
|
// This automatically resolves if we combine stage and env
|
||||||
unsanitised_pages_branch = "${var.stage}${var.env}"
|
unsanitised_pages_branch = "${var.stage}${var.env}"
|
||||||
pages_branch = replace(local.unsanitised_pages_branch, "/[^a-zA-Z\\d]/", "-")
|
pages_branch = replace(local.unsanitised_pages_branch, "/[^a-zA-Z\\d]/", "-")
|
||||||
pages_url_prefix = local.pages_branch == "prod" ? "" : "${local.pages_branch}."
|
pages_url_prefix = local.pages_branch == "prod" ? "" : "${local.pages_branch}."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
locals {
|
locals {
|
||||||
// Only include stage name in domain if its set
|
// Only include stage name in domain if its set
|
||||||
domain_stage = var.stage == "" ? "" : "${var.stage}."
|
domain_stage = var.stage == "" ? "" : "${var.stage}."
|
||||||
// We don't include the environment name in the URL for prod
|
// We don't include the environment name in the URL for prod
|
||||||
domain_env = var.env == "prod" ? "" : "${var.env}."
|
domain_env = var.env == "prod" ? "" : "${var.env}."
|
||||||
// Combine domain stage and environment, if stage is blank and env is prod, this will be an empty string
|
// Combine domain stage and environment, if stage is blank and env is prod, this will be an empty string
|
||||||
domain_prefix = "${local.domain_stage}${local.domain_env}"
|
domain_prefix = "${local.domain_stage}${local.domain_env}"
|
||||||
// Example: buy.immich.app or buy.dev.immich.app or buy.pr-55.dev.immich.app
|
// Example: buy.immich.app or buy.dev.immich.app or buy.pr-55.dev.immich.app
|
||||||
fqdn = "${var.app_name}.${local.domain_prefix}${var.domain}"
|
fqdn = "${var.app_name}.${local.domain_prefix}${var.domain}"
|
||||||
}
|
}
|
||||||
|
|
||||||
output fqdn {
|
output "fqdn" {
|
||||||
value = local.fqdn
|
value = local.fqdn
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user