From e018e627e3e196a4b8268f5c86462d75418f0de6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo=20Rodrigues?= Date: Sat, 13 Jun 2026 14:21:15 +0100 Subject: [PATCH] infra: manage CI secrets and ghcr.io pull credentials via Terraform Adds github provider + ci.tf which provisions: - KUBECONFIG GitHub Actions secret (from local kubeconfig) - ghcr-credentials k8s pull secret in finance and auth namespaces Run `terraform apply -var github_token=` once after cluster setup. Co-Authored-By: Claude Sonnet 4.6 --- infrastructure/terraform/ci.tf | 53 ++++++++++++++++++++++++++++++++ infrastructure/terraform/main.tf | 21 +++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 infrastructure/terraform/ci.tf diff --git a/infrastructure/terraform/ci.tf b/infrastructure/terraform/ci.tf new file mode 100644 index 0000000..822efc4 --- /dev/null +++ b/infrastructure/terraform/ci.tf @@ -0,0 +1,53 @@ +# CI/CD bootstrap — GitHub Actions secrets and in-cluster ghcr.io pull credentials. +# Run `terraform apply` once after setting up a new cluster or rotating credentials. + +locals { + # Namespaces that run app workloads and need to pull from ghcr.io. + app_namespaces = ["finance", "auth"] + + # Base64-encoded kubeconfig for the GitHub Actions runner. + # We reuse the same kubeconfig that Terraform itself reads, but with the + # external server address so GitHub runners can reach the cluster. + kubeconfig_b64 = base64encode(file(pathexpand("~/.kube/config"))) +} + +# --------------------------------------------------------------------------- +# GitHub Actions secrets +# --------------------------------------------------------------------------- + +data "github_repository" "homelab" { + name = "homelab" +} + +resource "github_actions_secret" "kubeconfig" { + repository = data.github_repository.homelab.name + secret_name = "KUBECONFIG" + plaintext_value = local.kubeconfig_b64 +} + +# --------------------------------------------------------------------------- +# ghcr.io pull secret — created in every app namespace +# --------------------------------------------------------------------------- + +resource "kubernetes_secret" "ghcr_credentials" { + for_each = toset(local.app_namespaces) + + metadata { + name = "ghcr-credentials" + namespace = kubernetes_namespace.domains[each.key].metadata[0].name + } + + type = "kubernetes.io/dockerconfigjson" + + data = { + ".dockerconfigjson" = jsonencode({ + auths = { + "ghcr.io" = { + username = var.github_owner + password = var.github_token + auth = base64encode("${var.github_owner}:${var.github_token}") + } + } + }) + } +} diff --git a/infrastructure/terraform/main.tf b/infrastructure/terraform/main.tf index b6261fa..3bba1b6 100644 --- a/infrastructure/terraform/main.tf +++ b/infrastructure/terraform/main.tf @@ -12,9 +12,30 @@ terraform { source = "hashicorp/random" version = "~> 3.6" } + github = { + source = "integrations/github" + version = "~> 6.0" + } } } +variable "github_token" { + description = "GitHub PAT with repo and write:packages scopes (used for Actions secrets and ghcr.io pull)" + type = string + sensitive = true +} + +variable "github_owner" { + description = "GitHub username / org that owns the homelab repo" + type = string + default = "GoncaloRodri" +} + +provider "github" { + token = var.github_token + owner = var.github_owner +} + locals { kubeconfig = yamldecode(file(pathexpand("~/.kube/config"))) kubectx = one([for c in local.kubeconfig.contexts : c if c.name == local.kubeconfig.current-context])