Acionar funções do Cloud Storage usando o Eventarc


Neste tutorial, mostramos como implantar uma função orientada a eventos no Cloud Run. e usar o Eventarc para acionar a função em resposta a Eventos do Cloud Storage usando a CLI do Google Cloud.

Ao especificar filtros para um gatilho do Eventarc, você pode configurar o roteamento de eventos, incluindo a origem e o destino do evento. Para o exemplo deste tutorial, a atualização de um bucket do Cloud Storage aciona o evento, e uma solicitação é enviada para a função na forma de uma solicitação HTTP.

Objetivos

Com este tutorial, você vai:

  1. Criar um bucket do Cloud Storage para ser a origem do evento.
  2. Implantar uma função orientada a eventos.
  3. Criar um gatilho do Eventarc.
  4. Acionar a função fazendo upload de um arquivo no Cloud Storage.

Custos

Neste documento, você usará os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem estar qualificados para uma avaliação gratuita.

Antes de começar

As restrições de segurança definidas pela sua organização podem impedir que você conclua as etapas a seguir. Para informações sobre solução de problemas, consulte Desenvolver aplicativos em um ambiente restrito do Google Cloud.

  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. To initialize the gcloud CLI, run the following command:

    gcloud init
  4. 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.

  5. Make sure that billing is enabled for your Google Cloud project.

  6. Install the Google Cloud CLI.
  7. To initialize the gcloud CLI, run the following command:

    gcloud init
  8. 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.

  9. Make sure that billing is enabled for your Google Cloud project.

  10. Se você não estiver usando o Cloud Shell, atualize os componentes da Google Cloud CLI e faça login usando sua conta:
    gcloud components update
    gcloud auth login
  11. Ative as APIs:
    gcloud services enable artifactregistry.googleapis.com \
        cloudbuild.googleapis.com \
        eventarc.googleapis.com \
        run.googleapis.com \
        storage.googleapis.com
  12. Defina as variáveis de configuração a serem usadas neste tutorial:
    export REGION=us-central1
    gcloud config set run/region ${REGION}
    gcloud config set run/platform managed
    gcloud config set eventarc/location ${REGION}
  13. Se você precisa seguir uma política da organização de restrição de domínio que restringe invocações não autenticadas para seu projeto, será necessário acessar o serviço implantado, conforme descrito em Como testar serviços particulares.

Defina os papéis necessários

  1. Se você for o criador do projeto, receberá o papel de proprietário básico (roles/owner). Por padrão, esse papel do gerenciamento de identidade e acesso (IAM) inclui as permissões necessárias para acesso total à maioria dos recursos do Google Cloud, e você pode pular esta etapa.

    Se você não é o criador do projeto, as permissões necessárias precisam ser concedidas ao principal apropriado. Por exemplo, um principal pode ser uma Conta do Google (para usuários finais) ou uma conta de serviço (para aplicativos e cargas de trabalho de computação). Para mais informações, consulte a página Papéis e permissões do destino do evento.

    Permissões necessárias

    Para conseguir as permissões necessárias para concluir o tutorial, peça ao administrador para conceder a você os seguintes papéis do IAM no seu projeto:

    Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

    Também é possível conseguir as permissões necessárias por meio de papéis personalizados ou de outros papéis predefinidos.

  2. Anote as propriedades da conta de serviço padrão do Compute Engine, porque você vai anexá-la a um gatilho do Eventarc para representar a identidade do acionador para fins de teste. Essa conta de serviço é criada automaticamente depois de ativar ou usar um serviço do Google Cloud que usa o Compute Engine e com o seguinte formato de e-mail:

    PROJECT_NUMBER-compute@developer.gserviceaccount.com

    Substitua PROJECT_NUMBER pelo número do projeto do Google Cloud. Encontre o número do projeto na página Boas-vindas do console do Google Cloud ou executando o seguinte comando:

    gcloud projects describe PROJECT_ID --format='value(projectNumber)'

    Para ambientes de produção, é altamente recomendável criar uma nova conta de serviço, conceder a ela um ou mais papéis do IAM que contenham as permissões mínimas necessárias, bem como seguir o princípio de privilégio mínimo.

  3. Por padrão, os serviços do Cloud Run só podem ser chamados por proprietários do projeto, editores do projeto e administradores e invocadores do Cloud Run. É possível controlar o acesso por serviço. No entanto, para fins de teste, conceda o papel de chamador do Cloud Run (run.invoker) no projeto do Google Cloud à conta de serviço do Compute Engine. Isso concede o papel em todos os serviços e jobs do Cloud Run em um projeto.
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com \
        --role=roles/run.invoker

    Se você criar um gatilho para um serviço autenticado do Cloud Run sem conceder o papel de chamador do Cloud Run, o gatilho será criado com sucesso e estará ativo. No entanto, o acionador não funcionará conforme o esperado e uma mensagem semelhante à seguinte aparecerá nos registros:

    The request was not authenticated. Either allow unauthenticated invocations or set the proper Authorization header.
  4. Conceda o papel de receptor de eventos do Eventarc (roles/eventarc.eventReceiver) no projeto à conta de serviço padrão do Compute Engine para que o gatilho do Eventarc possa receber eventos de provedores de eventos.
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com \
        --role=roles/eventarc.eventReceiver
  5. Antes de criar um gatilho para eventos diretos do Cloud Storage, conceda o papel de publisher do Pub/Sub (roles/pubsub.publisher) ao agente de serviço do Cloud Storage:

    SERVICE_ACCOUNT="$(gcloud storage service-agent --project=PROJECT_ID)"
    
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member="serviceAccount:${SERVICE_ACCOUNT}" \
        --role='roles/pubsub.publisher'
  6. Se você ativou o agente de serviço do Cloud Pub/Sub até 8 de abril de 2021, para oferecer compatibilidade com solicitações push autenticadas do Pub/Sub, conceda o papel de Criador de token da conta de serviço (roles/iam.serviceAccountTokenCreator) ao agente de serviço. Caso contrário, esse papel é concedido por padrão:
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \
        --role=roles/iam.serviceAccountTokenCreator

