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.
export CLOUD_BUILD_PROJECT_ID=$(terraform -chdir="terraform-example-foundation/0-bootstrap/" output -raw cloudbuild_project_id) echo ${CLOUD_BUILD_PROJECT_ID} gcloud source repos clone gcp-environments --project=${CLOUD_BUILD_PROJECT_ID}
-
Navigate into the repo, change to the non-main branch and copy contents of foundation to new repo. 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 cp -RT ../terraform-example-foundation/2-environments/ . cp ../terraform-example-foundation/build/cloudbuild-tf-* . cp ../terraform-example-foundation/build/tf-wrapper.sh . chmod 755 ./tf-wrapper.sh
-
Rename
terraform.example.tfvars
toterraform.tfvars
.mv terraform.example.tfvars terraform.tfvars
-
Update the file with values from your environment and bootstrap (you can re-run
terraform output
in 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.tfvars
file.export backend_bucket=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -raw gcs_bucket_tfstate) echo "remote_state_bucket = ${backend_bucket}" sed -i "s/REMOTE_STATE_BUCKET/${backend_bucket}/" terraform.tfvars
-
Commit changes.
git add . git commit -m 'Initialize environments repo'
-
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;region=DEFAULT_REGION?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;region=DEFAULT_REGION?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. Review the apply output in your cloud build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID
git checkout -b non-production git push origin non-production
-
Merge changes to production branch. Because this is a named environment branch, pushing to this branch triggers both terraform plan and terraform apply. Review the apply output in your cloud build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID
git checkout -b production git push origin production
-
You can now move to the instructions in the network step. To use the Dual Shared VPC network mode go to 3-networks-dual-svpc, or go to 3-networks-hub-and-spoke to use the Hub and Spoke network mode.
See 0-bootstrap
README-Jenkins.md
-
Change into
2-environments
folder, 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.tfvars
toterraform.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.tfvars
file. -
Use
terraform output
to get the backend bucket value from 0-bootstrap output.export backend_bucket=$(terraform -chdir="../0-bootstrap/" output -raw gcs_bucket_tfstate) echo "remote_state_bucket = ${backend_bucket}" sed -i "s/REMOTE_STATE_BUCKET/${backend_bucket}/" ./terraform.tfvars
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 output
to get the Cloud Build project ID and the environment step Terraform Service Account from 0-bootstrap output. An environment variableGOOGLE_IMPERSONATE_SERVICE_ACCOUNT
will 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
init
andplan
and review output for environment development../tf-wrapper.sh init development ./tf-wrapper.sh plan development
-
Run
validate
and check for violations../tf-wrapper.sh validate development $(pwd)/../policy-library ${CLOUD_BUILD_PROJECT_ID}
-
Run
apply
development../tf-wrapper.sh apply development
-
Run
init
andplan
and review output for environment non-production../tf-wrapper.sh init non-production ./tf-wrapper.sh plan non-production
-
Run
validate
and check for violations../tf-wrapper.sh validate non-production $(pwd)/../policy-library ${CLOUD_BUILD_PROJECT_ID}
-
Run
apply
non-production../tf-wrapper.sh apply non-production
-
Run
init
andplan
and review output for environment production../tf-wrapper.sh init production ./tf-wrapper.sh plan production
-
Run
validate
and check for violations../tf-wrapper.sh validate production $(pwd)/../policy-library ${CLOUD_BUILD_PROJECT_ID}
-
Run
apply
production../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