1. Introduzione
Panoramica
Funzioni di Cloud Run è una soluzione di calcolo leggera che consente agli sviluppatori di creare funzioni autonome a uso specifico che possono essere attivate utilizzando HTTPS o rispondere a CloudEvents senza la necessità di gestire un ambiente server o di runtime. Scopri di più sulle funzioni Cloud Run nel nostro post del blog.
Esistono due approcci principali per controllare le chiamate alle funzioni Cloud Run: protezione dell'accesso in base all'identità e protezione dell'accesso tramite controlli di accesso basati sulla rete. Questo codelab si concentra sul primo approccio e ti guida in 3 scenari per proteggere l'accesso in base all'identità per richiamare una funzione:
- Utilizzare il token di identità gcloud per invocare una funzione a scopo di sviluppo e test locali
- Rappresenta un account di servizio durante lo sviluppo e il test in locale per utilizzare le stesse credenziali dell'ambiente di produzione
- Utilizza le librerie client di Google per gestire l'autenticazione nelle API Google Cloud, ad esempio quando un servizio deve richiamare una funzione
Cosa imparerai a fare
- Come configurare l'autenticazione in una funzione Cloud Run e verificare che sia stata configurata correttamente
- Esegui una chiamata a una funzione autenticata da un ambiente di sviluppo locale fornendo il token per la tua identità gcloud
- Come creare un account di servizio e concedergli il ruolo appropriato per richiamare una funzione
- Come impersonare un servizio da un ambiente di sviluppo locale che dispone dei ruoli appropriati per richiamare una funzione
2. Configurazione e requisiti
Prerequisiti
- Hai eseguito l'accesso alla console Cloud
- In precedenza hai eseguito il deployment di una funzione Cloud Run attivata da HTTP. Guarda l'esempio di avvio rapido.
- (Facoltativo) Per il terzo scenario, questo codelab utilizza Node.js e npm come esempio, ma puoi utilizzare qualsiasi runtime supportato dalle librerie client di Google Auth.
Attiva Cloud Shell
- Nella console Cloud, fai clic su Attiva Cloud Shell
.
Se è la prima volta che avvii Cloud Shell, viene visualizzata una schermata intermedia che descrive di cosa si tratta. Se viene visualizzata una schermata intermedia, fai clic su Continua.
Il provisioning e la connessione a Cloud Shell dovrebbero richiedere solo qualche istante.
Questa macchina virtuale è caricata con tutti gli strumenti di sviluppo necessari. Offre una home directory permanente da 5 GB e viene eseguita in Google Cloud, migliorando notevolmente le prestazioni e l'autenticazione della rete. Gran parte, se non tutto, del lavoro in questo codelab può essere svolto con un browser.
Una volta eseguita la connessione a Cloud Shell, dovresti vedere che il tuo account è già autenticato e il progetto è già impostato sul tuo ID progetto.
- Esegui questo comando in Cloud Shell per verificare che l'account sia autenticato:
gcloud auth list
Output comando
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- Esegui il seguente comando in Cloud Shell per verificare che il comando gcloud conosca il tuo progetto:
gcloud config list project
Output comando
[core] project = <PROJECT_ID>
In caso contrario, puoi impostarlo con questo comando:
gcloud config set project <PROJECT_ID>
Output comando
Updated property [core/project].
3. Creare e testare una funzione Cloud Run autenticata
Se richiedi l'autenticazione, l'entità che richiama la funzione deve avere il ruolo Invoker di Cloud Run. In caso contrario, la funzione restituirà un errore 403 Forbidden. Questo codelab mostra come concedere i ruoli Invoker appropriati a un entità.
Configura le variabili di ambiente locali per i comandi gcloud semplificati
Innanzitutto, creerai alcune variabili di ambiente per migliorare la leggibilità dei comandi gcloud
utilizzati in questo codelab.
REGION=us-central1 PROJECT_ID=$(gcloud config get-value project)
Crea il codice sorgente della funzione
Sebbene questo codelab utilizzi Node.js, puoi utilizzare qualsiasi runtime supportato dalle librerie client di Google Auth.
Per prima cosa, crea una directory e accedi a quella directory.
mkdir auth-function-codelab && cd $_
Poi, crea il file package.json.
touch package.json echo '{ "dependencies": { "@google-cloud/functions-framework": "^3.0.0" } } ' > package.json
Quindi, crea il file di origine index.js.
touch index.js echo 'const functions = require("@google-cloud/functions-framework"); functions.http("helloWorld", (req, res) => { res.send(`Hello ${req.query.name || req.body.name || "World"}!`); });' > index.js
Crea la funzione autenticata
Di seguito sono riportati i passaggi per la creazione di una funzione autenticata per il runtime nodejs20. Tuttavia, puoi utilizzare qualsiasi runtime supportato dalle librerie client di autenticazione Google.
FUNCTION_NAME=authenticated-function-codelab ENTRY_POINT=helloWorld
Per eseguire il deployment di una funzione Cloud Run direttamente su Cloud Run, esegui il seguente comando:
gcloud beta run deploy $FUNCTION_NAME \ --source . \ --function helloWorld \ --region $REGION \ --no-allow-unauthenticated
e poi salvare l'URL della funzione come variabile di ambiente da utilizzare in seguito.
FUNCTION_URL="$(gcloud run services describe $FUNCTION_NAME --region $REGION --format 'value(status.url)')"
Se preferisci eseguire il deployment come Cloud Functions 2ª gen., utilizza il seguente comando:
gcloud functions deploy nodejs-http-function \ --gen2 \ --runtime=nodejs20 \ --region=$REGION \ --source=. \ --entry-point=helloWorld \ --trigger-http \ --no-allow-unauthenticated
e poi puoi salvare l'URL della funzione come variabile di ambiente da utilizzare in un secondo momento.
FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --gen2 --region us-central1 --format='get(serviceConfig.uri)')"
Verifica che la funzione richieda l'autenticazione tentando di richiamarla come chiamante anonimo
Evocherai la funzione senza autenticazione per verificare di ricevere l'errore 403 previsto.
Da una riga di comando, esegui il seguente comando curl
:
curl -i $FUNCTION_URL
Verrà visualizzato il seguente risultato:
<html><head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>403 Forbidden</title> </head> <body text=#000000 bgcolor=#ffffff> <h1>Error: Forbidden</h1> <h2>Your client does not have permission to get URL <code>/</code> from this server.</h2> <h2></h2> </body></html>
Ora puoi esaminare tre scenari in cui puoi richiamare la tua funzione fornendo l'autenticazione.
4. Scenario 1: utilizzo del token di identità gcloud
In qualità di sviluppatore, ti servirà un modo per testare la funzione durante lo sviluppo locale. In questa sezione, eseguirai un rapido test per verificare che la funzione sia autenticata correttamente utilizzando la tua identità.
Verifica di aver eseguito l'autenticazione utilizzando gcloud
eseguendo il seguente comando:
gcloud auth list
Dovresti vedere un asterisco accanto all'identità attiva, ad esempio:
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
Puoi trovare ulteriori informazioni sulla configurazione di gcloud init e gcloud auth login nella documentazione.
Quindi, richiama la funzione e passale il token di identità.
curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token)"
Ora vedrai il risultato:
Hello World!
Risoluzione dei problemi
Se ricevi un errore 403 Forbidden, assicurati che la tua identità abbia il ruolo Invoker di Cloud Run. Puoi utilizzare la console IAM per verificare i ruoli assegnati a un'entità.
Sebbene l'utilizzo del tuo token di identità sia un modo rapido per testare la funzione durante lo sviluppo, l'autore della chiamata della funzione autenticata avrà bisogno dei ruoli appropriati; in caso contrario, l'autore della chiamata riceverà un errore 403 Forbidden.
Ti consigliamo di seguire il principio del privilegio minimo limitando il numero di identità e account di servizio che dispongono dei ruoli per invocare la funzione. Nel prossimo scenario, imparerai a creare un nuovo account di servizio e a concedergli i ruoli appropriati per richiamare la funzione.
5. Scenario 2: simulazione dell'identità di un account di servizio
In questo scenario, assumerai l'identità (ovvero acquisirai le autorizzazioni) di un account di servizio per richiamare una funzione durante lo sviluppo e il test in locale. Se usi l'identità di un account di servizio, puoi testare la tua funzione con le stesse credenziali dell'account di produzione.
In questo modo non solo verificherai i ruoli, ma seguirai anche il principio del privilegio minimo, evitando di concedere il ruolo Invoker di funzioni Cloud ad altre identità solo per scopi di test locali.
Ai fini di questo codelab, creerai un nuovo account di servizio con solo i ruoli per invocare la funzione creata in questo codelab.
Crea un nuovo service account
Per prima cosa, creerai un paio di variabili di ambiente aggiuntive per rappresentare gli account di servizio utilizzati nei comandi gcloud.
SERVICE_ACCOUNT_NAME="invoke-functions-codelab" SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com
A questo punto, crea l'account di servizio.
gcloud iam service-accounts create $SERVICE_ACCOUNT_NAME \ --display-name="Cloud Run function Authentication codelab"
Concedi all'account di servizio il ruolo Invoker di Cloud Run:
gcloud run services add-iam-policy-binding $FUNCTION_NAME \ --region=us-central1 \ --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \ --role='roles/run.invoker'
Esegui la chiamata alla funzione fingendo di essere l'account di servizio
A questo scopo, dovrai rubare l'identità dell'account di servizio appena creato ottenendo il token ID.
Aggiungi i ruoli richiesti per la rappresentazione
Per rubare l'identità di un account di servizio, il tuo account utente deve disporre del ruolo Creatore token account di servizio (roles/iam.serviceAccountTokenCreator) per generare un token ID per l'account di servizio.
Per concedere questo ruolo al tuo account utente attivo, puoi eseguire i seguenti comandi:
ACCOUNT_EMAIL=$(gcloud auth list --filter=status:ACTIVE --format="value(account)") gcloud iam service-accounts add-iam-policy-binding $SERVICE_ACCOUNT_ADDRESS \ --member user:$ACCOUNT_EMAIL \ --role='roles/iam.serviceAccountTokenCreator'
Utilizza il token ID dell'account di servizio
Attendi un paio di minuti per la propagazione delle autorizzazioni. Ora puoi invocare la funzione passando il token ID dell'account di servizio.
curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token --impersonate-service-account $SERVICE_ACCOUNT_ADDRESS)"
Verrà visualizzato quanto segue:
WARNING: This command is using service account impersonation. All API calls will be executed as [invoke-functions-codelab@<project-id>.iam.gserviceaccount.com]. Hello World!
6. Scenario 3: utilizza le librerie client di Google
Per questa ultima parte del codelab, eseguirai un piccolo servizio localmente per generare un token ID per un account di servizio e poi chiamerai la funzione in modo programmatico utilizzando le librerie client di Google Auth e le credenziali predefinite dell'applicazione (ADC). Per saperne di più sulle librerie client di Google, consulta la sezione Descrizione delle librerie client della documentazione.
L'utilizzo di ADC è particolarmente importante quando vuoi scrivere e testare la funzione localmente (ad esempio sul tuo laptop, in Cloud Shell e così via) mentre interagisci con altre risorse Google Cloud (ad esempio Cloud Storage, API Vision e così via). Per questo esempio, vedrai come un servizio richiama un'altra funzione che richiede l'autenticazione. Per ulteriori informazioni su ADC e sviluppo locale, consulta il post del blog Come sviluppare e testare le funzioni Cloud in locale | Blog di Google Cloud
Esegui il comando gcloud per rubare l'identità di un account di servizio
ADC trova automaticamente le credenziali in base all'ambiente dell'applicazione e le utilizza per autenticarsi alle API Google Cloud. Il flag -impersonate-service-account ti consente di rubare l'identità di un account di servizio utilizzandola per l'autenticazione con le API Google Cloud.
Per rubare l'identità di un account di servizio, puoi eseguire il seguente comando:
gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS
Ora stai eseguendo i comandi gcloud con quell'account di servizio invece che con la tua identità.
Crea ed esegui un servizio per richiamare una funzione autenticata
Ogni runtime ha la propria libreria client di autenticazione Google che puoi installare. Questo codelab illustra la procedura per creare ed eseguire un'app Node.js localmente.
Ecco i passaggi per Node.js:
- Crea una nuova directory
mkdir local-dev && cd $_
- Crea una nuova app Node.js
npm init -y
- Installa la libreria client di Google Auth
npm install google-auth-library
- Crea un file
index.js
- Recupera l'URL della funzione Cloud Run, che aggiungerai al codice nel passaggio successivo.
echo $FUNCTION_URL
- Aggiungi il seguente codice a index.js. Assicurati di modificare la variabile targetAudience nell'URL della funzione Cloud Run.
index.js
// Cloud Functions uses your function's url as the `targetAudience` value
const targetAudience = '<YOUR-CLOUD-RUN-FUNCTION-URL>';
// For Cloud Functions, endpoint(`url`) and `targetAudience` should be equal
const url = targetAudience;
const { GoogleAuth } = require('google-auth-library');
const auth = new GoogleAuth();
async function request() {
console.info(`request ${url} with target audience ${targetAudience}`);
// this call retrieves the ID token for the impersonated service account
const client = await auth.getIdTokenClient(targetAudience);
const res = await client.request({ url });
console.info(res.data);
}
request().catch(err => {
console.error(err.message);
process.exitCode = 1;
});
- Esegui l'app
node index.js
Dovresti vedere il messaggio "Hello World!".
Risoluzione dei problemi
Se viene visualizzato l'errore "Autorizzazione "iam.serviceAccounts.getOpenIdToken" negata per la risorsa (o potrebbe non esistere), attendi alcuni minuti per la propagazione del ruolo Creatore token account di servizio.
Se hai ricevuto l'errore Impossibile recuperare il token ID in questo ambiente, utilizza GCE o imposta la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS su un file JSON delle credenziali dell'account di servizio, potresti aver dimenticato di eseguire il comando
gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS
7. Complimenti!
Complimenti per aver completato il codelab.
Ti consigliamo di consultare la documentazione su come proteggere le funzioni Cloud Run.
Consigliamo anche questo blog post sullo sviluppo locale con le funzioni di Cloud Run per scoprire come sviluppare e testare la funzione Cloud Run nell'ambiente di sviluppo locale.
Argomenti trattati
- Come configurare l'autenticazione in una funzione Cloud Run e verificare che sia stata configurata correttamente
- Esegui una chiamata a una funzione autenticata da un ambiente di sviluppo locale fornendo il token per la tua identità gcloud
- Come creare un account di servizio e concedergli il ruolo appropriato per richiamare una funzione
- Come eseguire l'impersonificazione di un servizio da un ambiente di sviluppo locale con i ruoli appropriati per l'invocazione di una funzione
8. Esegui la pulizia
Per evitare addebiti involontari, ad esempio se questa funzione Cloud Functions viene richiamata inavvertitamente più volte rispetto all'allocazione mensile dei richiami delle funzioni Cloud Run nel livello senza costi, puoi eliminare la funzione Cloud Functions o il progetto creato nel passaggio 2.
Per interrompere la simulazione dell'identità dell'account di servizio, puoi accedere di nuovo utilizzando la tua identità:
gcloud auth application-default login
Per eliminare la funzione Cloud Run, vai alla console Cloud Run all'indirizzo https://console.cloud.google.com/functions/. Assicurati che il progetto creato nel passaggio 2 sia quello attualmente selezionato.
Seleziona la funzione my-authenticated-function di cui hai eseguito il deployment in precedenza. Quindi, premi Elimina.
Se scegli di eliminare l'intero progetto, puoi andare all'indirizzo https://console.cloud.google.com/cloud-resource-manager, selezionare il progetto che hai creato nel passaggio 2 e scegliere Elimina. Se elimini il progetto, dovrai modificare i progetti nel tuo Cloud SDK. Puoi visualizzare l'elenco di tutti i progetti disponibili eseguendo gcloud projects list
.