Sécuriser les modèles de ML et la propriété intellectuelle à l'aide de l'espace confidentiel

1. Présentation

Confidential Space offre un environnement sécurisé permettant de collaborer entre plusieurs parties. Cet atelier de programmation explique comment utiliser Confidential Space pour protéger la propriété intellectuelle sensible, comme les modèles de machine learning.

Dans cet atelier de programmation, vous allez utiliser Confidential Space pour permettre à une entreprise de partager en toute sécurité son modèle de machine learning propriétaire avec une autre entreprise qui souhaite l'utiliser. Plus précisément, l'entreprise Primus dispose d'un modèle de machine learning qui ne serait distribué qu'à une charge de travail exécutée dans Confidential Space, ce qui lui permet de garder un contrôle total sur sa propriété intellectuelle. Secundus de l'entreprise sera l'opérateur de la charge de travail et exécutera la charge de travail de machine learning dans un espace confidentiel. Secundus charge ce modèle et exécute une inférence à l'aide d'échantillons de données appartenant à Secundus.

Ici, Primus est l'auteur de la charge de travail qui écrit le code de la charge de travail, et un collaborateur qui souhaite protéger sa propriété intellectuelle contre Secundus, un opérateur de charge de travail non approuvé. Secundus est l'opérateur de la charge de travail de machine learning.

5a86c47d935da998.jpeg

Points abordés

  • Comment configurer un environnement dans lequel une partie peut partager son modèle de ML propriétaire avec une autre partie sans perdre le contrôle de sa propriété intellectuelle

Prérequis

Rôles impliqués dans la configuration de Confidential Space

Dans cet atelier de programmation, Company Primus sera le propriétaire des ressources et l'auteur de la charge de travail, et sera responsable des tâches suivantes:

  1. Configurer les ressources cloud requises avec un modèle de machine learning
  2. Écrire le code de la charge de travail
  3. Publier l'image de la charge de travail
  4. Configurer la stratégie de pool d'identités de charge de travail pour protéger le modèle de ML contre un opérateur non approuvé

Secundus Company en sera l'opérateur et sera responsable:

  1. Configurer les ressources cloud requises pour stocker les exemples d'images utilisés par la charge de travail et les résultats
  2. Exécuter la charge de travail de ML dans un espace confidentiel à l'aide du modèle fourni par Primus

Fonctionnement de Confidential Space

Lorsque vous exécutez la charge de travail dans un espace confidentiel, le processus suivant a lieu à l'aide des ressources configurées:

  1. La charge de travail demande un jeton d'accès Google général pour $PRIMUS_SERVICEACCOUNT à partir du pool Workload Identity. Elle offre un jeton de service Attestation Verifier avec des revendications de charge de travail et d'environnement.
  2. Si les revendications de mesure de la charge de travail dans le jeton du service Attestation Verifier correspondent à la condition d'attribut dans l'atelier en cours, le jeton d'accès pour $PRIMUS_SERVICEACCOUNT. est renvoyé.
  3. La charge de travail utilise le jeton d'accès au compte de service associé à $PRIMUS_SERVICEACCOUNT pour accéder au modèle de machine learning stocké dans le bucket $PRIMUS_INPUT_STORAGE_BUCKET.
  4. La charge de travail effectue une opération sur les données appartenant à Secundus, et cette charge de travail est exploitée et exécutée par Secundus dans son projet.
  5. La charge de travail utilise le compte de service $WORKLOAD_SERVICEACCOUNT pour écrire les résultats de cette opération dans le bucket $SECUNDUS_RESULT_STORAGE_BUCKET.

2. Configurer les ressources cloud

Avant de commencer

  • Clonez ce dépôt à l'aide de la commande ci-dessous pour obtenir les scripts requis pour cet atelier de programmation.
git clone https://github.com/GoogleCloudPlatform/confidential-space.git
  • Changez de répertoire pour cet atelier de programmation.
cd confidential-space/codelabs/ml_model_protection/scripts
  • Assurez-vous d'avoir défini les variables d'environnement requises pour le projet, comme indiqué ci-dessous. Pour en savoir plus sur la configuration d'un projet GCP, consultez cet atelier de programmation. Vous pouvez vous reporter à cette page pour savoir comment récupérer l'ID de projet, et pour savoir en quoi il est différent du nom et du numéro du projet.
export PRIMUS_PROJECT_ID=<GCP project id of Primus>
export SECUNDUS_PROJECT_ID=<GCP project id of Secundus>
  • Activez la facturation pour vos projets.
  • Activez l'API d'informatique confidentielle et les API suivantes pour les deux projets.
