Criar um gatilho usando o Terraform

Neste documento, descrevemos como usar o Terraform e o recurso google_eventarc_trigger para criar gatilhos do Eventarc para os seguintes destinos Google Cloud:

Para mais informações sobre como usar o Terraform, consulte a documentação do Terraform no Google Cloud.

Os exemplos de código neste guia encaminham eventos diretos do Cloud Storage, mas podem ser adaptados para qualquer provedor de eventos. Por exemplo, para saber como rotear eventos diretos do Pub/Sub para o Cloud Run, consulte o guia de início rápido do Terraform.

Antes de começar

  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. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

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

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

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

  6. Enable the Cloud Resource Manager and Identity and Access Management (IAM) APIs.

    Enable the APIs

  7. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  8. O Terraform está integrado ao ambiente do Cloud Shell, e você pode usar o Cloud Shell para implantar seus recursos do Terraform sem precisar instalar o Terraform.

Preparar para implantar o Terraform

Antes de implantar recursos do Terraform, você precisa criar um arquivo de configuração do Terraform. Um arquivo de configuração do Terraform permite definir o estado final de sua preferência para a infraestrutura usando a sintaxe do Terraform.

Preparar o Cloud Shell

No Cloud Shell, defina o projeto padrão do Google Cloud em que você quer aplicar as configurações do Terraform. Você só precisa executar esse comando uma vez por projeto, e ele pode ser executado em qualquer diretório:

export GOOGLE_CLOUD_PROJECT=PROJECT_ID

Substitua PROJECT_ID pelo ID do projeto Google Cloud .

As variáveis de ambiente são substituídas se você definir valores explícitos no arquivo de configuração do Terraform.

Preparar o diretório

Cada arquivo de configuração do Terraform precisa ter o próprio diretório, também chamado de módulo raiz. No Cloud Shell, crie um diretório e um novo arquivo nele:

mkdir DIRECTORY && cd DIRECTORY && touch main.tf

O nome do arquivo precisa ter a extensão .tf. Por exemplo, neste documento, o arquivo é chamado de main.tf.

Definir a configuração do Terraform

Copie os exemplos de código do Terraform aplicáveis para o arquivo main.tf recém-criado. Se preferir, copie o código do GitHub. Isso é recomendado quando o snippet do Terraform faz parte de uma solução de ponta a ponta.

Normalmente, você aplica toda a configuração de uma vez. No entanto, é possível segmentar um recurso específico. Exemplo:

terraform apply -target="google_eventarc_trigger.default"

Os exemplos de código do Terraform usam interpolação para substituições, como variáveis de referência, atributos de recursos e funções de chamada.

Ativar APIs

As amostras do Terraform geralmente presumem que as APIs necessárias estejam ativadas no seu projeto doGoogle Cloud . Use o código a seguir para ativar as APIs:

Cloud Run

# Enable Cloud Run API
resource "google_project_service" "run" {
  service            = "run.googleapis.com"
  disable_on_destroy = false
}

# Enable Eventarc API
resource "google_project_service" "eventarc" {
  service            = "eventarc.googleapis.com"
  disable_on_destroy = false
}

# Enable Pub/Sub API
resource "google_project_service" "pubsub" {
  service            = "pubsub.googleapis.com"
  disable_on_destroy = false
}

GKE;

# Enable GKE API
resource "google_project_service" "container" {
  service            = "container.googleapis.com"
  disable_on_destroy = false
}

# Enable Eventarc API
resource "google_project_service" "eventarc" {
  service            = "eventarc.googleapis.com"
  disable_on_destroy = false
}

# Enable Pub/Sub API
resource "google_project_service" "pubsub" {
  service            = "pubsub.googleapis.com"
  disable_on_destroy = false
}

Fluxos de trabalho

# Enable Workflows API
resource "google_project_service" "workflows" {
  service            = "workflows.googleapis.com"
  disable_on_destroy = false
}

# Enable Eventarc API
resource "google_project_service" "eventarc" {
  service            = "eventarc.googleapis.com"
  disable_on_destroy = false
}

# Enable Pub/Sub API
resource "google_project_service" "pubsub" {
  service            = "pubsub.googleapis.com"
  disable_on_destroy = false
}

Criar uma conta de serviço e configurar o acesso

Cada gatilho do Eventarc é associado a uma conta de serviço do IAM no momento da criação. Use o código abaixo para criar uma conta de serviço dedicada e conceder à conta de serviço gerenciado pelo usuário papéis específicos do Identity and Access Management para gerenciar eventos:

Cloud Run

# Used to retrieve project information later
data "google_project" "project" {}

