#!/bin/bash set -e # Скрипт для динамической генерации GitLab CI пайплайна # Сканирует структуру live/ и создает джобы для каждого компонента OUTPUT_FILE=".gitlab-ci.generated.yml" # Функция для экранирования YAML yaml_escape() { echo "$1" | sed 's/"/\\"/g' } # Начало файла cat > "$OUTPUT_FILE" << 'EOF' # Автоматически сгенерированный файл GitLab CI # НЕ РЕДАКТИРУЙТЕ ВРУЧНУЮ! Этот файл генерируется скриптом scripts/generate-pipeline.sh stages: - validate - plan - apply EOF # Поиск всех terragrunt.hcl файлов в live/ find live -name "terragrunt.hcl" -not -path "*/.terragrunt-cache/*" | sort | while read -r config_file; do # Извлечение пути компонента component_dir=$(dirname "$config_file") relative_path=$(echo "$component_dir" | sed 's|^live/||') # Парсинг окружения и компонента из пути # Формат: live/{env}/{component}/terragrunt.hcl env=$(echo "$relative_path" | cut -d'/' -f1) component=$(echo "$relative_path" | cut -d'/' -f2) # Пропускаем если это не компонент (например, env.hcl) if [ -z "$component" ] || [ "$component" = "$env" ]; then continue fi # Формирование имени джобы job_prefix="${env}-${component}" # Определение переменных окружения для Yandex Cloud case "$env" in stage) folder_var="YC_STAGE_FOLDER_ID" ;; prod) folder_var="YC_PROD_FOLDER_ID" ;; preprod) folder_var="YC_PREPROD_FOLDER_ID" ;; *) folder_var="YC_FOLDER_ID" ;; esac # Джоба validate cat >> "$OUTPUT_FILE" << EOF validate-${job_prefix}: stage: validate variables: TG_ROOT: "${component_dir}" ENVIRONMENT: "${env}" YC_FOLDER_ID: "\${${folder_var}}" before_script: - apk add --no-cache curl unzip - | if [ ! -f /usr/local/bin/terragrunt ]; then TERRAFORM_VERSION=1.6.0 TERRAGRUNT_VERSION=0.50.0 curl -fsSL https://releases.hashicorp.com/terraform/\${TERRAFORM_VERSION}/terraform_\${TERRAFORM_VERSION}_linux_amd64.zip -o terraform.zip unzip terraform.zip -d /usr/local/bin/ chmod +x /usr/local/bin/terraform curl -fsSL https://github.com/gruntwork-io/terragrunt/releases/download/v\${TERRAGRUNT_VERSION}/terragrunt_linux_amd64 -o /usr/local/bin/terragrunt chmod +x /usr/local/bin/terragrunt rm -f terraform.zip fi - cd \${TG_ROOT} script: - terragrunt init -reconfigure -input=false --terragrunt-non-interactive - terragrunt validate-inputs --terragrunt-non-interactive - terragrunt validate --terragrunt-non-interactive rules: - if: '\$CI_PIPELINE_SOURCE == "merge_request_event"' - if: '\$CI_COMMIT_BRANCH == "master" || \$CI_COMMIT_BRANCH == "main"' tags: - yc interruptible: true EOF # Джоба plan cat >> "$OUTPUT_FILE" << EOF plan-${job_prefix}: stage: plan variables: TG_ROOT: "${component_dir}" ENVIRONMENT: "${env}" YC_FOLDER_ID: "\${${folder_var}}" before_script: - apk add --no-cache curl unzip - | if [ ! -f /usr/local/bin/terragrunt ]; then TERRAFORM_VERSION=1.6.0 TERRAGRUNT_VERSION=0.50.0 curl -fsSL https://releases.hashicorp.com/terraform/\${TERRAFORM_VERSION}/terraform_\${TERRAFORM_VERSION}_linux_amd64.zip -o terraform.zip unzip terraform.zip -d /usr/local/bin/ chmod +x /usr/local/bin/terraform curl -fsSL https://github.com/gruntwork-io/terragrunt/releases/download/v\${TERRAGRUNT_VERSION}/terragrunt_linux_amd64 -o /usr/local/bin/terragrunt chmod +x /usr/local/bin/terragrunt rm -f terraform.zip fi - cd \${TG_ROOT} script: - terragrunt init -reconfigure -input=false --terragrunt-non-interactive - terragrunt plan -input=false --terragrunt-non-interactive -out=tfplan rules: - if: '\$CI_COMMIT_BRANCH == "master" || \$CI_COMMIT_BRANCH == "main"' - if: '\$CI_PIPELINE_SOURCE == "merge_request_event"' tags: - yc interruptible: true artifacts: paths: - "\${TG_ROOT}/tfplan" - "\${TG_ROOT}/.terragrunt-cache/**/*" expire_in: 1 week when: always EOF # Джоба apply (manual для prod, автоматическая для остальных) if [ "$env" = "prod" ]; then when_clause="manual" else when_clause="on_success" fi cat >> "$OUTPUT_FILE" << EOF apply-${job_prefix}: stage: apply variables: TG_ROOT: "${component_dir}" ENVIRONMENT: "${env}" YC_FOLDER_ID: "\${${folder_var}}" before_script: - apk add --no-cache curl unzip - | if [ ! -f /usr/local/bin/terragrunt ]; then TERRAFORM_VERSION=1.6.0 TERRAGRUNT_VERSION=0.50.0 curl -fsSL https://releases.hashicorp.com/terraform/\${TERRAFORM_VERSION}/terraform_\${TERRAFORM_VERSION}_linux_amd64.zip -o terraform.zip unzip terraform.zip -d /usr/local/bin/ chmod +x /usr/local/bin/terraform curl -fsSL https://github.com/gruntwork-io/terragrunt/releases/download/v\${TERRAGRUNT_VERSION}/terragrunt_linux_amd64 -o /usr/local/bin/terragrunt chmod +x /usr/local/bin/terragrunt rm -f terraform.zip fi - cd \${TG_ROOT} script: - terragrunt init -reconfigure -input=false --terragrunt-non-interactive - terragrunt apply -input=false --terragrunt-non-interactive tfplan rules: - if: '\$CI_COMMIT_BRANCH == "master" || \$CI_COMMIT_BRANCH == "main"' when: ${when_clause} tags: - yc interruptible: true dependencies: - plan-${job_prefix} EOF done echo "Pipeline generated successfully: $OUTPUT_FILE" echo "Found components:" find live -name "terragrunt.hcl" -not -path "*/.terragrunt-cache/*" | sed 's|live/||; s|/terragrunt.hcl||' | sort