Instructivo de Workflows (1ª gen.)


En este instructivo, se muestra cómo usar Workflows para vincular una serie de servicios. Si conectas dos servicios de HTTP públicos (con Cloud Run Functions), una API de REST externa y un servicio privado de Cloud Run, puedes crear una aplicación flexible y sin servidores.

Objetivos

En este instructivo, usarás la Google Cloud CLI para crear un solo flujo de trabajo y conectar un servicio a la vez:

  1. Implementa dos servicios de Cloud Run Functions: la primera función genera un número al azar y, luego, pasa ese número a la segunda función, que lo multiplica.
  2. Con Workflows, conecta las dos funciones de HTTP. Ejecuta el flujo de trabajo para que se muestre un resultado que luego se pasa a una API externa.
  3. Con Workflows, conecta una API HTTP externa que muestre el log de un número determinado. Ejecuta el flujo de trabajo para que se muestre un resultado que luego se pasa a un servicio de Cloud Run.
  4. Implementa un servicio de Cloud Run que solo permita el acceso autenticado. El servicio muestra el math.floor de un número determinado.
  5. Con Workflows, conecta el servicio de Cloud Run, ejecuta todo el flujo de trabajo y obtén un resultado final.

En el siguiente diagrama, se muestra una descripción general del proceso y una visualización del flujo de trabajo final:

Visualización de los flujos de trabajo

Costos

En este documento, usarás los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.

Es posible que los usuarios de Google Cloud nuevos cumplan con los requisitos para acceder a una prueba gratuita.

Antes de comenzar

