We recommend that you use declarative infrastructure to deploy your foundation in a consistent and controllable manner. This approach helps enable consistent governance by enforcing policy controls about acceptable resource configurations into your pipelines. The blueprint is deployed using a GitOps flow, with Terraform used to define infrastructure as code (IaC), a Git repository for version control and approval of code, and Cloud Build for CI/CD automation in the deployment pipeline. For an introduction to this concept, see managing infrastructure as code with Terraform, Cloud Build, and GitOps.
The following sections describe how the deployment pipeline is used to manage resources in your organization.
Pipeline layers
To separate the teams and technology stack that are responsible for managing different layers of your environment, we recommend a model that uses different pipelines and different personas that are responsible for each layer of the stack.
The following diagram introduces our recommended model for separating a foundation pipeline, infrastructure pipeline, and application pipeline.
The diagram introduces the pipeline layers in this model:
- The foundation pipeline deploys the foundation resources that are used across the platform. We recommend that a single central team is responsible for managing the foundation resources that are consumed by multiple business units and workloads.
- The infrastructure pipeline deploys projects and infrastructure that are used by workloads, such as VM instances or databases. The blueprint sets up a separate infrastructure pipeline for each business unit, or you might prefer a single infrastructure pipeline used by multiple teams.
- The application pipeline deploys the artifacts for each workload, such as containers or images. You might have many different application teams with individual application pipelines.
The following sections introduce the usage of each pipeline layer.
The foundation pipeline
The foundation pipeline deploys the foundation resources. It also sets up the infrastructure pipeline that is used to deploy infrastructure used by workloads.
To create the foundation pipeline, you first clone or fork the
terraform-example-foundation to your own Git repository. Follow the steps in the
0-bootstrap
README file to configure your bootstrap folder and resources.
Stage | Description |
---|---|
Bootstraps a Google Cloud organization. This step also configures a CI/CD pipeline for the blueprint code in subsequent stages.
|
After you create the foundation pipeline in the 0-bootstrap
stage, the following
stages deploy resources on the foundation pipeline. Review the README directions
for each stage and implement each stage sequentially.
Stage | Description |
---|---|
Sets up top-level shared folders, projects for shared services, organization-level logging, and baseline security settings through organization policies. |
|
Sets up development, non-production, and production environments within the Google Cloud organization that you've created. |
|
or |
Sets up shared VPCs in your chosen topology and the associated network resources. |
The infrastructure pipeline
The infrastructure pipeline deploys the projects and infrastructure (for example, the VM instances and databases) that are used by workloads. The foundation pipeline deploys multiple infrastructure pipelines. This separation between the foundation pipeline and infrastructure pipeline allows for a separation between platform-wide resources and workload-specific resources.
The following diagram describes how the blueprint configures multiple infrastructure pipelines that are intended for use by separate teams.
The diagram describes the following key concepts:
- Each infrastructure pipeline is used to manage infrastructure resources independently of the foundation resources.
- Each business unit has its own infrastructure pipeline, managed in a dedicated
project in the
common
folder. - Each of the infrastructure pipelines has a service account with permission to deploy resources only to the projects that are associated with that business unit. This strategy creates a separation of duties between the privileged service accounts used for the foundation pipeline and those used by each infrastructure pipeline
This approach with multiple infrastructure pipelines is recommended when you have multiple entities inside your organization that have the skills and appetite to manage their infrastructure separately, particularly if they have different requirements such as the types of pipeline validation policy they want to enforce. Alternatively, you might prefer to have a single infrastructure pipeline managed by a single team with consistent validation policies.
In the terraform-example-foundation, stage 4 configures an infrastructure pipeline, and stage 5 demonstrates an example of using that pipeline to deploy infrastructure resources.
Stage | Description |
---|---|
Sets up a folder structure, projects, and an infrastructure pipeline. |
|
|
Deploys workload projects with a Compute Engine instance using the infrastructure pipeline as an example. |
The application pipeline
The application pipeline is responsible for deploying application artifacts for each individual workload, such as images or Kubernetes containers that run the business logic of your application. These artifacts are deployed to infrastructure resources that were deployed by your infrastructure pipeline.
The enterprise foundation blueprint sets up your foundation pipeline and infrastructure pipeline, but doesn't deploy an application pipeline. For an example application pipeline, see the enterprise application blueprint.
Automating your pipeline with Cloud Build
The blueprint uses Cloud Build to automate CI/CD processes. The following table describes the controls are built into the foundation pipeline and infrastructure pipeline that are deployed by the terraform-example-foundation repository. If you are developing your own pipelines using other CI/CD automation tools, we recommend that you apply similar controls.
Control | Description |
---|---|
Separate build configurations to validate code before deploying |
The blueprint uses two Cloud Build build configuration files for
the entire pipeline, and each repository that is associated with a stage has two
Cloud Build triggers that are
associated with those build configuration files. When code is pushed to a
repository branch, the build configuration files are triggered to first run |
Terraform policy checks | The blueprint includes a set of Open Policy Agent constraints that are enforced by the policy validation in Google Cloud CLI. These constraints define the acceptable resource configurations that can be deployed by your pipeline. If a build doesn't meet policy in the first build configuration, then the second build configuration doesn't deploy any resources. The policies
enforced in the blueprint are forked from |
Principle of least privilege | The foundation pipeline has a different service
account for each stage with an allow policy that grants only the minimum IAM
roles for that stage. Each Cloud Build trigger runs as the specific
service account for that stage. Using different accounts helps mitigate the risk
that modifying one repository could impact the resources that are managed by
another repository. To understand the particular IAM roles applied to each
service account, see the |
Cloud Build private pools | The blueprint uses Cloud Build private pools. Private pools let you optionally enforce additional controls such as restricting access to public repositories or running Cloud Build inside a VPC Service Controls perimeter. |
Cloud Build custom builders | The blueprint creates its own custom
builder to run Terraform. For more information, see |
Deployment approval | Optionally, you can add a manual approval stage to Cloud Build. This approval adds an additional checkpoint after the build is triggered but before it runs so that a privileged user can manually approve the build. |
Branching strategy
We recommend a persistent branch strategy for submitting code to your Git system and deploying resources through the foundation pipeline. The following diagram describes the persistent branch strategy.
The diagram describes three persistent branches in Git (development, non-production, and production) that reflect the corresponding Google Cloud environments. There are also multiple ephemeral feature branches that don't correspond to resources that are deployed in your Google Cloud environments.
We recommend that you enforce a pull request (PR) process into your Git system so that any code that is merged to a persistent branch has an approved PR.
To develop code with this persistent branch strategy, follow these high-level steps:
- When you're developing new capabilities or working on a bug fix, create a new
branch based off of the development branch. Use a naming convention for your
branch that includes the type of change, a ticket number or other identifier,
and a human-readable description, like
feature/123456-org-policies
. - When you complete the work in the feature branch, open a PR that targets the development branch.
- When you submit the PR, the PR triggers the foundation pipeline to perform
terraform plan
andterraform validate
to stage and verify the changes. - After you validate the changes to the code, merge the feature or bug fix into the development branch.
- The merge process triggers the foundation pipeline to run
terraform apply
to deploy the latest changes in the development branch to the development environment. - Review the changes in the development environment using any manual reviews, functional tests, or end-to-end tests that are relevant to your use case. Then promote changes to the non-production environment by opening a PR that targets the non-production branch and merge your changes.
- To deploy resources to the production environment, repeat the same process as step 6: review and validate the deployed resources, open a PR to the production branch, and merge.
What's next
- Read about operations best practices (next document in this series).