# Create a dedicated service account
resource "google_service_account" "eventarc" {
  account_id   = "eventarc-trigger-sa"
  display_name = "Eventarc Trigger Service Account"
}

# Grant permission to receive Eventarc events
resource "google_project_iam_member" "eventreceiver" {
  project = data.google_project.project.id
  role    = "roles/eventarc.eventReceiver"
  member  = "serviceAccount:${google_service_account.eventarc.email}"
}

# Grant permission to invoke Cloud Run services
resource "google_project_iam_member" "runinvoker" {
  project = data.google_project.project.id
  role    = "roles/run.invoker"
  member  = "serviceAccount:${google_service_account.eventarc.email}"
}

O agente de serviço do Pub/Sub é criado automaticamente quando a API Pub/Sub é ativada. Se o agente de serviço do Pub/Sub foi criado em ou antes de 8 de abril de 2021 e a conta de serviço não tem a função de agente de serviço do Cloud Pub/Sub (roles/pubsub.serviceAgent), conceda a função Criador de token da conta de serviço (roles/iam.serviceAccountTokenCreator) ao agente de serviço. Para mais informações, consulte Criar e conceder papéis a agentes de serviço.

resource "google_project_iam_member" "tokencreator" {
  project  = data.google_project.project.id
  role     = "roles/iam.serviceAccountTokenCreator"
  member   = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-pubsub.iam.gserviceaccount.com"
}

GKE;

  1. Antes de criar a conta de serviço, ative o Eventarc para gerenciar clusters do GKE:

    # Used to retrieve project_number later
    data "google_project" "project" {}
    
    # Enable Eventarc to manage GKE clusters
    # This is usually done with: gcloud eventarc gke-destinations init
    #
    # Eventarc creates a separate Event Forwarder pod for each trigger targeting a
    # GKE service, and  requires explicit permissions to make changes to the
    # cluster. This is done by granting permissions to a special service account
    # (the Eventarc P4SA) to manage resources in the cluster. This needs to be done
    # once per Google Cloud project.
    
    # This identity is created with: gcloud beta services identity create --service eventarc.googleapis.com
    # This local variable is used for convenience
    locals {
      eventarc_sa = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-eventarc.iam.gserviceaccount.com"
    }
    
    resource "google_project_iam_member" "computeViewer" {
      project = data.google_project.project.id
      role    = "roles/compute.viewer"
      member  = local.eventarc_sa
    }
    
    resource "google_project_iam_member" "containerDeveloper" {
      project = data.google_project.project.id
      role    = "roles/container.developer"
      member  = local.eventarc_sa
    }
    
    resource "google_project_iam_member" "serviceAccountAdmin" {
      project = data.google_project.project.id
      role    = "roles/iam.serviceAccountAdmin"
      member  = local.eventarc_sa
    }
  2. Crie a conta de serviço:

    # Create a service account to be used by GKE trigger
    resource "google_service_account" "eventarc_gke_trigger_sa" {
      account_id   = "eventarc-gke-trigger-sa"
      display_name = "Evenarc GKE Trigger Service Account"
    }
    
    # Grant permission to receive Eventarc events
    resource "google_project_iam_member" "eventreceiver" {
      project = data.google_project.project.id
      role    = "roles/eventarc.eventReceiver"
      member  = "serviceAccount:${google_service_account.eventarc_gke_trigger_sa.email}"
    }
    
    # Grant permission to subscribe to Pub/Sub topics
    resource "google_project_iam_member" "pubsubscriber" {
      project = data.google_project.project.id
      role    = "roles/pubsub.subscriber"
      member  = "serviceAccount:${google_service_account.eventarc_gke_trigger_sa.email}"
    }
    

Fluxos de trabalho

# Used to retrieve project information later
data "google_project" "project" {}

# Create a service account for Eventarc trigger and Workflows
resource "google_service_account" "eventarc" {
  account_id   = "eventarc-workflows-sa"
  display_name = "Eventarc Workflows Service Account"
}

# Grant permission to invoke Workflows
resource "google_project_iam_member" "workflowsinvoker" {
  project = data.google_project.project.id
  role    = "roles/workflows.invoker"
  member  = "serviceAccount:${google_service_account.eventarc.email}"
}

# Grant permission to receive events
resource "google_project_iam_member" "eventreceiver" {
  project = data.google_project.project.id
  role    = "roles/eventarc.eventReceiver"
  member  = "serviceAccount:${google_service_account.eventarc.email}"
}