gcloud services enable \
    cloudapis.googleapis.com \
    cloudresourcemanager.googleapis.com \
    cloudshell.googleapis.com \
    container.googleapis.com \
    containerregistry.googleapis.com \
    iam.googleapis.com \
    confidentialcomputing.googleapis.com
  • Attribuez des valeurs aux variables pour les noms de ressources spécifiés ci-dessus à l'aide de la commande suivante. Ces variables vous permettent de personnaliser les noms de ressources selon vos besoins et d'utiliser les ressources existantes si elles ont déjà été créées. (exemple : export PRIMUS_INPUT_STORAGE_BUCKET='my-input-bucket')
  1. Vous pouvez définir les variables suivantes avec les noms de ressources cloud existants dans le projet Primus. Si la variable est définie, la ressource cloud existante correspondante du projet Primus est utilisée. Si la variable n'est pas définie, le nom de la ressource cloud est généré à partir de project-name et une nouvelle ressource cloud est créée avec ce nom. Voici les variables acceptées pour les noms de ressources:

$PRIMUS_INPUT_STORAGE_BUCKET

Bucket qui stocke le modèle de machine learning de Primus.

$PRIMUS_WORKLOAD_IDENTITY_POOL

Pool d'identités de charge de travail (WIP) de Primus qui valide les affirmations.

$PRIMUS_WIP_PROVIDER

Fournisseur de pool d'identités de charge de travail de Primus qui inclut la condition d'autorisation à utiliser pour les jetons signés par le service Attestation Verifier.

$PRIMUS_SERVICE_ACCOUNT

Compte de service Primus utilisé par $PRIMUS_WORKLOAD_IDENTITY_POOL pour accéder aux ressources protégées (modèle de ML de cet atelier de programmation). Dans cette étape, il est autorisé à lire le modèle de machine learning stocké dans le bucket $PRIMUS_INPUT_STORAGE_BUCKET.

$PRIMUS_ARTIFACT_REPOSITORY

Dépôt d'artefacts dans lequel l'image Docker de la charge de travail sera transférée.

  1. Vous pouvez définir les variables suivantes avec des noms de ressources cloud existants dans le projet Secundus. Si la variable est définie, la ressource cloud existante correspondante du projet Secundus est utilisée. Si la variable n'est pas définie, le nom de la ressource cloud est généré à partir du nom du projet et une ressource cloud est créée avec ce nom. Voici les variables acceptées pour les noms de ressources:

$SECUNDUS_INPUT_STORAGE_BUCKET

Bucket qui stocke les exemples d'images que Secundus souhaite classer à l'aide du modèle fourni par Primus.

$SECUNDUS_RESULT_STORAGE_BUCKET

Bucket qui stocke les résultats de la charge de travail.

$WORKLOAD_IMAGE_NAME

Nom de l'image de conteneur de la charge de travail.

$WORKLOAD_IMAGE_TAG

Tag de l'image du conteneur de la charge de travail.

$WORKLOAD_SERVICE_ACCOUNT

Compte de service autorisé à accéder à la Confidential VM qui exécute la charge de travail.

  • Vous devez disposer de certaines autorisations pour ces deux projets. Pour savoir comment attribuer des rôles IAM à l'aide de la console GCP, consultez ce guide:
  • Pour $PRIMUS_PROJECT_ID, vous aurez besoin de l'administrateur de l'espace de stockage, d'un administrateur Artifact Registry, d'un administrateur de compte de service et d'un administrateur IAM de pools d'identités de charge de travail.
  • Pour $SECUNDUS_PROJECT_ID, vous aurez besoin des rôles d'administrateur Compute, d'administrateur de l'espace de stockage, d'administrateur de compte de service, d'administrateur IAM de pools d'identités de charge de travail et d'administrateur de sécurité (facultatif).
  • Exécutez le script suivant pour définir les noms de variables restants sur des valeurs basées sur l'ID de votre projet pour les noms de ressources.
source config_env.sh

Configurer les ressources de l'entreprise Primus

