Vous pouvez planifier des exécutions récurrentes d'Image Builder à l'aide de Cloud Scheduler et des déclencheurs Cloud Build. Lorsque vous planifiez des compilations d'images d'OS personnalisées, Cloud Build met automatiquement à jour vos images de référence avec des correctifs du système d'exploitation et des règles de sécurité de l'organisation, sans nécessiter d'intervention manuelle.
Avant de commencer
- Suivez les étapes de configuration de l'environnement dans Préparer votre environnement.
-
Si ce n'est pas déjà fait, configurez l'authentification.
L'authentification permet de valider votre identité pour accéder aux services et aux API Cloud de Confiance by S3NS . 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 :
Sélectionnez l'onglet correspondant à la façon dont vous prévoyez d'utiliser les exemples de cette page :
gcloud
-
Installez la Google Cloud CLI, puis connectez-vous à la gcloud CLI avec votre identité fédérée. Après vous être connecté, initialisez la Google Cloud CLI en exécutant la commande suivante :
gcloud init
-
- Définissez une région et une zone par défaut.
-
Installez la Google Cloud CLI.
-
Configurez la gcloud CLI afin d'utiliser votre identité fédérée.
Pour en savoir plus, consultez Se connecter à la gcloud CLI avec votre identité fédérée.
-
Créez des identifiants d'authentification locaux pour votre compte utilisateur :
gcloud auth application-default login
Si une erreur d'authentification est renvoyée et que vous utilisez un fournisseur d'identité (IdP) externe, vérifiez que vous vous êtes connecté à la gcloud CLI avec votre identité fédérée.
Go
Pour utiliser les exemples Go de cette page dans un environnement de développement local, installez et initialisez la gcloud CLI, puis configurez les Identifiants par défaut de l'application avec vos identifiants utilisateur.
Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.
Rôles requis
Pour obtenir les autorisations nécessaires pour créer des déclencheurs et planifier des compilations, demandez à votre administrateur de vous accorder les rôles IAM suivants sur votre projet :
- Éditeur Cloud Build (
roles/cloudbuild.builds.editor) - Exécuteur de tâches Cloud Scheduler (
roles/cloudscheduler.jobRunner) ou Administrateur Cloud Scheduler (roles/cloudscheduler.admin) -
Utilisateur du compte de service (
roles/iam.serviceAccountUser)
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.
Vous pouvez également obtenir les autorisations requises avec des rôles personnalisés ou d'autres rôles prédéfinis.
Créer un pipeline de compilation planifié
Vous pouvez configurer des compilations d'images récurrentes à l'aide de gcloud CLI ou des SDK clients Go :
gcloud
Pour planifier des compilations d'images OS récurrentes à l'aide de gcloud CLI, procédez comme suit :
Créez un déclencheur de compilation Cloud Build manuel qui spécifie votre fichier
cloudbuild.yamlcible en exécutant la commandegcloud builds triggers create manual. Étant donné que Cloud Scheduler appelle ce déclencheur manuellement plutôt que sur des événements de dépôt, ne spécifiez pas de filtres de requête push ou de demande d'extraction :gcloud builds triggers create manual \ --name="TRIGGER_NAME" \ --region=REGION \ --build-config=CLOUDBUILD_YAML_PATH \ --project=PROJECT_IDRécupérez l'ID unique (
trigger_id) généré pour votre nouveau déclencheur en exécutant la commandegcloud builds triggers describe:gcloud builds triggers describe TRIGGER_NAME \ --region=REGION \ --format="value(id)" \ --project=PROJECT_IDPour créer un job Cloud Scheduler qui envoie une requête
HTTP POSTà l'API Cloud Build (projects.locations.triggers.run) selon la planification cron Unix requise (par exemple, toutes les semaines le lundi à 6h00 du matin à l'aide de'0 6 * * 1'), exécutez la commandegcloud scheduler jobs create http:gcloud scheduler jobs create http JOB_NAME \ --schedule="CRON_SCHEDULE" \ --uri="https://cloudbuild.googleapis.com/v1/projects/PROJECT_ID/locations/REGION/triggers/TRIGGER_ID:run" \ --message-body="{}" \ --oauth-service-account-email="SERVICE_ACCOUNT_EMAIL" \ --location=REGION \ --project=PROJECT_ID
Remplacez les éléments suivants :
TRIGGER_NAME: nom de votre déclencheur de compilation Cloud Build manuel, par exempleweekly-ubuntu-builder.REGION: région dans laquelle créer le déclencheur, par exempleus-central1.CLOUDBUILD_YAML_PATH: chemin d'accès à votre fichiercloudbuild.yamldans votre répertoire local, par exemplecloudbuild.yaml.PROJECT_ID: ID de votre projet.JOB_NAME: nom de votre job cron Cloud Scheduler (par exemple,weekly-custom-os-patching).CRON_SCHEDULE: expression de planification cron Unix, par exemple'0 6 * * 1'.TRIGGER_ID: identifiant unique (trigger_id) généré pour votre déclencheur.SERVICE_ACCOUNT_EMAIL: adresse e-mail du compte de service qui autorise Cloud Scheduler à appeler le déclencheur. Ce compte de service nécessite des autorisationsroles/cloudbuild.builds.editor.
Go
Vous pouvez planifier des pipelines de manière programmatique dans vos applications d'entreprise à l'aide des bibliothèques clientes de l'API Cloud de Confiance Go (cloudbuild/v1 et cloudscheduler/v1).
L'exemple Go complet suivant montre comment analyser les indicateurs de ligne de commande et construire la requête Build à partir de votre définition imagebuilder.yaml. Le programme enregistre ensuite un déclencheur Cloud Build manuel et provisionne une tâche Cloud Scheduler lorsque vous fournissez l'indicateur --cron_schedule.
// Program main demonstrates how to submit or schedule a Image Builder pipeline using Go SDKs.
package main
import (
"context"
"flag"
"fmt"
"os"
"google.golang.org/api/cloudbuild/v1"
"google.golang.org/api/cloudscheduler/v1"
)
var (
projectID = flag.String("project_id", "", "The target Project ID")
region = flag.String("region", "us-central1", "Region of resources")
gcsWorkdir = flag.String("gcs_workdir", "", "The storage workspace directory URI, e.g. gs://my-bucket/workdir/")
serviceAccount = flag.String("service_account", "", "Service account email to run the worker VM")
imageBuilderYAML = flag.String("config_path", "imagebuilder.yaml", "Path to the imagebuilder.yaml configuration file")
arRepositoryID = flag.String("ar_repo_id", "os-images", "Name of the target generic Artifact Registry repository")
arPackageName = flag.String("ar_package_name", "custom-os", "Package identifier for OS images")
cronSchedule = flag.String("cron_schedule", "", "Optional cron schedule to run this build periodically (e.g. '0 6 * * 1')")
)
func main() {
flag.Parse()
if *projectID == "" || *serviceAccount == "" || *gcsWorkdir == "" {
fmt.Fprintln(os.Stderr, "Error: --project_id, --gcs_workdir, and --service_account are required flags")
flag.Usage()
os.Exit(1)
}
ctx := context.Background()
if *cronSchedule != "" {
fmt.Printf("Scheduling build with cron schedule: %s\n", *cronSchedule)
if err := scheduleBuild(ctx); err != nil {
fmt.Fprintf(os.Stderr, "Failed to schedule Cloud Build: %v\n", err)
os.Exit(1)
}
} else {
fmt.Println("Submitting build request immediately to Cloud Build API...")
if err := triggerBuild(ctx); err != nil {
fmt.Fprintf(os.Stderr, "Failed to trigger Cloud Build: %v\n", err)
os.Exit(1)
}
}
}
func createBuildRequest() *cloudbuild.Build {
subs := map[string]string{
"_GCS_WORKDIR": *gcsWorkdir,
"_SERVICE_ACCOUNT": fmt.Sprintf("projects/%s/serviceAccounts/%s", *projectID, *serviceAccount),
"_IMAGE_OUTPUT_PATH": "image-builder/binaryOut",
"_IMAGE_BUILDER_CONFIG_PATH": *imageBuilderYAML,
"_ARTIFACT_REGISTRY_RESOURCE_URI": fmt.Sprintf("projects/%s/locations/%s/repositories/%s/packages/%s/versions/v${BUILD_ID}", *projectID, *region, *arRepositoryID, *arPackageName),
}
return &cloudbuild.Build{
Steps: []*cloudbuild.BuildStep{
{
Name: "us-central1-docker.pkg.dev/image-builder-official/release/builder:stable",
Script: "#!/usr/bin/env bash\n/build",
Id: "imagebuilder-customize",
},
{
Name: "us-central1-docker.pkg.dev/image-builder-official/release/validator:stable",
Script: "#!/usr/bin/env bash\n/validate",
Id: "imagebuilder-validate",
},
{
Name: "us-central1-docker.pkg.dev/image-builder-official/release/builder:stable",
Script: "#!/usr/bin/env bash\n/publish",
Id: "imagebuilder-publish",
},
},
Substitutions: subs,
Options: &cloudbuild.BuildOptions{
AutomapSubstitutions: true,
RequestedVerifyOption: "VERIFIED",
SubstitutionOption: "ALLOW_LOOSE",
DynamicSubstitutions: true,
},
Timeout: "3600s",
}
}
func triggerBuild(ctx context.Context) error {
cbService, err := cloudbuild.NewService(ctx)
if err != nil {
return err
}
build := createBuildRequest()
op, err := cbService.Projects.Locations.Builds.Create(fmt.Sprintf("projects/%s/locations/%s", *projectID, *region), build).Do()
if err != nil {
return err
}
fmt.Printf("Build submitted: %s\n", op.Name)
return nil
}
func scheduleBuild(ctx context.Context) error {
cbService, err := cloudbuild.NewService(ctx)
if err != nil {
return err
}
csService, err := cloudscheduler.NewService(ctx)
if err != nil {
return err
}
// 1. Create a manual Cloud Build trigger
trigger := &cloudbuild.BuildTrigger{
Build: createBuildRequest(),
Name: "scheduled-image-builder-trigger",
Description: "Manual trigger invoked periodically via Cloud Scheduler for Image Builder",
}
createdTrigger, err := cbService.Projects.Locations.Triggers.Create(fmt.Sprintf("projects/%s/locations/%s", *projectID, *region), trigger).Do()
if err != nil {
return fmt.Errorf("failed creating trigger: %w", err)
}
fmt.Printf("Created Cloud Build trigger with ID: %s\n", createdTrigger.Id)
// 2. Create the Cloud Scheduler job
targetURI := fmt.Sprintf("https://cloudbuild.googleapis.com/v1/projects/%s/locations/%s/triggers/%s:run", *projectID, *region, createdTrigger.Id)
job := &cloudscheduler.Job{
Name: fmt.Sprintf("projects/%s/locations/%s/jobs/weekly-image-builder-job", *projectID, *region),
Schedule: *cronSchedule,
Description: "Scheduled job to run custom OS Image Builder pipeline",
HttpTarget: &cloudscheduler.HttpTarget{
Uri: targetURI,
HttpMethod: "POST",
OauthToken: &cloudscheduler.OAuthToken{
ServiceAccountEmail: *serviceAccount,
},
},
}
createdJob, err := csService.Projects.Locations.Jobs.Create(fmt.Sprintf("projects/%s/locations/%s", *projectID, *region), job).Do()
if err != nil {
return fmt.Errorf("failed creating scheduler job: %w", err)
}
fmt.Printf("Successfully scheduled job: %s\n", createdJob.Name)
return nil
}
Exécuter l'application Go planifiée
Pour exécuter le binaire Go compilé et planifier une exécution récurrente tous les lundis à 6h00, exécutez la commande suivante :
go run main.go \ --project_id PROJECT_ID \ --region us-central1 \ --gcs_workdir gs://STAGING_BUCKET/workdir/ \ --service_account SERVICE_ACCOUNT_EMAIL \ --config_path gs://STAGING_BUCKET/imagebuilder.yaml \ --cron_schedule '0 6 * * 1'
Étapes suivantes
- Découvrez comment automatiser les compilations lors d'événements de dépôt sur les événements Git push, tag ou merge à l'aide de Terraform.
- Consultez le schéma de recette de personnalisation pour définir les packages logiciels et les procédures de validation.