From ae63a513234a3f124112a83d5dd8841b97d99404 Mon Sep 17 00:00:00 2001 From: gitlab-pusher Date: Fri, 17 Jul 2026 11:08:08 +0000 Subject: [PATCH] ++ add wf dispatch trigger --- .gitlab-ci.yml | 200 +++++++++++++++++++++++++++++++------------------ 1 file changed, 126 insertions(+), 74 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 820671e..5ccb2c1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,81 +1,133 @@ -stages: - - generate - - trigger - - deploy +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. - -generate-pipeline: - stage: generate - image: alpine:latest - before_script: - - apk add --no-cache bash findutils - script: - - echo "=== DEBUG INFO ===" - - echo "CI_PIPELINE_SOURCE=$CI_PIPELINE_SOURCE" - - echo "CI_COMMIT_BRANCH=$CI_COMMIT_BRANCH" - - echo "CI_MERGE_REQUEST_SOURCE_BRANCH_NAME=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" - - pwd && ls -la - - echo "=== Finding terragrunt files ===" - - find live -name "terragrunt.hcl" -not -path "*/.terragrunt-cache/*" | head -20 || echo "No files found" - - echo "=== Generating pipeline ===" - - chmod +x ./scripts/generate-pipeline.sh - - ./scripts/generate-pipeline.sh - - echo "=== Generated pipeline content ===" - - cat .gitlab-ci.generated.yml - artifacts: +on: + workflow_dispatch: + pull_request: + branches: [contour] paths: - - .gitlab-ci.generated.yml - expire_in: 1 hour - rules: - - if: '$CI_PIPELINE_SOURCE == "pipeline"' - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - - if: '$CI_COMMIT_BRANCH == "stage"' - - if: '$CI_COMMIT_BRANCH == "master"' - - if: '$CI_COMMIT_BRANCH =~ /^feature\/.*/' + - "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 }} -# Prod environment -trigger-downstream-prod: - stage: trigger - needs: - - generate-pipeline - trigger: - include: - - artifact: .gitlab-ci.generated.yml - job: generate-pipeline - strategy: depend - forward: - pipeline_variables: true - yaml_variables: true - variables: - TERRAFORM_IMAGE_NAME: cr.yandex/crp3ccidau046kdj8g9q/terraform/terragrunt:v9.11 - YC_SERVICE_ACCOUNT_KEY_FILE: ${YC_PROD_SERVICE_ACCOUNT_KEY_FILE} - YC_CLOUD_ID: ${YC_CLOUD_ID} - YC_STAGE_FOLDER_ID: ${YC_STAGE_FOLDER_ID} - YC_PROD_FOLDER_ID: ${YC_PROD_FOLDER_ID} - YC_PREPROD_FOLDER_ID: ${YC_PREPROD_FOLDER_ID} - S3_ACCESS_KEY: ${S3_PROD_ACCESS_KEY} - S3_SECRET_KEY: ${S3_PROD_SECRET_KEY} - S3_STATE_BUCKET: ${S3_PROD_STATE_BUCKET} - AWS_ACCESS_KEY_ID: ${S3_PROD_ACCESS_KEY} - AWS_SECRET_ACCESS_KEY: ${S3_PROD_SECRET_KEY} - TARGET_ENV: "prod" - rules: - - if: '$CI_PIPELINE_SOURCE == "pipeline"' - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - - if: '$CI_COMMIT_BRANCH == "master"' - - if: '$CI_COMMIT_BRANCH =~ /^feature\/.*/' +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 -mirror-contour: - stage: deploy - image: alpine:3.21 - variables: - GIT_DEPTH: "0" - before_script: - - apk add --no-cache git ca-certificates - script: - - git push --force "$CONTOUR_MIRROR_PUSH_URL" "$CI_COMMIT_SHA:refs/heads/contour" - rules: - - if: '$CI_COMMIT_BRANCH == "contour" && $CI_PIPELINE_SOURCE == "push"' \ No newline at end of file + 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