É possível programar execuções recorrentes do Image Builder usando gatilhos do Cloud Scheduler e do Cloud Build. Ao programar builds de imagens de SO personalizadas, o Cloud Build atualiza automaticamente as imagens de referência com patches do sistema operacional e políticas de segurança da organização 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 Google Cloud serviços e APIs do. Para executar
código ou amostras de um ambiente de desenvolvimento local, autentique-se no
Compute Engine com uma destas opções:
Selecione a guia para como planeja usar as amostras nesta página:
gcloud
-
Instale a Google Cloud CLI. Após a instalação, inicialize a Google Cloud CLI executando o seguinte comando:
gcloud initAo usar um provedor de identidade (IdP) externo, primeiro faça login na CLI gcloud com sua identidade federada.
-
- Defina uma região e uma zona padrão.
-
Instale a Google Cloud CLI.
-
Ao usar um provedor de identidade (IdP) externo, primeiro faça login na CLI gcloud com sua identidade federada.
-
Se você estiver usando um shell local, crie credenciais de autenticação local para sua conta de usuário:
gcloud auth application-default login
Não é necessário fazer isso se você estiver usando o Cloud Shell.
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 do Go desta 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 com 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 do cliente Go:
gcloud
Para programar builds de imagens de SO recorrentes usando a CLI gcloud, siga estas etapas:
Crie um gatilho de build manual do Cloud Build que especifique o arquivo de destino
cloudbuild.yamlexecutando o comandogcloud builds triggers create manual. Como o Cloud Scheduler invoca esse gatilho manualmente em vez de eventos de repositório, não especifique filtros de solicitação de envio ou solicitação de pull filters: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 o novo gatilho executando ogcloud builds triggers describecomando: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 POSTpara a API Cloud Build (projects.locations.triggers.run) de acordo com a programação cron do Unix necessária, por exemplo, semanalmente às segundas-feiras às 6h usando'0 6 * * 1', execute ogcloud scheduler jobs create httpcomando: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 gatilho de build manual do Cloud Build, por exemplo,weekly-ubuntu-builder.REGION: a região para criar o gatilho, 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 empresariais
usando as Google Cloud bibliotecas de cliente da API Go
(cloudbuild/v1 e cloudscheduler/v1).
O exemplo completo do Go a seguir demonstra como analisar flags de linha de comando e construir a solicitação Build da 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 Go compilado 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 de repositório em eventos de envio, tag ou mesclagem do Git usando o Terraform.
- Analise o esquema de receita de personalização para definir pacotes de software e procedimentos de validação.