mirror of
https://gitlab.sarex.io/infra/terraform-contour-mirror.git
synced 2026-08-05 18:31:00 +03:00
++ contour: gitea workflow (runner contract via CI vars INFRA_ENV/RUNNER_LABEL/RUNNER_IMAGE) + load_admin_creds.sh (infra admin creds from Vault) + run_all_stacks.sh
This commit is contained in:
parent
b8b77536c3
commit
83291cee1e
132
.gitea/workflows/terraform.yml
Normal file
132
.gitea/workflows/terraform.yml
Normal file
@ -0,0 +1,132 @@
|
||||
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
|
||||
# secrets: TF_STATE_S3_ENDPOINT, TF_STATE_S3_BUCKET, S3_ACCESS_KEY, S3_SECRET_KEY,
|
||||
# VAULT_ADDR, VAULT_TOKEN, SOPS_AGE_KEY, 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:
|
||||
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 }}
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: ${{ vars.RUNNER_LABEL || 'ubuntu-latest' }}
|
||||
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 }}
|
||||
SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }}
|
||||
KUBE_CONTEXT: ${{ secrets.KUBE_CONTEXT }}
|
||||
KUBECONFIG_B64: ${{ secrets.KUBECONFIG_B64 }}
|
||||
KUBECONFIG: /workspace/.kube/config
|
||||
GIT_AUTH_TOKEN: ${{ github.token }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- 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: Run validate for all stacks
|
||||
run: |
|
||||
. ./scripts/load_admin_creds.sh
|
||||
./scripts/run_all_stacks.sh validate
|
||||
|
||||
plan:
|
||||
needs: [validate]
|
||||
runs-on: ${{ vars.RUNNER_LABEL || 'ubuntu-latest' }}
|
||||
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 }}
|
||||
SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }}
|
||||
KUBE_CONTEXT: ${{ secrets.KUBE_CONTEXT }}
|
||||
KUBECONFIG_B64: ${{ secrets.KUBECONFIG_B64 }}
|
||||
KUBECONFIG: /workspace/.kube/config
|
||||
GIT_AUTH_TOKEN: ${{ github.token }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- 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: Run plan for all stacks
|
||||
run: |
|
||||
. ./scripts/load_admin_creds.sh
|
||||
./scripts/run_all_stacks.sh plan
|
||||
|
||||
apply:
|
||||
needs: [plan]
|
||||
if: github.event_name == 'push'
|
||||
runs-on: ${{ vars.RUNNER_LABEL || 'ubuntu-latest' }}
|
||||
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 }}
|
||||
SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }}
|
||||
KUBE_CONTEXT: ${{ secrets.KUBE_CONTEXT }}
|
||||
KUBECONFIG_B64: ${{ secrets.KUBECONFIG_B64 }}
|
||||
KUBECONFIG: /workspace/.kube/config
|
||||
GIT_AUTH_TOKEN: ${{ github.token }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- 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: Run apply for all stacks
|
||||
run: |
|
||||
. ./scripts/load_admin_creds.sh
|
||||
./scripts/run_all_stacks.sh apply
|
||||
40
scripts/load_admin_creds.sh
Executable file
40
scripts/load_admin_creds.sh
Executable file
@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env sh
|
||||
# Read in-cluster infra-service ADMIN creds from the contour Vault and export them
|
||||
# for the providers generated in live/terragrunt.hcl. Sourced (not executed) by the
|
||||
# CI run steps so the exported vars live in the same shell as terragrunt.
|
||||
#
|
||||
# Paths are the platform bootstrap layout (same as the bootstrap cronjobs read):
|
||||
# secrets/postgresql/admin postgres-password
|
||||
# secrets/kafka/bootstrap interBrokerPassword
|
||||
# secrets/minio/admin rootUser / rootPassword
|
||||
# secrets/rabbitmq/auth username / password
|
||||
set -eu
|
||||
: "${VAULT_ADDR:?VAULT_ADDR is required}"
|
||||
: "${VAULT_TOKEN:?VAULT_TOKEN is required}"
|
||||
|
||||
_kv() {
|
||||
curl -sf -H "X-Vault-Token: ${VAULT_TOKEN}" "${VAULT_ADDR}/v1/secrets/data/$1" \
|
||||
| jq -r --arg k "$2" '.data.data[$k] // ""'
|
||||
}
|
||||
|
||||
# Service endpoints default to the in-cluster svc DNS (consistent across contours);
|
||||
# override via CI vars if a contour differs.
|
||||
export PG_ADMIN_HOST="${PG_ADMIN_HOST:-postgresql.postgresql.svc.cluster.local}"
|
||||
export PG_ADMIN_PORT="${PG_ADMIN_PORT:-5432}"
|
||||
export PG_ADMIN_USER="${PG_ADMIN_USER:-postgres}"
|
||||
export PG_ADMIN_PASSWORD="$(_kv postgresql/admin postgres-password)"
|
||||
|
||||
export KAFKA_BOOTSTRAP="${KAFKA_BOOTSTRAP:-kafka-kafka-contour.kafka.svc.cluster.local:9092}"
|
||||
export KAFKA_ADMIN_USER="${KAFKA_ADMIN_USER:-inter_broker_user}"
|
||||
export KAFKA_ADMIN_PASSWORD="$(_kv kafka/bootstrap interBrokerPassword)"
|
||||
export KAFKA_SASL_MECHANISM="${KAFKA_SASL_MECHANISM:-plain}"
|
||||
|
||||
export MINIO_ENDPOINT="${MINIO_ENDPOINT:-minio.minio.svc.cluster.local:9000}"
|
||||
export MINIO_ADMIN_USER="$(_kv minio/admin rootUser)"
|
||||
export MINIO_ADMIN_PASSWORD="$(_kv minio/admin rootPassword)"
|
||||
|
||||
export RABBITMQ_ENDPOINT="${RABBITMQ_ENDPOINT:-http://rabbitmq.rabbitmq.svc.cluster.local:15672}"
|
||||
export RABBITMQ_ADMIN_USER="$(_kv rabbitmq/auth username)"
|
||||
export RABBITMQ_ADMIN_PASSWORD="$(_kv rabbitmq/auth password)"
|
||||
|
||||
echo "infra admin creds loaded from Vault (${VAULT_ADDR})"
|
||||
45
scripts/run_all_stacks.sh
Executable file
45
scripts/run_all_stacks.sh
Executable file
@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ACTION="${1:-}"
|
||||
if [[ -z "$ACTION" ]]; then
|
||||
echo "Usage: $0 <validate|plan|apply>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
STACK_FILES=()
|
||||
while IFS= read -r tg; do
|
||||
STACK_FILES+=("$tg")
|
||||
done < <(find live -name 'terragrunt.hcl' -not -path '*/.terragrunt-cache/*' | sort)
|
||||
|
||||
if [[ ${#STACK_FILES[@]} -eq 0 ]]; then
|
||||
echo "No terragrunt stacks found under live/"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for tg in "${STACK_FILES[@]}"; do
|
||||
stack_dir="$(dirname "$tg")"
|
||||
# Skip only root-level Terragrunt configuration file (live/terragrunt.hcl).
|
||||
# Execute concrete stacks like live/<component> and live/<group>/<component>.
|
||||
if [[ "$stack_dir" == "live" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "=== STACK: ${stack_dir} ==="
|
||||
|
||||
(
|
||||
cd "$stack_dir"
|
||||
terragrunt init -reconfigure
|
||||
|
||||
if [[ "$ACTION" == "validate" ]]; then
|
||||
terragrunt validate
|
||||
elif [[ "$ACTION" == "plan" ]]; then
|
||||
terragrunt plan -out=tfplan
|
||||
elif [[ "$ACTION" == "apply" ]]; then
|
||||
terragrunt apply -auto-approve
|
||||
else
|
||||
echo "Unknown action: $ACTION"
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
done
|
||||
Loading…
Reference in New Issue
Block a user