mirror of
https://gitlab.sarex.io/infra/terraform-contour-mirror.git
synced 2026-08-05 18:31:00 +03:00
224 lines
9.9 KiB
YAML
224 lines
9.9 KiB
YAML
name: Terraform Terragrunt (contour)
|
|
|
|
# One workflow for ALL closed contours. Per-contour differentiation is done via
|
|
# repository variables/secrets in each contour's Gitea — this is the downstream
|
|
# runner contract:
|
|
# vars: INFRA_ENV, RUNNER_LABEL, RUNNER_IMAGE, RABBITMQ_ENDPOINT, PG_ADMIN_HOST,
|
|
# KAFKA_BOOTSTRAP, SKIP_POSTGRES_ADMIN, SKIP_KAFKA_ADMIN, SKIP_MINIO_ADMIN
|
|
# secrets: TF_STATE_S3_ENDPOINT, TF_STATE_S3_BUCKET, S3_ACCESS_KEY, S3_SECRET_KEY,
|
|
# VAULT_ADDR, VAULT_TOKEN, SOPS_AGE_KEY_CONTOUR, KUBECONFIG_B64 (external
|
|
# runner only), KUBE_CONTEXT (external runner only)
|
|
# Infra-service admin creds are NOT passed as secrets — they are read from Vault
|
|
# at run time (see the "Run ... stacks" step) so the single source of truth stays
|
|
# in the contour Vault.
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
pull_request:
|
|
branches: [contour]
|
|
paths:
|
|
- "live/**"
|
|
- "modules/**"
|
|
- "infrastructure.yaml"
|
|
- "infrastructure-secrets.yaml"
|
|
- "scripts/**"
|
|
- ".gitea/workflows/**"
|
|
push:
|
|
branches: [contour]
|
|
paths:
|
|
- "live/**"
|
|
- "modules/**"
|
|
- "infrastructure.yaml"
|
|
- "infrastructure-secrets.yaml"
|
|
- "scripts/**"
|
|
- ".gitea/workflows/**"
|
|
|
|
env:
|
|
TF_STATE_S3_REGION: ru-central1
|
|
INFRA_ENV: ${{ vars.INFRA_ENV }}
|
|
SKIP_POSTGRES_ADMIN: ${{ vars.SKIP_POSTGRES_ADMIN }}
|
|
SKIP_KAFKA_ADMIN: ${{ vars.SKIP_KAFKA_ADMIN }}
|
|
SKIP_MINIO_ADMIN: ${{ vars.SKIP_MINIO_ADMIN }}
|
|
PG_ADMIN_HOST: ${{ vars.PG_ADMIN_HOST }}
|
|
KAFKA_BOOTSTRAP: ${{ vars.KAFKA_BOOTSTRAP }}
|
|
RABBITMQ_ENDPOINT: ${{ vars.RABBITMQ_ENDPOINT }}
|
|
# Bootstrap escape hatch (see scripts/run_all_stacks.sh) - normally unset;
|
|
# set temporarily to a space-separated stack subset (e.g. "namespace
|
|
# rabbitmq vault-secrets") for one run when a stack's plan can't succeed
|
|
# until another stack has already been applied, then clear it back to "".
|
|
STACKS: ${{ vars.STACKS }}
|
|
|
|
jobs:
|
|
validate:
|
|
runs-on: ${{ vars.RUNNER_LABEL || 'incluster' }}
|
|
container:
|
|
image: ${{ vars.RUNNER_IMAGE || 'cr.yandex/crp3ccidau046kdj8g9q/terraform/terragrunt:v9.11' }}
|
|
env:
|
|
TF_STATE_S3_ENDPOINT: ${{ secrets.TF_STATE_S3_ENDPOINT }}
|
|
TF_STATE_S3_BUCKET: ${{ secrets.TF_STATE_S3_BUCKET }}
|
|
S3_ACCESS_KEY: ${{ secrets.S3_ACCESS_KEY }}
|
|
S3_SECRET_KEY: ${{ secrets.S3_SECRET_KEY }}
|
|
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
|
|
VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }}
|
|
KUBE_CONTEXT: ${{ secrets.KUBE_CONTEXT }}
|
|
KUBECONFIG_B64: ${{ secrets.KUBECONFIG_B64 }}
|
|
KUBECONFIG: /workspace/.kube/config
|
|
GIT_AUTH_TOKEN: ${{ github.token }}
|
|
steps:
|
|
- name: Checkout (without Node.js action)
|
|
run: |
|
|
if [ -f infrastructure.yaml ] && [ -d live ]; then
|
|
echo "Workspace already contains repository files, skip checkout."
|
|
exit 0
|
|
fi
|
|
|
|
TOKEN="${GIT_AUTH_TOKEN:-${GITHUB_TOKEN:-${GITEA_TOKEN:-}}}"
|
|
if [ -z "$TOKEN" ]; then
|
|
echo "No token found for git checkout (github.token/GITHUB_TOKEN/GITEA_TOKEN)."
|
|
exit 1
|
|
fi
|
|
|
|
REPO_URL="${GITHUB_SERVER_URL%/}/${GITHUB_REPOSITORY}.git"
|
|
git init .
|
|
git remote add origin "$REPO_URL" 2>/dev/null || git remote set-url origin "$REPO_URL"
|
|
git -c http.extraHeader="Authorization: token ${TOKEN}" fetch --depth=1 origin "${GITHUB_SHA}"
|
|
git checkout -f FETCH_HEAD
|
|
- name: Prepare kubeconfig
|
|
run: |
|
|
if [ -n "${KUBECONFIG_B64:-}" ]; then
|
|
mkdir -p /workspace/.kube
|
|
echo "$KUBECONFIG_B64" | base64 -d > /workspace/.kube/config
|
|
chmod 600 /workspace/.kube/config
|
|
else
|
|
echo "No KUBECONFIG_B64 — in-cluster runner: kubernetes/vault providers use the pod ServiceAccount kubeconfig or in-cluster config."
|
|
fi
|
|
- name: Decrypt secret values
|
|
# SOPS_AGE_KEY only reaches this step, not the whole job - the rest
|
|
# (checkout, kubeconfig, terragrunt run) never sees it.
|
|
env:
|
|
SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY_CONTOUR }}
|
|
run: |
|
|
if ! command -v sops >/dev/null 2>&1; then apk add --no-cache sops || (apk add --no-cache curl && curl -fsSL https://github.com/getsops/sops/releases/download/v3.9.0/sops-v3.9.0.linux.amd64 -o /usr/local/bin/sops && chmod +x /usr/local/bin/sops); fi
|
|
sops --decrypt infrastructure-secrets.yaml > /tmp/infra-secret-values.yaml
|
|
echo "INFRA_SECRET_VALUES_FILE=/tmp/infra-secret-values.yaml" >> "$GITHUB_ENV"
|
|
- name: Run validate for all stacks
|
|
run: |
|
|
. ./scripts/load_admin_creds.sh
|
|
./scripts/run_all_stacks.sh validate
|
|
rm -f /tmp/infra-secret-values.yaml
|
|
|
|
plan:
|
|
needs: [validate]
|
|
runs-on: ${{ vars.RUNNER_LABEL || 'incluster' }}
|
|
container:
|
|
image: ${{ vars.RUNNER_IMAGE || 'cr.yandex/crp3ccidau046kdj8g9q/terraform/terragrunt:v9.11' }}
|
|
env:
|
|
TF_STATE_S3_ENDPOINT: ${{ secrets.TF_STATE_S3_ENDPOINT }}
|
|
TF_STATE_S3_BUCKET: ${{ secrets.TF_STATE_S3_BUCKET }}
|
|
S3_ACCESS_KEY: ${{ secrets.S3_ACCESS_KEY }}
|
|
S3_SECRET_KEY: ${{ secrets.S3_SECRET_KEY }}
|
|
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
|
|
VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }}
|
|
KUBE_CONTEXT: ${{ secrets.KUBE_CONTEXT }}
|
|
KUBECONFIG_B64: ${{ secrets.KUBECONFIG_B64 }}
|
|
KUBECONFIG: /workspace/.kube/config
|
|
GIT_AUTH_TOKEN: ${{ github.token }}
|
|
steps:
|
|
- name: Checkout (without Node.js action)
|
|
run: |
|
|
if [ -f infrastructure.yaml ] && [ -d live ]; then
|
|
echo "Workspace already contains repository files, skip checkout."
|
|
exit 0
|
|
fi
|
|
|
|
TOKEN="${GIT_AUTH_TOKEN:-${GITHUB_TOKEN:-${GITEA_TOKEN:-}}}"
|
|
if [ -z "$TOKEN" ]; then
|
|
echo "No token found for git checkout (github.token/GITHUB_TOKEN/GITEA_TOKEN)."
|
|
exit 1
|
|
fi
|
|
|
|
REPO_URL="${GITHUB_SERVER_URL%/}/${GITHUB_REPOSITORY}.git"
|
|
git init .
|
|
git remote add origin "$REPO_URL" 2>/dev/null || git remote set-url origin "$REPO_URL"
|
|
git -c http.extraHeader="Authorization: token ${TOKEN}" fetch --depth=1 origin "${GITHUB_SHA}"
|
|
git checkout -f FETCH_HEAD
|
|
- name: Prepare kubeconfig
|
|
run: |
|
|
if [ -n "${KUBECONFIG_B64:-}" ]; then
|
|
mkdir -p /workspace/.kube
|
|
echo "$KUBECONFIG_B64" | base64 -d > /workspace/.kube/config
|
|
chmod 600 /workspace/.kube/config
|
|
fi
|
|
- name: Decrypt secret values
|
|
# SOPS_AGE_KEY only reaches this step, not the whole job - the rest
|
|
# (checkout, kubeconfig, terragrunt run) never sees it.
|
|
env:
|
|
SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY_CONTOUR }}
|
|
run: |
|
|
if ! command -v sops >/dev/null 2>&1; then apk add --no-cache sops || (apk add --no-cache curl && curl -fsSL https://github.com/getsops/sops/releases/download/v3.9.0/sops-v3.9.0.linux.amd64 -o /usr/local/bin/sops && chmod +x /usr/local/bin/sops); fi
|
|
sops --decrypt infrastructure-secrets.yaml > /tmp/infra-secret-values.yaml
|
|
echo "INFRA_SECRET_VALUES_FILE=/tmp/infra-secret-values.yaml" >> "$GITHUB_ENV"
|
|
- name: Run plan for all stacks
|
|
run: |
|
|
. ./scripts/load_admin_creds.sh
|
|
./scripts/run_all_stacks.sh plan
|
|
rm -f /tmp/infra-secret-values.yaml
|
|
|
|
apply:
|
|
needs: [plan]
|
|
if: github.event_name == 'push'
|
|
runs-on: ${{ vars.RUNNER_LABEL || 'incluster' }}
|
|
container:
|
|
image: ${{ vars.RUNNER_IMAGE || 'cr.yandex/crp3ccidau046kdj8g9q/terraform/terragrunt:v9.11' }}
|
|
env:
|
|
TF_STATE_S3_ENDPOINT: ${{ secrets.TF_STATE_S3_ENDPOINT }}
|
|
TF_STATE_S3_BUCKET: ${{ secrets.TF_STATE_S3_BUCKET }}
|
|
S3_ACCESS_KEY: ${{ secrets.S3_ACCESS_KEY }}
|
|
S3_SECRET_KEY: ${{ secrets.S3_SECRET_KEY }}
|
|
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
|
|
VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }}
|
|
KUBE_CONTEXT: ${{ secrets.KUBE_CONTEXT }}
|
|
KUBECONFIG_B64: ${{ secrets.KUBECONFIG_B64 }}
|
|
KUBECONFIG: /workspace/.kube/config
|
|
GIT_AUTH_TOKEN: ${{ github.token }}
|
|
steps:
|
|
- name: Checkout (without Node.js action)
|
|
run: |
|
|
if [ -f infrastructure.yaml ] && [ -d live ]; then
|
|
echo "Workspace already contains repository files, skip checkout."
|
|
exit 0
|
|
fi
|
|
|
|
TOKEN="${GIT_AUTH_TOKEN:-${GITHUB_TOKEN:-${GITEA_TOKEN:-}}}"
|
|
if [ -z "$TOKEN" ]; then
|
|
echo "No token found for git checkout (github.token/GITHUB_TOKEN/GITEA_TOKEN)."
|
|
exit 1
|
|
fi
|
|
|
|
REPO_URL="${GITHUB_SERVER_URL%/}/${GITHUB_REPOSITORY}.git"
|
|
git init .
|
|
git remote add origin "$REPO_URL" 2>/dev/null || git remote set-url origin "$REPO_URL"
|
|
git -c http.extraHeader="Authorization: token ${TOKEN}" fetch --depth=1 origin "${GITHUB_SHA}"
|
|
git checkout -f FETCH_HEAD
|
|
- name: Prepare kubeconfig
|
|
run: |
|
|
if [ -n "${KUBECONFIG_B64:-}" ]; then
|
|
mkdir -p /workspace/.kube
|
|
echo "$KUBECONFIG_B64" | base64 -d > /workspace/.kube/config
|
|
chmod 600 /workspace/.kube/config
|
|
fi
|
|
- name: Decrypt secret values
|
|
# SOPS_AGE_KEY only reaches this step, not the whole job - the rest
|
|
# (checkout, kubeconfig, terragrunt run) never sees it.
|
|
env:
|
|
SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY_CONTOUR }}
|
|
run: |
|
|
if ! command -v sops >/dev/null 2>&1; then apk add --no-cache sops || (apk add --no-cache curl && curl -fsSL https://github.com/getsops/sops/releases/download/v3.9.0/sops-v3.9.0.linux.amd64 -o /usr/local/bin/sops && chmod +x /usr/local/bin/sops); fi
|
|
sops --decrypt infrastructure-secrets.yaml > /tmp/infra-secret-values.yaml
|
|
echo "INFRA_SECRET_VALUES_FILE=/tmp/infra-secret-values.yaml" >> "$GITHUB_ENV"
|
|
- name: Run apply for all stacks
|
|
run: |
|
|
. ./scripts/load_admin_creds.sh
|
|
./scripts/run_all_stacks.sh apply
|
|
rm -f /tmp/infra-secret-values.yaml
|