By now, you may have already read through our previous blog posts covering the Security Foundations Blueprint and perused the security foundations guide. If you did, then the next question you might ask is how you could put these blueprints to use for your Google Cloud infrastructure and benefit from all of these security-focused best practices.
Fortunately, the second part of the security foundations blueprint is the Terraform automation repository. There you’ll find the curated most secured implementations of the best practices discussed in the guide in the form of Terraform code. To help you make the most of this repository this blog will provide you with additional guidance to help you become better acquainted with the Terraform code, its use, and some of the infrastructure you can expect it to create.
Before diving in
Before you get started with the automation repository you’ll need to be familiar with Terraform. Terraform is a leading open source infrastructure as code (IaC) solution for managing resources in the cloud. Terraform interfaces with the Google Cloud APIs to create, update, and configure all types of Google Cloud resources – virtual machines, VPC’s, load balancers, IAM policies, you name it. The advantage of the infrastructure as code approach is how it allows your infrastructure to be treated as code, complete with version control and code reviews.
In addition to a basic understanding of Terraform, to use the automation repository from start to finish, you’ll need to have set up a Google Cloud organization along with a Google Cloud billing account. As for IAM permissions, the user who’s going to be running the Terraform from step 0 will have to have the following IAM roles granted on the organization resource:
And finally, take a second look at sections 3 and 4 of part II in the security foundations guide for a reminder of what the Terraform code will essentially be creating. Be sure to refer back to the guide when you come across any questions about the design decisions or the code in the Terraform automation repository.
A look around the example foundation
Directories and important files
The Terraform automation repository (or example foundation) is a codified demonstration and deployable landing zone instance of how to adhere to the Google Cloud security foundations guide. It’s made up of pre-configured Terraform resources organized into 6 distinct layers that are meant to be created separately and sequentially. Each of the numbered directories at the root of this repository represent one of these layers. Each one contains individual Terraform configurations with its own corresponding state files.
Numbers 1 through 5 contain Terraform code that will be copied into its own Google Source repository. From there, the Terraform configurations will be deployable using Cloud Build or your preferred CI/CD pipeline. Because 0-bootstrap deploys that pipeline, including the Google Source repositories, it’s the only one that should be deployed manually.
Along with those numbered directories are the build and policy-library directories. These contain Cloud Build configuration files and policies used to validate the Terraform code during stages of deployment. The files in these directories will be copied into your Google Source repositories throughout the example foundation.
Also in the root directory of the repository it’s worth noting the ERRATA.md file. This file will list any deltas between the example foundation landing zone instance and the foundations guide, and whether you should expect any changes to those deltas in a future release.
Cloud Foundation Toolkit modules
If you take a look at the Terraform code used in any of the example foundation layers, you’ll notice that in addition to standalone resources, there are some Terraform modules too. The source of these Terraform modules is the Cloud Foundation Toolkit (CFT). The goal of CFT is to provide a common baseline library of Google Cloud Platform components with best practices implemented in code. These modules were created with the Security Foundations Blueprint in mind, so they provide curated and secured combinations of resources and default values. The additional level of abstraction they create can help to simplify each layer of the example foundation and provides some consistency across your infrastructure deployment.
For example, wherever a project is required to be created, the project factory module is used. Beyond provisioning a project, this module configures resources associated with the project, such as enabling APIs, disabling default service accounts and creating least privilege IAM policies in adherence to the security foundations blueprint. A complete list of CFT modules can be found here, where they’re linked to their corresponding git repository. Each one is meant to be ingested directly from the Terraform registry and does not need to be forked or cloned. They are referenced in module blocks with their Terraform registry path and version number:
You are encouraged to continue to use CFT modules when expanding and building out your infrastructure beyond an example foundation landing zone to customize and match to your business use cases.
What to expect
When you run through the example foundation you’ll realize that it includes many resources across several projects and folders. When you go through the steps, pay close attention to the README.md files in each layer’s directory. There you’ll find step-by-step instructions for deploying the infrastructure with Cloud Build, or as an alternative, Jenkins. When browsing through the Terraform code, it’ll be helpful to dig into each of CFT modules’ source and documentation and refer back to the context in the Security Foundations Guide to get a full understanding of the resources that will be created once you apply them. It’ll also get you familiar with the modules so that you can use them later on when you need to deploy resources extending and customizing the example foundation. In addition to their corresponding repository, each CFT module has documentation and usage information on the Terraform Registry website.
Should you run into any problems going through any of the foundation code, you can take a look at the FAQ.md and TROUBLESHOOTING.md files located in the docs directory in the example foundations repo. Those files are regularly updated with troubleshooting tips and common issues you may encounter.
Jumping into the layers
The bootstrap step is where the bootstrap module and its cloudbuild submodule are used to create the resources and permissions needed in your organization as well as the resources associated with the Cloud Build CI/CD pipeline. Among other things, the bootstrap step will provision:
organization-wide IAM policy bindings for billing and organization admins and project creators
the bootstrap folder for your organization that will contain the seed and CI/CD projects
the seed project along with any Terraform-related resources such as the Terraform service account, associated IAM policies, and Google Cloud Storage buckets for state files
the CI/CD project containing the Cloud Build pipeline and the Google Source repositories for each layer of your infrastructure
The bootstrap step should be executed by a user with the IAM permissions specified previously. After this step, all subsequent Terraform code will be executed automatically via Cloud Build and the Terraform service account. Generally, in each remaining step you’re going to do the following:
Clone the empty repository corresponding to that layer to your local working directory (gcp-environments, gcp-networks, gcp-org, gcp-project). These were created in the bootstrap step with the cloud build bootstrap module.
In a new branch, copy any files indicated in README.md from the example foundation to your empty repository
Edit any files and variables, also indicated in the README.md file
Commit and push any changes on your branch to the repository
This is the point where the automatic magic happens. The magic is actually just some triggers that were created in the Cloud Build bootstrap. You can review them on the Cloud Build triggers page of your CI/CD project. Pushing to any branch not named “development”, “production”, or “non-production” will trigger the terraform plan command that provides a preview of what resources would be created or modified. Additionally, the Terraform code will be validated using terraform-validator, a tool that will check for constraint violations and provide warnings or halt invalid deployments before they can ever reach production. The constraints are defined in the files found in the policy-library directory.
A successful build will capture the plan output and verify that the Terraform code is valid. You can promote changes between environments by merging into the “development” branch, then into the “non-production” branch, and then finally into the “production” branch. Merging into any of these branches will trigger terraform apply in addition to terraform plan and terraform-validator.
By understanding each layer of your infrastructure, you’ll know where to provision resources later on. When a business unit in your organization is ready to launch a new service, you’ll know that the networking resources can be added to the gcp-networks repository. New tenant projects associated with the service can be provisioned into the gcp-projects repository. Then, you’ll use the app-infra pipelines to provision into those projects any new resources needed for hosting the service. You’ll also be able to leverage the increasing portfolio of other Google Cloud curated security blueprints – like our Secured AI Notebook for Confidential Datablueprint and additional workload security posture blueprints, all of which have been tested for compatibility and interoperability with this foundation’s landing zone. Along the way, you’ll also use CFT modules as needed. For example, you’ll use the project factory module for projects, and the VM module for compute instances instead of their corresponding bare Terraform resources.
The cloud infrastructure you build based on the foundation guide is just that – the foundational landing zone for your infrastructure. Once you have that, you will continue building out your infrastructure as needed. However, it’s important that you consider the security practices that should be continued going forward. Just as the security foundations guide is the basis for the Terraform code in the example foundation repository, and for the CFT modules that make up much of it, it should serve as the basis for any future expansion of infrastructure and cloud resources in order to maintain those best practices. This includes designing processes, pipelines, and tests that enforce these best practices in code. A strong foundation is of utmost importance, and fortunately, the example foundation helps with much of the initial heavy lifting involved.
Read More for the details.