This repo is part of a multi-part guide that shows how to configure and deploy the example.com reference architecture described in Google Cloud security foundations guide. The following table lists the parts of the guide.
| 0-bootstrap | Bootstraps a Google Cloud organization, creating all the required resources and permissions to start using the Cloud Foundation Toolkit (CFT). This step also configures a CI/CD Pipeline for foundations code in subsequent stages. |
| 1-org | Sets up top level shared folders, monitoring and networking projects, and organization-level logging, and sets baseline security settings through organizational policy. |
| 2-environments (this file) | Sets up development, non-production, and production environments within the Google Cloud organization that you've created. |
| 3-networks-dual-svpc | Sets up base and restricted shared VPCs with default DNS, NAT (optional), Private Service networking, VPC service controls, on-premises Dedicated Interconnect, and baseline firewall rules for each environment. It also sets up the global DNS hub. |
| 3-networks-hub-and-spoke | Sets up base and restricted shared VPCs with all the default configuration found on step 3-networks-dual-svpc, but here the architecture will be based on the Hub and Spoke network model. It also sets up the global DNS hub |
| 4-projects | Sets up a folder structure, projects, and application infrastructure pipeline for applications, which are connected as service projects to the shared VPC created in the previous stage. |
| 5-app-infra | Deploy a simple Compute Engine instance in one of the business unit projects using the infra pipeline set up in 4-projects. |
For an overview of the architecture and the parts, see the terraform-example-foundation README.
The purpose of this step is to setup development, non-production, and production environments within the Google Cloud organization that you've created.
- 0-bootstrap executed successfully.
- 1-org executed successfully.
- Cloud Identity / Google Workspace group for monitoring admins.
- Membership in the monitoring admins group for user running Terraform.
Please refer to troubleshooting if you run into issues during this step.
Note: If you are using MacOS, replace cp -RT with cp -R in the relevant
commands. The -T flag is needed for Linux, but causes problems for MacOS.
-
Clone repo.
gcloud source repos clone gcp-environments --project=YOUR_CLOUD_BUILD_PROJECT_ID -
Navigate into the repo and change to the non-main branch. All subsequent steps assume you are running them from the gcp-environments directory. If you run them from another directory, adjust your copy paths accordingly.
cd gcp-environments git checkout -b plan -
Copy contents of foundation to new repo.
cp -RT ../terraform-example-foundation/2-environments/ . -
Copy cloud build configuration files for Terraform.
cp ../terraform-example-foundation/build/cloudbuild-tf-* . -
Copy Terraform wrapper script to the root of your new repository.
cp ../terraform-example-foundation/build/tf-wrapper.sh . -
Ensure wrapper script can be executed.
chmod 755 ./tf-wrapper.sh -
Rename
terraform.example.tfvarstoterraform.tfvarsand update the file with values from your environment and bootstrap (you can re-runterraform outputin the 0-bootstrap directory to find these values). See any of the envs folder README.md files for additional information on the values in theterraform.tfvarsfile. -
Commit changes.
git add . git commit -m 'Your message' -
Push your plan branch to trigger a plan for all environments. Because the plan branch is not a named environment branch, pushing your plan branch triggers terraform plan but not terraform apply.
git push --set-upstream origin plan -
Review the plan output in your cloud build project https://console.cloud.google.com/cloud-build/builds?project=YOUR_CLOUD_BUILD_PROJECT_ID
-
Merge changes to development branch. Because this is a named environment branch, pushing to this branch triggers both terraform plan and terraform apply.
git checkout -b development git push origin development -
Review the apply output in your cloud build project https://console.cloud.google.com/cloud-build/builds?project=YOUR_CLOUD_BUILD_PROJECT_ID
-
Merge changes to non-production. Because this is a named environment branch, pushing to this branch triggers both terraform plan and terraform apply.
git checkout -b non-production git push origin non-production -
Review the apply output in your cloud build project https://console.cloud.google.com/cloud-build/builds?project=YOUR_CLOUD_BUILD_PROJECT_ID
-
Merge changes to production branch. Because this is a named environment branch, pushing to this branch triggers both terraform plan and terraform apply.
git checkout -b production git push origin production -
Review the apply output in your cloud build project https://console.cloud.google.com/cloud-build/builds?project=YOUR_CLOUD_BUILD_PROJECT_ID
-
You can now move to the instructions in the step go to for the Dual Shared VPC mode 3-networks-dual-svpc, or go to 3-networks-hub-and-spoke to use the Hub and Spoke network mode.
-
Clone the repo you created manually in 0-bootstrap.
git clone <YOUR_NEW_REPO-2-environments> -
Navigate into the repo and change to a non-production branch. All subsequent steps assume you are running them from the gcp-environments directory. If you run them from another directory, adjust your copy paths accordingly.
cd YOUR_NEW_REPO_CLONE-2-environments git checkout -b plan -
Copy contents of foundation to new repo.
cp -RT ../terraform-example-foundation/2-environments/ . -
Copy the Jenkinsfile script to the root of your new repository.
cp ../terraform-example-foundation/build/Jenkinsfile . -
Update the variables located in the
environment {}section of theJenkinsfilewith values from your environment:_TF_SA_EMAIL _STATE_BUCKET_NAME _PROJECT_ID (the CI/CD project ID) -
Copy Terraform wrapper script to the root of your new repository.
cp ../terraform-example-foundation/build/tf-wrapper.sh . -
Ensure wrapper script can be executed.
chmod 755 ./tf-wrapper.sh -
Rename
terraform.example.tfvarstoterraform.tfvarsand update the file with values from your environment and bootstrap (you can re-runterraform outputin the 0-bootstrap directory to find these values). See any of the envs folder README.md files for additional information on the values in theterraform.tfvarsfile. -
Commit changes.
git add . git commit -m 'Your message' -
Push your plan branch.
git push --set-upstream origin plan- Assuming you configured an automatic trigger in your Jenkins Controller (see Jenkins sub-module README), this will trigger a plan. You can also trigger a Jenkins job manually. Given the many options to do this in Jenkins, it is out of the scope of this document see Jenkins website for more details.
-
Review the plan output in your Controller's web UI.
-
Merge changes to development.
git checkout -b development git push origin development -
Review the apply output in your Controller's web UI (you might want to use the option to "Scan Multibranch Pipeline Now" in your Jenkins Controller UI).
-
Merge changes to non-production with.
git checkout -b non-production git push origin non-production -
Review the apply output in your Controller's web UI (you might want to use the option to "Scan Multibranch Pipeline Now" in your Jenkins Controller UI).
-
Merge changes to production branch.
git checkout -b production git push origin production -
Review the apply output in your Controller's web UI (you might want to use the option to "Scan Multibranch Pipeline Now" in your Jenkins Controller UI).
- Change into
2-environmentsfolder, copy the Terraform wrapper script and ensure it can be executed.cd 2-environments cp ../build/tf-wrapper.sh . chmod 755 ./tf-wrapper.sh - Rename
terraform.example.tfvarstoterraform.tfvars.mv terraform.example.tfvars terraform.tfvars - Update the file with values from your environment and 0-bootstrap output.See any of the envs folder README.md files for additional information on the values in the
terraform.tfvarsfile. - Use
terraform outputto get the backend bucket value from 0-bootstrap output.export backend_bucket=$(terraform -chdir="../0-bootstrap/" output -raw gcs_bucket_tfstate) echo "backend_bucket = ${backend_bucket}" sed -i "s/TERRAFORM_STATE_BUCKET/${backend_bucket}/" ./terraform.tfvars - Also update
backend.tfwith your backend bucket from 0-bootstrap output.for i in `find -name 'backend.tf'`; do sed -i "s/UPDATE_ME/${backend_bucket}/" $i; done
We will now deploy each of our environments(development/production/non-production) using this script. When using Cloud Build or Jenkins as your CI/CD tool each environment corresponds to a branch is the repository for 2-environments step and only the corresponding environment is applied.
To use the validate option of the tf-wrapper.sh script, please follow the instructions to install the terraform-tools component.
- Use
terraform outputto get the Cloud Build project ID and the environment step Terraform Service Account from 0-bootstrap output. An environment variableGOOGLE_IMPERSONATE_SERVICE_ACCOUNTwill be set using the Terraform Service Account to enable impersonation.export CLOUD_BUILD_PROJECT_ID=$(terraform -chdir="../0-bootstrap/" output -raw cloudbuild_project_id) echo ${CLOUD_BUILD_PROJECT_ID} export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../0-bootstrap/" output -raw environment_step_terraform_service_account_email) echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} - Run
initandplanand review output for environment development../tf-wrapper.sh init development ./tf-wrapper.sh plan development - Run
validateand check for violations../tf-wrapper.sh validate development $(pwd)/../policy-library ${CLOUD_BUILD_PROJECT_ID} - Run
applydevelopment../tf-wrapper.sh apply development - Run
initandplanand review output for environment non-production../tf-wrapper.sh init non-production ./tf-wrapper.sh plan non-production - Run
validateand check for violations../tf-wrapper.sh validate non-production $(pwd)/../policy-library ${CLOUD_BUILD_PROJECT_ID} - Run
applynon-production../tf-wrapper.sh apply non-production - Run
initandplanand review output for environment production../tf-wrapper.sh init production ./tf-wrapper.sh plan production - Run
validateand check for violations../tf-wrapper.sh validate production $(pwd)/../policy-library ${CLOUD_BUILD_PROJECT_ID} - Run
applyproduction../tf-wrapper.sh apply production
If you received any errors or made any changes to the Terraform config or terraform.tfvars you must re-run ./tf-wrapper.sh plan <env> before running ./tf-wrapper.sh apply <env>.
Before executing the next stages, unset the GOOGLE_IMPERSONATE_SERVICE_ACCOUNT environment variable.
unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT