Résoudre les problèmes liés à Cloud Functions

Ce document décrit quelques-uns des problèmes courants que vous pouvez rencontrer et la manière de les résoudre.

Déploiement

La phase de déploiement constitue une source fréquente de problèmes. La plupart des problèmes que vous pouvez rencontrer lors du déploiement sont liés aux rôles et autorisations. D'autres ont pour origine une configuration incorrecte.

Un utilisateur disposant du rôle de lecteur ne peut pas déployer une fonction

Un utilisateur qui dispose du rôle de lecteur de projet ou de lecteur Cloud Functions ne bénéficie que d'un accès en lecture seule aux fonctions et aux détails des fonctions. Ces rôles ne sont pas autorisés à déployer de nouvelles fonctions.

Message d'erreur

Cloud Console

You need permissions for this action. Required permission(s): cloudfunctions.functions.create

SDK Cloud

ERROR: (gcloud.functions.deploy) PERMISSION_DENIED: Permission
'cloudfunctions.functions.sourceCodeSet' denied on resource
'projects/<PROJECT_ID>/locations/<LOCATION>` (or resource may not exist)

Solution

Attribuez à l'utilisateur un rôle doté de l'accès approprié.

Un utilisateur disposant du rôle de lecteur de projet ou de lecteur de fonction Cloud ne peut pas déployer une fonction

Pour déployer une fonction, un utilisateur doté du rôle de lecteur de projet, de développeur de fonction Cloud ou d'administrateur de fonction Cloud doit disposer d'un rôle supplémentaire.

Message d'erreur

Cloud Console

User does not have the iam.serviceAccounts.actAs permission on
<PROJECT_ID>@appspot.gserviceaccount.com required to create function.
You can fix this by running
'gcloud iam service-accounts add-iam-policy-binding <PROJECT_ID>@appspot.gserviceaccount.com --member=user: --role=roles/iam.serviceAccountUser'

SDK Cloud

ERROR: (gcloud.functions.deploy) ResponseError: status=[403], code=[Forbidden],
message=[Missing necessary permission iam.serviceAccounts.actAs for <USER>
on the service account <PROJECT_ID>@appspot.gserviceaccount.com. Ensure that
service account <PROJECT_ID>@appspot.gserviceaccount.com is a member of the
project <PROJECT_ID>, and then grant <USER> the role 'roles/iam.serviceAccountUser'.
You can do that by running
'gcloud iam service-accounts add-iam-policy-binding <PROJECT_ID>@appspot.gserviceaccount.com --member=<USER> --role=roles/iam.serviceAccountUser'
In case the member is a service account please use the prefix 'serviceAccount:' instead of 'user:'.]

Solution

Attribuez à l'utilisateur un rôle supplémentaire, le rôle IAM d'utilisateur du compte de service (roles/iam.serviceAccountUser), limité au compte de service d'exécution de Cloud Functions.

Le compte de service de déploiement ne contient pas le rôle d'agent de service nécessaire lors du déploiement de fonctions

Le service Cloud Functions utilise le compte de service de l'agent de service Cloud Functions (service-<PROJECT_NUMBER>@gcf-admin-robot.iam.gserviceaccount.com) pour effectuer des actions d'administration sur votre projet. Le rôle cloudfunctions.serviceAgent Cloud Functions est attribué par défaut à ce compte de service. Ce rôle est nécessaire pour les intégrations Cloud Pub/Sub, Cloud IAM, Cloud Storage et Firebase. Si vous avez modifié le rôle de ce compte de service, le déploiement échoue.

Message d'erreur

Cloud Console

Missing necessary permission resourcemanager.projects.getIamPolicy for
serviceAccount:service-<PROJECT_NUMBER>@gcf-admin-robot.iam.gserviceaccount.com on project <PROJECT_ID>.
Please grant serviceAccount:service-<PROJECT_NUMBER>@gcf-admin-robot.iam.gserviceaccount.com
the roles/cloudfunctions.serviceAgent role. You can do that by running
'gcloud projects add-iam-policy-binding <PROJECT_ID> --member=serviceAccount:service-<PROJECT_NUMBER>@gcf-admin-robot.iam.gserviceaccount.com --role=roles/cloudfunctions.serviceAgent'

SDK Cloud

