Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/release-please.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2021 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion .github/trusted-contribution.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2023-2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2023-2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -35,7 +35,7 @@ jobs:
name: 'lint'
runs-on: 'ubuntu-latest'
steps:
- uses: 'actions/checkout@v6'
- uses: 'actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803'
- id: variables
run: |
MAKEFILE=$(find . -name Makefile -print -quit)
Expand All @@ -58,11 +58,11 @@ jobs:
commitlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803
with:
fetch-depth: 0
- name: Setup node
uses: actions/setup-node@v6
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38
with:
node-version: lts/*
- name: Install commitlint
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/periodic-reporter.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2023-2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -33,7 +33,7 @@ jobs:
runs-on: 'ubuntu-latest'

steps:
- uses: 'actions/github-script@v8'
- uses: 'actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd'
with:
script: |-
// label for all issues opened by reporter
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/stale.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2022-2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -31,7 +31,7 @@ jobs:
if: github.repository_owner == 'GoogleCloudPlatform' || github.repository_owner == 'terraform-google-modules'
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v10
- uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days'
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2019 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -18,7 +18,7 @@
# Make will use bash instead of sh
SHELL := /usr/bin/env bash

DOCKER_TAG_VERSION_DEVELOPER_TOOLS := 1.14
DOCKER_TAG_VERSION_DEVELOPER_TOOLS := 1.25
DOCKER_IMAGE_DEVELOPER_TOOLS := cft/developer-tools
REGISTRY_URL := gcr.io/cloud-foundation-cicd
ENABLE_BPMETADATA := 1
Expand Down
57 changes: 36 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ The Terraform modules in this repository provide an opinionated architecture tha
Create a CI/CD pipeline that follows security best practices.

### Detailed
Set up a secure CI/CD pipeline that follows best practices for building, scanning, storing, and deploying containers to GKE.
Set up a secure CI/CD pipeline that follows best practices for building, scanning, storing, and deploying containers to GKE, Anthos, or Cloud Run.
You can choose whether to deploy your solution through the console directly or download as Terraform from GitHub to deploy later.

### Architecture
1. A developer pushes new code or a code change for a container-based application to Cloud Source Repositories.
1. A developer pushes new code or a code change for a container-based application to a Source Repository (Cloud Source Repositories, GitHub, or GitLab).
1. The code push invokes a Cloud Build trigger. The Cloud Build trigger starts a build in a Cloud Build private worker pool that's hosted in a customer-managed VPC. The outputs of the build are metadata files, Cloud Build logs, and containers.
1. The metadata files and the Cloud Build logs are stored in a Cloud Storage bucket.
1. The pipeline runs security scans (which you configure) and validates the container structure. When the scans and structure pass, the containers are stored in Artifact Registry.
Expand All @@ -36,51 +36,63 @@ Basic usage of this module is as follows:
module "ci_pipeline" {
source = "GoogleCloudPlatform/secure-cicd/google//modules/secure-ci"

project_id = var.project_id
project_id = {PROJECT_ID}
primary_location = "us-central1"
repository_type = "CSR"
csr_app_source_repo = "my-app-source"
attestor_names_prefix = ["build", "security", "quality"]
app_build_trigger_yaml = "cloudbuild-ci.yaml"
runner_build_folder = "../../../examples/app_cicd/cloud-build-builder"
build_image_config_yaml = "cloudbuild-skaffold-build-image.yaml"
trigger_branch_name = ".*"
trigger_branch_name = "^main$"
}

# Secure-CD
module "cd_pipeline" {
source = "GoogleCloudPlatform/secure-cicd/google//modules/secure-cd"

project_id = var.project_id
primary_location = "us-central1"
gar_repo_name = module.ci_pipeline.app_artifact_repo
cloudbuild_cd_repo = "cloudbuild-cd-config-pc"
project_id = {PROJECT_ID}
primary_location = "us-central1"
repository_type = "CSR"
csr_cloudbuild_cd_repo = "cloudbuild-cd-config-pc"
gar_repo_name = module.ci_pipeline.app_artifact_repo
app_deploy_trigger_yaml = "cloudbuild-cd.yaml"
cache_bucket_name = module.ci_pipeline.cache_bucket_name
clouddeploy_pipeline_name = "my-app-delivery-pipeline"
cloudbuild_service_account = module.ci_pipeline.build_sa_email

deploy_branch_clusters = {
dev = {
cluster = "dev-cluster",
project_id = "gke-proj-dev",
anthos_membership = "",
project_id = "{PROJECT_ID}",
location = "us-central1",
required_attestations = ["projects/${var.project_id}/attestors/build-attestor"]
env_attestation = "projects/${var.project_id}/attestors/security-attestor"
required_attestations = ["projects/${{PROJECT_ID}}/attestors/build-attestor"]
env_attestation = "projects/${{PROJECT_ID}}/attestors/security-attestor"
next_env = "qa"
target_type = "gke"
},
qa = {
cluster = "qa-cluster",
project_id = "gke-proj-prod",
anthos_membership = "",
project_id = "{PROJECT_ID}",
location = "us-central1",
required_attestations = ["projects/${var.project_id}/attestors/security-attestor", "projects/${var.project_id}/attestors/build-attestor"]
env_attestation = "projects/${var.project_id}/attestors/quality-attestor"
required_attestations = ["projects/${{PROJECT_ID}}/attestors/security-attestor", "projects/${{PROJECT_ID}}/attestors/build-attestor"]
env_attestation = "projects/${{PROJECT_ID}}/attestors/quality-attestor"
next_env = "prod"
target_type = "gke"
},
prod = {
cluster = "prod-cluster",
project_id = "gke-proj-prod",
anthos_membership = "",
project_id = "{PROJECT_ID}",
location = "us-central1",
required_attestations = ["projects/${var.project_id}/attestors/quality-attestor", "projects/${var.project_id}/attestors/security-attestor", "projects/${var.project_id}/attestors/build-attestor"]
required_attestations = ["projects/${{PROJECT_ID}}/attestors/quality-attestor", "projects/${{PROJECT_ID}}/attestors/security-attestor", "projects/${{PROJECT_ID}}/attestors/build-attestor"]
env_attestation = ""
next_env = ""
target_type = "gke"
},
}
app_deploy_trigger_yaml = "cloudbuild-cd.yaml"
cache_bucket_name = module.ci_pipeline.cache_bucket_name

depends_on = [
module.ci_pipeline
]
Expand Down Expand Up @@ -118,7 +130,8 @@ the resources of this blueprint:
- CI/CD project
- `roles/artifactregistry.admin`
- `roles/binaryauthorization.attestorsAdmin`
- `roles/cloudbuild.builds.builder`
- `roles/cloudbuild.builds.editor`
- `roles/cloudbuild.connectionAdmin`
- `roles/cloudbuild.workerPoolOwner`
- `roles/clouddeploy.admin`
- `roles/cloudkms.admin`
Expand All @@ -128,7 +141,8 @@ the resources of this blueprint:
- `roles/gkehub.editor`
- `roles/iam.serviceAccountAdmin`
- `roles/iam.serviceAccountUser`
- `roles/pubsub.editor`
- `roles/pubsub.admin`
- `roles/secretmanager.secretAccessor`
- `roles/serviceusage.serviceUsageAdmin`
- `roles/source.admin`
- `roles/storage.admin`
Expand Down Expand Up @@ -168,6 +182,7 @@ CI/CD Project
- Cloud KMS API `cloudkms.googleapis.com`
- Binary Authorization API `binaryauthorization.googleapis.com`
- Container Scanning API `containerscanning.googleapis.com`
- Secret Manager API `secretmanager.googleapis.com`

GKE Projects:
- Cloud Resource Manager API `cloudresourcemanager.googleapis.com`
Expand Down
23 changes: 3 additions & 20 deletions build/cloudbuild-cd.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2021 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -20,16 +20,15 @@ options:
pool:
name: $_CLOUDBUILD_PRIVATE_POOL
substitution_option: 'ALLOW_LOOSE'
# machineType: 'E2_HIGHCPU_32'
artifacts:
objects:
location: gs://$_CACHE_BUCKET_NAME/artifacts/$BRANCH_NAME
paths:
- '/workspace/svcs-endpoints-filtered.json'
- '/workspace/zap_report_${_TARGET_ID}_${_RELEASE_ID}.html'
logsBucket: gs://$_CACHE_BUCKET_NAME/build_logs
steps:

steps:
############################### Post-Deploy Checks ###########################

# Get endpoint IPs
Expand Down Expand Up @@ -78,7 +77,7 @@ steps:
ENDPOINT="$${ENDPOINTS[$$INDEX]}"
echo "Checking $$ENDPOINT"

docker container run --user root -v zapvolume:/zap/wrk/:rw -t owasp/zap2docker-stable zap-baseline.py -t http://$$ENDPOINT -r zap_report_${_TARGET_ID}_${_RELEASE_ID}.html -z '-config api.disablekey=true' -I
docker container run --user root -v zapvolume:/zap/wrk/:rw -t zaproxy/zap-stable zap-baseline.py -t http://$$ENDPOINT -r zap_report_${_TARGET_ID}_${_RELEASE_ID}.html -z '-config api.disablekey=true' -I
cp /zap/wrk/zap_report_${_TARGET_ID}_${_RELEASE_ID}.html /workspace/zap_report_${_TARGET_ID}_${_RELEASE_ID}.html
volumes:
- name: 'zapvolume'
Expand All @@ -94,8 +93,6 @@ steps:
- '-xe'
- -c
- |
# Only run this step if there is an attestor supplied in the trigger substitutions
# This step will be skipped for the final environment, when there are no more attestations to add
if [ -n "${_ATTESTOR_NAME}" ]; then
gcloud config set project ${PROJECT_ID}

Expand Down Expand Up @@ -126,17 +123,3 @@ steps:
fi
waitFor:
- 'zaproxy-endpoint-scan'

############################### Artifact Promotion ###########################

- name: $_DEFAULT_REGION-docker.pkg.dev/$PROJECT_ID/$_GAR_REPOSITORY/skaffold-builder
id: "promote-manifests"
entrypoint: "/bin/bash"
args:
- '-xe'
- -c
- |
gcloud deploy releases promote --release=$_RELEASE_ID --delivery-pipeline=$_CLOUDDEPLOY_PIPELINE_NAME --region=$_DEFAULT_REGION

waitFor:
- 'binary-authorization-checkpoint'
2 changes: 1 addition & 1 deletion build/cloudbuild-ci.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2021 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
Loading