Skip to content
This repository has been archived by the owner on Jan 4, 2023. It is now read-only.

Commit

Permalink
CICD Implementation (Issue #2) (#111)
Browse files Browse the repository at this point in the history
* Adding cloudbuild.yml
* Added Inspec steps
* Added Readme for cicd setup
  • Loading branch information
KonradSchieban authored May 28, 2020
1 parent 8385333 commit e8198a0
Show file tree
Hide file tree
Showing 7 changed files with 398 additions and 9 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Here are the projects/services we make use of in this Blueprint:
* [Diagrams](docs/diagrams.md)
* [Kubernetes RBAC via Google Groups membership demonstration](docs/Google-Groups-and-RBAC.md)
* [Development](/docs/development.md)
* [Continuous Integration with Cloud Build](/docs/cicd.md)
* [Known Issues and Limitations](#known-issues-and-limitations)
* [Helpful Links](#helpful-links)

Expand Down
8 changes: 6 additions & 2 deletions _helpers/admin_project_setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@ echo "Continuing in 10 seconds. Ctrl+C to cancel"
sleep 10

echo "=> Creating project inside the folder ${TF_VAR_folder_id}"
gcloud projects create "${TF_ADMIN_PROJECT}" \
--folder "${TF_VAR_folder_id}"
project_exists=`gcloud projects list --filter "${TF_ADMIN_PROJECT}" | grep "${TF_ADMIN_PROJECT}" | wc -l | tr -d ' '`
if [ "$project_exists" = "0" ];then
gcloud projects create "${TF_ADMIN_PROJECT}" --folder "${TF_VAR_folder_id}"
else
echo "Project already exists. Skipping"
fi

echo "=> Linking ${TF_VAR_billing_account} Billing Account to your project"
gcloud beta billing projects link "${TF_ADMIN_PROJECT}" \
Expand Down
49 changes: 43 additions & 6 deletions _helpers/build-infra.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,61 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# Set up the admin resources run
echo 'Setting up the Terraform Admin Project'
usage() {
echo "Usage: build-infra [-ach] "
echo
echo "Builds infrastructure of pci-gke-blueprint"
echo
echo " -c (optional) Running script in continuous integration and skipping service account creation"
echo " -a (optional) Admin project setup will be skipped"
echo " -h (optional) Print this help menu"
}

unset run_type skip_admin_project
skip_admin_project=false

while getopts 'ach' c
do
case $c in
c) run_type="cicd";;
a) skip_admin_project=true;;
h|?)
usage
exit 2
;;
esac
done

# Source the environment setup file you created previously
source ./workstation.env

# Create the Admin project
./_helpers/admin_project_setup.sh
if [ "$skip_admin_project" = "false" ];then
# Set up the admin resources run
echo 'Setting up the Terraform Admin Project'

# Create the Admin project
./_helpers/admin_project_setup.sh
fi

# Create the Terraform service account
./_helpers/setup_service_account.sh
if [ "$run_type" = "cicd" ];then
# Prepare CloudBuild service account
cloud_build_service_account=`gcloud config get-value account`
./_helpers/setup_cloud_build_service_account.sh $cloud_build_service_account
else
# Create the Terraform service account
./_helpers/setup_service_account.sh
fi

# run terraform
sed "s/<SET TO THE VALUE OF TF_ADMIN_BUCKET>/${TF_ADMIN_BUCKET}/" terraform/infrastructure/backend.tf.example > terraform/infrastructure/backend.tf
pushd terraform/infrastructure
terraform init
terraform plan -out terraform.out
terraform apply terraform.out
if [ $? -ne 0 ];then
echo "Terraform apply failed. Aborting..."
exit 1
fi
popd

# DNS
Expand Down
123 changes: 123 additions & 0 deletions _helpers/setup_cloud_build_service_account.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#!/bin/bash
# Copyright 2020 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
#
# http://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.

cloud_build_service_account=$1

# Fail fast when a command fails or a variable is undefined
set -eu

echo ""
echo "Preparing to execute with the following values:"
echo "==================================================="
echo "Admin Project: ${TF_ADMIN_PROJECT:?}"
echo "Organization: ${TF_VAR_org_id:?}"
echo "Billing Account: ${TF_VAR_billing_account:?}"
echo "Folder: ${TF_VAR_folder_id:?}"
echo "State Bucket: ${TF_ADMIN_BUCKET:?}"
echo "Cloud Build Service Account: ${cloud_build_service_account:?}"
echo "==================================================="
echo ""
echo "Continuing in 10 seconds. Ctrl+C to cancel"
sleep 10


echo "=> Binding IAM roles to service account"

# Add Viewer permissions for the Terraform Admin project
gcloud projects add-iam-policy-binding "${TF_ADMIN_PROJECT}" \
--member "serviceAccount:$cloud_build_service_account" \
--role roles/viewer

# Enable Access Context Manager API for the Terraform Admin project
gcloud services --project ${TF_ADMIN_PROJECT} enable accesscontextmanager.googleapis.com

# Add Storage Admin permissions for the Terraform Admin project
gcloud projects add-iam-policy-binding "${TF_ADMIN_PROJECT}" \
--member "serviceAccount:$cloud_build_service_account" \
--role roles/storage.admin