ERROR: (gcloud.functions.deploy) OperationError: code=7,
message=Missing necessary permission resourcemanager.projects.getIamPolicy
for serviceAccount:service-<PROJECT_NUMBER>@gcf-admin-robot.iam.gserviceaccount.com
on project <PROJECT_ID>. Please grant
serviceAccount:service-<PROJECT_NUMBER>@gcf-admin-robot.iam.gserviceaccount.com
the roles/cloudfunctions.serviceAgent role. You can do that by running
'gcloud projects add-iam-policy-binding <PROJECT_ID> --member=serviceAccount:service-<PROJECT_NUMBER>@gcf-admin-robot.iam.gserviceaccount.com --role=roles/cloudfunctions.serviceAgent'

Solution

Réinitialisez ce compte de service pour rétablir le rôle par défaut.

Le compte de service de déploiement ne dispose pas des autorisations Pub/Sub nécessaires lors du déploiement d'une fonction d'arrière-plan

Le service Cloud Functions utilise le compte de service de l'agent de service Cloud Functions (service-<PROJECT_NUMBER>@gcf-admin-robot.iam.gserviceaccount.com) pour effectuer des tâches d'administration. Le rôle cloudfunctions.serviceAgent Cloud Functions est attribué par défaut à ce compte de service. Pour déployer des fonctions d'arrière-plan, le service Cloud Functions doit accéder à Cloud Pub/Sub pour configurer les sujets et les abonnements. Si le rôle attribué au compte de service est modifié et que les autorisations appropriées ne sont pas accordées d'une autre manière, le service Cloud Functions ne peut pas accéder à Cloud Pub/Sub et le déploiement échoue.

Message d'erreur

Cloud Console

Failed to configure trigger PubSub projects/<PROJECT_ID>/topics/<FUNCTION_NAME>

SDK Cloud

ERROR: (gcloud.functions.deploy) OperationError: code=13,
message=Failed to configure trigger PubSub projects/<PROJECT_ID>/topics/<FUNCTION_NAME>

Solution

Vous pouvez :

  • Réinitialiser ce compte de service pour rétablir le rôle par défaut

    ou

  • Accorder manuellement les autorisations pubsub.subscriptions.* et pubsub.topics.* à votre compte de service

L'utilisateur ne dispose pas des autorisations nécessaires sur le compte de service d'exécution lors du déploiement d'une fonction

Dans les environnements où plusieurs fonctions accèdent à des ressources différentes, il est courant d'utiliser des identités par fonction, avec des comptes de service d'exécution nommés plutôt que le compte de service d'exécution par défaut. (PROJECT_ID@appspot.gserviceaccount.com).

Toutefois, pour utiliser un compte de service d'exécution autre que celui par défaut, l'utilisateur à l'origine du déploiement doit disposer de l'autorisation iam.serviceAccounts.actAs sur cet autre compte de service d'exécution. Cette autorisation est automatiquement accordée à un utilisateur qui crée un compte de service d'exécution autre que celui par défaut. Pour que d'autres "déployeurs" puissent en disposer, elle doit leur être accordée par un utilisateur disposant des autorisations appropriées.

Message d'erreur

SDK Cloud

ERROR: (gcloud.functions.deploy) ResponseError: status=[400], code=[Bad Request],
message=[Invalid function service account requested: <SERVICE_ACCOUNT_NAME@<PROJECT_ID>.iam.gserviceaccount.com]

Solution

Attribuez à l'utilisateur le rôle roles/iam.serviceAccountUser sur le compte de service d'exécution qui n'est pas celui par défaut. Ce rôle inclut l'autorisation iam.serviceAccounts.actAs.

Le compte de service d'exécution ne dispose pas des autorisations nécessaires sur le bucket du projet lors du déploiement d'une fonction

Les fonctions Cloud Functions ne peuvent être déclenchées par des événements qu'à partir de buckets Cloud Storage situés dans le même projet Google Cloud Platform. En outre, le compte de service de l'agent de service Cloud Functions (service-<PROJECT_NUMBER>@gcf-admin-robot.iam.gserviceaccount.com) doit disposer d'un rôle cloudfunctions.serviceAgent sur votre projet.

Message d'erreur

Cloud Console

Deployment failure: Insufficient permissions to (re)configure a trigger
(permission denied for bucket <BUCKET_ID>). Please, give owner permissions
to the editor role of the bucket and try again.

SDK Cloud

ERROR: (gcloud.functions.deploy) OperationError: code=7, message=Insufficient
permissions to (re)configure a trigger (permission denied for bucket <BUCKET_ID>).
Please, give owner permissions to the editor role of the bucket and try again.

Solution

Vous pouvez :

  • Réinitialiser ce compte de service pour rétablir le rôle par défaut

    ou

  • Attribuer le rôle cloudfunctions.serviceAgent au compte de service d'exécution

    ou

  • Attribuer au compte de service d'exécution les autorisations storage.buckets.{get, update} et resourcemanager.projects.get