Lors de cette étape, vous allez configurer les ressources cloud requises pour Primus. Exécutez le script suivant pour configurer les ressources pour Primus. Les ressources suivantes seront créées lors de l'exécution du script:

  • Bucket Cloud Storage ($PRIMUS_INPUT_STORAGE_BUCKET) pour stocker le modèle de machine learning de Primus.
  • Pool d'identités de charge de travail ($PRIMUS_WORKLOAD_IDENTITY_POOL) pour valider les revendications en fonction des conditions d'attributs configurées sous son fournisseur.
  • Compte de service ($PRIMUS_SERVICEACCOUNT) associé au pool d'identités de charge de travail ($PRIMUS_WORKLOAD_IDENTITY_POOL) mentionné ci-dessus, disposant d'un accès IAM pour lire les données du bucket Cloud Storage (avec le rôle objectViewer) et pour connecter ce compte de service au pool d'identités de charge de travail (avec le rôle roles/iam.workloadIdentityUser).

Pour la configuration des ressources cloud, nous allons utiliser un modèle TensorFlow. Nous pouvons enregistrer l'intégralité du modèle, y compris son architecture, ses pondérations et sa configuration d'entraînement, dans une archive ZIP. Pour les besoins de cet atelier de programmation, nous utiliserons le modèle MobileNet V1 entraîné sur l'ensemble de données ImageNet disponible ici.

./setup_primus_company_resources.sh

Le script mentionné ci-dessus va configurer la ressource cloud. Nous allons maintenant télécharger et publier le modèle dans le bucket Cloud Storage créé par le script.

  1. Pour télécharger le modèle pré-entraîné, cliquez ici.
  2. Une fois le fichier téléchargé, renommez-le model.tar.gz.
  3. Publiez le fichier model.tar.gz dans le bucket Cloud Storage à l'aide de la commande suivante depuis le répertoire contenant le fichier model.tar.gz.
gsutil cp model.tar.gz gs://${PRIMUS_INPUT_STORAGE_BUCKET}/

Configurer des ressources d'entreprise Secundus

Lors de cette étape, vous allez configurer les ressources cloud requises pour Secundus. Exécutez le script suivant pour configurer les ressources pour Secundus. Lors de ces étapes, les ressources suivantes seront créées:

  • Bucket Cloud Storage ($SECUNDUS_INPUT_STORAGE_BUCKET) où stocker les exemples d'images pour exécuter des inférences par Secundus.
  • Bucket Cloud Storage ($SECUNDUS_RESULT_STORAGE_BUCKET) pour stocker le résultat de l'exécution de la charge de travail de ML par Secundus.

Des exemples d'images sont disponibles sur cette page pour cet atelier de programmation.

./setup_secundus_company_resources.sh

3. Créer une charge de travail

Créer un compte de service de charge de travail

Vous allez maintenant créer un compte de service pour la charge de travail avec les rôles et les autorisations requis. Exécutez le script suivant pour créer un compte de service de charge de travail dans le projet Secundus. Ce compte de service sera utilisé par la VM qui exécute la charge de travail de ML.

Ce compte de service de charge de travail ($WORKLOAD_SERVICEACCOUNT) disposera des rôles suivants:

  • confidentialcomputing.workloadUser pour obtenir un jeton d'attestation
  • logging.logWriter pour écrire des journaux dans Cloud Logging.
  • objectViewer pour lire les données dans le bucket Cloud Storage $SECUNDUS_INPUT_STORAGE_BUCKET.
  • objectUser pour écrire le résultat de la charge de travail dans le bucket Cloud Storage $SECUNDUS_RESULT_STORAGE_BUCKET.
./create_workload_service_account.sh

Créer une charge de travail

Lors de cette étape, vous allez créer une image Docker de charge de travail. La charge de travail sera écrite par Primus. La charge de travail utilisée dans cet atelier de programmation est du code Python de machine learning qui accède au modèle de ML stocké dans le bucket de stockage de Primus et exécute des inférences avec les exemples d'images stockés dans un bucket de stockage.

Le modèle de machine learning stocké dans le bucket de stockage de Primus ne serait accessible qu'aux charges de travail remplissant les conditions d'attribut requises. Ces conditions d'attribut sont décrites plus en détail dans la section suivante, portant sur l'autorisation de la charge de travail.

Voici la méthode run_inference() de la charge de travail qui sera créée et utilisée dans cet atelier de programmation. Vous trouverez l'intégralité du code de la charge de travail sur cette page.