# Grant permission to write logs
resource "google_project_iam_member" "logwriter" {
  project = data.google_project.project.id
  role    = "roles/logging.logWriter"
  member  = "serviceAccount:${google_service_account.eventarc.email}"
}

O agente de serviço do Pub/Sub é criado automaticamente quando a API Pub/Sub é ativada. Se o agente de serviço do Pub/Sub foi criado em ou antes de 8 de abril de 2021 e a conta de serviço não tem a função de agente de serviço do Cloud Pub/Sub (roles/pubsub.serviceAgent), conceda a função Criador de token da conta de serviço (roles/iam.serviceAccountTokenCreator) ao agente de serviço. Para mais informações, consulte Criar e conceder papéis a agentes de serviço.

resource "google_project_iam_member" "tokencreator" {
  project  = data.google_project.project.id
  role     = "roles/iam.serviceAccountTokenCreator"
  member   = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-pubsub.iam.gserviceaccount.com"
}

Criar um bucket do Cloud Storage como um provedor de eventos

Use o código abaixo para criar um bucket do Cloud Storage e conceder o papel de editor do Pub/Sub (roles/pubsub.publisher) ao agente de serviço do Cloud Storage.

Cloud Run

# 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          = "trigger-cloudrun-${data.google_project.project.name}-${random_id.bucket_name_suffix.hex}"
  location      = google_cloud_run_v2_service.default.location
  force_destroy = true

  uniform_bucket_level_access = true
}

# Grant the Cloud Storage service account permission to publish pub/sub topics
data "google_storage_project_service_account" "gcs_account" {}
resource "google_project_iam_member" "pubsubpublisher" {
  project = data.google_project.project.id
  role    = "roles/pubsub.publisher"
  member  = "serviceAccount:${data.google_storage_project_service_account.gcs_account.email_address}"
}

GKE;

# 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          = "trigger-gke-${data.google_project.project.name}-${random_id.bucket_name_suffix.hex}"
  location      = "us-central1"
  force_destroy = true

  uniform_bucket_level_access = true
}

# Grant the Cloud Storage service account permission to publish pub/sub topics
data "google_storage_project_service_account" "gcs_account" {}
resource "google_project_iam_member" "pubsubpublisher" {
  project = data.google_project.project.id
  role    = "roles/pubsub.publisher"
  member  = "serviceAccount:${data.google_storage_project_service_account.gcs_account.email_address}"
}

Fluxos de trabalho

# 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          = "trigger-workflows-${data.google_project.project.name}-${random_id.bucket_name_suffix.hex}"
  location      = google_workflows_workflow.default.region
  force_destroy = true

  uniform_bucket_level_access = true
}

# Grant the Cloud Storage service account permission to publish Pub/Sub topics
data "google_storage_project_service_account" "gcs_account" {}
resource "google_project_iam_member" "pubsubpublisher" {
  project = data.google_project.project.id
  role    = "roles/pubsub.publisher"
  member  = "serviceAccount:${data.google_storage_project_service_account.gcs_account.email_address}"
}

Criar um receptor de eventos para ser o destino do evento

Crie um receptor de eventos usando um dos seguintes recursos do Terraform:

Cloud Run

Crie um serviço do Cloud Run como destino do evento para o gatilho do Eventarc:

# Deploy Cloud Run service
resource "google_cloud_run_v2_service" "default" {
  name     = "hello-events"
  location = "us-central1"

  deletion_protection = false # set to "true" in production

  template {
    containers {
      # This container will log received events
      image = "us-docker.pkg.dev/cloudrun/container/hello"
    }
    service_account = google_service_account.eventarc.email
  }

  depends_on = [google_project_service.run]
}

GKE;

