원클릭으로
cloudbuild-ops
Cloud Build CI/CD patterns with Terraform-via-Cloud-Build workflows
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Cloud Build CI/CD patterns with Terraform-via-Cloud-Build workflows
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
Podman container operations best practices and patterns
Issue-driven DevOps workflow with pre-flight checks, workspace isolation, and PR lifecycle
Google Cloud Platform operations patterns and best practices
Best practices for creating and reviewing pull requests
Create consistent releases and changelogs using semantic versioning and conventional commits
Makefile and modular scripts conventions for DevOps projects
SOC 직업 분류 기준
| name | cloudbuild-ops |
| description | Cloud Build CI/CD patterns with Terraform-via-Cloud-Build workflows |
cloudbuild.yaml authoring and step configurationcicd/ directory layout conventionsUse this skill when setting up CI/CD pipelines with Cloud Build, when configuring Terraform to run inside Cloud Build, or when troubleshooting build failures.
cicd/ Directory Layoutcicd/
Dockerfile # Application container build
.dockerignore # Build context exclusions
cloudbuild.yaml # Main pipeline: build image + push to AR
cloudbuild-plan.yaml # Terraform plan (triggered by PR)
cloudbuild-apply.yaml # Terraform apply (triggered by merge)
terraform/
providers.tf # Google provider + required version
backend.tf # GCS state backend
variables.tf # Input variables (project_id, region, etc.)
main.tf # GCP resources (AR repo, Cloud Run, IAM)
outputs.tf # Output values (service URL, repo URL)
cloudbuild.yaml StructureA Cloud Build config defines a sequence of steps:
steps:
- name: 'gcr.io/cloud-builders/docker' # Builder image
args: ['build', '-t', '${_IMAGE}', '.'] # Command and arguments
dir: '.' # Working directory (optional)
env: ['KEY=VALUE'] # Environment variables (optional)
images: ['${_IMAGE}'] # Images to push after build
substitutions:
_IMAGE: 'us-central1-docker.pkg.dev/${PROJECT_ID}/app/app:latest'
options:
logging: CLOUD_LOGGING_ONLY
| Concept | Description |
|---|---|
steps | Ordered list of build steps. Each runs in its own container. |
name | Docker image for the step. Use gcr.io/cloud-builders/* or any public image. |
args | Command-line arguments (the image's ENTRYPOINT receives these). |
dir | Working directory relative to the source root. |
images | Images to push to a registry after all steps complete. |
substitutions | User-defined variables prefixed with _. Also $PROJECT_ID, $BUILD_ID, etc. |
| Variable | Description |
|---|---|
$PROJECT_ID | GCP project ID |
$BUILD_ID | Unique build identifier |
$COMMIT_SHA | Git commit SHA (when triggered by repo) |
$BRANCH_NAME | Git branch name |
$TAG_NAME | Git tag name |
$SHORT_SHA | First 7 chars of commit SHA |
The core pattern: Terraform never runs locally. Cloud Build is the execution environment for all infrastructure changes.
Pipeline 1: Plan (PR trigger)
terraform init + terraform planPipeline 2: Apply (Merge trigger)
terraform init + terraform apply -auto-approveterraform destroy via substitution override# cloudbuild-plan.yaml
steps:
- name: 'hashicorp/terraform:1.7'
dir: 'cicd/terraform'
args: ['init', '-backend-config=bucket=${_TF_STATE_BUCKET}']
env: ['TF_IN_AUTOMATION=true']
- name: 'hashicorp/terraform:1.7'
dir: 'cicd/terraform'
args: ['plan', '-no-color', '-input=false']
env:
- 'TF_IN_AUTOMATION=true'
- 'TF_VAR_project_id=${PROJECT_ID}'
Terraform state is stored in GCS:
terraform {
backend "gcs" {
# bucket and prefix set via -backend-config flags in cloudbuild YAML
}
}
The bucket name is passed as a substitution: _TF_STATE_BUCKET.
Convention: ${PROJECT_ID}-tfstate with prefix matching the service name.
The Cloud Build service account (<project-number>@cloudbuild.gserviceaccount.com)
needs these roles:
| Role | Purpose |
|---|---|
roles/artifactregistry.admin | Push images to Artifact Registry |
roles/run.admin | Deploy Cloud Run services |
roles/iam.serviceAccountUser | Act as the service account |
roles/storage.admin | Read/write Terraform state in GCS |
Grant via:
gcloud projects add-iam-policy-binding PROJECT_ID \
--member="serviceAccount:<number>@cloudbuild.gserviceaccount.com" \
--role="roles/run.admin"
Fires on push to a branch matching a pattern:
gcloud builds triggers create github \
--repo-name=my-repo --repo-owner=my-org \
--branch-pattern="^main$" \
--build-config=cicd/cloudbuild-apply.yaml
Fires on PR creation or update:
gcloud builds triggers create github \
--repo-name=my-repo --repo-owner=my-org \
--pull-request-pattern="^main$" \
--build-config=cicd/cloudbuild-plan.yaml
Run on demand:
gcloud builds triggers run TRIGGER_ID --branch=main
Never put secrets in cloudbuild.yaml -- Use Secret Manager:
availableSecrets:
secretManager:
- versionName: projects/$PROJECT_ID/secrets/my-secret/versions/latest
env: 'MY_SECRET'
Least-privilege service account -- Only grant the roles the build needs.
Pin builder image versions -- Use hashicorp/terraform:1.7 not
hashicorp/terraform:latest.
Set TF_IN_AUTOMATION=true -- Suppresses interactive prompts and
produces cleaner output.
Use -input=false -- Prevent Terraform from waiting for user input
in a non-interactive environment.
Review plans before apply -- The two-pipeline model ensures a human reviews the plan (in PR logs) before apply runs.
| Problem | Solution |
|---|---|
| Build fails with auth error | Check service account roles |
| Terraform state locked | Run terraform force-unlock LOCK_ID via Cloud Build |
| Image push fails | Verify Artifact Registry repo exists and SA has artifactregistry.admin |
| Substitution not resolved | Ensure variable starts with _ and is declared in substitutions |
| Build timeout | Increase timeout in options (default: 10 minutes) |
cicd/.terraform apply or terraform destroy without first showing
the plan output and getting user confirmation.terraform apply without user
confirmation.