Usa flujos de trabajo para conectar servicios

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 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, crearás un flujo de trabajo único conectando un servicio a la vez:

  1. Implementa dos servicios de Cloud 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 instructivo, se usan componentes facturables de Google Cloud, incluidos los siguientes:

Usa la calculadora de precios para generar una estimación de los costos según el uso previsto.

Es posible que los usuarios nuevos de Google Cloud sean aptos para obtener una prueba gratuita.

Antes de comenzar

Algunos de los pasos de este documento podrían no funcionar correctamente si tu organización aplica restricciones a tu entorno de Google Cloud. En ese caso, es posible que no puedas completar tareas como crear direcciones IP públicas o claves de cuenta de servicio. Si realizas una solicitud que muestra un error sobre las restricciones, consulta cómo desarrollar aplicaciones en un entorno restringido de Google Cloud.

  1. Accede a tu cuenta de Google Cloud. Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
  2. En la página del selector de proyectos de Google Cloud Console, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  3. Asegúrate de que la facturación esté habilitada para tu proyecto de Cloud. Descubre cómo confirmar que tienes habilitada la facturación en un proyecto.

  4. Habilita las API de Cloud Build, Cloud Functions, Cloud Run, Cloud Storage, Container Registry, Workflows .

    Habilita las API

  5. En la página del selector de proyectos de Google Cloud Console, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  6. Asegúrate de que la facturación esté habilitada para tu proyecto de Cloud. Descubre cómo confirmar que tienes habilitada la facturación en un proyecto.

  7. Habilita las API de Cloud Build, Cloud Functions, Cloud Run, Cloud Storage, Container Registry, Workflows .

    Habilita las API

  8. Instala e inicializa el SDK de Cloud.
  9. Actualiza los componentes de gcloud:
    gcloud components update
  10. Accede con tu cuenta:
    gcloud auth login
  11. Crea una cuenta de servicio para que Workflows la use:

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

  12. 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 ${GOOGLE_CLOUD_PROJECT} \
        --member "serviceAccount:${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
        --role "roles/run.invoker"
    

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

    Reemplaza lo siguiente:

    • PROJECT_ID por el ID del proyecto de Google Cloud
    • REGION por la ubicación de clúster compatible que elijas de Workflows

Implementa el primer servicio de Cloud 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 random, json
    from flask import jsonify
    
    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
    
  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 Functions en Cloud Console para implementar la función.

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

    gcloud functions describe randomgen
    
  6. 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 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 random, json
    from flask import jsonify
    
    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
    
  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 Functions en Cloud Console para implementarla.

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

    gcloud functions describe multiply
    
  6. 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 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 tenga 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 el nombre del flujo de trabajo.

  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

Con Google Cloud Console, actualiza el flujo de trabajo existente y conecta una API de REST pública (math.js) que pueda evaluar expresiones matemáticas, por ejemplo, curl https://api.mathjs.org/v4/?'expr=log(56)'.

  1. Abre la página Flujos de trabajo en Google Cloud Console:
    Ir a la página Flujos de trabajo

  2. Selecciona el nombre del flujo de trabajo que deseas actualizar.

  3. Para editar la fuente del flujo de trabajo, haz clic en Editar y, luego, en Siguiente.

  4. Reemplaza el código fuente en el editor de flujo de trabajo 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 Functions y muestra un resultado final.

  5. Haga clic en Implementar.

Implementa un servicio de Cloud Run

Implementa un servicio de Cloud Run que, luego de recibir una solicitud HTTP, extraiga input del cuerpo JSON, calcule su math.floor y muestre 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. Compila la imagen del contenedor:

    export SERVICE_NAME=floor
    gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME}
    
  5. Implementa la imagen de contenedor en Cloud Run y asegúrate de que solo acepte llamadas autenticadas:

    gcloud run deploy ${SERVICE_NAME} \
    --image gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME} \
    --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

  1. Abre la página Flujos de trabajo en Google Cloud Console:
    Ir a la página Flujos de trabajo

  2. Selecciona el nombre del flujo de trabajo que deseas actualizar.

  3. Para editar la fuente del flujo de trabajo, haz clic en Editar y, luego, en Siguiente.

  4. Reemplaza el código fuente en el editor de flujo de trabajo 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
    - return_result:
        return: ${floor_result}
    

    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 Autenticación en Workflows.

  5. Haga clic en Implementar.

Ejecuta el flujo de trabajo final

  1. Actualiza el flujo de trabajo ingresando la cuenta de servicio:

    cd ~
    gcloud workflows deploy workflow \
    --source=workflow.yaml \
    --service-account=${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com
    
  2. Ejecuta el flujo de trabajo:

    gcloud workflows run WORKFLOW_NAME
    

    El resultado debe parecerse al siguiente:

    result: '{"body":{"multiplied":192},"code":200,"headers":{"Alt-Svc":"h3-29=\":443\";
    ...
    startTime: '2021-05-05T14:36:48.762896438Z'
    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 sintaxis de flujos de trabajo y la descripción general de la biblioteca estándar.

Limpia

Si creaste un proyecto nuevo para este instructivo, bórralo. Si usaste un proyecto existente y deseas 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, haz lo siguiente:

  1. En Cloud Console, ve a la página Administrar recursos.

    Ir a Administrar recursos

  2. En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
  3. En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.

Elimina recursos de instructivos

  1. Usa este comando para borrar el servicio de Cloud Run que implementaste en este instructivo:

    gcloud run services delete SERVICE_NAME

    En el ejemplo anterior, SERVICE_NAME es el nombre del servicio que elegiste.

    También puedes borrar los servicios de Cloud Run desde Google Cloud Console.

  2. Quita las opciones de configuración predeterminadas de gcloud que agregaste durante la configuración del instructivo.

     gcloud config unset run/region
     gcloud config unset workflows/location
     gcloud config unset project
    

  3. Borra el flujo de trabajo que se creó en este instructivo:

    gcloud workflows delete WORKFLOW_NAME
    
  4. Borra la imagen del contenedor llamada gcr.io/PROJECT_ID/SERVICE_NAME de Container Registry.

¿Qué sigue?