É possível programar execuções recorrentes do Image Builder usando o Cloud Scheduler e os gatilhos do Cloud Build. Quando você programa builds de imagens personalizadas do SO, o Cloud Build atualiza automaticamente as imagens de base com patches do sistema operacional e políticas de segurança organizacionais sem exigir intervenção manual.
Antes de começar
- Conclua as etapas de configuração do ambiente em Preparar o ambiente.
-
Configure a autenticação, caso ainda não tenha feito isso.
Com isso, você confirma sua identidade para acesso a serviços e APIs do Cloud de Confiance by S3NS . Para executar
códigos ou amostras de um ambiente de desenvolvimento local, autentique-se no
Compute Engine selecionando uma das seguintes opções:
Selecione a guia para como planeja usar as amostras nesta página:
gcloud
-
Instale a Google Cloud CLI e faça login na CLI gcloud com sua identidade federada. Depois de fazer login, inicialize a Google Cloud CLI executando o seguinte comando:
gcloud init
-
- Defina uma região e uma zona padrão.
-
Instale a CLI do Google Cloud.
-
Configure a CLI gcloud para usar sua identidade federada.
Para mais informações, consulte Fazer login na CLI gcloud com sua identidade federada.
-
Crie credenciais de autenticação local para sua conta de usuário:
gcloud auth application-default login
Se um erro de autenticação for retornado e você estiver usando um provedor de identidade (IdP) externo, confirme se você fez login na CLI gcloud com sua identidade federada.
Go
Para usar os exemplos de Go nesta página em um ambiente de desenvolvimento local, instale e inicialize a CLI gcloud e configure o Application Default Credentials com suas credenciais de usuário.
Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.
Funções exigidas
Para receber as permissões necessárias para criar gatilhos e programar builds, peça ao administrador para conceder a você os seguintes papéis do IAM no projeto:
- Editor do Cloud Build (
roles/cloudbuild.builds.editor) - Executor de jobs do Cloud Scheduler (
roles/cloudscheduler.jobRunner) ou administrador do Cloud Scheduler (roles/cloudscheduler.admin) - Usuário da conta de serviço (
roles/iam.serviceAccountUser)
Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.
Também é possível conseguir as permissões necessárias usando papéis personalizados ou outros papéis predefinidos.
Criar um pipeline de build programado
É possível configurar builds de imagens recorrentes usando a CLI gcloud ou os SDKs de cliente Go:
gcloud
Para programar builds recorrentes de imagens do SO usando a CLI gcloud, siga estas etapas:
Crie um gatilho de build manual do Cloud Build que especifique o arquivo
cloudbuild.yamlde destino executando o comandogcloud builds triggers create manual. Como o Cloud Scheduler invoca esse gatilho manualmente em vez de eventos do repositório, não especifique filtros de push ou solicitação de envio:gcloud builds triggers create manual \ --name="TRIGGER_NAME" \ --region=REGION \ --build-config=CLOUDBUILD_YAML_PATH \ --project=PROJECT_IDRecupere o ID exclusivo (
trigger_id) gerado para seu novo gatilho executando o comandogcloud builds triggers describe:gcloud builds triggers describe TRIGGER_NAME \ --region=REGION \ --format="value(id)" \ --project=PROJECT_IDPara criar um job do Cloud Scheduler que envie uma solicitação
HTTP POSTà API Cloud Build (projects.locations.triggers.run) de acordo com a programação unix cron necessária, por exemplo, semanalmente às segundas-feiras às 6h usando'0 6 * * 1', execute o comandogcloud 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
Substitua:
TRIGGER_NAME: o nome do seu gatilho de build do Cloud Build. Por exemplo,weekly-ubuntu-builder.REGION: a região em que o gatilho será criado, por exemplo,us-central1.CLOUDBUILD_YAML_PATH: o caminho para o arquivocloudbuild.yamlno diretório local. Por exemplo,cloudbuild.yaml.PROJECT_ID: o ID do projeto.JOB_NAME: o nome do cron job do Cloud Scheduler, por exemplo,weekly-custom-os-patching.CRON_SCHEDULE: a expressão de programação cron do Unix, por exemplo,'0 6 * * 1'.TRIGGER_ID: o ID exclusivo (trigger_id) gerado para o gatilho.SERVICE_ACCOUNT_EMAIL: o e-mail da conta de serviço que autoriza o Cloud Scheduler a invocar o gatilho. Essa conta de serviço exige permissõesroles/cloudbuild.builds.editor.
Go
É possível programar pipelines de maneira programática nos aplicativos
corporativos usando as Cloud de Confiance bibliotecas de cliente da API Go
(cloudbuild/v1 e cloudscheduler/v1).
O exemplo completo de Go a seguir demonstra como analisar flags da linha de comando e construir a solicitação Build com base na definição imagebuilder.yaml. Em seguida, o programa registra um gatilho manual do Cloud Build
e provisiona um job do Cloud Scheduler quando você fornece a flag
--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
}
Executar o aplicativo Go programado
Para executar o binário compilado do Go e programar a execução recorrente todas as segundas-feiras às 6h, execute o seguinte comando:
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'
A seguir
- Saiba como automatizar builds em eventos do repositório em eventos de push, tag ou mesclagem do Git usando o Terraform.
- Analise o esquema de roteiro de personalização para definir pacotes de software e procedimentos de validação.