Crie um bucket do Cloud Storage

Crie um bucket do Cloud Storage para usar como origem do evento:

gcloud storage buckets create -l us-central1 gs://PROJECT_ID-bucket/

Criar uma função orientada a eventos

Para escrever uma função orientada a eventos, siga estas etapas:

Node.js

  1. Crie um novo diretório com o nome helloGCS e altere o diretório nele:

       mkdir helloGCS
       cd helloGCS
    

  2. Crie um arquivo package.json no diretório helloGCS para especificar as dependências do Node.js:

    {
      "name": "nodejs-docs-samples-functions-v2-storage",
      "version": "0.0.1",
      "private": true,
      "license": "Apache-2.0",
      "author": "Google LLC",
      "repository": {
        "type": "git",
        "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git"
      },
      "engines": {
        "node": ">=16.0.0"
      },
      "scripts": {
        "test": "c8 mocha -p -j 2 test/*.test.js --timeout=60000"
      },
      "dependencies": {
        "@google-cloud/functions-framework": "^3.0.0"
      },
      "devDependencies": {
        "c8": "^10.0.0",
        "mocha": "^10.0.0",
        "sinon": "^18.0.0",
        "supertest": "^7.0.0"
      }
    }
    
  3. Crie um arquivo index.js no diretório helloGCS com o seguinte exemplo de Node.js:

    const functions = require('@google-cloud/functions-framework');
    
    // Register a CloudEvent callback with the Functions Framework that will
    // be triggered by Cloud Storage.
    functions.cloudEvent('helloGCS', cloudEvent => {
      console.log(`Event ID: ${cloudEvent.id}`);
      console.log(`Event Type: ${cloudEvent.type}`);
    
      const file = cloudEvent.data;
      console.log(`Bucket: ${file.bucket}`);
      console.log(`File: ${file.name}`);
      console.log(`Metageneration: ${file.metageneration}`);
      console.log(`Created: ${file.timeCreated}`);
      console.log(`Updated: ${file.updated}`);
    });

Python

  1. Crie um novo diretório com o nome helloGCS e altere o diretório nele:

       mkdir helloGCS
       cd helloGCS
    

  2. Crie um arquivo requirements.txt no diretório helloGCS para especificar dependências do Python:

    functions-framework==3.5.0
    cloudevents==1.11.0

    Isso adiciona os pacotes necessários para a amostra.

  3. Crie um arquivo main.py no diretório helloGCS com o seguinte Exemplo em Python:

    from cloudevents.http import CloudEvent
    
    import functions_framework
    
    
    # Triggered by a change in a storage bucket
    @functions_framework.cloud_event
    def hello_gcs(cloud_event: CloudEvent) -> tuple:
        """This function is triggered by a change in a storage bucket.
    
        Args:
            cloud_event: The CloudEvent that triggered this function.
        Returns:
            The event ID, event type, bucket, name, metageneration, and timeCreated.
        """
        data = cloud_event.data
    
        event_id = cloud_event["id"]
        event_type = cloud_event["type"]
    
        bucket = data["bucket"]
        name = data["name"]
        metageneration = data["metageneration"]
        timeCreated = data["timeCreated"]
        updated = data["updated"]
    
        print(f"Event ID: {event_id}")
        print(f"Event type: {event_type}")
        print(f"Bucket: {bucket}")
        print(f"File: {name}")
        print(f"Metageneration: {metageneration}")
        print(f"Created: {timeCreated}")
        print(f"Updated: {updated}")
    
        return event_id, event_type, bucket, name, metageneration, timeCreated, updated
    
    