Para simplificar este guia, crie um serviço do Google Kubernetes Engine como destino de evento fora do Terraform, entre a aplicação das configurações do Terraform.

  1. Se você ainda não criou um acionador neste projeto Google Cloud , execute o comando a seguir para criar o agente de serviço do Eventarc:

    gcloud beta services identity create --service eventarc.googleapis.com
  2. Crie um cluster do GKE:

    # Create an auto-pilot GKE cluster
    resource "google_container_cluster" "gke_cluster" {
      name     = "eventarc-cluster"
      location = "us-central1"
    
      enable_autopilot = true
    
      depends_on = [
        google_project_service.container
      ]
    }
  3. Implante um serviço do Kubernetes no GKE que receberá solicitações HTTP e eventos de registro usando uma imagem pré-criada do Cloud Run, us-docker.pkg.dev/cloudrun/container/hello:

    1. Consiga as credenciais de autenticação para interagir com o cluster:

      gcloud container clusters get-credentials eventarc-cluster \
         --region=us-central1
      
    2. Crie uma implantação chamada hello-gke:

      kubectl create deployment hello-gke \
         --image=us-docker.pkg.dev/cloudrun/container/hello
      
    3. Exponha a implantação como um serviço do Kubernetes:

      kubectl expose deployment hello-gke \
         --type ClusterIP --port 80 --target-port 8080
      
    4. Verifique se o pod está em execução:

      kubectl get pods
      

      A saída será semelhante a esta:

      NAME                         READY   STATUS    RESTARTS   AGE
      hello-gke-5b6574b4db-rzzcr   1/1     Running   0          2m45s
      

      Se STATUS for Pending ou ContainerCreating, o pod está sendo implantado. Aguarde um minuto até que a implantação seja concluída e verifique o status novamente.

    5. Verifique se o serviço está em execução:

      kubectl get svc
      

      A saída será semelhante a esta:

      NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
      hello-gke    ClusterIP   34.118.230.123   <none>        80/TCP    4m46s
      kubernetes   ClusterIP   34.118.224.1     <none>        443/TCP   14m
      

Fluxos de trabalho

Implante um fluxo de trabalho que seja executado quando um objeto for atualizado no bucket do Cloud Storage:

# Create a workflow
resource "google_workflows_workflow" "default" {
  name            = "storage-workflow-tf"
  region          = "us-central1"
  description     = "Workflow that returns information about storage events"
  service_account = google_service_account.eventarc.email

  deletion_protection = false # set to "true" in production

  # Note that $$ is needed for Terraform
  source_contents = <<EOF
  main:
    params: [event]
    steps:
      - log_event:
          call: sys.log
          args:
            text: $${event}
            severity: INFO
      - gather_data:
          assign:
            - bucket: $${event.data.bucket}
            - name: $${event.data.name}
            - message: $${"Received event " + event.type + " - " + bucket + ", " + name}
      - return_data:
          return: $${message}
  EOF

  depends_on = [
    google_project_service.workflows
  ]
}

Definir um gatilho do Eventarc

Um gatilho do Eventarc encaminha eventos de um provedor de eventos para um destino de evento. Use o recurso google_eventarc_trigger para especificar atributos do CloudEvents no matching_criteria e filtrar os eventos. Para mais informações, siga as instruções ao criar um gatilho para um provedor, tipo de evento e destino específicos. Eventos que correspondam a todos os filtros são enviados para o destino.

Cloud Run

Crie um gatilho do Eventarc que roteie eventos do Cloud Storage para o serviço hello-event do Cloud Run.

# Create an Eventarc trigger, routing Cloud Storage events to Cloud Run
resource "google_eventarc_trigger" "default" {
  name     = "trigger-storage-cloudrun-tf"
  location = google_cloud_run_v2_service.default.location

  # 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 Cloud Run
  destination {
    cloud_run_service {
      service = google_cloud_run_v2_service.default.name
      region  = google_cloud_run_v2_service.default.location
    }
  }

  service_account = google_service_account.eventarc.email
  depends_on = [
    google_project_service.eventarc,
    google_project_iam_member.pubsubpublisher
  ]
}

GKE;

Crie um gatilho do Eventarc que direcione eventos do Cloud Storage para o serviço hello-gke do GKE.

# Create an Eventarc trigger, routing Storage events to GKE
resource "google_eventarc_trigger" "default" {
  name     = "trigger-storage-gke-tf"
  location = "us-central1"

  # 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 GKE service
  destination {
    gke {
      cluster   = "eventarc-cluster"
      location  = "us-central1"
      namespace = "default"
      path      = "/"
      service   = "hello-gke"
    }
  }

  service_account = google_service_account.eventarc_gke_trigger_sa.email
}

Fluxos de trabalho

Crie um gatilho do Eventarc que encaminha eventos do Cloud Storage para o fluxo de trabalho chamado storage-workflow-tf.

# Create an Eventarc trigger, routing Cloud Storage events to Workflows
resource "google_eventarc_trigger" "default" {
  name     = "trigger-storage-workflows-tf"
  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.eventarc.email

  depends_on = [
    google_project_service.eventarc,
    google_project_service.workflows,
  ]
}

Aplicar o Terraform

Use a CLI do Terraform para provisionar a infraestrutura com base no arquivo de configuração.

