Exécuter une tâche Cloud Run à l'aide de Workflows

Workflows vous permet d'exécuter des jobs Cloud Run dans le cadre d'un workflow pour effectuer un traitement de données plus complexe ou orchestrer un système de jobs existants.

Ce tutoriel explique comment utiliser Workflows pour exécuter un job Cloud Run qui traite les données transmises en tant que variables d'environnement au job, en réponse à un événement Cloud Storage.

Notez que vous pouvez également stocker les données d'événement dans un bucket Cloud Storage, ce qui vous permet de les chiffrer à l'aide de clés de chiffrement gérées par le client. Pour en savoir plus, consultez Exécuter un job Cloud Run qui traite les données d'événement enregistrées dans Cloud Storage.

Créer un job Cloud Run

Ce tutoriel utilise un exemple de job Cloud Run provenant de GitHub. Le job lit les données d'un fichier d'entrée dans Cloud Storage et effectue un traitement arbitraire pour chaque ligne du fichier.

  1. Récupérez l'exemple de code en clonant le dépôt de l'exemple d'application sur votre ordinateur local :

    git clone https://github.com/GoogleCloudPlatform/jobs-demos.git

    Vous pouvez également télécharger l'exemple en tant que fichier ZIP et l'extraire.

  2. Accédez au répertoire qui contient l'exemple de code :

    cd jobs-demos/parallel-processing
  3. Créez un bucket Cloud Storage pour stocker un fichier d'entrée dans lequel vous pouvez écrire et qui peut déclencher un événement :

    Console

    1. Dans la console Google Cloud , accédez à la page Buckets de Cloud Storage.

      Accéder à la page "Buckets"

    2. Cliquez sur add Créer.
    3. Sur la page Créer un bucket, saisissez un nom pour votre bucket :
      input-PROJECT_ID
      Remplacez PROJECT_ID par l'ID de votre projet Google Cloud .
    4. Conservez les autres valeurs par défaut.
    5. Cliquez sur Créer.

    gcloud

    Exécutez la commande gcloud storage buckets create :

    gcloud storage buckets create gs://input-PROJECT_ID

    Si la requête aboutit, la commande renvoie le message suivant :

    Creating gs://input-PROJECT_ID/...

    Terraform

    Pour créer un bucket Cloud Storage, utilisez la ressource google_storage_bucket et modifiez votre fichier main.tf comme indiqué dans l'exemple suivant.

    Pour savoir comment appliquer ou supprimer une configuration Terraform, consultez Commandes Terraform de base.

    Notez que dans un workflow Terraform typique, vous appliquez l'intégralité du plan en une seule fois. Toutefois, pour les besoins de ce tutoriel, vous pouvez cibler une ressource spécifique. Exemple :

    terraform apply -target="random_id.bucket_name_suffix"
    et
    terraform apply -target="google_storage_bucket.default"

    # Cloud Storage bucket names must be globally unique
    resource "random_id" "bucket_name_suffix" {
      byte_length = 4
    }
    
    # Create a Cloud Storage bucket
    resource "google_storage_bucket" "default" {
      name                        = "input-${data.google_project.project.name}-${random_id.bucket_name_suffix.hex}"
      location                    = "us-central1"
      storage_class               = "STANDARD"
      force_destroy               = false
      uniform_bucket_level_access = true
    }
  4. Créez un dépôt standard Artifact Registry dans lequel vous pouvez stocker votre image de conteneur :

    Console

    1. Dans la console Google Cloud , accédez à la page Dépôts d'Artifact Registry :

      Accédez aux dépôts.

    2. Cliquez sur Créer un dépôt.

    3. Saisissez un nom pour le dépôt (par exemple, my-repo). Pour chaque emplacement de dépôt d'un projet, les noms de dépôt doivent être uniques.

    4. Conservez le format par défaut, qui doit être Docker.

    5. Conservez le mode par défaut, qui doit être Standard.

    6. Pour la région, sélectionnez us-central1 (Iowa).

    7. Conservez toutes les autres valeurs par défaut.

    8. Cliquez sur Créer.

    gcloud

    Exécutez la commande suivante :

    gcloud artifacts repositories create REPOSITORY \
        --repository-format=docker \
        --location=us-central1

    Remplacez REPOSITORY par un nom unique pour le dépôt, par exemple my-repo. Pour chaque emplacement de dépôt d'un projet, les noms de dépôt doivent être uniques.

    Terraform

    Pour créer un dépôt Artifact Registry, utilisez la ressource google_artifact_registry_repository et modifiez votre fichier main.tf comme indiqué dans l'exemple suivant.

    Notez que dans un workflow Terraform typique, vous appliquez l'intégralité du plan en une seule fois. Toutefois, pour les besoins de ce tutoriel, vous pouvez cibler une ressource spécifique. Exemple :

    terraform apply -target="google_artifact_registry_repository.default"

    # Create an Artifact Registry repository
    resource "google_artifact_registry_repository" "default" {
      location      = "us-central1"
      repository_id = "my-repo"
      format        = "docker"
    }
  5. Créez l'image de conteneur à l'aide d'un buildpack Google Cloud par défaut :

    export SERVICE_NAME=parallel-job
    gcloud builds submit \
        --pack image=us-central1-docker.pkg.dev/PROJECT_ID/REPOSITORY/${SERVICE_NAME}

    Remplacez REPOSITORY par le nom de votre dépôt Artifact Registry.

    La compilation peut prendre quelques minutes.

  6. Créez un job Cloud Run qui déploie l'image de conteneur :

    Console

    1. Dans la console Google Cloud , accédez à la page Cloud Run :

      Accédez à Cloud Run

    2. Cliquez sur Créer un job pour afficher le formulaire Créer un job.

      1. Dans le formulaire, sélectionnez us-central1-docker.pkg.dev/PROJECT_ID/REPOSITORY/parallel-job:latest comme URL de l'image de conteneur Artifact Registry.
      2. (Facultatif) Saisissez parallel-job comme nom de job.
      3. Facultatif : Pour la région, sélectionnez us-central1 (Iowa).
      4. Pour le nombre de tâches que vous souhaitez exécuter dans le job, saisissez 10. Toutes les tâches doivent réussir pour que le job aboutisse. Par défaut, les tâches s'exécutent en parallèle.
    3. Développez la section Conteneur, variables et secrets, connexions, sécurité et conservez toutes les valeurs par défaut, à l'exception des paramètres suivants :

      1. Cliquez sur l'onglet Général.

        1. Pour la commande de conteneur, saisissez python.
        2. Pour l'argument du conteneur, saisissez process.py.
      2. Cliquez sur l'onglet Variables et secrets.

        1. Cliquez sur Ajouter une variable, puis saisissez INPUT_BUCKET pour le nom et input-PROJECT_ID pour la valeur.
        2. Cliquez sur Ajouter une variable, puis saisissez INPUT_FILE pour le nom et input_file.txt pour la valeur.
    4. Pour créer le job, cliquez sur Créer.

    gcloud

    1. Définissez la région Cloud Run par défaut :

      gcloud config set run/region us-central1
    2. Créez le job Cloud Run :

      gcloud run jobs create parallel-job \
          --image us-central1-docker.pkg.dev/PROJECT_ID/REPOSITORY/parallel-job:latest \
          --command python \
          --args process.py \
          --tasks 10 \
          --set-env-vars=INPUT_BUCKET=input-PROJECT_ID,INPUT_FILE=input_file.txt

      Notez que si vous ne spécifiez pas de tag d'image, Artifact Registry recherche l'image avec le tag par défaut latest.

      Pour obtenir la liste complète des options disponibles lors de la création d'un job, consultez la documentation de ligne de commande gcloud run jobs create.

      Une fois le job créé, un message de confirmation devrait s'afficher.

    Terraform

    Pour créer un job Cloud Run, utilisez la ressource google_cloud_run_v2_job et modifiez votre fichier main.tf comme indiqué dans l'exemple suivant.

    Notez que dans un workflow Terraform typique, vous appliquez l'intégralité du plan en une seule fois. Toutefois, pour les besoins de ce tutoriel, vous pouvez cibler une ressource spécifique. Exemple :

    terraform apply -target="google_cloud_run_v2_job.default"

    # Create a Cloud Run job
    resource "google_cloud_run_v2_job" "default" {
      name     = "parallel-job"
      location = "us-central1"
    
      template {
        task_count = 10
        template {
          containers {
            image   = "us-central1-docker.pkg.dev/${data.google_project.project.name}/${google_artifact_registry_repository.default.repository_id}/parallel-job:latest"
            command = ["python"]
            args    = ["process.py"]
            env {
              name  = "INPUT_BUCKET"
              value = google_storage_bucket.default.name
            }
            env {
              name  = "INPUT_FILE"
              value = "input_file.txt"
            }
          }
        }
      }
    }