# Add accesscontextmanager.policyAdmin
gcloud organizations add-iam-policy-binding "${TF_VAR_org_id}" \
--member "serviceAccount:$cloud_build_service_account" \
--role="roles/accesscontextmanager.policyAdmin"

# Add resourcemanager.organizationAdmin
gcloud organizations add-iam-policy-binding "${TF_VAR_org_id}" \
--member "serviceAccount:$cloud_build_service_account" \
--role="roles/resourcemanager.organizationAdmin"

# Add orgpolicy.policyAdmin
gcloud organizations add-iam-policy-binding "${TF_VAR_org_id}" \
--member "serviceAccount:$cloud_build_service_account" \
--role="roles/orgpolicy.policyAdmin"

# Add billing admin
gcloud organizations add-iam-policy-binding "${TF_VAR_org_id}" \
--member "serviceAccount:$cloud_build_service_account" \
--role="roles/billing.admin"

# Add Storage Admin permissions to entire Folder
gcloud resource-manager folders add-iam-policy-binding "${TF_VAR_folder_id}" \
--member "serviceAccount:$cloud_build_service_account" \
--role roles/storage.admin

# Add Container cluster admin permissions to entire Folder
gcloud resource-manager folders add-iam-policy-binding "${TF_VAR_folder_id}" \
--member "serviceAccount:$cloud_build_service_account" \
--role roles/container.admin

# Add serviceusage.serviceUsageAdmin
gcloud resource-manager folders add-iam-policy-binding "${TF_VAR_folder_id}" \
--member "serviceAccount:$cloud_build_service_account" \
--role roles/serviceusage.serviceUsageAdmin

# Add IAM serviceAccountUser permissions to entire Folder
gcloud resource-manager folders add-iam-policy-binding "${TF_VAR_folder_id}" \
--member "serviceAccount:$cloud_build_service_account" \
--role roles/iam.serviceAccountUser

# Add Project Creator permissions to entire Folder
gcloud resource-manager folders add-iam-policy-binding "${TF_VAR_folder_id}" \
--member "serviceAccount:$cloud_build_service_account" \
--role roles/resourcemanager.projectCreator

gcloud resource-manager folders add-iam-policy-binding "${TF_VAR_folder_id}" \
--member "serviceAccount:$cloud_build_service_account" \
--role roles/resourcemanager.folderIamAdmin

# Add Billing Project Manager permissions to all projects in Folder
gcloud resource-manager folders add-iam-policy-binding "${TF_VAR_folder_id}" \
--member "serviceAccount:$cloud_build_service_account" \
--role roles/billing.projectManager

# Add Compute Admin permissions to all projects in Folder
gcloud resource-manager folders add-iam-policy-binding "${TF_VAR_folder_id}" \
--member "serviceAccount:$cloud_build_service_account" \
--role roles/compute.admin

# Add Shared VPC Admin permissions to all projects in Folder
gcloud resource-manager folders add-iam-policy-binding "${TF_VAR_folder_id}" \
--member "serviceAccount:$cloud_build_service_account" \
--role roles/compute.xpnAdmin

echo "=> Setting up IAM roles for StackDriver Logging"

gcloud resource-manager folders add-iam-policy-binding "${TF_VAR_folder_id}" \
--member "serviceAccount:$cloud_build_service_account" \
--role roles/logging.configWriter

echo ""
echo "Service Account set up successfully"
echo ""
158 changes: 158 additions & 0 deletions cicd/cloudbuild.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# Copyright 2020 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.

substitutions:
_GOOGLE_GROUPS_DOMAIN: ''
_TF_ADMIN_BUCKET: ''
_TF_ADMIN_PROJECT: ''
_TF_VAR_BILLING_ACCOUNT: ''
_TF_VAR_FOLDER_ID: ''
_TF_VAR_FRONTEND_ZONE_DNS_NAME: ''
_TF_VAR_GSUITE_ID: ''
_TF_VAR_ORG_ID: ''
_TF_VAR_PROJECT_PREFIX: ''
_GCR_PROJECT_ID: ''
_REPORTS_BUCKET: ''
_DESTROY_INFRA_AFTER_CREATE: ''