Un utilisateur doté du rôle d'éditeur de projet ne peut pas rendre une fonction disponible publiquement

Pour garantir que les développeurs non autorisés ne peuvent pas modifier les paramètres d'authentification associés aux appels de fonctions, il est nécessaire que l'utilisateur ou le service qui déploie la fonction dispose de l'autorisation cloudfunctions.functions.setIamPolicy.

Message d'erreur

SDK Cloud

ERROR: (gcloud.functions.add-iam-policy-binding) ResponseError: status=[403], code=[Forbidden], message=[Permission 'cloudfunctions.functions.setIamPolicy' denied on resource 'projects/<PROJECT_ID>/locations/<LOCATION>/functions/<FUNCTION_NAME> (or resource may not exist).]

Solution

Vous pouvez :

Échec du déploiement de la fonction, car Cloud Build n'est pas compatible avec VPC-SC

Cloud Functions crée votre code source dans un conteneur exécutable à l'aide de Cloud Build. Pour utiliser Cloud Functions avec VPC Service Controls, vous devez configurer un niveau d'accès pour le compte de service Cloud Build dans votre périmètre de service :

Message d'erreur

Cloud Console

Vous rencontrez l'un des messages d'erreur ci-dessous :

Error in the build environment

OR

Unable to build your function due to VPC Service Controls. The Cloud Build
service account associated with this function needs an appropriate access
level on the service perimeter. Please grant access to the Cloud Build
service account: '{PROJECT_NUMBER}@cloudbuild.gserviceaccount.com' by following
the instructions at
https://cloud.google.com/functions/docs/securing/using-vpc-service-controls#grant-build-access"

SDK Cloud

Vous rencontrez l'un des messages d'erreur ci-dessous :

ERROR: (gcloud.functions.deploy) OperationError: code=13, message=Error in
the build environment

OR

Unable to build your function due to VPC Service Controls. The Cloud Build
service account associated with this function needs an appropriate access
level on the service perimeter. Please grant access to the Cloud Build
service account: '{PROJECT_NUMBER}@cloudbuild.gserviceaccount.com' by
following the instructions at
https://cloud.google.com/functions/docs/securing/using-vpc-service-controls#grant-build-access"

Solution

Si la section VPC Service Controls des journaux d'audit des ressources de votre projet indique "Request is prohibited by organization's policy" (La requête est interdite par une règle de l'organisation) et que vous disposez d'un libellé Cloud Storage, vous devez accorder au compte de service Cloud Build l'accès au périmètre de VPC Service Controls.

Échec du déploiement de la fonction, car un point d'entrée a été incorrectement spécifié

Le déploiement de Cloud Functions peut échouer si le point d'entrée vers votre code (le nom de la fonction exportée) n'est pas correctement spécifié.

Message d'erreur

Cloud Console

Deployment failure: Function failed on loading user code. Error message:
Error: please examine your function logs to see the error cause:
https://cloud.google.com/functions/docs/monitoring/logging#viewing_logs

SDK Cloud

ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Function
failed on loading user code. Error message: Please examine your function
logs to see the error cause:
https://cloud.google.com/functions/docs/monitoring/logging#viewing_logs

Solution

Votre code source doit contenir un point d'entrée de fonction qui a été correctement spécifié dans votre déploiement via Cloud Console ou le SDK Cloud.

Échec du déploiement de la fonction lors de l'exécution du champ d'application global de la fonction

Cette erreur indique qu'un problème est lié au code. Le pipeline de déploiement a fini de déployer la fonction, mais a échoué à la dernière étape en envoyant une vérification d'état à la fonction. Cette vérification d'état est destinée à exécuter le champ d'application global d'une fonction, ce qui peut générer une exception, un plantage ou un dépassement de délai. Le champ d'application global est l'endroit où vous chargez généralement les bibliothèques et initialisez les clients.

Message d'erreur

Dans les journaux Cloud Logging : "La fonction a échoué lors du chargement du code utilisateur. Cela est probablement dû à un bug dans le code utilisateur."

Solution

Pour afficher un message d'erreur plus détaillé, consultez les journaux des builds de votre fonction, ainsi que les journaux d'exécution de la fonction. Si vous ne comprenez pas pourquoi votre fonction n'a pas réussi à exécuter son champ d'application global, envisagez de déplacer temporairement le code dans l'appel de la requête, en utilisant l'initialisation différée des variables globales. Cela vous permet d'ajouter des entrées de journal supplémentaires à vos bibliothèques clientes, qui pourraient expirer lors de leur instanciation (surtout si elles appellent d'autres services), ou pour éviter tout plantage/toute génération d'exceptions.