Es posible que las restricciones de seguridad que define tu organización no te permitan completar los siguientes pasos. Para obtener información sobre la solución de problemas, consulta Desarrolla aplicaciones en un entorno Google Cloud restringido.

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.

  3. Si usas un proveedor de identidad externo (IdP), primero debes acceder a gcloud CLI con tu identidad federada.

  4. Para inicializar gcloud CLI, ejecuta el siguiente comando:

    gcloud init
  5. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Artifact Registry, Cloud Build, Cloud Run functions, Cloud Run, Cloud Storage, and Workflows APIs:

    gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com cloudfunctions.googleapis.com run.googleapis.com storage.googleapis.com workflows.googleapis.com
  8. Install the Google Cloud CLI.

  9. Si usas un proveedor de identidad externo (IdP), primero debes acceder a gcloud CLI con tu identidad federada.

  10. Para inicializar gcloud CLI, ejecuta el siguiente comando:

    gcloud init
  11. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  12. Verify that billing is enabled for your Google Cloud project.

  13. Enable the Artifact Registry, Cloud Build, Cloud Run functions, Cloud Run, Cloud Storage, and Workflows APIs:

    gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com cloudfunctions.googleapis.com run.googleapis.com storage.googleapis.com workflows.googleapis.com
  14. Actualiza los componentes de la CLI de Google Cloud:
    gcloud components update
  15. Si ejecutas comandos dentro de Cloud Shell, ya estás autenticado con gcloud CLI, de lo contrario, ingresa con tu cuenta:
    gcloud auth login
  16. Crea una cuenta de servicio para que Workflows la use:

    export SERVICE_ACCOUNT=workflows-sa
    gcloud iam service-accounts create ${SERVICE_ACCOUNT}

  17. Para permitir que la cuenta de servicio llame a los servicios autenticados de Cloud Run, otorga la función run.invoker a la cuenta de servicio de Workflows:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member "serviceAccount:${SERVICE_ACCOUNT}@PROJECT_ID.iam.gserviceaccount.com" \
        --role "roles/run.invoker"

    Reemplaza PROJECT_ID por el Google Cloud ID del proyecto.

  18. Establece la ubicación predeterminada que se usa en este instructivo:
    gcloud config set project PROJECT_ID
    export REGION=REGION
    gcloud config set functions/region ${REGION}
    gcloud config set run/region ${REGION}
    gcloud config set workflows/location ${REGION}

    Reemplaza REGION por la ubicación de Workflows compatible que prefieras.

  19. Implementa el primer servicio de Cloud Run Functions

    Después de recibir una solicitud HTTP, esta función de HTTP genera un número aleatorio entre 1 y 100 y, luego, lo muestra en formato JSON.

    1. Crea un directorio llamado randomgen y cámbialo como se indica a continuación:

      mkdir ~/randomgen
      cd ~/randomgen
    2. Crea un archivo de texto con el nombre de archivo main.py que contenga el siguiente código de Python:

      import functions_framework
      import random
      from flask import jsonify
      
      
      @functions_framework.http
      def randomgen(request):
          randomNum = random.randint(1, 100)
          output = {"random": randomNum}
          return jsonify(output)
    3. A fin de admitir una dependencia en Flask para el procesamiento de HTTP, crea un archivo de texto destinado al administrador de paquetes pip. Asígnale el nombre requirements.txt y agrega lo siguiente:

      flask>=1.0.2
      functions-framework==3.0.0
    4. Implementa la función con un activador de HTTP y permite el acceso no autenticado:

      gcloud functions deploy randomgen \
          --runtime python37 \
          --trigger-http \
          --allow-unauthenticated

    La función puede tardar unos minutos en implementarse. También puedes usar la interfaz de Cloud Run Functions en la consola de Google Cloud para implementar la función.

    1. Una vez que se implementa la función, puedes confirmar la propiedad httpsTrigger.url:

      gcloud functions describe randomgen
    2. Puedes probar la función con el siguiente comando curl:

      curl $(gcloud functions describe randomgen --format='value(httpsTrigger.url)')

      Se genera y se muestra un número de forma aleatoria.

    Implementa el segundo servicio de Cloud Run Functions

    Después de recibir una solicitud HTTP, esta función de HTTP extrae el input del cuerpo JSON, lo multiplica por 2 y muestra el resultado en formato JSON.

    1. Crea un directorio llamado multiply y cámbialo como se indica a continuación:

      mkdir ~/multiply
      cd ~/multiply
    2. Crea un archivo de texto con el nombre de archivo main.py que contenga el siguiente código de Python:

      import functions_framework
      from flask import jsonify
      
      
      @functions_framework.http
      def multiply(request):
          request_json = request.get_json()
          output = {"multiplied": 2 * request_json['input']}
          return jsonify(output)
    3. A fin de admitir una dependencia en Flask para el procesamiento de HTTP, crea un archivo de texto destinado al administrador de paquetes pip. Asígnale el nombre requirements.txt y agrega lo siguiente:

      flask>=1.0.2
      functions-framework==3.0.0
    4. Implementa la función con un activador de HTTP y permite el acceso no autenticado:

      gcloud functions deploy multiply \
          --runtime python37 \
          --trigger-http \
          --allow-unauthenticated

    La función puede tardar unos minutos en implementarse.Como alternativa, puedes usar la interfaz de Cloud Run Functions en la consola de Google Cloud para implementar la función.

    1. Una vez que se implementa la función, puedes confirmar la propiedad httpsTrigger.url:

      gcloud functions describe multiply
    2. Puedes probar la función con el siguiente comando curl:

      curl $(gcloud functions describe multiply --format='value(httpsTrigger.url)') \
          -X POST \
          -H "content-type: application/json" \
          -d '{"input": 5}'

      Se debería mostrar el número 10.

    Conecta los dos servicios de Cloud Run Functions en un flujo de trabajo

    Un flujo de trabajo está compuesto por una serie de pasos descritos con la sintaxis de Workflows, que se pueden escribir en formato YAML o JSON. Esta es la definición del flujo de trabajo. Para obtener una explicación detallada, consulta la página Referencia de sintaxis.

    1. Regresa al directorio principal:

      cd ~
    2. Crea un archivo de texto con el nombre de archivo workflow.yaml que incluya el siguiente contenido:

      - randomgen_function:
          call: http.get
          args:
              url: https://REGION-PROJECT_ID.cloudfunctions.net/randomgen
          result: randomgen_result
      - multiply_function:
          call: http.post
          args:
              url: https://REGION-PROJECT_ID.cloudfunctions.net/multiply
              body:
                  input: ${randomgen_result.body.random}
          result: multiply_result
      - return_result:
          return: ${multiply_result}
      

      Esto vincula las dos funciones de HTTP y muestra un resultado final.

    3. Después de crear el flujo de trabajo, puedes implementarlo, con lo que estará listo para ejecutarse.

      gcloud workflows deploy WORKFLOW_NAME --source=workflow.yaml

      Reemplaza WORKFLOW_NAME por un nombre para tu VPC.

    4. Ejecuta el flujo de trabajo:

      gcloud workflows run WORKFLOW_NAME

      Una ejecución es una ejecución única de la lógica que se incluye en la definición de un flujo de trabajo. Todas las ejecuciones de flujos de trabajo son independientes, y el escalamiento rápido Workflows permite una gran cantidad de ejecuciones simultáneas.

      Una vez que se ejecuta el flujo de trabajo, el resultado debería ser similar al siguiente:

      result: '{"body":{"multiplied":120},"code":200,"headers":{"Alt-Svc":"h3-29=\":443\";
      ...
      startTime: '2021-05-05T14:17:39.135251700Z'
      state: SUCCEEDED
      ...
      

    Conecta un servicio público de REST en el flujo de trabajo

    Actualiza tu flujo de trabajo existente y conecta una API de REST pública (math.js) que pueda evaluar las expresiones matemáticas. Por ejemplo, curl https://api.mathjs.org/v4/?'expr=log(56)'

    Ten en cuenta que, como implementaste tu flujo de trabajo, también puedes editarlo en la página Flujos de trabajo en la consola de Google Cloud .

    1. Edita el archivo fuente de tu flujo de trabajo y reemplázalo por el siguiente contenido:

      - randomgen_function:
          call: http.get
          args:
              url: https://REGION-PROJECT_ID.cloudfunctions.net/randomgen
          result: randomgen_result
      - multiply_function:
          call: http.post
          args:
              url: https://REGION-PROJECT_ID.cloudfunctions.net/multiply
              body:
                  input: ${randomgen_result.body.random}
          result: multiply_result
      - log_function:
          call: http.get
          args:
              url: https://api.mathjs.org/v4/
              query:
                  expr: ${"log(" + string(multiply_result.body.multiplied) + ")"}
          result: log_result
      - return_result:
          return: ${log_result}
      

      Esto vincula el servicio de REST externo a los servicios de Cloud Run Functions y muestra un resultado final.

    2. Implementa el flujo de trabajo modificado:

      gcloud workflows deploy WORKFLOW_NAME --source=workflow.yaml

    Implementa un servicio de Cloud Run

    Implementa un servicio de Cloud Run que, luego de recibir una solicitud HTTP, extrae input del cuerpo JSON, calcula su math.floor y muestra el resultado.

    1. Crea un directorio llamado floor y cámbialo como se indica a continuación:

      mkdir ~/floor
      cd ~/floor
    2. Crea un archivo de texto con el nombre de archivo app.py que contenga el siguiente código de Python:

      import json
      import logging
      import os
      import math
      
      from flask import Flask, request
      
      app = Flask(__name__)
      
      
      @app.route('/', methods=['POST'])
      def handle_post():
          content = json.loads(request.data)
          input = float(content['input'])
          return f"{math.floor(input)}", 200
      
      
      if __name__ != '__main__':
          # Redirect Flask logs to Gunicorn logs
          gunicorn_logger = logging.getLogger('gunicorn.error')
          app.logger.handlers = gunicorn_logger.handlers
          app.logger.setLevel(gunicorn_logger.level)
          app.logger.info('Service started...')
      else:
          app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))

    3. En el mismo directorio, crea un Dockerfile con el siguiente contenido:

      # Use an official lightweight Python image.
      # https://hub.docker.com/_/python
      FROM python:3.7-slim
      
      # Install production dependencies.
      RUN pip install Flask gunicorn
      
      # Copy local code to the container image.
      WORKDIR /app
      COPY . .
      
      # Run the web service on container startup. Here we use the gunicorn
      # webserver, with one worker process and 8 threads.
      # For environments with multiple CPU cores, increase the number of workers
      # to be equal to the cores available.
      CMD exec gunicorn --bind 0.0.0.0:8080 --workers 1 --threads 8 app:app

    4. Crea un repositorio estándar de Artifact Registry en el que puedas almacenar la imagen de contenedor de Docker:

      gcloud artifacts repositories create REPOSITORY \
          --repository-format=docker \
          --location=${REGION}

      Reemplaza REPOSITORY por un nombre único para el repositorio.

    5. Compila la imagen del contenedor:

      export SERVICE_NAME=floor
      gcloud builds submit --tag ${REGION}-docker.pkg.dev/PROJECT_ID/REPOSITORY/${SERVICE_NAME}
    6. Implementa la imagen de contenedor en Cloud Run y asegúrate de que solo acepte llamadas autenticadas:

      gcloud run deploy ${SERVICE_NAME} \
          --image ${REGION}-docker.pkg.dev/PROJECT_ID/REPOSITORY/${SERVICE_NAME}:latest \
          --platform managed \
          --no-allow-unauthenticated

    Cuando veas la URL del servicio, se completará la implementación. Deberás especificar esa URL cuando actualices la definición del flujo de trabajo.

    Conecta el servicio de Cloud Run en el flujo de trabajo

    Actualiza tu flujo de trabajo existente y especifica la URL para el servicio de Cloud Run.

    1. Edita el archivo fuente de tu flujo de trabajo y reemplázalo por el siguiente contenido:

      - randomgen_function:
          call: http.get
          args:
              url: https://REGION-PROJECT_ID.cloudfunctions.net/randomgen
          result: randomgen_result
      - multiply_function:
          call: http.post
          args:
              url: https://REGION-PROJECT_ID.cloudfunctions.net/multiply
              body:
                  input: ${randomgen_result.body.random}
          result: multiply_result
      - log_function:
          call: http.get
          args:
              url: https://api.mathjs.org/v4/
              query:
                  expr: ${"log(" + string(multiply_result.body.multiplied) + ")"}
          result: log_result
      - floor_function:
          call: http.post
          args:
              url: CLOUD_RUN_SERVICE_URL
              auth:
                  type: OIDC
              body:
                  input: ${log_result.body}
          result: floor_result
      - create_output_map:
          assign:
            - outputMap:
                randomResult: ${randomgen_result}
                multiplyResult: ${multiply_result}
                logResult: ${log_result}
                floorResult: ${floor_result}
      - return_output:
          return: ${outputMap}
      

      Reemplaza CLOUD_RUN_SERVICE_URL por la URL de servicio de Cloud Run.

      Esto conecta el servicio de Cloud Run en el flujo de trabajo. Ten en cuenta que la clave auth garantiza que se transmita un token de autenticación en la llamada al servicio de Cloud Run. Para obtener más información, consulta Realiza solicitudes autenticadas desde un flujo de trabajo.

    2. Implementa el flujo de trabajo modificado:

      gcloud workflows deploy WORKFLOW_NAME \
          --source=workflow.yaml
    3. Ejecuta el flujo de trabajo final:

      gcloud workflows run WORKFLOW_NAME

      El resultado debe parecerse al siguiente:

      result: '{"Floor":{"body":"4","code":200
        ...
        "Log":{"body":"4.02535169073515","code":200
        ...
        "Multiply":{"body":{"multiplied":56},"code":200
        ...
        "Random":{"body":{"random":28},"code":200
        ...
      startTime: '2023-11-13T21:22:56.782669001Z'
      state: SUCCEEDED
      

    ¡Felicitaciones! Implementaste y ejecutaste un flujo de trabajo que conecta una serie de servicios.

    Para crear flujos de trabajo más complejos con expresiones, saltos condicionales, codificación y decodificación de Base64, subflujos de trabajo y más, consulta la página sobre la referencia de sintaxis de flujos de trabajo y la descripción general de la biblioteca estándar.

    Realiza una limpieza

    Si creaste un proyecto nuevo para este instructivo, bórralo. Si usaste un proyecto existente y quieres conservarlo sin los cambios que se agregaron en este instructivo, borra los recursos creados para el instructivo.

    Borra el proyecto

    La manera más fácil de eliminar la facturación es borrar el proyecto que creaste para el instructivo.

    Para borrar el proyecto, sigue estos pasos:

    1. In the Google Cloud console, go to the Manage resources page.

      Go to Manage resources

    2. In the project list, select the project that you want to delete, and then click Delete.
    3. In the dialog, type the project ID, and then click Shut down to delete the project.

    Elimina recursos de instructivos

    ¿Qué sigue?