Configurar a saída direta de VPC para funções de segunda geração

Com a saída de VPC direta, é possível rotear o tráfego da função do Cloud Run functions (2ª geração) diretamente para a rede VPC.

Limitações

  • A saída direta de VPC não está disponível para funções de primeira geração.
  • Não é possível usar a saída VPC direta e os conectores de acesso VPC sem servidor ao mesmo tempo. Consulte Comparar a saída direta de VPC e os conectores de VPC para mais detalhes.

Antes de começar

  • Ative a API Cloud Functions.
  • Instale a Google Cloud CLI e inicialize-a executando gcloud init.
  • Atualize os componentes gcloud para a versão 545.0.0 ou mais recente:

    gcloud components update
    

  • Se você ainda não tiver uma rede VPC no projeto, crie uma.

  • Opcional: se a função precisar acessar APIs e serviços do Google usando os endereços IP internos deles, ative o Acesso privado do Google na sub-rede que você usa para saída direta da VPC.

Configurar permissões do IAM

Para autorizar o tráfego de saída direto da VPC, peça ao administrador para conceder o papel de Invocador do Cloud Run (roles/run.invoker) à conta de serviço da sua função.

Verifique se o Cloud Run tem acesso à rede VPC usando um dos seguintes métodos:

  • Papel de agente de serviço do Cloud Run: por padrão, o agente de serviço do Cloud Run tem o papel de agente de serviço do Cloud Run (roles/run.serviceAgent) que contém as permissões necessárias.

  • Permissões personalizadas: para ter um controle mais granular, conceda ao agente de serviço do Cloud Run as seguintes permissões extras no projeto:

    • compute.networks.get
    • compute.subnetworks.get
    • compute.subnetworks.use no projeto host ou na sub-rede específica
    • compute.addresses.get
    • compute.addresses.list
    • compute.addresses.create (obrigatório apenas para sub-redes de pilha dupla com IPv6 externo)
    • compute.addresses.delete (necessário apenas para sub-redes de pilha dupla com IPv6 externo)
    • compute.addresses.createInternal
    • compute.addresses.deleteInternal
    • compute.regionOperations.get
  • Papel de usuário da rede do Compute: se você não usar o papel padrão do Agente de serviço do Cloud Run ou as permissões personalizadas, conceda o papel de usuário da rede do Compute (roles/compute.networkUser) na conta de serviço do agente de serviço do Cloud Run. As sub-redes com IPv6 externo também exigem o papel de administrador de IP público do Compute (roles/compute.publicIpAdmin).

    Por exemplo, para conceder o papel de usuário da rede do Compute, execute o seguinte comando:

    gcloud projects add-iam-policy-binding PROJECT_ID \
    --member "serviceAccount:service-PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com" \
    --role "roles/compute.networkUser"

    Substitua:

    • PROJECT_ID: ID do projeto.
    • PROJECT_NUMBER: o número do projeto em que você implanta a função do Cloud Run.

Configurar a saída de VPC direta

Configure a saída da VPC direta para funções da 2ª geração novas ou atuais.

gcloud

  1. Para configurar a saída da VPC direta ao implantar uma função, use o comando gcloud beta functions deploy com flags para as configurações de rede.

    gcloud beta functions deploy FUNCTION_NAME \
        --source . \
        --runtime RUNTIME \
        --trigger-http \
        --region REGION \
        --network=NETWORK \
        --subnet=SUBNET \
        --network-tags=NETWORK_TAG_NAMES \
        --direct-vpc-egress=EGRESS_SETTING
    

    Substitua:

    • FUNCTION_NAME: o nome da sua função.
    • RUNTIME: o ambiente de execução da sua função, por exemplo, nodejs20.
    • REGION: a região em que você implanta a função.
    • Opcional: NETWORK com o nome da sua rede VPC. Especifique uma rede VPC ou uma sub-rede, ou ambas. Se você especificar apenas uma rede, a sub-rede usará o mesmo nome da rede.
    • Opcional: SUBNET com o nome da sub-rede. Especifique uma rede VPC, uma sub-rede ou ambas. Se você especificar apenas uma rede, a sub-rede usará o mesmo nome da rede. É possível implantar ou executar várias funções na mesma sub-rede.
    • Opcional: NETWORK_TAG_NAMES pelos nomes separados por vírgula das tags de rede que você quer associar a uma função. Cada função pode ter tags de rede diferentes, como network-tag-2.
    • EGRESS_SETTING por um valor de configuração de saída:
      • all: Padrão. Envia todo o tráfego de saída pela rede VPC.
      • private-ranges-only: envia o tráfego apenas para endereços internos pela rede VPC.
  2. Opcional: para remover todas as configurações de saída VPC direta de uma função, reimplante a função com as flags --clear-network e --clear-network-tags.