Implantar uma função orientada a eventos

Implante a função chamada helloworld-events executando o seguinte comando no diretório que contém o exemplo de código:

Node.js

gcloud beta run deploy helloworld-events \
      --source . \
      --function helloGCS \
      --base-image nodejs20 \
      --region us-central1 \

Python

gcloud beta run deploy helloworld-events \
      --source . \
      --function hello_gcs \
      --base-image python312 \
      --region us-central1 \

Quando a implantação for concluída, a CLI do Google Cloud vai mostrar um URL em que o serviço helloworld-events está em execução.

Criar um gatilho do Eventarc

O gatilho do Eventarc envia eventos do bucket do Cloud Storage para o serviço helloworld-events do Cloud Run.

  1. Crie um gatilho que filtre eventos do Cloud Storage:

    gcloud eventarc triggers create TRIGGER_NAME  \
        --location=${REGION} \
        --destination-run-service=helloworld-events  \
        --destination-run-region=${REGION} \
        --event-filters="type=google.cloud.storage.object.v1.finalized" \
        --event-filters="bucket=PROJECT_ID-bucket" \
        --service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com

    Substitua:

    • TRIGGER_NAME pelo nome do gatilho.
    • PROJECT_ID pelo ID de projeto do Google Cloud;
    • PROJECT_NUMBER pelo número do projeto do Google Cloud.

    Ao criar um gatilho do Eventarc pela primeira vez em um projeto do Google Cloud, pode haver um atraso no provisionamento do agente de serviço do Eventarc. Esse problema geralmente pode ser resolvido ao tentar criar o acionador novamente. Para mais informações, consulte Erros de permissão negada.

  2. Confirme se o gatilho foi criado com êxito. Embora o gatilho seja criado imediatamente, pode levar até dois minutos para que ele seja totalmente funcional.

    gcloud eventarc triggers list --location=${REGION}

    A saída será semelhante a esta:

    NAME: helloworld-events
    TYPE: google.cloud.storage.object.v1.finalized
    DESTINATION: Cloud Run service: helloworld-events
    ACTIVE: Yes
    LOCATION: us-central1
    

Gerar e visualizar um evento

Faça upload de um arquivo de texto para o bucket do Cloud Storage para gerar um evento roteado para a função. A função do Cloud Run registra o evento nos registros do serviço.

  1. Para gerar um evento, faça o upload de um arquivo de texto no Cloud Storage:

     echo "Hello World" > random.txt
     gcloud storage cp random.txt gs://PROJECT_ID-bucket/random.txt
    

    O upload gera um evento e a função do Cloud Run registra a mensagem do evento.

  2. Para visualizar a entrada de registro:

    1. Filtre as entradas de registro e retorne a saída no formato JSON:

      gcloud logging read "resource.labels.service_name=helloworld-events AND textPayload:random.txt" --format=json
      
    2. Procure uma entrada de registro semelhante a esta:

      [
        {
         ....
          "resource": {
            "labels": {
              ....
              "location": "us-central1",
              .....
              "service_name": "helloworld-events"
            },
          },
          "textPayload": "File: random.txt",
           .....
        }
      ]
      

      Os registros podem demorar alguns instantes para aparecer. Se eles não aparecerem imediatamente, verifique novamente após um minuto.

A entrada de registro confirma que você implantou uma função orientada a eventos que foi acionada quando um arquivo de texto foi enviado para o Cloud Storage.

Limpar

Se você criou um novo projeto para este tutorial, exclua o projeto. Se você usou um projeto já existente e quer mantê-lo sem as alterações incluídas com este tutorial, exclua os recursos criados para o tutorial.

Exclua o projeto

O jeito mais fácil de evitar cobranças é excluindo o projeto que você criou para o tutorial.

Para excluir o projeto:

  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.

delete-tutorial-resources

  1. Exclua o serviço do Cloud Run que você implantou neste tutorial:

    gcloud run services delete SERVICE_NAME

    SERVICE_NAME é o nome escolhido do serviço.

    Também é possível excluir os serviços do Cloud Run no Console do Google Cloud.

  2. Remova as configurações padrão do gcloud CLI que você adicionou durante a configuração do tutorial.

    Exemplo:

    gcloud config unset run/region

    ou

    gcloud config unset project

  3. Exclua outros recursos do Google Cloud criados neste tutorial:

    • Exclua o gatilho do Eventarc:
      gcloud eventarc triggers delete TRIGGER_NAME
      
      Substitua TRIGGER_NAME pelo nome do gatilho.

A seguir