Diffusion

La phase de diffusion peut également constituer une source d'erreurs.

Erreur d'autorisation de diffusion, car la fonction est privée

Cloud Functions vous permet de déclarer des fonctions private, c'est-à-dire de restreindre l'accès aux utilisateurs finaux et aux comptes de service disposant de l'autorisation appropriée. Par défaut, les fonctions déployées sont définies comme privées. Ce message d'erreur indique que le demandeur n'est pas autorisé à appeler la fonction.

Message d'erreur

Code de réponse d'erreur HTTP : 403 Forbidden

Corps de la réponse d'erreur HTTP : Error: Forbidden Votre client ne dispose pas des autorisations nécessaires pour accéder à l'URL /<FUNCTION_NAME> à partir de ce serveur.

Solution

Vous pouvez :

Erreur d'autorisation de diffusion due à la configuration "Autoriser uniquement le trafic interne"

Les paramètres d'entrée limitent les appels d'une fonction HTTP par des ressources extérieures à votre projet Google Cloud ou au périmètre de service VPC Service Controls. Lorsque le paramètre "Autoriser le trafic interne uniquement" est configuré pour le trafic réseau entrant, ce message d'erreur indique que seules les requêtes provenant des réseaux VPC du même projet ou du même périmètre VPC Service Controls sont autorisées.

Message d'erreur

Code de réponse d'erreur HTTP : 403 Forbidden

Corps de la réponse d'erreur HTTP : Error 403 (Forbidden) 403. Il s'agit d'une erreur. L'accès est interdit. Nous n'en savons pas plus.

Solution

Vous pouvez opter pour les solutions suivantes :

  • Vous assurer que la requête provient bien de votre projet Google Cloud ou de votre périmètre de service VPC Service Controls

    ou

  • Modifier les paramètres d'entrée pour autoriser tout le trafic pour la fonction

L'appel de fonction ne contient pas d'identifiants d'authentification valides

L'appel d'une fonction Cloud Functions configurée avec un accès restreint nécessite un jeton d'ID. Les jetons d'accès ou les jetons d'actualisation ne fonctionnent pas.

Message d'erreur

Code de réponse d'erreur HTTP : 401 (Non autorisé)

Corps de la réponse d'erreur HTTP : Votre client n'est pas autorisé à accéder à l'URL demandée.

Solution

Assurez-vous que vos requêtes incluent un en-tête Authorization: Bearer ID_TOKEN et qu'il s'agit d'un jeton d'ID, et non d'un jeton d'accès ou d'actualisation. Si vous générez ce jeton manuellement avec la clé privée d'un compte de service, vous devez remplacer le jeton JWT autosigné par un jeton d'identité signé par Google, en suivant ce guide.

L'application plante et l'exécution de la fonction échoue

Cette erreur indique que le processus en cours d'exécution de votre fonction est mort. Cela est généralement dû à un plantage de l'environnement d'exécution en raison de problèmes liés au code de la fonction. Cela peut également se produire lorsqu'un interblocage ou une autre condition dans le code de votre fonction entraîne l'absence de réponse de l'environnement d'exécution aux requêtes entrantes.

Message d'erreur

Dans les journaux Cloud Logging : "L'infrastructure ne peut pas communiquer avec la fonction. Le code fourni par l'utilisateur a probablement été planté ou bloqué."

Solution

Différents environnements d'exécution peuvent planter en fonction de différents scénarios. Pour trouver la cause première, affichez des journaux détaillés au niveau du débogage, vérifiez la logique de votre application et testez les cas spéciaux.

L'environnement d'exécution Python37 de Cloud Functions est actuellement soumis à une limite connue sur le taux qui peut gérer la journalisation. Si les instructions de journalisation d'une instance d'exécution Python37 sont écrites à un taux suffisamment élevé, cette erreur peut se produire. Les versions d'exécution Python antérieures à 3.8 n'ont pas cette limite. Pour éviter ce problème, nous encourageons les utilisateurs à passer à une version plus récente de l'environnement d'exécution Python.

Si vous avez toujours des doutes sur la cause de l'erreur, veuillez consulter notre page d'assistance.

La fonction s'arrête en cours d'exécution ou continue de s'exécuter une fois votre code terminé

Certains environnements d'exécution Cloud Functions permettent aux utilisateurs d'exécuter des tâches asynchrones. Si votre fonction crée ces tâches, elle doit également attendre explicitement que ces tâches soient terminées. Sinon, votre fonction pourrait cesser de s'exécuter au mauvais moment.