Terraform

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

Para configurar a saída da VPC direta, use o provedor google-beta do Terraform.

Usando o exemplo de saída VPC direta das funções do Cloud Run (2ª geração) como ponto de partida, atualize os seguintes campos:

  • service_config.network: o nome da sua rede VPC.
  • service_config.subnetwork: o nome da sub-rede VPC.
  • service_config.direct_vpc_egress: qual tráfego enviar para a rede VPC. O VPC_EGRESS_ALL_TRAFFIC envia todo o tráfego de saída pela rede VPC. O VPC_EGRESS_PRIVATE_RANGES_ONLY envia tráfego somente para intervalos de endereços IP particulares na rede VPC.

Exemplo: chamar um serviço interno de uma função

Este exemplo mostra como criar um serviço interno do Cloud Run e chamá-lo de uma função do Cloud Run functions (2ª geração) que usa saída direta da VPC.

Criar o serviço de back-end interno

  1. Crie um diretório para o serviço de back-end e mude para ele:

    mkdir backend-service
    cd backend-service
    
  2. Crie um arquivo package.json com o seguinte conteúdo:

    {
        "name": "backend-service",
        "version": "1.0.0",
        "description": "",
        "scripts": {
            "start": "node index.js"
        },
        "dependencies": {
            "express": "^4.18.1"
        }
    }
    
  3. Crie um arquivo index.js com o seguinte conteúdo:

    const express = require('express');
    const app = express();
    
    app.get('/', (req, res) => {
        res.send("hello world");
    });
    
    const port = parseInt(process.env.PORT) || 8080;
    app.listen(port, () => {
        console.log(`helloworld: listening on port ${port}`);
    });
    
  4. Implante o serviço no Cloud Run com entrada interna:

    gcloud run deploy backend \
        --source . \
        --no-allow-unauthenticated \
        --region=REGION \
        --ingress internal
    

    Substitua REGION pela sua região, por exemplo, us-west1.

  5. Salve o URL do novo serviço. Você precisará dele na próxima seção.

Criar e implantar a função

  1. Crie um diretório para a função e mude para ele:

    cd ..
    mkdir dvpc-function
    cd dvpc-function
    
  2. Crie um arquivo package.json com o seguinte conteúdo:

    {
      "name": "sample-http",
      "version": "0.0.1",
      "dependencies": {
        "axios": "0.21.1",
        "@google-cloud/functions-framework": "^3.0.0"
      }
    }
    
  3. Crie um arquivo index.js com o seguinte conteúdo. Esse código faz uma solicitação autenticada ao serviço de back-end interno.

    const axios = require('axios');
    const functions = require('@google-cloud/functions-framework');
    
    const callVPCService = async (req, res) => {
      const backendUrl = process.env.BACKEND_URL;
    
      if (!backendUrl) {
        console.error('BACKEND_URL environment variable not set.');
        res.status(500).send('BACKEND_URL not configured.');
        return;
      }
    
      try {
        const metadataServerURL = 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=';
        const tokenUrl = metadataServerURL + backendUrl;
    
        const tokenResponse = await axios.get(tokenUrl, {
          headers: {
            'Metadata-Flavor': 'Google',
          },
        });
        const token = tokenResponse.data;
    
        const response = await axios.get(backendUrl, {
          headers: {
            Authorization: `bearer ${token}`,
          },
    });
    
    res.status(200).send(`Response from backend: ${response.data}`);
      } catch (error) {
        console.error(`Error calling backend service: ${error.message}`);
        res.status(500).send(`Error calling backend: ${error.message}`);
      }
    };
    
    functions.http('callVPCService', callVPCService);
    
  4. Implante a função com a saída VPC direta configurada para rotear todo o tráfego para a rede VPC padrão:

    gcloud beta functions deploy my-2ndgen-function \
      --source . \
      --runtime nodejs20 \
      --trigger-http \
      --entry-point callVPCService \
      --network=default \
      --subnet=default \
      --direct-vpc-egress=all \
      --region=REGION \
      --allow-unauthenticated \
      --set-env-vars BACKEND_URL=BACKEND_URL
    

    Substitua:

    • REGION: a região em que você implantou o serviço de back-end.
    • BACKEND_URL: o URL do serviço de back-end que você criou.
  5. Depois que a função for implantada, acesse o URL dela para invocá-la. A função chama o serviço de back-end interno e retorna a resposta dele.

A seguir