Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions 02-cluster/local/variables.tf
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
variable "infisical_client_id" {
type = string
}
# variable "infisical_client_id" {
# type = string
# }

variable "infisical_client_secret" {
type = string
}
# variable "infisical_client_secret" {
# type = string
# }

variable "gitops_revision" {
type = string
Expand Down
16 changes: 8 additions & 8 deletions 02-cluster/scaleway/argocd.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
data "infisical_secrets" "this" {
env_slug = "staging"
workspace_id = "7ecb6ed4-058a-46cd-ac9f-7e792469cf0f" // project ID
folder_path = "/"
}
# data "infisical_secrets" "this" {
# env_slug = "staging"
# workspace_id = "7ecb6ed4-058a-46cd-ac9f-7e792469cf0f" // project ID
# folder_path = "/"
# }

resource "helm_release" "argocd" {
name = "argocd"
Expand All @@ -21,9 +21,9 @@ resource "helm_release" "argocd" {

set_sensitive = [{
name = "configs.secret.argocdServerAdminPassword"
# ArgoCD expects a bcrypt() hash here. bcrypt() would regenerate on every
# run, so we store the hash directly in Infisical to avoid spurious diffs.
value = data.infisical_secrets.this.secrets["ArgoCD_admin_encrypted"].value
# ArgoCD require a `bcrypt()` hashed password here. But `bcrypt` generate a new hash at each execution
# So instead, we store the hash directly, so terraform is not confused anymore by fake changes
value = var.argocd_admin_password_hash
}]

values = [<<EOF
Expand Down
39 changes: 39 additions & 0 deletions 02-cluster/scaleway/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,42 @@ resource "null_resource" "update_kubeconfig" {
EOT
}
}


resource "kubernetes_namespace" "openbao" {
metadata {
name = "openbao"
}
depends_on = [scaleway_k8s_pool.default]
}

resource "kubernetes_secret" "scaleway_s3_credentials" {
metadata {
name = "scaleway-s3-credentials"
namespace = kubernetes_namespace.openbao.metadata[0].name
}

data = {
bucket = "backup-dev-id"
AWS_ACCESS_KEY_ID = "SCW8FGA70P4HY3A120KV"
AWS_SECRET_ACCESS_KEY = var.scaleway_s3_secret_key
}
}

# AWS credentials OpenBao reads at startup for KMS auto-unseal (seal "awskms").
# Sourced here — outside OpenBao — by necessity: OpenBao can't supply the very
# creds it needs to unseal itself (chicken-and-egg). Values come from the
# 03-backup/scaleway kms.tf outputs, fed via the gitignored *.auto.tfvars.
# Key names (access_key/secret_key) mirror scaleway-s3-credentials so the
# OpenBao chart's extraSecretEnvironmentVars mapping stays uniform.
resource "kubernetes_secret" "openbao_unseal_aws" {
metadata {
name = "openbao-unseal-aws"
namespace = kubernetes_namespace.openbao.metadata[0].name
}

data = {
AWS_ACCESS_KEY_ID = var.openbao_unseal_aws_access_key_id
AWS_SECRET_ACCESS_KEY = var.openbao_unseal_aws_secret_access_key
}
}
67 changes: 50 additions & 17 deletions 02-cluster/scaleway/variables.tf
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
# Infisical provide many way to authenticate.
# You can use `infisical_client_id` and `infisical_client_secret` when running terraform locally
# Or use `infisical_oidc_identity_id` when OIDC integration is available.
variable "infisical_client_id" {
type = string
default = ""
}
# # Infisical provide many way to authenticate.
# # You can use `infisical_client_id` and `infisical_client_secret` when running terraform locally
# # Or use `infisical_oidc_identity_id` when OIDC integration is available.
# variable "infisical_client_id" {
# type = string
# default = ""
# }

variable "infisical_client_secret" {
type = string
default = ""
sensitive = true
}
# variable "infisical_client_secret" {
# type = string
# default = ""
# sensitive = true
# }

variable "infisical_oidc_identity_id" {
description = "Infisical OIDC machine-identity ID. When set, the provider authenticates via GitHub-OIDC; when empty, via universal auth."
type = string
default = ""
}
# variable "infisical_oidc_identity_id" {
# description = "Infisical OIDC machine-identity ID. When set, the provider authenticates via GitHub-OIDC; when empty, via universal auth."
# type = string
# default = ""
# }

variable "k8s_version" {
type = string
Expand Down Expand Up @@ -44,3 +44,36 @@ variable "update_kubeconfig" {
default = false
description = "Set to true when using locally to automatically update you ~/.kube/config. Require `kubectl` and `scw` installed & configured."
}


# variable "gitops_revision" {
# type = string
# default = "main"
# }

variable "argocd_admin_password_hash" {
description = "Pre-computed bcrypt hash of the ArgoCD admin password. When set, Infisical is not consulted."
type = string
# default = ""
}

variable "scaleway_s3_secret_key" {
description = "Scaleway S3 secret key for OpenBao backup bucket"
type = string
sensitive = true
# default = ""
}

variable "openbao_unseal_aws_access_key_id" {
description = "AWS access key id OpenBao uses for KMS auto-unseal. From 03-backup/scaleway output `openbao_unseal_access_key_id`."
type = string
sensitive = true
# default = ""
}

variable "openbao_unseal_aws_secret_access_key" {
description = "AWS secret access key OpenBao uses for KMS auto-unseal. From 03-backup/scaleway output `openbao_unseal_secret_access_key`."
type = string
sensitive = true
# default = ""
}
24 changes: 12 additions & 12 deletions 02-cluster/scaleway/version.tf
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,24 @@ terraform {
source = "hashicorp/helm"
version = "~> 3.0"
}
infisical = {
source = "infisical/infisical"
version = "~> 0.16"
}
# infisical = {
# source = "infisical/infisical"
# version = "~> 0.16"
# }
}
}

provider "scaleway" {}

provider "infisical" {
# provider "infisical" {

auth = {
## Uncomment `universal` and comment `oidc` when running terraform locally.
## By default, even with `INFISICAL_UNIVERSAL_AUTH_CLIENT_XXXX` environment variable, due to `auth.oidc` being present, infisical provider expect OIDC configuration, and nothing else.
# universal = {}
oidc = {}
}
}
# auth = {
# ## Uncomment `universal` and comment `oidc` when running terraform locally.
# ## By default, even with `INFISICAL_UNIVERSAL_AUTH_CLIENT_XXXX` environment variable, due to `auth.oidc` being present, infisical provider expect OIDC configuration, and nothing else.
# # universal = {}
# oidc = {}
# }
# }

provider "kubernetes" {
host = scaleway_k8s_cluster.this.kubeconfig[0].host
Expand Down
69 changes: 69 additions & 0 deletions 04-dns/scaleway/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions 04-dns/scaleway/env/04-dns-scaleway.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
project_id = "6283c05b-a4c7-4f83-a75f-83adad236d54"

# api_key_rotation_days defaults to 365
36 changes: 36 additions & 0 deletions 04-dns/scaleway/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# IAM identity for external-dns (gitops: platform/scaleway/external-dns.yml),
# scoped to Domains & DNS zone record management only — it can read/write DNS
# records, nothing else (no domain registration/transfer, no other product).
#
# scalepack.fr was bought directly through Scaleway Domains & DNS, so its zone
# already lives in the project this key is scoped to.
resource "scaleway_iam_application" "external_dns" {
name = "external-dns-${terraform.workspace}"
description = "Kubernetes workload identity for external-dns (${terraform.workspace}) — manages DNS zone records for domains bought through Scaleway."
}

resource "scaleway_iam_policy" "external_dns" {
name = "external-dns-${terraform.workspace}"
description = "DNS zone record read/write for the external-dns workload. No domain registration/transfer access."
application_id = scaleway_iam_application.external_dns.id

rule {
project_ids = [var.project_id]
permission_set_names = ["DomainsDNSFullAccess"]
}
}

# Scaleway requires every API key to carry an expiry. time_rotating keeps the
# expiry self-renewing: once the window elapses, the next apply rotates the
# key — re-copy it into OpenBao by hand afterward (no automated push yet, see
# gitops apps/external-dns-init).
resource "time_rotating" "external_dns_key" {
rotation_days = var.api_key_rotation_days
}

resource "scaleway_iam_api_key" "external_dns" {
application_id = scaleway_iam_application.external_dns.id
description = "external-dns workload credentials (${terraform.workspace})."
default_project_id = var.project_id
expires_at = time_rotating.external_dns_key.rotation_rfc3339
}
10 changes: 10 additions & 0 deletions 04-dns/scaleway/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
output "workload_access_key" {
description = "Public access key for the external-dns workload identity."
value = scaleway_iam_api_key.external_dns.access_key
}

output "workload_secret_key" {
description = "Secret key for the external-dns workload identity. Not pushed anywhere yet (terraform output) — copy into OpenBao by hand at apps/external-dns/scaleway-dns-credentials (see gitops apps/external-dns-init)."
sensitive = true
value = scaleway_iam_api_key.external_dns.secret_key
}
10 changes: 10 additions & 0 deletions 04-dns/scaleway/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
variable "project_id" {
description = "Scaleway project ID for IAM resource scoping. Must be the project scalepack.fr's DNS zone lives in."
type = string
}

variable "api_key_rotation_days" {
description = "Rotation window (days) for the external-dns API key expiry."
type = number
default = 365
}
24 changes: 24 additions & 0 deletions 04-dns/scaleway/version.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
terraform {
backend "s3" {
bucket = "id-terraform-state20260612164136440800000001"
region = "eu-west-3"
workspace_key_prefix = "dns/scaleway"
key = "terraform.tfstate"
encrypt = true
use_lockfile = true
}

required_providers {
scaleway = {
source = "scaleway/scaleway"
version = "~> 2.0"
}
time = {
source = "hashicorp/time"
version = "~> 0.12"
}
}
}

# Creds, region and project_id come from the scw CLI config (like the other roots).
provider "scaleway" {}
1 change: 1 addition & 0 deletions mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,5 @@ terraform -chdir=01-iam/ci-managed/aws-state-access providers lock -platform=dar
terraform -chdir=02-cluster/local providers lock -platform=darwin_arm64 -platform=linux_amd64
terraform -chdir=02-cluster/scaleway providers lock -platform=darwin_arm64 -platform=linux_amd64
terraform -chdir=03-backup/scaleway providers lock -platform=darwin_arm64 -platform=linux_amd64
terraform -chdir=04-dns/scaleway providers lock -platform=darwin_arm64 -platform=linux_amd64
"""
Loading