Para saber como aplicar ou remover uma configuração do Terraform, consulte Comandos básicos do Terraform.

  1. Inicialize o Terraform. Você só precisa fazer isso uma vez por diretório.

    terraform init

    Opcionalmente, para usar a versão mais recente do provedor do Google, inclua a opção -upgrade:

    terraform init -upgrade
  2. Revise a configuração e verifique se os recursos que o Terraform vai criar ou atualizar correspondem às suas expectativas:

    terraform plan

    Faça as correções necessárias na configuração.

  3. Para aplicar a configuração do Terraform, execute o comando a seguir e digite yes no prompt:

    terraform apply

    Aguarde até que o Terraform exiba a mensagem "Apply complete!".

Verificar a criação de recursos

Cloud Run

  1. Confirme se o serviço foi criado:

    gcloud run services list --region us-central1
    
  2. Confirme se o gatilho foi criado:

    gcloud eventarc triggers list --location us-central1
    

    A saída será semelhante a esta:

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

GKE;

  1. Confirme se o serviço foi criado:

    kubectl get service hello-gke
    
  2. Confirme se o gatilho foi criado:

    gcloud eventarc triggers list --location us-central1
    

    A saída será semelhante a esta:

    NAME: trigger-storage-gke-tf
    TYPE: google.cloud.storage.object.v1.finalized
    DESTINATION: GKE: hello-gke
    ACTIVE: Yes
    LOCATION: us-central1
    

Fluxos de trabalho

  1. Confirme se o fluxo de trabalho foi criado:

    gcloud workflows list --location us-central1
    
  2. Confirme se o gatilho do Eventarc foi criado:

    gcloud eventarc triggers list --location us-central1
    

    A saída será semelhante a esta:

    NAME: trigger-storage-workflows-tf
    TYPE: google.cloud.storage.object.v1.finalized
    DESTINATION: Workflows: storage-workflow-tf
    ACTIVE: Yes
    LOCATION: us-central1
    

Gerar e visualizar um evento

É possível gerar um evento e confirmar se o gatilho do Eventarc está funcionando conforme o esperado.

  1. Extraia o nome do bucket do Cloud Storage que você criou:

    gcloud storage ls
    
  2. Faça upload de um arquivo de texto para o bucket do Cloud Storage:

    echo "Hello World" > random.txt
    gcloud storage cp random.txt gs://BUCKET_NAME/random.txt
    

    Substitua BUCKET_NAME pelo nome do bucket do Cloud Storage que você extraiu na etapa anterior. Exemplo:

    gcloud storage cp random.txt gs://BUCKET_NAME/random.txt

    O upload gera um evento, e o serviço de receptor de eventos registra a mensagem do evento.

  3. Verifique se um evento foi recebido:

    Cloud Run

    1. Filtre as entradas de registro criadas pelo seu serviço:

      gcloud logging read 'jsonPayload.message: "Received event of type google.cloud.storage.object.v1.finalized."'
      
    2. Procure uma entrada de registro semelhante a esta:

      Received event of type google.cloud.storage.object.v1.finalized.
      Event data: { "kind": "storage#object", "id": "trigger-cloudrun-BUCKET_NAME/random.txt", ...}
      

    GKE;

    1. Encontre o ID do pod:

      POD_NAME=$(kubectl get pods -o custom-columns=":metadata.name" --no-headers)
      

      Esse comando usa a saída formatada de kubectl.

    2. Verifique os registros do pod:

      kubectl logs $POD_NAME
      
    3. Procure uma entrada de registro semelhante a esta:

      {"severity":"INFO","eventType":"google.cloud.storage.object.v1.finalized","message":
      "Received event of type google.cloud.storage.object.v1.finalized. Event data: ...}
      

    Fluxos de trabalho

    1. Liste as últimas cinco execuções para verificar se uma execução de fluxos de trabalho foi acionada:

      gcloud workflows executions list storage-workflow-tf --limit=5
      

      A saída precisa incluir uma lista de execuções com NAME, STATE, START_TIME e END_TIME.

    2. Consulte os resultados da execução mais recente:

      EXECUTION_NAME=$(gcloud workflows executions list storage-workflow-tf --limit=1 --format "value(name)")
      gcloud workflows executions describe $EXECUTION_NAME
      
    3. Confirme se a saída é semelhante a esta:

      ...
      result: '"Received event google.cloud.storage.object.v1.finalized - BUCKET_NAME, random.txt"'
      startTime: '2024-12-13T17:23:50.451316533Z'
      state: SUCCEEDED
      ...
      

Limpar

Remova os recursos aplicados anteriormente com a configuração do Terraform executando o seguinte comando e inserindo yes no prompt:

terraform destroy

Também é possível excluir seu projeto do Google Cloud para evitar cobranças. A exclusão do projeto do Google Cloud interrompe o faturamento de todos os recursos usados nele.

  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.

A seguir