Commit c5e7f19c authored by Clement Bois's avatar Clement Bois
Browse files

Merge branch 'feat/check-json-plan' into 'master'

feat: rebuild plan and compare with report

See merge request to-be-continuous/terraform!153
parents 3f79cd0e 9af6440f
Loading
Loading
Loading
Loading
+20 −7
Original line number Diff line number Diff line
@@ -877,7 +877,7 @@ stages:
    opts=${ENV_PLAN_OPTS:-$TF_PLAN_OPTS}
    extra_opts=${ENV_EXTRA_OPTS:-$TF_EXTRA_OPTS}
    tf_plan=${ENV_TYPE}.tfplan
    gitlab_report=${ENV_TYPE}-plan.json
    tfplan_report=${ENV_TYPE}-plan.json

    # shellcheck disable=SC2154
    log_info "--- \\e[32mplan\\e[0m"
@@ -894,23 +894,24 @@ stages:
    # shellcheck disable=SC2154,SC2086,SC2046
    terraform plan ${env_vars:+-var-file=${env_vars}} ${TF_PLAN_LOCK:+-lock=$TF_PLAN_LOCK} -out "$tf_plan" $(echo "$extra_opts" | envsubst_cli) $(echo "$opts" | envsubst_cli)

    # then generate GitLab TF report
    # then generate GitLab TF report json
    if ! command -v jq > /dev/null
    then
      log_info "--- installing jq (required to generate GitLab report)..."
      log_info "--- installing jq (required to generate json report)..."
      # shellcheck disable=SC2086
      apk add --no-cache ${TF_APK_EXTRA_OPTS:-$TBC_APK_EXTRA_OPTS} jq
    fi
    log_info "--- now generating GitLab report..."
    log_info "--- now generating json report..."
    # impl inspired by GitLab Terraform template
    # see https://gitlab.com/gitlab-org/gitlab-foss/-/blob/master/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml
    terraform show --json "$tf_plan" | jq -r '([.resource_changes[]?.change.actions?]|flatten)|{"create":(map(select(.=="create"))|length),"update":(map(select(.=="update"))|length),"delete":(map(select(.=="delete"))|length)}' > "$gitlab_report"
    terraform show --json "$tf_plan" | jq -r '([.resource_changes[]?.change.actions?]|flatten)|{"create":(map(select(.=="create"))|length),"update":(map(select(.=="update"))|length),"delete":(map(select(.=="delete"))|length)}' > "$tfplan_report"
  }

  # $tf_plan is declared in .tf-create script (optional)
  function tf_apply() {
    opts=${ENV_APPLY_OPTS:-$TF_APPLY_OPTS}
    extra_opts=${ENV_EXTRA_OPTS:-$TF_EXTRA_OPTS}
    tfplan_report=${ENV_TYPE}-plan.json

    # shellcheck disable=SC2154
    log_info "--- \\e[32mapply\\e[0m"
@@ -927,9 +928,21 @@ stages:
      log_info "--- \\e[32mpre-apply\\e[0m hook (\\e[33;1m${prescript}\\e[0m) not found: skip"
    fi

    if [[ "$tf_plan" ]]; then
    if [[ -f "$tf_plan" ]]; then
      log_info "--- applying upstream plan: \\e[33;1m${tf_plan}\\e[0m"
      terraform apply "$tf_plan"
    elif [[ -f "$tfplan_report" ]]
    then
      log_info "--- checking upstream partial plan report: \\e[33;1m${tfplan_report}\\e[0m"
      mv "$tfplan_report" /tmp/tfplan.json
      tf_plan
      if ! diff -q /tmp/tfplan.json "$tfplan_report" > /dev/null
      then
        diff /tmp/tfplan.json "$tfplan_report"
        fail "Upstream plan report differs from current plan, please re-run the pipeline with the new plan"
      fi
      log_info "--- applying current plan: \\e[33;1m${tf_plan}\\e[0m"
      terraform apply -refresh=false "$tf_plan"
    else
      # implicit tfvars
      env_vars=$(ls -1 "${environment_type}.env.tfvars" 2>/dev/null || ls -1 "${environment_type}.env.tfvars.json" 2>/dev/null || echo "")
@@ -1111,7 +1124,7 @@ stages:
    expire_in: 1 day
    access: developer
    paths:
      - $TF_PROJECT_DIR/${ENV_TYPE}.tfplan
      - $TF_PROJECT_DIR/${ENV_TYPE}-plan.json
    reports:
      terraform: $TF_PROJECT_DIR/${ENV_TYPE}-plan.json