Le comportement de l'erreur

Votre fonction présente l'un des comportements suivants :

  • Votre fonction s'arrête pendant l'exécution des tâches asynchrones, mais avant la fin du délai avant expiration spécifié.
  • Votre fonction ne s'arrête pas une fois ces tâches terminées et continue de s'exécuter jusqu'à la fin du délai d'expiration.

Solution

Si votre fonction s'arrête prématurément, vous devez vous assurer que toutes les tâches asynchrones de votre fonction sont terminées avant d'effectuer l'une des opérations suivantes :

  • renvoyer une valeur
  • résoudre ou refuser un objet Promise renvoyé (fonctions Node.js uniquement)
  • générer des exceptions ou des erreurs non interceptées
  • envoyer une réponse HTTP
  • appeler une fonction de rappel

Si votre fonction ne s'arrête pas une fois toutes les tâches asynchrones terminées, vous devez vérifier qu'elle transmet correctement l'information à Cloud Functions une fois qu'elle terminée. Veillez en particulier à effectuer l'une des opérations répertoriées ci-dessus dès que votre fonction a terminé ses tâches asynchrones.

Tas de mémoire JavaScript saturé

Pour Node.js 12 et versions ultérieures, les fonctions dont les limites de mémoire peuvent être définies au-delà de 2 Gio exigent que les utilisateurs configurent NODE_OPTIONS pour qu'il dispose de max_old_space_size afin que la limite du tas de mémoire JavaScript soit équivalente à la limite de mémoire de la fonction.

Message d'erreur

Cloud Console

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

Solution

Déployez la fonction Node.js 12+ avec le paramètre NODE_OPTIONS configuré pour que max_old_space_size soit défini sur la limite de mémoire de votre fonction. Exemple :

gcloud functions deploy envVarMemory \
--runtime nodejs12 \
--set-env-vars NODE_OPTIONS="--max_old_space_size=8Gi" \
--memory 8Gi \
--trigger-http

Logging

La configuration de la journalisation à des fins de détection des problèmes peut elle-même en engendrer d'autres.

Les entrées de journal n'ont pas de niveaux de gravité des journaux, ou ceux-ci sont incorrects.

Par défaut, Cloud Functions inclut la journalisation d'exécution simple. Les journaux écrits dans stdout ou stderr s'affichent automatiquement dans Cloud Console. Par défaut, ces entrées de journal ne contiennent que des messages de chaîne simples.

Erreur

Les niveaux de gravité sont absents ou incorrects dans les journaux.

Solution

Pour inclure les niveaux de gravité dans les journaux, vous devez plutôt envoyer une entrée de journal structurée.

Gérer ou consigner les exceptions différemment en cas de plantage

Vous souhaiterez peut-être personnaliser la manière dont vous gérez et consignez les informations sur les plantages.

Solution

Encapsulez votre fonction dans un bloc try/catch pour personnaliser la gestion des exceptions et les traces de la pile de journalisation.

Exemple


import logging
import traceback
def try_catch_log(wrapped_func):
  def wrapper(*args, **kwargs):
    try:
      response = wrapped_func(*args, **kwargs)
    except Exception:
      # Replace new lines with spaces so as to prevent several entries which
      # would trigger several errors.
      error_message = traceback.format_exc().replace('\n', '  ')
      logging.error(error_message)
      return 'Error';
    return response;
  return wrapper;

#Example hello world function
@try_catch_log
def python_hello_world(request):
  request_args = request.args

  if request_args and 'name' in request_args:
    1 + 's'
  return 'Hello World!'

Journaux trop volumineux dans Node.js 10 et versions ultérieures, Python 3.8, Go 1.13 et Java 11

La taille maximale d'une entrée de journal standard dans ces environnements d'exécution est de 105 Kio.

Solution

Veillez à envoyer des entrées de journal qui ne dépassent pas cette limite.

Les journaux Cloud Functions n'apparaissent pas via le récepteur du routeur de journaux

Les entrées de journal sont acheminées vers leurs différentes destinations à l'aide des récepteurs du routeur de journaux.

Capture d&#39;écran du routeur de journaux dans Cloud Console avec l&#39;option &quot;Afficher les détails du récepteur&quot; encadrée

Les paramètres incluent les filtres d'exclusion, qui définissent les entrées qui peuvent simplement être supprimées.

Capture d&#39;écran de la fenêtre pop-up contenant les détails du récepteur du routeur de journaux de Cloud Console et affichant un filtre d&#39;exclusion

Solution

Assurez-vous qu'aucun filtre d'exclusion n'est défini pour resource.type="cloud_functions".