def run_inference(image_path, model):
  try:
    # Read and preprocess the image
    image = tf.image.decode_image(tf.io.read_file(image_path), channels=3)
    image = tf.image.resize(image, (128, 128))
    image = tf.image.convert_image_dtype(image, tf.float32)
    image = tf.expand_dims(image, axis=0)

    # Get predictions from the model
    predictions = model(image)
    predicted_class = np.argmax(predictions)

    top_k = 5
    top_indices = np.argsort(predictions[0])[-top_k:][::-1]

    # Convert top_indices to a TensorFlow tensor
    top_indices_tensor = tf.convert_to_tensor(top_indices, dtype=tf.int32)

    # Use TensorFlow tensor for indexing
    top_scores = tf.gather(predictions[0], top_indices_tensor)

    return {
        "predicted_class": int(predicted_class),
        "top_k_predictions": [
            {"class_index": int(idx), "score": float(score)}
            for idx, score in zip(top_indices, top_scores)
        ],
    }
  except Exception as e:
    return {"error": str(e)}

Exécutez le script suivant pour créer une charge de travail dans laquelle s'effectuent les étapes suivantes:

  • Créez Artifact Registry($PRIMUS_ARTIFACT_REGISTRY) appartenant à Primus.
  • Mettez à jour le code de la charge de travail avec les noms de ressources requis.
  • Créez la charge de travail de ML et créez un Dockerfile pour créer une image Docker du code de la charge de travail. Voici le Dockerfile utilisé pour cet atelier de programmation.
  • Créez et publiez l'image Docker dans Artifact Registry ($PRIMUS_ARTIFACT_REGISTRY) appartenant à Primus.
  • Accorder l'autorisation de lecture à $WORKLOAD_SERVICEACCOUNT pour $PRIMUS_ARTIFACT_REGISTRY. Cette opération est nécessaire pour que le conteneur de charge de travail puisse extraire l'image Docker de la charge de travail d'Artifact Registry.
./create_workload.sh

En outre, les charges de travail peuvent être codées pour s'assurer qu'elles chargent la version attendue du modèle de machine learning, en vérifiant le hachage ou la signature du modèle avant de l'utiliser. Ces vérifications supplémentaires ont l'avantage de garantir l'intégrité du modèle de machine learning. Ainsi, l'opérateur de charge de travail doit également mettre à jour l'image de la charge de travail ou ses paramètres lorsque la charge de travail est censée utiliser différentes versions du modèle de ML.

4. Autoriser et exécuter la charge de travail

Autoriser la charge de travail

Primus souhaite autoriser les charges de travail à accéder à son modèle de machine learning en fonction des attributs des ressources suivantes:

  • Problème: code validé
  • Emplacement: environnement sécurisé.
  • Qui: opérateur de confiance

Primus utilise la fédération d'identité de charge de travail pour appliquer une règle d'accès basée sur ces exigences. La fédération d'identité de charge de travail vous permet de spécifier des conditions d'attribut. Ces conditions limitent les identités pouvant s'authentifier auprès du pool d'identités de charge de travail (WIP). Vous pouvez ajouter le service Attestation Verifier à l'étape WIP en tant que fournisseur de pool d'identités de charge de travail pour présenter les mesures et appliquer la règle.

Le pool d'identités de charge de travail a déjà été créé précédemment lors de l'étape de configuration des ressources cloud. Primus va maintenant créer un fournisseur de pool d'identités de charge de travail OIDC. Le --attribute-condition spécifié autorise l'accès au conteneur de charge de travail. Cela nécessite :

  • Problème: dernière version de $WORKLOAD_IMAGE_NAME importée dans le dépôt $PRIMUS_ARTIFACT_REPOSITORY.
  • Emplacement: l'environnement d'exécution sécurisé Confidential Space s'exécute sur l'image de VM Confidential Space entièrement compatible.
  • Qui: compte de service Secundus $WORKLOAD_SERVICE_ACCOUNT.