Déployer un workflow qui exécute le job Cloud Run

Définissez et déployez un workflow qui exécute le job Cloud Run que vous venez de créer. Une définition de workflow est constituée d'une série d'étapes décrites à l'aide de la syntaxe Workflows.

Console

  1. Dans la console Google Cloud , accédez à la page Workflows :

    Accéder à "Workflows"

  2. Cliquez sur Créer.

  3. Saisissez un nom pour le nouveau workflow, par exemple cloud-run-job-workflow.

  4. Pour la région, sélectionnez us-central1 (Iowa).

  5. Dans le champ Compte de service, sélectionnez le compte de service que vous avez créé précédemment.

    Le compte de service sert d'identité au workflow. Vous devez déjà avoir attribué le rôle Administrateur Cloud Run au compte de service pour que le workflow puisse exécuter le job Cloud Run.

  6. Cliquez sur Suivant.

  7. Dans l'éditeur de workflow, saisissez la définition suivante pour votre workflow :

    main:
        params: [event]
        steps:
            - init:
                assign:
                    - project_id: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
                    - event_bucket: ${event.data.bucket}
                    - event_file: ${event.data.name}
                    - target_bucket: ${"input-" + project_id}
                    - job_name: parallel-job
                    - job_location: us-central1
            - check_input_file:
                switch:
                    - condition: ${event_bucket == target_bucket}
                      next: run_job
                    - condition: true
                      next: end
            - run_job:
                call: googleapis.run.v1.namespaces.jobs.run
                args:
                    name: ${"namespaces/" + project_id + "/jobs/" + job_name}
                    location: ${job_location}
                    body:
                        overrides:
                            containerOverrides:
                                env:
                                    - name: INPUT_BUCKET
                                      value: ${event_bucket}
                                    - name: INPUT_FILE
                                      value: ${event_file}
                result: job_execution
            - finish:
                return: ${job_execution}
  8. Cliquez sur Déployer.