timeout: 3000s
steps:
- id: 'Build Infra'
name: 'gcr.io/cloud-foundation-cicd/cft/developer-tools:0'
waitFor: ['-']
entrypoint: 'sh'
env:
- GOOGLE_GROUPS_DOMAIN=${_GOOGLE_GROUPS_DOMAIN}
- TF_ADMIN_BUCKET=${_TF_ADMIN_BUCKET}
- TF_ADMIN_PROJECT=${_TF_ADMIN_PROJECT}
- TF_VAR_billing_account=${_TF_VAR_BILLING_ACCOUNT}
- TF_VAR_folder_id=${_TF_VAR_FOLDER_ID}
- TF_VAR_frontend_zone_dns_name=${_TF_VAR_FRONTEND_ZONE_DNS_NAME}
- TF_VAR_gsuite_id=${_TF_VAR_GSUITE_ID}
- TF_VAR_org_id=${_TF_VAR_ORG_ID}
- TF_VAR_project_prefix=${_TF_VAR_PROJECT_PREFIX}
args:
- '-c'
- |
cloud_build_service_account=`gcloud config get-value account`
cp workstation.env.example workstation.env
sed -i "s/YOUR_ORG_ID/${_TF_VAR_ORG_ID}/g" workstation.env
sed -i "s/YOUR_GSUITE_ID/${_TF_VAR_GSUITE_ID}/g" workstation.env
sed -i "s/YOUR_BILLING_ACCOUNT_ID/${_TF_VAR_BILLING_ACCOUNT}/g" workstation.env
sed -i "s/YOUR_PROJECT_FOLDER/${_TF_VAR_FOLDER_ID}/g" workstation.env
sed -i "s/demo-pci/${_TF_VAR_PROJECT_PREFIX}/g" workstation.env
sed -i "/export TF_ADMIN_PROJECT/c\export TF_ADMIN_PROJECT=${_TF_ADMIN_PROJECT}" workstation.env
sed -i "s/terraform-admin-<INSERT-RANDOM-IDENTIFIER-HERE>/${_TF_ADMIN_BUCKET}/g" workstation.env
sed -i "/TF_VAR_frontend_zone_dns_name=/c\export TF_VAR_frontend_zone_dns_name=\"${_TF_VAR_FRONTEND_ZONE_DNS_NAME}\"" workstation.env
sed -i "/GOOGLE_GROUPS_DOMAIN=/c\GOOGLE_GROUPS_DOMAIN=\"${_GOOGLE_GROUPS_DOMAIN}\"" workstation.env
sed -i '/GOOGLE_APPLICATION_CREDENTIALS/d' workstation.env
sed -i "/TF_VAR_terraform_service_account/c\export TF_VAR_terraform_service_account=\"serviceAccount:$cloud_build_service_account\"" workstation.env
cat workstation.env
source workstation.env
./_helpers/build-infra.sh -c
- id: 'Write input file'
waitFor: ['Build Infra']
name: gcr.io/cloud-foundation-cicd/cft/developer-tools:0
entrypoint: '/bin/sh'
args:
- '-c'
- |
cloud_build_service_account=`gcloud config get-value account`
cat <<EOF > /workspace/inputs.yml
gcp_project_id: "${_TF_VAR_PROJECT_PREFIX}-in-scope"
gcp_gke_locations:
- 'us-central1'
gce_zones:
- 'us-central1'
- 'us-central1-a'
- 'us-central1-b'
- 'us-central1-c'
- 'us-central1-d'
- 'us-central1-e'
- 'us-central1-f'
cis_version: ""
cis_url: ""
fw_change_control_id_regex: 'CID:'
fw_override_control_id_regex: 'CID:'
logging_viewer_list: []
logging_admin_list: []
project_owners_list: ["serviceAccount:$cloud_build_service_account"]
gcs_logging_buckets: []
cai_inventory_bucket_name: ""
cai_inventory_file_path: ""
cai_inventory_age_seconds: 60
gcs_pii_buckets: []
kms_regions_list:
- "us-central1"
kms_admins_list: []
kms_encrypters_list: []
kms_decrypters_list: []
kms_encrypterdecrypters_list: []
kms_rotation_period_seconds: 7776000
environment_label: 'env'
memorystore_admins_list: []
cloudsql_admins_list: []
cloudsql_clients_list: []
bq_admins_list: []
spanner_admins_list: []
environment_label: "goog-gke-node"
allow_all_tcp_ports: []
allow_all_udp_ports: []
EOF
cat /workspace/inputs.yml
- id: 'Run PCI Profile on in-scope project'
waitFor: ['Write input file']
name: gcr.io/${_GCR_PROJECT_ID}/inspec-gcp-pci-profile:v3.2.1-3
entrypoint: '/bin/sh'
args:
- '-c'
- |
inspec exec /share/. -t gcp:// \
--input-file /workspace/inputs.yml \
--reporter cli json:/workspace/pci_report.json html:/workspace/pci_report.html | tee out.json
- id: 'Store json Report'
waitFor: ['Run PCI Profile on in-scope project']
name: gcr.io/cloud-builders/gsutil
args:
- cp
- /workspace/pci_report.json
- gs://${_REPORTS_BUCKET}/pci_report-${BUILD_ID}.json

- id: 'Store HTML Report'
waitFor: ['Run PCI Profile on in-scope project']
name: gcr.io/cloud-builders/gsutil
args:
- cp
- /workspace/pci_report.html
- gs://${_REPORTS_BUCKET}/pci_report-${BUILD_ID}.html

- id: 'Destroy Infra'
waitFor: ['Store HTML Report']
name: gcr.io/cloud-foundation-cicd/cft/developer-tools:0
entrypoint: '/bin/sh'
args:
- '-c'
- |
if [ "${_DESTROY_INFRA_AFTER_CREATE}" = "true" ];then
cat workstation.env
source workstation.env
cd terraform/infrastructure
terraform destroy -auto-approve
fi
Loading

0 comments on commit e8198a0

Please sign in to comment.