export WORKLOAD_IMAGE_DIGEST=$(docker images digests ${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/${PRIMUS_PROJECT_ID}/${PRIMUS_ARTIFACT_REPOSITORY}/${WORKLOAD_IMAGE_NAME}:${WORKLOAD_IMAGE_TAG}| awk 'NR>1{ print $3 }')
gcloud config set project $PRIMUS_PROJECT_ID
gcloud iam workload-identity-pools providers create-oidc $PRIMUS_WIP_PROVIDER \
  --location="global" \
  --workload-identity-pool="$PRIMUS_WORKLOAD_IDENTITY_POOL" \
  --issuer-uri="https://confidentialcomputing.googleapis.com/" \
  --allowed-audiences="https://sts.googleapis.com" \
  --attribute-mapping="google.subject='assertion.sub'" \
  --attribute-condition="assertion.swname == 'CONFIDENTIAL_SPACE' && 
'STABLE' in assertion.submods.confidential_space.support_attributes && 
assertion.submods.container.image_digest == '${WORKLOAD_IMAGE_DIGEST}' &&
 assertion.submods.container.image_reference == '${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/$PRIMUS_PROJECT_ID/$PRIMUS_ARTIFACT_REPOSITORY/$WORKLOAD_IMAGE_NAME:$WORKLOAD_IMAGE_TAG' && 
'$WORKLOAD_SERVICEACCOUNT@$SECUNDUS_PROJECT_ID.iam.gserviceaccount.com' in assertion.google_service_accounts"

Exécuter la charge de travail

Lors de cette étape, nous exécuterons la charge de travail dans la VM Confidential Space. Les arguments TEE requis sont transmis à l'aide de l'indicateur de métadonnées. Les arguments du conteneur de charge de travail sont transmis à l'aide de "tee-cmd" du drapeau. Le résultat de l'exécution de la charge de travail sera publié dans $SECUNDUS_RESULT_STORAGE_BUCKET.

gcloud config set project $SECUNDUS_PROJECT_ID
gcloud compute instances create ${WORKLOAD_VM} \
 --confidential-compute-type=SEV \
 --shielded-secure-boot \
 --maintenance-policy=TERMINATE \
 --scopes=cloud-platform --zone=${SECUNDUS_PROJECT_ZONE} \
 --image-project=confidential-space-images \
 --image-family=confidential-space \
 --service-account=${WORKLOAD_SERVICEACCOUNT}@${SECUNDUS_PROJECT_ID}.iam.gserviceaccount.com \
 --metadata  ^~^tee-image-reference=${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/${PRIMUS_PROJECT_ID}/${PRIMUS_ARTIFACT_REPOSITORY}/${WORKLOAD_IMAGE_NAME}:${WORKLOAD_IMAGE_TAG}

Afficher les résultats

Une fois la charge de travail terminée, le résultat de la charge de travail de ML est publié dans $SECUNDUS_RESULT_STORAGE_BUCKET.

gsutil cat gs://$SECUNDUS_RESULT_STORAGE_BUCKET/result

Voici quelques exemples de résultats d'inférence sur des exemples d'images:

Image: sample_image_1.jpeg, Response: {'predicted_class': 531, 'top_k_predictions': [{'class_index': 531, 'score': 12.08437442779541}, {'class_index': 812, 'score': 10.269512176513672}, {'class_index': 557, 'score': 9.202644348144531}, {'class_index': 782, 'score': 9.08737564086914}, {'class_index': 828, 'score': 8.912498474121094}]}

Image: sample_image_2.jpeg, Response: {'predicted_class': 905, 'top_k_predictions': [{'class_index': 905, 'score': 9.53619384765625}, {'class_index': 557, 'score': 7.928380966186523}, {'class_index': 783, 'score': 7.70129919052124}, {'class_index': 531, 'score': 7.611623287200928}, {'class_index': 906, 'score': 7.021416187286377}]}

Image: sample_image_3.jpeg, Response: {'predicted_class': 905, 'top_k_predictions': [{'class_index': 905, 'score': 6.09878396987915}, {'class_index': 447, 'score': 5.992854118347168}, {'class_index': 444, 'score': 5.9582319259643555}, {'class_index': 816, 'score': 5.502010345458984}, {'class_index': 796, 'score': 5.450454235076904}]}

Pour chaque exemple d'image stockée dans un bucket de stockage Secundus, une entrée s'affiche dans les résultats. Cette entrée inclura deux informations clés:

  • Index of predicted_class:index numérique représentant la classe à laquelle le modèle prédit que l'image appartient.
  • Top_k_predictions::cette valeur fournit jusqu'à k prédictions pour l'image, classées de la plus probable à la moins probable. Dans cet atelier de programmation, la valeur de k est définie sur 5, mais vous pouvez l'ajuster dans le code de la charge de travail pour obtenir plus ou moins de prédictions.

Pour traduire l'index de classe en un nom de classe lisible, consultez la liste des étiquettes disponible sur cette page. Par exemple, si vous voyez un index de classe de 2, cela correspond au libellé de classe "tench". dans la liste des étiquettes.

Dans cet atelier de programmation, nous avons démontré qu'un modèle détenu par Primus n'est publié que sur la charge de travail exécutée dans un TEE. Secundus exécute la charge de travail de ML dans un TEE. Cette charge de travail est en mesure d'utiliser le modèle appartenant à Primus, tandis que Primus conserve un contrôle total sur le modèle.

Exécuter une charge de travail non autorisée

Secundus modifie l'image de la charge de travail en extrayant une image de charge de travail différente de son propre dépôt d'artefacts non autorisé par Primus. Le pool d'identités de charge de travail de Primus n'a autorisé que ${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/$PRIMUS_PROJECT_ID/$PRIMUS_ARTIFACT_REPOSITORY/$WORKLOAD_IMAGE_NAME:$WORKLOAD_IMAGE_TAG image de charge de travail.

Réexécuter la charge de travail

Lorsque Secundus tente d'exécuter la charge de travail d'origine avec cette nouvelle image, l'opération échoue. Pour afficher l'erreur, supprimez le fichier de résultats et l'instance de VM d'origine, puis réessayez d'exécuter la charge de travail.

Veuillez vous assurer qu'une nouvelle image Docker a été publiée dans le registre Artifact Registry de Secundus (sous le nom us-docker.pkg.dev/${SECUNDUS_PROJECT_ID}/custom-image/${WORKLOAD_IMAGE_NAME}:${WORKLOAD_IMAGE_TAG}) et que le compte de service de charge de travail ($WORKLOAD_SERVICEACCOUNT) a autorisé le lecteur Artifact Registry à lire cette nouvelle image de charge de travail. Cela permet de s'assurer que la charge de travail ne se termine pas avant que la règle WIP de Primus ne refuse le jeton présenté par la charge de travail.

Supprimer le fichier de résultats et l'instance de VM existants

  1. Définissez le projet sur $SECUNDUS_PROJECT_ID.
gcloud config set project $SECUNDUS_PROJECT_ID
  1. Supprimez le fichier de résultats.
gsutil rm gs://$SECUNDUS_RESULT_STORAGE_BUCKET/result
  1. Supprimez l'instance de Confidential VM.
gcloud compute instances delete ${WORKLOAD_VM}

Exécutez la charge de travail non autorisée:

gcloud compute instances create ${WORKLOAD_VM} \
 --confidential-compute-type=SEV \
 --shielded-secure-boot \
 --maintenance-policy=TERMINATE \
 --scopes=cloud-platform --zone=${SECUNDUS_PROJECT_ZONE} \
 --image-project=confidential-space-images \
 --image-family=confidential-space \ 
--service-account=${WORKLOAD_SERVICE_ACCOUNT}@${SECUNDUS_PROJECT_ID}.iam.gserviceaccount.com \
 --metadata  ^~^tee-image-reference=us-docker.pkg.dev/${SECUNDUS_PROJECT_ID}/custom-image/${WORKLOAD_IMAGE_NAME}:${WORKLOAD_IMAGE_TAG}

Afficher l'erreur

Au lieu des résultats de la charge de travail, une erreur (The given credential is rejected by the attribute condition) s'affiche.

gsutil cat gs://$SECUNDUS_RESULT_STORAGE_BUCKET/result

5. Effectuer un nettoyage

Voici le script qui peut être utilisé pour nettoyer les ressources que nous avons créées dans cet atelier de programmation. Lors de ce nettoyage, les ressources suivantes seront supprimées:

  • Bucket de stockage d'entrée de Primus ($PRIMUS_INPUT_STORAGE_BUCKET).
  • Compte de service Primus ($PRIMUS_SERVICEACCOUNT)
  • Dépôt d'artefacts de Primus ($PRIMUS_ARTIFACT_REPOSITORY).
  • Pool d'identités de charge de travail Primus ($PRIMUS_WORKLOAD_IDENTITY_POOL).
  • Compte de service de charge de travail de Secundus ($WORKLOAD_SERVICEACCOUNT).
  • Bucket de stockage d'entrée de Secundus ($SECUNDUS_INPUT_STORAGE_BUCKET).
  • Instances Compute de charge de travail.
  • Bucket de stockage des résultats de Secundus ($SECUNDUS_RESULT_STORAGE_BUCKET).
$ ./cleanup.sh

Si vous avez terminé l'exploration, pensez à supprimer votre projet.

  • Accédez à la console Cloud Platform.
  • Sélectionnez le projet que vous souhaitez arrêter, puis cliquez sur "Supprimer". en haut: cette option planifie la suppression du projet.

Et ensuite ?

Découvrez quelques-uns de ces ateliers de programmation similaires...