gcloud

  1. Créez un fichier de code source pour votre workflow :

    touch cloud-run-job-workflow.yaml
  2. Copiez la définition de workflow suivante dans votre fichier de code source :

    main:
        params: [event]
        steps:
            - init:
                assign:
                    - project_id: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
                    - event_bucket: ${event.data.bucket}
                    - event_file: ${event.data.name}
                    - target_bucket: ${"input-" + project_id}
                    - job_name: parallel-job
                    - job_location: us-central1
            - check_input_file:
                switch:
                    - condition: ${event_bucket == target_bucket}
                      next: run_job
                    - condition: true
                      next: end
            - run_job:
                call: googleapis.run.v1.namespaces.jobs.run
                args:
                    name: ${"namespaces/" + project_id + "/jobs/" + job_name}
                    location: ${job_location}
                    body:
                        overrides:
                            containerOverrides:
                                env:
                                    - name: INPUT_BUCKET
                                      value: ${event_bucket}
                                    - name: INPUT_FILE
                                      value: ${event_file}
                result: job_execution
            - finish:
                return: ${job_execution}
  3. Déployez le workflow en saisissant la commande suivante :

    gcloud workflows deploy cloud-run-job-workflow \
        --location=us-central1 \
        --source=cloud-run-job-workflow.yaml \
        --service-account=SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com

    Remplacez les éléments suivants :

    • SERVICE_ACCOUNT_NAME : nom du compte de service que vous avez créé précédemment
    • PROJECT_ID : ID de votre projetGoogle Cloud

    Le compte de service sert d'identité au workflow. Vous devez déjà avoir attribué le rôle roles/run.admin au compte de service pour que le workflow puisse exécuter le job Cloud Run.

