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

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 558.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 functions deploy com flags para as configurações de rede.

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

Esse recurso (suporte para usar saída da VPC direta com funções do Cloud Run de segunda geração) adiciona os campos direct_vpc_network_interface.network e direct_vpc_egress.

Para usar esse recurso, siga estas diretrizes:

  • Use a versão 7.21.0 ou mais recente do Terraform.
  • Se você reimplantar uma função que já tem a VPC direta, agora será necessário definir explicitamente os valores na configuração.

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.direct_vpc_network_interface.network: o nome da sua rede VPC.
  • service_config.direct_vpc_network_interface.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 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