Implantación de Rollback Automático

Utilice scripts para implantar el rollback automático cuando falle un trabajo de aplicación en Resource Manager. Los scripts de rollback automáticos implican la supervisión de fallos de trabajo y la definición de un procedimiento de rollback que incluye validación, disparadores personalizados y acciones.

En entornos de producción, es esencial establecer una estrategia de despliegue sólida y flexible. Una mejor práctica habitual es integrar OCI Resource Manager con un sistema de integración/entrega continua (CI/CD) para gestionar todo el ciclo de vida del despliegue, incluido el rollback automático.

Oracle Cloud Infrastructure (OCI) ofrece una plataforma de integración y despliegue continuos nativa con todas las funciones: OCI DevOps. Este servicio proporciona las herramientas y pipelines necesarios para organizar sin problemas las operaciones de despliegue, prueba, supervisión y rollback.

Script de rollback automático

Para ayudarle a empezar, hemos proporcionado el siguiente script de Bash de ejemplo, que se puede utilizar en un pipeline de despliegue DevOps de OCI. Este script demuestra un mecanismo para realizar automáticamente un rollback de una pila de OCI Resource Manager en caso de fallo de despliegue.

El script sirve como punto de partida que puede personalizar para adaptarlo a sus requisitos específicos, asegurándose de que se ajuste a las necesidades únicas de sus flujos de trabajo de despliegue.

Script
version: 0.1
component: command
timeoutInSeconds: 600
shell: bash
steps:
  - type: Command
    name: "Deployment Runner Functionality"
    command: |
      # The STACK_OCID variable is externally injected and remains unescaped.
      STACK_OCID="${STACK_OCID}"

      echo "Starting Resource Manager Apply Job for Stack: ${STACK_OCID}"

      # 1. Create the Apply Job and capture its OCID.
      job_id=$(
        oci resource-manager job create-apply-job \
          --execution-plan-strategy AUTO_APPROVED \
          --display-name "DevOps-Apply-$(date +%s)" \
          --stack-id "${STACK_OCID}" \
          --wait-for-state 'ACCEPTED' \
          --query 'data.id' \
          --raw-output \
      )

      # Check if the job creation command returned a valid ID
      if [ -z "$job_id" ]; then
        echo "ERROR: Failed to create Resource Manager Apply job or command failed."
        exit 1
      fi

      echo "Resource Manager Job OCID: $job_id"

      # 2. Polling Loop to monitor job status
      max_poll_time_seconds=600 # 10 minutes maximum wait time
      poll_interval_seconds=10
      elapsed_time=0

      while [ $elapsed_time -le $max_poll_time_seconds ]; do

        # Get the current job status.
        status=$(
          oci resource-manager job get \
            --job-id "$job_id" \
            --query 'data."lifecycle-state"' \
            --raw-output \
        )

        echo "Time Elapsed: ${elapsed_time}s / ${max_poll_time_seconds}s - Current Job Status: $status"

        if [ "$status" == "SUCCEEDED" ]; then
          echo "Resource Manager Apply Job SUCCEEDED."
          exit 0 # Success exit code
        elif [ "$status" == "FAILED" ] || [ "$status" == "CANCELED" ]; then
          echo "Resource Manager Apply Job FAILED or CANCELED."

          # Check failure reason and conditionally trigger rollback
          if [ "$status" == "FAILED" ]; then
            # Fetch failure code
            failure_code=$(
              oci resource-manager job get \
                --job-id "$job_id" \
                --query 'data."failure-details".code' \
                --raw-output \
            )
            if [ -z "$failure_code" ]; then
              echo "No failure-details.code found in job output (field is empty or missing)"
              echo "==== Full job JSON output for debugging: ===="
              oci resource-manager job get \
                --job-id "$job_id" \
            else
              echo "Failure code: $failure_code"
            fi

            if [ "$failure_code" == "TERRAFORM_EXECUTION_ERROR" ]; then
              echo "Detected Terraform configuration error. Starting automatic rollback process..."

              # Define a rollback function
              automatic_rollback() {
                # List all jobs, filter for successful Apply jobs, sort by time-created desc, and get latest job OCID
                # Part 1: Fetch and count all succeeded APPLY jobs
                matched_jobs=$(
                  oci resource-manager job list \
                    --stack-id "$STACK_OCID" \
                    --query 'data[?operation==`APPLY` && "lifecycle-state"==`SUCCEEDED`] | sort_by(@, &`"time-created"`)' \
                )
                job_count=$(echo "$matched_jobs" | jq 'length')
                echo "Number of matching jobs found: $job_count"

                # Part 2: Extract and print first OCID if any
                last_succeeded_apply_job_ocid=$(echo "$matched_jobs" | jq -r '.[0].id // empty')

                if [ -n "$last_succeeded_apply_job_ocid" ]; then
                  echo "Last succeeded apply job OCID: $last_succeeded_apply_job_ocid"
                else
                  echo "No previous successful apply jobs found. Rollback skipped."
                  return 0
                fi
                
                echo "Invoking OCI CLI to create rollback job for OCID: $last_succeeded_apply_job_ocid"
                
                oci resource-manager job create \
                  --from-json "{\"stackId\":\"${STACK_OCID}\",\"displayName\":\"DevOps-Apply-Rollback-$(date +%s)\",\"jobOperationDetails\":{\"operation\":\"APPLY_ROLLBACK\",\"executionPlanRollbackStrategy\":\"AUTO_APPROVED\",\"targetRollbackJobId\":\"$last_succeeded_apply_job_ocid\"}}" \
                
                echo "======Apply Rollback Job Creation Complete========="
              }

              # Call the rollback function
              automatic_rollback
            fi
          fi
          exit 1 # Failure exit code
        fi

        # Wait before polling again
        sleep $poll_interval_seconds

        let "elapsed_time = elapsed_time + poll_interval_seconds"
      done

      # If the loop finished without SUCCEEDED or FAILED status
      echo "Error: Resource Manager Apply Job timed out after ${max_poll_time_seconds} seconds."
      exit 1

La lógica de rollback automático implementada en el script incluye los siguientes pasos:

  1. Iniciar despliegue: cree un trabajo de aplicación para desplegar la configuración de Terraform actualizada.
  2. Supervisar Estado de Despliegue: Supervise continuamente el estado del trabajo de aplicación. Consulte Obtención de Detalles de un Trabajo.
  3. Evaluar fallo: si el trabajo de aplicación falla, evalúe los criterios predefinidos para determinar si se debe disparar un rollback automático.
  4. Identificar el estado estable: recupere los trabajos de aplicación correctos para la pila y determine el trabajo de destino al que desea realizar un rollback. Consulte Listado de trabajos.
  5. Rollback de disparador: cree un trabajo de rollback de aplicación para restaurar la pila al estado estable anteriormente.