build/cloudbuild-cd.yaml (101 lines of code) (raw):
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
timeout: "3600s" # 1 hour
tags:
- "secure-cicd-cd"
substitutions:
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:
############################### Post-Deploy Checks ###########################
# Get endpoint IPs
- name: $_DEFAULT_REGION-docker.pkg.dev/$PROJECT_ID/$_GAR_REPOSITORY/skaffold-builder
id: "get-svc-endpoints"
entrypoint: "/bin/bash"
args:
- '-xe'
- -c
- |
gcloud config set project $_CLUSTER_PROJECT
echo "Target Type ${_TARGET_TYPE}"
case ${_TARGET_TYPE} in
"anthos_cluster")
gcloud container fleet memberships get-credentials $_ANTHOS_MEMBERSHIP
;;
*)
gcloud container clusters get-credentials $_CLUSTER_NAME --region=$_DEFAULT_REGION
;;
esac
kubectl get svc -ojson > /workspace/svcs.json
### Below only grabs external IP'd svcs
jq '[.items[] | (select(.status.loadBalancer.ingress != null) | {svc: .metadata.name, endpoint: "\(.status.loadBalancer.ingress[].ip):\(.spec.ports[].port)"})]' /workspace/svcs.json > /workspace/svcs-endpoints-filtered.json
SVC_NAMES=( $$(jq -r '.[].svc' /workspace/svcs-endpoints-filtered.json))
ENDPOINTS=( $$(jq -r '.[].endpoint' /workspace/svcs-endpoints-filtered.json))
echo $$SVC_NAMES > /workspace/svc_names_env.txt
echo $$ENDPOINTS > /workspace/endpoints_env.txt
volumes:
- name: 'zapvolume'
path: '/zap/wrk'
# ZAProxy Scan
- name: 'gcr.io/cloud-builders/docker'
id: "zaproxy-endpoint-scan"
entrypoint: "bash"
args:
- -c
- |
SVC_NAMES=( $$(cat /workspace/svc_names_env.txt))
ENDPOINTS=( $$(cat /workspace/endpoints_env.txt))
INDEX=0
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
cp /zap/wrk/zap_report_${_TARGET_ID}_${_RELEASE_ID}.html /workspace/zap_report_${_TARGET_ID}_${_RELEASE_ID}.html
volumes:
- name: 'zapvolume'
path: '/zap/wrk'
waitFor:
- 'get-svc-endpoints'
# Binary Authorization
- name: $_DEFAULT_REGION-docker.pkg.dev/$PROJECT_ID/$_GAR_REPOSITORY/skaffold-builder
id: "binary-authorization-checkpoint"
entrypoint: "/bin/bash"
args:
- '-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}
gsutil cp gs://$_CACHE_BUCKET_NAME/artifacts/build-artifacts-notag.json /artifacts/build-artifacts-notag.json
IMAGES=( $$(jq -r '.builds[].tag' /artifacts/build-artifacts-notag.json))
# Public Key for attestor
PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${_ATTESTOR_NAME} \
--format='value(userOwnedGrafeasNote.publicKeys[0].id)')
for IMAGE in "$${IMAGES[@]}"; do
HAS_ATTESTATION=$(gcloud container binauthz attestations list \
--project="${PROJECT_ID}" \
--attestor="${_ATTESTOR_NAME}" \
--artifact-url="$${IMAGE}" \
--format="value(name)")
if [ -z $${HAS_ATTESTATION} ]; then
gcloud beta container binauthz attestations sign-and-create \
--artifact-url="$${IMAGE}" \
--attestor="${_ATTESTOR_NAME}" \
--keyversion=$( echo "$${PUBLIC_KEY_ID}" | sed "s|//cloudkms.googleapis.com/v1/||" )
fi
done
else
echo "_ATTESTOR_NAME not specified. No attestation to add."
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'