Terraform

Pour créer un workflow, utilisez la ressource google_workflows_workflow et modifiez votre fichier main.tf comme indiqué dans l'exemple suivant.

Pour savoir comment appliquer ou supprimer une configuration Terraform, consultez Commandes Terraform de base.

Notez que dans un workflow Terraform typique, vous appliquez l'intégralité du plan en une seule fois. Toutefois, pour les besoins de ce tutoriel, vous pouvez cibler une ressource spécifique. Exemple :

terraform apply -target="google_workflows_workflow.default"

# Create a workflow
resource "google_workflows_workflow" "default" {
  name        = "cloud-run-job-workflow"
  region      = "us-central1"
  description = "Workflow that routes a Cloud Storage event and executes a Cloud Run job"

  deletion_protection = false # set to "true" in production

  # Note that $$ is needed for Terraform
  source_contents = <<EOF
  main:
      params: [event]
      steps:
          - init:
              assign:
                  - project_id: $${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
                  - event_bucket: $${event.data.bucket}
                  - event_file: $${event.data.name}
                  - target_bucket: "${google_storage_bucket.default.name}"
                  - job_name: parallel-job
                  - job_location: us-central1
          - check_input_file:
              switch:
                  - condition: $${event_bucket == target_bucket}
                    next: run_job
                  - condition: true
                    next: end
          - run_job:
              call: googleapis.run.v1.namespaces.jobs.run
              args:
                  name: $${"namespaces/" + project_id + "/jobs/" + job_name}
                  location: $${job_location}
                  body:
                      overrides:
                          containerOverrides:
                              env:
                                  - name: INPUT_BUCKET
                                    value: $${event_bucket}
                                  - name: INPUT_FILE
                                    value: $${event_file}
              result: job_execution
          - finish:
              return: $${job_execution}
  EOF
}

Le workflow effectue les opérations suivantes :

  1. Étape init : accepte un événement Cloud Storage en tant qu'argument, puis définit les variables nécessaires.

  2. Étape check_input_file : vérifie si le bucket Cloud Storage spécifié dans l'événement est celui utilisé par le job Cloud Run.

    • Si la réponse est oui, le workflow passe à l'étape run_job.
    • Si ce n'est pas le cas, le workflow se termine et tout traitement ultérieur est interrompu.
  3. L'étape run_job utilise la méthode googleapis.run.v1.namespaces.jobs.run du connecteur de l'API Cloud Run Admin pour exécuter le job. Les noms du bucket Cloud Storage et du fichier de données sont transmis en tant que variables de remplacement du workflow à la tâche.

  4. Étape finish : renvoie des informations sur l'exécution du job en tant que résultat du workflow.

Créer un déclencheur Eventarc pour le workflow

Pour exécuter automatiquement le workflow et, par conséquent, le job Cloud Run chaque fois que le fichier de données d'entrée est mis à jour, créez un déclencheur Eventarc qui répond aux événements Cloud Storage dans le bucket contenant le fichier de données d'entrée.

Console

  1. Dans la console Google Cloud , accédez à la page Workflows :

    Accéder à "Workflows"

  2. Cliquez sur le nom de votre workflow, par exemple cloud-run-job-workflow.

  3. Sur la page Détails du workflow, cliquez sur Modifier.

  4. Sur la page Modifier le workflow, dans la section Déclencheurs, cliquez sur Ajouter un déclencheur > Eventarc.

    Le volet Déclencheur Eventarc s'ouvre.

  5. Dans le champ Nom du déclencheur, saisissez un nom pour le déclencheur (par exemple, cloud-run-job-workflow-trigger).

  6. Dans la liste Fournisseur d'événements, sélectionnez Cloud Storage.

  7. Dans la liste Événement, sélectionnez google.cloud.storage.object.v1.finalized.

  8. Dans le champ Bucket, sélectionnez le bucket contenant le fichier de données d'entrée. Le nom du bucket se présente sous la forme input-PROJECT_ID.

  9. Dans le champ Compte de service, sélectionnez le compte de service que vous avez créé précédemment.

    Le compte de service sert d'identité au déclencheur. Vous devez déjà avoir attribué les rôles suivants au compte de service :

    • Destinataire des événements Eventarc : pour recevoir des événements
    • Demandeur de workflows : pour exécuter des workflows
  10. Cliquez sur Enregistrer le déclencheur.

    Le déclencheur Eventarc s'affiche désormais dans la section Déclencheurs de la page Modifier le workflow.

  11. Cliquez sur Suivant.

  12. Cliquez sur Déployer.

gcloud

Créez un déclencheur Eventarc en exécutant la commande suivante :

gcloud eventarc triggers create cloud-run-job-workflow-trigger \
    --location=us \
    --destination-workflow=cloud-run-job-workflow  \
    --destination-workflow-location=us-central1 \
    --event-filters="type=google.cloud.storage.object.v1.finalized" \
    --event-filters="bucket=input-PROJECT_ID" \
    --service-account=SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com

Remplacez les éléments suivants :

  • PROJECT_ID : ID de votre projet Google Cloud
  • SERVICE_ACCOUNT_NAME : nom du compte de service que vous avez créé précédemment.

Le compte de service sert d'identité au déclencheur. Vous devez déjà avoir attribué les rôles suivants au compte de service :

  • roles/eventarc.eventReceiver : pour recevoir les événements
  • roles/workflows.invoker : pour exécuter des workflows

Terraform

Pour créer un déclencheur, utilisez la ressource google_eventarc_trigger et modifiez votre fichier main.tf comme indiqué dans l'exemple suivant.

Pour savoir comment appliquer ou supprimer une configuration Terraform, consultez Commandes Terraform de base.

Notez que dans un workflow Terraform typique, vous appliquez l'intégralité du plan en une seule fois. Toutefois, pour les besoins de ce tutoriel, vous pouvez cibler une ressource spécifique. Exemple :

terraform apply -target="google_eventarc_trigger.default"

# Create an Eventarc trigger that routes Cloud Storage events to Workflows
resource "google_eventarc_trigger" "default" {
  name     = "cloud-run-job-trigger"
  location = google_workflows_workflow.default.region

  # Capture objects changed in the bucket
  matching_criteria {
    attribute = "type"
    value     = "google.cloud.storage.object.v1.finalized"
  }
  matching_criteria {
    attribute = "bucket"
    value     = google_storage_bucket.default.name
  }

  # Send events to Workflows
  destination {
    workflow = google_workflows_workflow.default.id
  }

  service_account = google_service_account.workflows.email

}

Chaque fois qu'un fichier est importé ou écrasé dans le bucket Cloud Storage contenant le fichier de données d'entrée, le workflow est exécuté avec l'événement Cloud Storage correspondant comme argument.

Déclencher le workflow

Testez le système de bout en bout en mettant à jour le fichier de données d'entrée dans Cloud Storage.

  1. Générez de nouvelles données pour le fichier d'entrée et importez-les dans Cloud Storage à l'emplacement attendu par le job Cloud Run :

    base64 /dev/urandom | head -c 100000 >input_file.txt
    gcloud storage cp input_file.txt gs://input-PROJECT_ID/input_file.txt

    Si vous avez créé un bucket Cloud Storage à l'aide de Terraform, vous pouvez récupérer son nom en exécutant la commande suivante :

    gcloud storage buckets list gs://input*

    L'exécution du job Cloud Run peut prendre quelques minutes.

  2. Vérifiez que le job Cloud Run s'est exécuté comme prévu en consultant les exécutions du job :

    gcloud config set run/region us-central1
    gcloud run jobs executions list --job=parallel-job

    Vous devriez voir une exécution de job réussie dans le résultat, indiquant que les tâches 10/10 sont terminées.

Découvrez comment déclencher un workflow avec des événements ou des messages Pub/Sub.