terraform-contour-mirror/scripts/generate-pipeline.sh

251 lines
7.3 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
set -e
OUTPUT_FILE=".gitlab-ci.generated.yml"
cat > "$OUTPUT_FILE" << 'HEADER'
workflow:
rules:
- when: always
variables:
AWS_EC2_METADATA_DISABLED: "true"
TF_CLI_ARGS: "-no-color"
TG_LOG_LEVEL: "error"
TG_DEPENDENCY_FETCH_OUTPUT_FROM_STATE: "true"
stages:
- validate
- plan
- apply
HEADER
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/||')
env=$(echo "$relative_path" | cut -d'/' -f1)
component=$(echo "$relative_path" | cut -d'/' -f2)
if [ -z "$component" ] || [ "$component" = "$env" ]; then
continue
fi
job_prefix="${env}-${component}"
full_component_dir="${component_dir}"
secrets_dependency_components=()
needs_section=""
# Для secrets: расшифровать sops-файл с live-значениями во временный файл вне артефактов
# и передать путь в terragrunt через INFRA_SECRET_VALUES_FILE (требуется SOPS_AGE_KEY в CI).
secrets_decrypt_before=""
if [ "$component" = "secrets" ]; then
secrets_decrypt_before=" - sops --decrypt infrastructure-secrets.yaml > /tmp/infra-secret-values.yaml
- export INFRA_SECRET_VALUES_FILE=/tmp/infra-secret-values.yaml"
fi
if [ "$component" = "secrets" ]; then
for dep_component in namespace s3 database rabbitmq kafka-topics; do
if [ -f "live/${env}/${dep_component}/terragrunt.hcl" ]; then
secrets_dependency_components+=("$dep_component")
fi
done
needs_section=" needs:"
dependencies_section=" dependencies:"
for dep_component in "${secrets_dependency_components[@]}"; do
needs_section="${needs_section}
- validate-${env}-${dep_component}"
dependencies_section="${dependencies_section}
- validate-${env}-${dep_component}"
done
needs_section="${needs_section}
${dependencies_section}"
fi
validate_before_script=" - cd \$TG_ROOT
- echo \"Working directory:\" && pwd
- ls -la"
if [ "$component" = "secrets" ]; then
validate_before_script="${secrets_decrypt_before}
${validate_before_script}"
fi
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
if [ "$env" = "prod" ]; then
runner_tags=" tags:
- prod"
branch_rules=" - if: '\$CI_PIPELINE_SOURCE == \"parent_pipeline\"'
- if: '\$CI_COMMIT_BRANCH == \"master\"'
- if: '\$CI_PIPELINE_SOURCE == \"pipeline\" && \$TARGET_ENV == \"prod\"'"
else
runner_tags=""
branch_rules=" - if: '\$CI_PIPELINE_SOURCE == \"parent_pipeline\"'
- if: '\$CI_PIPELINE_SOURCE == \"pipeline\"'
- if: '\$CI_PIPELINE_SOURCE == \"merge_request_event\"'
- if: '\$CI_COMMIT_BRANCH == \"stage\"'
- if: '\$CI_COMMIT_BRANCH =~ /^feature\\/.*/'
- if: '\$CI_PIPELINE_SOURCE == \"pipeline\" && \$TARGET_ENV == \"stage\"'"
fi
if [ "$component" = "kafka-topics" ]; then
validate_before_script=" - cd \$TG_ROOT
- echo \"Working directory:\" && pwd
- ls -la"
fi
cat >> "$OUTPUT_FILE" << VALIDATE_JOB
validate-${job_prefix}:
stage: validate
image: \$TERRAFORM_IMAGE_NAME
${runner_tags}
variables:
TG_ROOT: "${full_component_dir}"
ENVIRONMENT: "${env}"
YC_FOLDER_ID: "\$${folder_var}"
TG_SKIP_DEPENDENCY_OUTPUTS: "true"
before_script:
${validate_before_script}
script:
- terragrunt init -upgrade -reconfigure
- terragrunt validate
rules:
${branch_rules}
interruptible: true
artifacts:
paths:
- ${full_component_dir}/.terragrunt-cache/
expire_in: 1 hour
when: always
${needs_section}
VALIDATE_JOB
plan_needs="validate-${job_prefix}"
plan_before_script=" - cd \$TG_ROOT && ls -la"
if [ "$component" = "secrets" ]; then
for dep_component in "${secrets_dependency_components[@]}"; do
plan_needs="${plan_needs}
- plan-${env}-${dep_component}"
done
dependency_init_chain=""
for dep_component in "${secrets_dependency_components[@]}"; do
if [ -z "$dependency_init_chain" ]; then
dependency_init_chain="cd live/${env}/${dep_component} && terragrunt init -upgrade -reconfigure"
else
dependency_init_chain="${dependency_init_chain} && cd ../${dep_component} && terragrunt init -upgrade -reconfigure"
fi
done
plan_before_script="${secrets_decrypt_before}
- ${dependency_init_chain} && cd ../secrets && ls -la"
fi
if [ "$component" = "kafka-topics" ]; then
plan_before_script=" - cd \$TG_ROOT && ls -la"
fi
plan_allow_failure=""
if [ "$env" = "stage" ] && [ "$component" = "secrets" ]; then
plan_allow_failure=" allow_failure: true"
fi
cat >> "$OUTPUT_FILE" << PLAN_JOB
plan-${job_prefix}:
stage: plan
image: \$TERRAFORM_IMAGE_NAME
${runner_tags}
${plan_allow_failure}
variables:
TG_ROOT: "${full_component_dir}"
ENVIRONMENT: "${env}"
YC_FOLDER_ID: "\$${folder_var}"
needs:
- ${plan_needs}
before_script:
${plan_before_script}
script:
- terragrunt init -upgrade -reconfigure
- terragrunt plan -out=tfplan
rules:
${branch_rules}
interruptible: true
artifacts:
paths:
- ${full_component_dir}/tfplan
- ${full_component_dir}/.terragrunt-cache/
expire_in: 1 week
when: always
PLAN_JOB
when_clause="manual"
apply_needs="plan-${job_prefix}"
apply_before_script=" - cd \$TG_ROOT && ls -la"
if [ "$component" = "secrets" ]; then
for dep_component in "${secrets_dependency_components[@]}"; do
apply_needs="${apply_needs}
- apply-${env}-${dep_component}"
done
dependency_init_chain=""
for dep_component in "${secrets_dependency_components[@]}"; do
if [ -z "$dependency_init_chain" ]; then
dependency_init_chain="cd live/${env}/${dep_component} && terragrunt init -upgrade -reconfigure"
else
dependency_init_chain="${dependency_init_chain} && cd ../${dep_component} && terragrunt init -upgrade -reconfigure"
fi
done
apply_before_script="${secrets_decrypt_before}
- ${dependency_init_chain} && cd ../secrets && ls -la"
fi
if [ "$component" = "kafka-topics" ]; then
apply_before_script=" - cd \$TG_ROOT && ls -la"
fi
if [ "$env" = "prod" ]; then
apply_rules=" - if: '\$CI_COMMIT_BRANCH == \"master\"'
when: ${when_clause}
- if: '\$CI_PIPELINE_SOURCE == \"pipeline\" && \$TARGET_ENV == \"prod\"'
when: ${when_clause}"
else
apply_rules=" - if: '\$CI_COMMIT_BRANCH == \"stage\"'
when: ${when_clause}
- if: '\$CI_PIPELINE_SOURCE == \"pipeline\" && \$TARGET_ENV == \"stage\"'
when: ${when_clause}"
fi
cat >> "$OUTPUT_FILE" << APPLY_JOB
apply-${job_prefix}:
stage: apply
image: \$TERRAFORM_IMAGE_NAME
${runner_tags}
variables:
TG_ROOT: "${full_component_dir}"
ENVIRONMENT: "${env}"
YC_FOLDER_ID: "\$${folder_var}"
needs:
- ${apply_needs}
before_script:
${apply_before_script}
script:
- terragrunt init -upgrade -reconfigure
- terragrunt apply -auto-approve
rules:
${apply_rules}
interruptible: true
APPLY_JOB
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||' | grep '/' | sort