Merge forgejo/master into wizard/errorpages-buffer
This commit is contained in:
commit
f3cb5661a6
2 changed files with 95 additions and 30 deletions
89
stacks/kyverno/modules/kyverno/ghcr-credentials.tf
Normal file
89
stacks/kyverno/modules/kyverno/ghcr-credentials.tf
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
# =============================================================================
|
||||||
|
# ghcr.io pull credentials — synced ONLY to namespaces running PRIVATE ghcr
|
||||||
|
# images (ADR-0002 off-infra builds)
|
||||||
|
# =============================================================================
|
||||||
|
# The credential is Viktor's admin PAT (Vault secret/viktor/ghcr_pull_token —
|
||||||
|
# an alias of github_pat: GitHub has no API to mint tokens, so a UI-minted
|
||||||
|
# read:packages token can replace the alias value later with no TF change).
|
||||||
|
# Because the PAT is broad, this is a positive allowlist, NOT cluster-wide
|
||||||
|
# like registry-credentials: any workload in a listed namespace can read the
|
||||||
|
# secret, so every entry widens the blast radius. Public-image namespaces
|
||||||
|
# need no credentials — keep this list to private-image consumers only.
|
||||||
|
|
||||||
|
locals {
|
||||||
|
ghcr_private_namespaces = [
|
||||||
|
"tripit",
|
||||||
|
"f1-stream",
|
||||||
|
"job-hunter",
|
||||||
|
"instagram-poster",
|
||||||
|
"payslip-ingest",
|
||||||
|
"wealthfolio",
|
||||||
|
"fire-planner",
|
||||||
|
"recruiter-responder",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "kubernetes_secret" "ghcr_credentials" {
|
||||||
|
metadata {
|
||||||
|
name = "ghcr-credentials"
|
||||||
|
namespace = kubernetes_namespace.kyverno.metadata[0].name
|
||||||
|
}
|
||||||
|
type = "kubernetes.io/dockerconfigjson"
|
||||||
|
data = {
|
||||||
|
".dockerconfigjson" = jsonencode({
|
||||||
|
auths = {
|
||||||
|
"ghcr.io" = {
|
||||||
|
username = "ViktorBarzin"
|
||||||
|
password = try(data.vault_kv_secret_v2.viktor.data["ghcr_pull_token"], "")
|
||||||
|
auth = base64encode("ViktorBarzin:${try(data.vault_kv_secret_v2.viktor.data["ghcr_pull_token"], "")}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "kubectl_manifest" "sync_ghcr_credentials" {
|
||||||
|
yaml_body = yamlencode({
|
||||||
|
apiVersion = "kyverno.io/v1"
|
||||||
|
kind = "ClusterPolicy"
|
||||||
|
metadata = {
|
||||||
|
name = "sync-ghcr-credentials"
|
||||||
|
}
|
||||||
|
spec = {
|
||||||
|
rules = [
|
||||||
|
{
|
||||||
|
name = "sync-ghcr-secret"
|
||||||
|
match = {
|
||||||
|
any = [
|
||||||
|
{
|
||||||
|
resources = {
|
||||||
|
kinds = ["Namespace"]
|
||||||
|
names = local.ghcr_private_namespaces
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
generate = {
|
||||||
|
generateExisting = true
|
||||||
|
apiVersion = "v1"
|
||||||
|
kind = "Secret"
|
||||||
|
name = "ghcr-credentials"
|
||||||
|
namespace = "{{request.object.metadata.name}}"
|
||||||
|
synchronize = true
|
||||||
|
clone = {
|
||||||
|
namespace = "kyverno"
|
||||||
|
name = "ghcr-credentials"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
depends_on = [
|
||||||
|
helm_release.kyverno,
|
||||||
|
kubernetes_secret.ghcr_credentials,
|
||||||
|
kubernetes_cluster_role_binding.kyverno_admission_secret_manager,
|
||||||
|
kubernetes_cluster_role_binding.kyverno_background_secret_manager,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -142,34 +142,10 @@ resource "kubernetes_namespace" "tripit" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# GHCR pull secret (tripit ns only) for the private ghcr.io/viktorbarzin/tripit image
|
# GHCR pull secret: the ghcr-credentials Secret in this namespace is cloned in
|
||||||
# now built off-infra by GitHub Actions. Uses viktor's github_pat as the pull
|
# by the kyverno stack's sync-ghcr-credentials ClusterPolicy (allowlisted
|
||||||
# credential — admin-scoped, accepted as an interim (rotate to a fine-grained
|
# private-ghcr namespaces only — ADR-0002). Source of truth:
|
||||||
# read:packages token later). Scoped to this namespace to limit the broad token's
|
# stacks/kyverno/modules/kyverno/ghcr-credentials.tf.
|
||||||
# blast radius (deliberately NOT folded into the cluster-wide registry-credentials).
|
|
||||||
data "vault_kv_secret_v2" "viktor" {
|
|
||||||
mount = "secret"
|
|
||||||
name = "viktor"
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "kubernetes_secret" "ghcr_credentials" {
|
|
||||||
metadata {
|
|
||||||
name = "ghcr-credentials"
|
|
||||||
namespace = kubernetes_namespace.tripit.metadata[0].name
|
|
||||||
}
|
|
||||||
type = "kubernetes.io/dockerconfigjson"
|
|
||||||
data = {
|
|
||||||
".dockerconfigjson" = jsonencode({
|
|
||||||
auths = {
|
|
||||||
"ghcr.io" = {
|
|
||||||
username = "ViktorBarzin"
|
|
||||||
password = data.vault_kv_secret_v2.viktor.data["github_pat"]
|
|
||||||
auth = base64encode("ViktorBarzin:${data.vault_kv_secret_v2.viktor.data["github_pat"]}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# App secrets — seed these in Vault before applying:
|
# App secrets — seed these in Vault before applying:
|
||||||
# secret/tripit
|
# secret/tripit
|
||||||
|
|
@ -370,7 +346,7 @@ resource "kubernetes_deployment" "tripit" {
|
||||||
name = "registry-credentials"
|
name = "registry-credentials"
|
||||||
}
|
}
|
||||||
image_pull_secrets {
|
image_pull_secrets {
|
||||||
name = kubernetes_secret.ghcr_credentials.metadata[0].name
|
name = "ghcr-credentials"
|
||||||
}
|
}
|
||||||
|
|
||||||
init_container {
|
init_container {
|
||||||
|
|
@ -650,7 +626,7 @@ resource "kubernetes_cron_job_v1" "tripit_worker" {
|
||||||
name = "registry-credentials"
|
name = "registry-credentials"
|
||||||
}
|
}
|
||||||
image_pull_secrets {
|
image_pull_secrets {
|
||||||
name = kubernetes_secret.ghcr_credentials.metadata[0].name
|
name = "ghcr-credentials"
|
||||||
}
|
}
|
||||||
container {
|
container {
|
||||||
name = "worker"
|
name = "worker"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue