Créer des programmations pour les instantanés de disque


Vous créez une programmation d'instantanés pour sauvegarder régulièrement et automatiquement les volumes Persistent Disk zonaux et régionaux, ainsi que Google Cloud Hyperdisk. Nous vous recommandons d'utiliser ces programmations d'instantanés pour sauvegarder vos charges de travail Compute Engine.

Si vous souhaitez créer une programmation d'instantanés qui capture l'état des données d'application au moment de la sauvegarde, également appelés cohérents avec les applications, guest-flush ouInstantané VSS, consultezCréer des instantanés de disque cohérents pour les applications Linux ou Créer un instantané de disque d'application cohérent Windows.

Pour en savoir plus sur les propriétés de la programmation d'instantanés, consultez la section Propriétés de la programmation d'instantanés.

Avant de commencer

  • Consultez les limites applicables aux programmations d'instantanés.
  • Si ce n'est pas déjà fait, configurez l'authentification. L'authentification est le processus permettant de valider votre identité pour accéder aux Google Cloud services et aux API. Pour exécuter du code ou des exemples depuis un environnement de développement local, vous pouvez vous authentifier auprès de Compute Engine en sélectionnant l'une des options suivantes:

    Select the tab for how you plan to use the samples on this page:

    Console

    When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.

    gcloud

    1. Install the Google Cloud CLI, then initialize it by running the following command:

      gcloud init
    2. Set a default region and zone.
    3. Go

      Pour utiliser les exemples Go de cette page dans un environnement de développement local, installez et initialisez gcloud CLI, puis configurez le service Identifiants par défaut de l'application à l'aide de vos identifiants utilisateur.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. If you're using a local shell, then create local authentication credentials for your user account:

        gcloud auth application-default login

        You don't need to do this if you're using Cloud Shell.

      Pour en savoir plus, consultez Set up authentication for a local development environment.

      Java

      Pour utiliser les exemples Java de cette page dans un environnement de développement local, installez et initialisez gcloud CLI, puis configurez le service Identifiants par défaut de l'application à l'aide de vos identifiants utilisateur.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. If you're using a local shell, then create local authentication credentials for your user account:

        gcloud auth application-default login

        You don't need to do this if you're using Cloud Shell.

      Pour en savoir plus, consultez Set up authentication for a local development environment.

      Node.js

      Pour utiliser les exemples Node.js de cette page dans un environnement de développement local, installez et initialisez gcloud CLI, puis configurez le service Identifiants par défaut de l'application à l'aide de vos identifiants utilisateur.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. If you're using a local shell, then create local authentication credentials for your user account:

        gcloud auth application-default login

        You don't need to do this if you're using Cloud Shell.

      Pour en savoir plus, consultez Set up authentication for a local development environment.

      Python

      Pour utiliser les exemples Python de cette page dans un environnement de développement local, installez et initialisez gcloud CLI, puis configurez le service Identifiants par défaut de l'application à l'aide de vos identifiants utilisateur.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. If you're using a local shell, then create local authentication credentials for your user account:

        gcloud auth application-default login

        You don't need to do this if you're using Cloud Shell.

      Pour en savoir plus, consultez Set up authentication for a local development environment.

      REST

      Pour utiliser les exemples d'API REST de cette page dans un environnement de développement local, vous devez utiliser les identifiants que vous fournissez à gcloud CLI.

        Install the Google Cloud CLI, then initialize it by running the following command:

        gcloud init

      Pour en savoir plus, consultez la section S'authentifier pour utiliser REST dans la documentation sur l'authentification Google Cloud.

Rôles et autorisations requis

Pour obtenir les autorisations nécessaires pour créer une programmation d'instantanés, demandez à votre administrateur de vous accorder les rôles IAM suivants sur le projet:

Pour en savoir plus sur l'attribution de rôles, consultez la page Gérer l'accès aux projets, aux dossiers et aux organisations.

Ces rôles prédéfinis contiennent les autorisations requises pour créer une programmation d'instantanés. Pour connaître les autorisations exactes requises, développez la section Autorisations requises :

Autorisations requises

Les autorisations suivantes sont requises pour créer une programmation d'instantanés:

  • Pour créer une programmation d'instantanés : compute.resourcePolicies.create sur le projet ou l'organisation
  • Pour associer une programmation d'instantanés à un disque :
    • compute.disks.addResourcePolicies sur le disque
    • compute.resourcePolicies.use sur la règle de ressource
  • Créer un disque avec une programmation d'instantanés :
    • compute.disks.create sur le projet
    • compute.resourcePolicies.create sur le projet
    • compute.disks.addResourcePolicies sur le disque

Vous pouvez également obtenir ces autorisations avec des rôles personnalisés ou d'autres rôles prédéfinis.

Présentation de la création de programmations d'instantanés

Lors de la création d'une programmation d'instantanés, vous créez une règle de ressource que vous pouvez appliquer à un ou plusieurs volumes Persistent Disk ou Hyperdisk.

Vous pouvez créer des programmations d'instantanés comme suit :

Utiliser le chiffrement avec des programmations d'instantanés

Si un disque utilise une clé de chiffrement gérée par le client (CMEK), lorsque vous utilisez une programmation d'instantanés pour créer des instantanés de ce disque, tous les instantanés créés sont automatiquement chiffrés avec la même clé.

Vous ne pouvez pas utiliser de programmations d'instantanés avec des disques utilisant une clé de chiffrement fournie par le client (CSEK).

Créer une programmation d'instantanés

Vous pouvez créer une programmation d'instantanés pour vos disques à l'aide de la console Google Cloud, de Google Cloud CLI ou de REST. Vous devez créer votre programmation d'instantanés dans la région où se trouve votre disque. Par exemple, si votre disque se trouve dans la zone us-west1-a, vous devez créer la programmation d'instantanés dans la région us-west1. Toutefois, vous pouvez choisir de stocker les instantanés générés par la programmation d'instantanés dans un autre emplacement.

Console

  1. Dans la console Google Cloud, accédez à la page Instances de VM.

    Accéder à la page "Instances de VM"
    Les étapes restantes apparaîtront automatiquement dans la console Google Cloud.

  2. Sélectionnez le projet contenant vos instances de VM.
  3. Dans la colonne Nom, cliquez sur le nom de la VM sur laquelle figure le disque persistant pour lequel vous souhaitez créer une programmation d'instantanés.
  4. Dans Stockage, cliquez sur le nom du disque de démarrage ou du disque supplémentaire pour lequel vous souhaitez créer une programmation d'instantanés.
  5. Cliquez sur Modifier. Vous devrez peut-être cliquer sur le menu Autres actions, puis sur Modifier.
  6. Dans Programmation d'instantanés, sélectionnez Créer une programmation.
  7. Dans Nom, saisissez l'un des noms suivants pour la programmation d'instantanés :
    • boot-disk-snapshot-schedule
    • attached-persistent-disk-snapshot-schedule
  8. Dans la section Emplacement, choisissez l'emplacement de stockage de votre instantané. L'emplacement par défaut prédéfini ou personnalisé configuré dans vos paramètres d'instantanés est automatiquement sélectionné. Vous pouvez éventuellement remplacer les paramètres d'instantané et stocker vos instantanés dans un emplacement de stockage personnalisé en procédant comme suit :

    1. Choisissez le type d'emplacement de stockage souhaité pour votre instantané.

      • Choisissez Multirégional pour une disponibilité plus élevée à un coût plus élevé.
      • Choisissez des instantanés régionaux pour mieux contrôler l'emplacement physique de vos données, à moindre coût.
    2. Dans le champ Sélectionner un emplacement, sélectionnez la région ou l'emplacement multirégional spécifique que vous souhaitez utiliser. Pour utiliser celui qui est le plus proche de votre disque source, sélectionnez Basé sur l'emplacement du disque source.

  9. Pour terminer la création de la programmation d'instantanés, cliquez sur Créer.
  10. Pour associer cette programmation d'instantanés au disque persistant, cliquez sur Enregistrer.

gcloud

Pour créer une programmation d'instantanés pour un disque, utilisez la commande gcloud compute resource-policies create snapshot-schedule. Définissez la fréquence de la programmation sur "hourly" (horaire), "daily" (quotidienne) ou "weekly" (hebdomadaire).

gcloud compute resource-policies create snapshot-schedule SCHEDULE_NAME \
    --description "SCHEDULE_DESCRIPTION" \
    --max-retention-days MAX_RETENTION_DAYS \
    --start-time START_TIME \
    --hourly-schedule SNAPSHOT_INTERVAL \
    --daily-schedule \
    [--weekly-schedule SNAPSHOT_INTERVAL or \
    --weekly-schedule-from-file FILE_NAME] \
    --on-source-disk-delete DELETION_OPTION \
    --storage-location=STORAGE_LOCATION

Remplacez les éléments suivants :

  • SCHEDULE_NAME : nom de la programmation d'instantanés.
  • SCHEDULE_DESCRIPTION : description de la programmation d'instantanés. Utilisez des guillemets autour de votre description.
  • MAX_RETENTION_DAYS : nombre de jours de conservation de l'instantané.

    Par exemple, une valeur 3 signifie que les instantanés sont conservés pendant trois jours avant d'être supprimés. Vous devez utiliser une valeur d'au moins 1.

  • START_TIME : heure de début dans le fuseau horaire UTC. L'heure ne doit pas inclure de minutes.

    Exemple :

    • 14h PST doit être spécifiée comme suit : 22:00.
    • Si vous définissez une heure de début ayant la valeur 22:13, une erreur est renvoyée.

    Si vous utilisez l'option --weekly-schedule-from-file et spécifiez une heure de début dans le fichier, vous n'avez pas besoin d'inclure cette option.

  • SNAPSHOT_INTERVAL: intervalle entre la création d'instantanés successifs. Les options de fréquence d'instantanés hourly-schedule, daily-schedule, weekly-schedule et weekly-schedule-from-file s'excluent mutuellement. Vous ne pouvez en utiliser qu'une seule pour la programmation d'instantanés.

    • Définissez une programmation à fréquence quotidienne en incluant l'option --daily-schedule sans aucune valeur.
    • Définissez une programmation à fréquence horaire avec l'option --hourly-schedule définie sur une valeur entière comprise entre 1 et 23. Pour générer des instantanés au même moment chaque jour, choisissez un nombre horaire divisible de manière égale par 24. Par exemple, si vous définissez --hourly-schedule sur 12, un instantané est créé toutes les 12 heures.
    • Définissez une programmation à fréquence hebdomadaire avec l'option --weekly-schedule définie sur le jour de la semaine où vous souhaitez créer l'instantané. Vous devez rédiger en entier le jour de la semaine. Les valeurs ne sont pas sensibles à la casse. Par exemple, pour sauvegarder votre disque tous les vendredis, votre commande inclut --weekly-schedule=friday.
    • Définissez une programmation hebdomadaire avancée, en spécifiant différents jours de la semaine et avec des heures de début différentes, en incluant l'option --weekly-schedule-from-file. Remplacez FILE_NAME par le nom de fichier contenant la programmation d'instantanés à fréquence hebdomadaire. Bien que vous puissiez spécifier différents jours de la semaine et différentes heures de début à l'aide d'un fichier, vous ne pouvez pas spécifier plusieurs programmations à fréquence hebdomadaire directement sur la ligne de commande. Par exemple, votre fichier peut spécifier deux programmations à fréquence hebdomadaire, le lundi et le mercredi, mais vous ne pouvez pas dupliquer ce paramètre sur la ligne de commande:

      [
        {"day": "MONDAY", "startTime": "04:00"},
        {"day": "WEDNESDAY", "startTime": "02:00"}
      ]
      

      Si vous incluez une heure de début dans votre fichier, vous n'avez pas besoin de définir l'option --start-time sur la ligne de commande. La programmation utilise le fuseau horaire UTC standard.

  • DELETION_OPTION : détermine ce qu'il advient de vos instantanés si le disque source est supprimé. Si vous souhaitez conserver tous les instantanés générés, vous pouvez omettre cette option. Sinon, spécifiez apply-retention-policy pour utiliser les paramètres d'une règle de conservation.

  • STORAGE_LOCATION : (facultatif) emplacement de stockage. Si vous omettez cette option, l'emplacement de stockage par défaut est utilisé.

Exemples

Tous ces exemples incluent les éléments suivants :

  • La règle de suppression du disque est incluse, l'option --on-source-disk-delete est définie sur la valeur par défaut keep-auto-snapshots, laquelle permet de conserver indéfiniment tous les instantanés générés automatiquement. L'alternative consiste à définir cette option sur apply-retention-policy pour utiliser votre règle de conservation des instantanés.
  • L'emplacement de stockage est défini manuellement sur US, afin que tous les instantanés générés soient stockés dans l'emplacement multirégional des États-Unis.
  • Les libellés env=dev et media=images sont appliqués à tous les instantanés générés.
  • La règle de conservation est définie sur 10 jours.

Programmation à fréquence horaire : dans cet exemple, la programmation d'instantanés commence à 22h UTC (14h PST) et se produit toutes les 4 heures.

  gcloud compute resource-policies create snapshot-schedule hourly-schedule1 \
      --description "MY HOURLY SNAPSHOT SCHEDULE" \
      --max-retention-days 10 \
      --start-time 22:00 \
      --hourly-schedule 4 \
      --region us-west1 \
      --on-source-disk-delete keep-auto-snapshots \
      --snapshot-labels env=dev,media=images \
      --storage-location US

Programmation à fréquence quotidienne : dans cet exemple, la programmation d'instantanés commence à 22h UTC (14h PST) et se déroule tous les jours à la même heure. L'option --daily-schedule doit être présente, mais sans valeur associée.

gcloud compute resource-policies create snapshot-schedule daily-schedule2 \
    --description "MY DAILY SNAPSHOT SCHEDULE" \
    --max-retention-days 10 \
    --start-time 22:00 \
    --daily-schedule \
    --region us-west1 \
    --on-source-disk-delete keep-auto-snapshots \
    --snapshot-labels env=dev,media=images \
    --storage-location US

Programmation à fréquence hebdomadaire : dans cet exemple, la programmation d'instantanés commence à 22h UTC (14h PST) et a lieu toutes les semaines les mardis.

gcloud compute resource-policies create snapshot-schedule weekly-schedule3 \
    --description "MY WEEKLY SNAPSHOT SCHEDULE" \
    --max-retention-days 10 \
    --start-time 22:00 \
    --weekly-schedule tuesday \
    --region us-west1 \
    --on-source-disk-delete keep-auto-snapshots \
    --snapshot-labels env=dev,media=images \
    --storage-location US

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
	"google.golang.org/protobuf/proto"
)

// createSnapshotSchedule creates a snapshot schedule.
func createSnapshotSchedule(w io.Writer, projectID, scheduleName, region string) error {
	// projectID := "your_project_id"
	// snapshotName := "your_snapshot_name"
	// region := "eupore-central2"

	ctx := context.Background()

	snapshotsClient, err := compute.NewResourcePoliciesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewResourcePoliciesRESTClient: %w", err)
	}
	defer snapshotsClient.Close()

	req := &computepb.InsertResourcePolicyRequest{
		Project: projectID,
		Region:  region,
		ResourcePolicyResource: &computepb.ResourcePolicy{
			Name:        proto.String(scheduleName),
			Description: proto.String("MY DAILY SNAPSHOT SCHEDULE"),
			Region:      proto.String("europe-central2"),
			SnapshotSchedulePolicy: &computepb.ResourcePolicySnapshotSchedulePolicy{
				RetentionPolicy: &computepb.ResourcePolicySnapshotSchedulePolicyRetentionPolicy{
					MaxRetentionDays: proto.Int32(10),
					// Check the OnSourceDiskDelete enum for the list of possible values.
					OnSourceDiskDelete: proto.String("KEEP_AUTO_SNAPSHOTS"),
				},
				Schedule: &computepb.ResourcePolicySnapshotSchedulePolicySchedule{
					DailySchedule: &computepb.ResourcePolicyDailyCycle{
						DaysInCycle: proto.Int32(1),
						StartTime:   proto.String("22:00"),
					},
				},
				SnapshotProperties: &computepb.ResourcePolicySnapshotSchedulePolicySnapshotProperties{
					StorageLocations: []string{"eu"},
					Labels: map[string]string{
						"env":   "dev",
						"media": "images",
					},
				},
			},
		},
	}
	op, err := snapshotsClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create snapshot schedule: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprint(w, "Snapshot schedule created\n")

	return nil
}

Java

import com.google.cloud.compute.v1.InsertResourcePolicyRequest;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Operation.Status;
import com.google.cloud.compute.v1.ResourcePoliciesClient;
import com.google.cloud.compute.v1.ResourcePolicy;
import com.google.cloud.compute.v1.ResourcePolicyHourlyCycle;
import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicy;
import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicyRetentionPolicy;
import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicyRetentionPolicy.OnSourceDiskDelete;
import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicySchedule;
import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicySnapshotProperties;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateSnapshotSchedule {
  public static void main(String[] args)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String projectId = "YOUR_PROJECT_ID";
    // Name of the region in which you want to create the snapshot schedule.
    String region = "us-central1";
    // Name of the snapshot schedule you want to create.
    String snapshotScheduleName = "YOUR_SCHEDULE_NAME";
    // Description of the snapshot schedule.
    String scheduleDescription = "YOUR_SCHEDULE_DESCRIPTION";
    // Maximum number of days to retain snapshots.
    int maxRetentionDays = 10;
    // Storage location for the snapshots.
    // More about storage locations:
    // https://cloud.google.com/compute/docs/disks/snapshots?authuser=0#selecting_a_storage_location
    String storageLocation = "US";

    createSnapshotSchedule(projectId, region, snapshotScheduleName, scheduleDescription,
            maxRetentionDays, storageLocation);
  }

  // Creates a snapshot schedule policy.
  public static Status createSnapshotSchedule(String projectId, String region,
            String snapshotScheduleName, String scheduleDescription, int maxRetentionDays,
            String storageLocation)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (ResourcePoliciesClient resourcePoliciesClient = ResourcePoliciesClient.create()) {
      int snapshotInterval = 10; // Create a snapshot every 10 hours
      String startTime = "08:00"; // Define the hourly schedule

      ResourcePolicyHourlyCycle hourlyCycle = ResourcePolicyHourlyCycle.newBuilder()
              .setHoursInCycle(snapshotInterval)
              .setStartTime(startTime)
              .build();

      ResourcePolicySnapshotSchedulePolicyRetentionPolicy retentionPolicy =
              ResourcePolicySnapshotSchedulePolicyRetentionPolicy.newBuilder()
                      .setMaxRetentionDays(maxRetentionDays)
                      .setOnSourceDiskDelete(OnSourceDiskDelete.KEEP_AUTO_SNAPSHOTS.toString())
              .build();

      ResourcePolicySnapshotSchedulePolicySnapshotProperties snapshotProperties =
              ResourcePolicySnapshotSchedulePolicySnapshotProperties.newBuilder()
                      .addStorageLocations(storageLocation)
                      .build();

      ResourcePolicySnapshotSchedulePolicy snapshotSchedulePolicy =
              ResourcePolicySnapshotSchedulePolicy.newBuilder()
                      .setRetentionPolicy(retentionPolicy)
                      .setSchedule(ResourcePolicySnapshotSchedulePolicySchedule.newBuilder()
                               .setHourlySchedule(hourlyCycle)
                               .build())
                      .setSnapshotProperties(snapshotProperties)
                      .build();

      ResourcePolicy resourcePolicy = ResourcePolicy.newBuilder()
              .setName(snapshotScheduleName)
              .setDescription(scheduleDescription)
              .setSnapshotSchedulePolicy(snapshotSchedulePolicy)
              .build();
      InsertResourcePolicyRequest request = InsertResourcePolicyRequest.newBuilder()
              .setProject(projectId)
              .setRegion(region)
              .setResourcePolicyResource(resourcePolicy)
              .build();

      Operation response = resourcePoliciesClient.insertAsync(request)
              .get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        throw new Error("Snapshot schedule creation failed! " + response.getError());
      }
      return response.getStatus();
    }
  }
}

Node.js

// Import the Compute library
const computeLib = require('@google-cloud/compute');
const compute = computeLib.protos.google.cloud.compute.v1;

// Instantiate a resourcePoliciesClient
const resourcePoliciesClient = new computeLib.ResourcePoliciesClient();
// Instantiate a regionOperationsClient
const regionOperationsClient = new computeLib.RegionOperationsClient();

/**
 * TODO(developer): Update/uncomment these variables before running the sample.
 */
// The project name.
const projectId = await resourcePoliciesClient.getProjectId();

// The location of the snapshot schedule resource policy.
// region = 'us-central1';

// The name of the snapshot schedule.
// snapshotScheduleName = 'snapshot-schedule-name';

// The description of the snapshot schedule.
const snapshotScheduleDescription = 'snapshot schedule description...';

async function callCreateSnapshotSchedule() {
  const [response] = await resourcePoliciesClient.insert({
    project: projectId,
    region,
    resourcePolicyResource: new compute.ResourcePolicy({
      name: snapshotScheduleName,
      description: snapshotScheduleDescription,
      snapshotSchedulePolicy:
        new compute.ResourcePolicyInstanceSchedulePolicySchedule({
          retentionPolicy:
            new compute.ResourcePolicySnapshotSchedulePolicyRetentionPolicy({
              maxRetentionDays: 5,
            }),
          schedule: new compute.ResourcePolicySnapshotSchedulePolicySchedule({
            // Similarly, you can create a weekly or monthly schedule.
            // Review the resourcePolicies.insert method for details specific to setting a weekly or monthly schedule.
            // To see more details, open: `https://cloud.google.com/compute/docs/disks/scheduled-snapshots?authuser=0#create_snapshot_schedule`
            dailySchedule: new compute.ResourcePolicyDailyCycle({
              startTime: '12:00',
              daysInCycle: 1,
            }),
          }),
          snapshotProperties:
            new compute.ResourcePolicySnapshotSchedulePolicySnapshotProperties(
              {
                guestFlush: false,
                labels: {
                  env: 'dev',
                  media: 'images',
                },
                // OPTIONAL: the storage location. If you omit this flag, the default storage location is used.
                // storageLocations: 'storage-location',
              }
            ),
        }),
    }),
  });

  let operation = response.latestResponse;

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await regionOperationsClient.wait({
      operation: operation.name,
      project: projectId,
      region,
    });
  }

  console.log(`Snapshot schedule: ${snapshotScheduleName} created.`);
}

await callCreateSnapshotSchedule();

Python

from __future__ import annotations

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def snapshot_schedule_create(
    project_id: str,
    region: str,
    schedule_name: str,
    schedule_description: str,
    labels: dict,
) -> compute_v1.ResourcePolicy:
    """
    Creates a snapshot schedule for disks for a specified project and region.
    Args:
        project_id (str): The ID of the Google Cloud project.
        region (str): The region where the snapshot schedule will be created.
        schedule_name (str): The name of the snapshot schedule group.
        schedule_description (str): The description of the snapshot schedule group.
        labels (dict): The labels to apply to the snapshots. Example: {"env": "dev", "media": "images"}
    Returns:
        compute_v1.ResourcePolicy: The created resource policy.
    """

    # # Every hour, starts at 12:00 AM
    # hourly_schedule = compute_v1.ResourcePolicyHourlyCycle(
    #     hours_in_cycle=1, start_time="00:00"
    # )
    #
    # # Every Monday, starts between 12:00 AM and 1:00 AM
    # day = compute_v1.ResourcePolicyWeeklyCycleDayOfWeek(
    #     day="MONDAY", start_time="00:00"
    # )
    # weekly_schedule = compute_v1.ResourcePolicyWeeklyCycle(day_of_weeks=[day])

    # In this example we use daily_schedule - every day, starts between 12:00 AM and 1:00 AM
    daily_schedule = compute_v1.ResourcePolicyDailyCycle(
        days_in_cycle=1, start_time="00:00"
    )

    schedule = compute_v1.ResourcePolicySnapshotSchedulePolicySchedule()
    # You can change the schedule type to daily_schedule, weekly_schedule, or hourly_schedule
    schedule.daily_schedule = daily_schedule

    # Autodelete snapshots after 5 days
    retention_policy = compute_v1.ResourcePolicySnapshotSchedulePolicyRetentionPolicy(
        max_retention_days=5
    )
    snapshot_properties = (
        compute_v1.ResourcePolicySnapshotSchedulePolicySnapshotProperties(
            guest_flush=False, labels=labels
        )
    )

    snapshot_policy = compute_v1.ResourcePolicySnapshotSchedulePolicy()
    snapshot_policy.schedule = schedule
    snapshot_policy.retention_policy = retention_policy
    snapshot_policy.snapshot_properties = snapshot_properties

    resource_policy_resource = compute_v1.ResourcePolicy(
        name=schedule_name,
        description=schedule_description,
        snapshot_schedule_policy=snapshot_policy,
    )

    client = compute_v1.ResourcePoliciesClient()
    operation = client.insert(
        project=project_id,
        region=region,
        resource_policy_resource=resource_policy_resource,
    )
    wait_for_extended_operation(operation, "Resource Policy creation")

    return client.get(project=project_id, region=region, resource_policy=schedule_name)

REST

Pour créer une programmation d'instantanés, envoyez une requête POST à resourcePolicies.insert. Vous devez inclure le nom de la programmation d'instantanés et la fréquence d'instantanés.

Vous pouvez également spécifier manuellement un emplacement de stockage d'instantanés et ajouter des libellés de ressources à votre requête.

Par défaut, le paramètre onSourceDiskDelete est défini sur keepAutoSnapshots. Cela signifie que si le disque source est supprimé, l'instantané généré automatiquement pour ce disque est conservé indéfiniment. Vous pouvez également définir l'option sur applyRetentionPolicy pour appliquer votre règle de conservation.

L'exemple suivant définit une programmation d'instantanés à fréquence quotidienne qui commence à 12h UTC (04h00 PST) et se répète chaque jour. L'exemple définit également une règle de conservation de 5 jours. Au bout de ces cinq jours, les instantanés sont automatiquement supprimés.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION/resourcePolicies

    {
     "name": "SCHEDULE_NAME",
     "description": "SCHEDULE_DESCRIPTION",
     "snapshotSchedulePolicy": {
       "schedule": {
         "dailySchedule": {
           "startTime": "12:00",
           "daysInCycle": "1"
         }
       },
       "retentionPolicy": {
         "maxRetentionDays": "5"
       },
       "snapshotProperties": {
         "guestFlush": "False",
         "labels": {
           "env": "dev",
           "media": "images"
         },
         "storageLocations": "STORAGE_LOCATION"
       }
     }
    }

Remplacez les éléments suivants :

  • PROJECT_ID : nom du projet
  • REGION : emplacement de la règle de ressource de la programmation d'instantanés
  • SCHEDULE_DESCRIPTION : description de la programmation d'instantanés
  • SCHEDULE_NAME : nom de la programmation d'instantanés
  • STORAGE_LOCATION : (facultatif) emplacement de stockage. Si vous omettez cette option, l'emplacement de stockage par défaut est utilisé.

De même, vous pouvez créer une programmation à fréquence hebdomadaire ou mensuelle. Consultez la méthode resourcePolicies.insert pour en savoir plus sur la définition d'une programmation à fréquence hebdomadaire ou mensuelle.

Par exemple, la requête suivante crée une programmation à fréquence hebdomadaire qui s'exécute le mardi à 9 h UTC.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION/resourcePolicies

{
   "name": "SCHEDULE_NAME",
   "description": "SCHEDULE_DESCRIPTION",
   "snapshotSchedulePolicy": {
      "schedule": {
        "weeklySchedule": {
          "dayOfWeeks": [
          {
            "day": "Tuesday",
            "startTime": "9:00"
          }
          ]
        }
      },
      "retentionPolicy": {
          "maxRetentionDays": "5"
      },
      "snapshotProperties": {
          "guestFlush": "False",
          "labels": {
               "production": "webserver"
          },
          "storageLocations": "US"
      }
  }
}

Associer une programmation d'instantanés à un disque

Après avoir créé une programmation, associez-la à un disque existant. Utilisez la console, gcloud CLI ou l'API Compute Engine.

Console

Pour associer une programmation d'instantanés à un disque existant, procédez comme suit.

  1. Dans la console Google Cloud, accédez à la page Disques.

    Accéder à la page Disques

  2. Sélectionnez le nom du disque auquel vous souhaitez associer une programmation d'instantanés. La page Gérer le disque s'ouvre.

  3. Sur la page Gérer le disque, cliquez sur Modifier. Vous devrez peut-être d'abord cliquer sur le menu Autres actions.

  4. Utilisez le menu déroulant Programmation des instantanés pour ajouter la programmation au disque, ou créez une programmation.

  5. Si vous avez choisi de créer une programmation, cliquez sur Créer.

  6. Cliquez sur Enregistrer pour terminer la tâche.

gcloud

Pour associer une programmation d'instantanés à un disque, utilisez la commande gcloud disks add-resource-policies.

gcloud compute disks add-resource-policies DISK_NAME \
    --resource-policies SCHEDULE_NAME \
    --zone ZONE

Remplacez les éléments suivants :

  • DISK_NAME : nom du disque existant
  • SCHEDULE_NAME : nom de la programmation d'instantanés
  • ZONE : emplacement de votre disque

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
)

// attachSnapshotSchedule attaches a snapshot schedule to disk.
func attachSnapshotSchedule(w io.Writer, projectID, scheduleName, diskName, region string) error {
	// projectID := "your_project_id"
	// snapshotName := "your_snapshot_name"
	// diskName := "your_disk_name"
	// region := "europe-central2"

	ctx := context.Background()

	disksClient, err := compute.NewRegionDisksRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewDisksRESTClient: %w", err)
	}
	defer disksClient.Close()

	req := &computepb.AddResourcePoliciesRegionDiskRequest{
		Project: projectID,
		Region:  region,
		Disk:    diskName,
		RegionDisksAddResourcePoliciesRequestResource: &computepb.RegionDisksAddResourcePoliciesRequest{
			ResourcePolicies: []string{
				fmt.Sprintf("projects/%s/regions/%s/resourcePolicies/%s", projectID, region, scheduleName),
			},
		},
	}
	op, err := disksClient.AddResourcePolicies(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to attach schedule: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprint(w, "Snapshot schedule attached\n")

	return nil
}

Java

import com.google.cloud.compute.v1.AddResourcePoliciesDiskRequest;
import com.google.cloud.compute.v1.DisksAddResourcePoliciesRequest;
import com.google.cloud.compute.v1.DisksClient;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Operation.Status;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class AttachSnapshotScheduleToDisk {
  public static void main(String[] args) throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String projectId = "YOUR_PROJECT_ID";
    // Name of the zone where your disk is located.
    String zone = "us-central1-a";
    // Name of the disk you want to attach the snapshot schedule to.
    String diskName = "YOUR_DISK_NAME";
    // Name of the snapshot schedule you want to attach.
    String snapshotScheduleName = "YOUR_SNAPSHOT_SCHEDULE_NAME";
    // Name of the region where your snapshot schedule is located.
    String region = "us-central1";

    attachSnapshotScheduleToDisk(projectId, zone, diskName, snapshotScheduleName, region);
  }

  // Attaches a snapshot schedule to a disk.
  public static Status attachSnapshotScheduleToDisk(
        String projectId, String zone, String diskName, String snapshotScheduleName, String region)
        throws IOException, ExecutionException, InterruptedException, TimeoutException {

    String resourcePolicyLink = String.format(
            "projects/%s/regions/%s/resourcePolicies/%s", projectId, region, snapshotScheduleName);
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (DisksClient disksClient = DisksClient.create()) {

      AddResourcePoliciesDiskRequest request = AddResourcePoliciesDiskRequest.newBuilder()
              .setProject(projectId)
              .setZone(zone)
              .setDisk(diskName)
              .setDisksAddResourcePoliciesRequestResource(
                      DisksAddResourcePoliciesRequest.newBuilder()
                              .addResourcePolicies(resourcePolicyLink)
                              .build())
              .build();

      Operation response = disksClient.addResourcePoliciesAsync(request).get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        throw new Error("Error attaching snapshot schedule to disk: " + response.getError());
      }
      return response.getStatus();
    }
  }
}

Python

from __future__ import annotations

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def snapshot_schedule_attach(
    project_id: str, zone: str, region: str, disk_name: str, schedule_name: str
) -> None:
    """
    Attaches a snapshot schedule to a specified disk.
    Args:
        project_id (str): The ID of the Google Cloud project.
        zone (str): The zone where the disk is located.
        region (str): The region where the snapshot schedule was created
        disk_name (str): The name of the disk to which the snapshot schedule will be attached.
        schedule_name (str): The name of the snapshot schedule that you are applying to this disk
    Returns:
        None
    """
    disks_add_request = compute_v1.DisksAddResourcePoliciesRequest(
        resource_policies=[f"regions/{region}/resourcePolicies/{schedule_name}"]
    )

    client = compute_v1.DisksClient()
    operation = client.add_resource_policies(
        project=project_id,
        zone=zone,
        disk=disk_name,
        disks_add_resource_policies_request_resource=disks_add_request,
    )
    wait_for_extended_operation(operation, "Attaching snapshot schedule to disk")

REST

Envoyez une requête POST à disks.addResourcePolicies pour associer une programmation d'instantanés à un disque existant.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/disks/DISK_NAME/addResourcePolicies

{
  "resourcePolicies": [
    "regions/REGION/resourcePolicies/SCHEDULE_NAME"
  ]
}

Remplacez les éléments suivants :

  • PROJECT_ID : nom du projet
  • ZONE : zone où se trouve le disque.
  • REGION: région dans laquelle la programmation d'instantanés a été créée
  • DISK_NAME : le nom du disque
  • SCHEDULE_NAME: nom de la programmation d'instantanés que vous appliquez à ce disque.

Créer un disque avec une programmation d'instantanés

Vous pouvez utiliser la console Google Cloud ou gcloud CLI pour créer un disque et une programmation d'instantanés simultanément.

Console

  1. Dans la console Google Cloud, accédez à la page Disques.

    Accéder à la page Disques

  2. Cliquez sur Créer un disque.

  3. Remplissez les champs requis pour créer un disque zonal ou régional.

  4. Créez votre disque dans la même région que celle de votre programmation d'instantanés.

  5. Complétez les champs pour la programmation d'instantanés.

  6. Utilisez le menu déroulant et remplissez les champs pour créer la programmation.

  7. Cliquez sur Créer pour créer la programmation.

  8. Cliquez sur Créer pour créer le disque.

gcloud

Utilisez la commande gcloud disks create pour créer un disque persistant ou Hyperdisk zonal ou régional et lui associer une programmation d'instantanés.

gcloud compute disks create DISK_NAME \
     --resource-policies SCHEDULE_NAME \
     --zone ZONE

Remplacez les éléments suivants :

  • DISK_NAME : le nom du nouveau disque
  • SCHEDULE_NAME : nom de la programmation d'instantanés
  • ZONE : emplacement où vous créez le disque Ce disque doit se trouver dans une zone située dans la même région que la programmation d'instantanés.

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
	"google.golang.org/protobuf/proto"
)

// createDiskWithSnapshotSchedule creates a new empty regional disk with snapshot schedule
func createDiskWithSnapshotSchedule(
	w io.Writer,
	projectID, region, diskName, diskType, scheduleName string,
	replicaZones []string,
	diskSizeGb int64,
) error {
	// projectID := "your_project_id"
	// region := "us-west3" // should match diskType below
	// diskName := "your_disk_name"
	// diskType := "regions/us-west3/diskTypes/pd-ssd"
	// scheduleName := "your_schedule_name"
	// replicaZones := []string{"us-west3-a", "us-west3-b"}
	// diskSizeGb := 120

	// Exactly two replica zones must be specified
	replicaZoneURLs := []string{
		fmt.Sprintf("projects/%s/zones/%s", projectID, replicaZones[0]),
		fmt.Sprintf("projects/%s/zones/%s", projectID, replicaZones[1]),
	}

	ctx := context.Background()
	disksClient, err := compute.NewRegionDisksRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewRegionDisksRESTClient: %w", err)
	}
	defer disksClient.Close()

	req := &computepb.InsertRegionDiskRequest{
		Project: projectID,
		Region:  region,
		DiskResource: &computepb.Disk{
			Name:         proto.String(diskName),
			Region:       proto.String(region),
			Type:         proto.String(diskType),
			SizeGb:       proto.Int64(diskSizeGb),
			ReplicaZones: replicaZoneURLs,
			ResourcePolicies: []string{
				fmt.Sprintf("projects/%s/regions/%s/resourcePolicies/%s", projectID, region, scheduleName),
			},
		},
	}

	op, err := disksClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create disk with schedule: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Disk with schedule created\n")

	return nil
}

Java

import com.google.cloud.compute.v1.Disk;
import com.google.cloud.compute.v1.DisksClient;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.Operation.Status;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateDiskWithSnapshotSchedule {
  public static void main(String[] args)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String projectId = "YOUR_PROJECT_ID";
    // Name of the zone in which you want to create the disk.
    String zone = "us-central1-a";
    // Name of the disk you want to create.
    String diskName = "YOUR_DISK_NAME";
    // Name of the schedule you want to link to the disk.
    String snapshotScheduleName = "YOUR_SCHEDULE_NAME";

    createDiskWithSnapshotSchedule(projectId, zone, diskName, snapshotScheduleName);
  }

  // Creates disk with linked snapshot schedule.
  public static Status createDiskWithSnapshotSchedule(
      String projectId, String zone, String diskName, String snapshotScheduleName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (DisksClient disksClient = DisksClient.create()) {
      String region = zone.substring(0, zone.lastIndexOf('-'));
      // Get the resource policy to link to the disk
      String resourcePolicyLink = String.format("projects/%s/regions/%s/resourcePolicies/%s",
              projectId, region, snapshotScheduleName);

      Disk disk = Disk.newBuilder()
              .setName(diskName)
              .setZone(zone)
              .addAllResourcePolicies(List.of(resourcePolicyLink))
              .build();

      Operation response = disksClient.insertAsync(projectId, zone, disk).get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        throw new Error("Disk creation failed! " + response.getError());
      }
      return response.getStatus();
    }
  }
}

Étape suivante