Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
55 changes: 55 additions & 0 deletions .checkov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright 2026 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.

#Scan for GCP High level findings
check:
#Public
- CKV2_GCP_6 #"Ensure that Cloud KMS cryptokeys are not anonymously or publicly accessible"
- CKV2_GCP_9 #"Ensure that Container Registry repositories are not anonymously or publicly accessible"
- CKV_GCP_28 #"Ensure that Cloud Storage bucket is not anonymously or publicly accessible"
- CKV_GCP_94 #"Ensure Dataflow jobs are private"
- CKV_GCP_98 #"Ensure that Dataproc clusters are not anonymously or publicly accessible"
- CKV_GCP_100 #"Ensure that BigQuery Tables are not anonymously or publicly accessible"
- CKV_GCP_101 #"Ensure that Artifact Registry repositories are not anonymously or publicly accessible"
- CKV_GCP_103 #"Ensure Dataproc Clusters do not have public IPs"
#Network
- CKV_GCP_11 #"Ensure that Cloud SQL database Instances are not open to the world"
- CKV_GCP_32 #"Ensure 'Block Project-wide SSH keys' is enabled for VM instances"
#IAM
- CKV2_GCP_8 #"Ensure that Cloud KMS Key Rings are not anonymously or publicly accessible"
- CKV_GCP_41 #"Ensure that IAM users are not assigned the Service Account User or Service Account Token Creator roles at project level"
- CKV_GCP_42 #"Ensure that Service Account has no Admin privileges"
- CKV_GCP_44 #"Ensure no roles that enable to impersonate and manage all service accounts are used at a folder level"
- CKV_GCP_45 #"Ensure no roles that enable to impersonate and manage all service accounts are used at an organization level"
- CKV_GCP_46 #"Ensure Default Service account is not used at a project level"
- CKV_GCP_47 #"Ensure default service account is not used at an organization level"
- CKV_GCP_48 #"Ensure Default Service account is not used at a folder level"
- CKV_GCP_112 #"Ensure KMS policy should not allow public access"
- CKV_GCP_113 #"Ensure IAM policy should not define public access"
- CKV_GCP_115 #"Ensure basic roles are not used at organization level"
- CKV_GCP_117 #"Ensure basic roles are not used at project level."
- CKV_GCP_118 #"Ensure IAM workload identity pool provider is restricted"
- CKV_GCP_125 #"Ensure GCP GitHub Actions OIDC trust policy is configured securely"
#General
- CKV_GCP_14 #"Ensure all Cloud SQL database instance have backup configuration enabled"
- CKV_GCP_15 #"Ensure that BigQuery datasets are not anonymously or publicly accessible"
- CKV_GCP_38 #"Ensure VM disks for critical VMs are encrypted with Customer Supplied Encryption Keys (CSEK)"
- CKV_GCP_114 #"Ensure public access prevention is enforced on Cloud Storage bucket"
- CKV_GCP_120 #"Ensure Spanner Database has drop protection enabled"


# Checks not run
# To do a full scan of all Checkov checks with just these omitted, comment out everything above and uncomment the lines below.
#skip-check:
# - CKV_GCP_33 #-false positive- "Ensure oslogin is enabled for a Project"
24 changes: 24 additions & 0 deletions .codespellrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2026 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.

[codespell]
# Skip specific directories or file extensions
skip = ./.git,./.terraform,*.png,*.jpg,*.pdf,*.gif,*.pyc,*.svg,package-lock.json,./__pycache__,*.md,*.pem

# Interactive or Summary mode settings
count =
quiet-level = 1

# The allowed dictionary file
ignore-words = codespellignore.txt
25 changes: 25 additions & 0 deletions .devcontainer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!--
Copyright 2026 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.
-->

## Development Environment

**To use the Dev Container:**

1. Open project in **VS Code**.
2. Install the **Dev Containers** extension if not already installed.
3. When prompted (or via the Command Palette `F1`), select **Dev Containers: Reopen in Container**.
4. Once the container builds, you will have a terminal with all tools ready to use.
5. Run `gcloud auth login` and `gcloud auth application-default login` to authenticate.
32 changes: 32 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "stellar-engine Dev Container",
"image": "mcr.microsoft.com/devcontainers/python:3.11",
"features": {
"ghcr.io/devcontainers/features/terraform:1": {
"version": "latest",
"tflint": "latest",
"terragrunt": "latest"
}
},
"customizations": {
"vscode": {
"extensions": [
"hashicorp.terraform",
"ms-python.python",
"bridgecrew.checkov",
"redhat.vscode-yaml"
],
"settings": {
"python.defaultInterpreterPath": "/usr/local/bin/python",
"terraform.languageServer.enable": true,
"[terraform]": {
"editor.defaultFormatter": "hashicorp.terraform",
"editor.formatOnSave": true,
"editor.formatOnSaveMode": "file"
}
}
}
},
"postCreateCommand": "bash .devcontainer/post-create.sh",
"remoteUser": "vscode"
}
46 changes: 46 additions & 0 deletions .devcontainer/post-create.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash
# Copyright 2026 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.

set -e

echo "Starting post-create setup..."

# Install dependencies
echo "Installing system dependencies and Google Cloud SDK..."
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates gnupg curl jq shellcheck

# Add Google Cloud SDK
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee /etc/apt/sources.list.d/google-cloud-sdk.list

# Import the Google Cloud public key
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor --yes -o /usr/share/keyrings/cloud.google.gpg

# Install the Cloud SDK
sudo apt-get update && sudo apt-get install -y google-cloud-cli

# Install python dependencies
if [ -f "tools/requirements.txt" ]; then
echo "Installing requirements from tools/requirements.txt..."
pip install -r tools/requirements.txt
else
echo "Warning: tools/requirements.txt not found."
fi

# Install checkov
echo "Installing Checkov..."
pip install checkov

echo "Dev container setup complete!"
3 changes: 2 additions & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2025 Google LLC
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.


workflow:
rules:
- when: never # This rule will always prevent the pipeline from running until we have a properly configured and registered runner instance.
Expand Down
105 changes: 105 additions & 0 deletions .gitlab/ci/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Terraform Landing Zone Automation Pipeline

## Overview
This repository contains the Continuous Deployment (CD) pipeline for our Terraform-based Landing Zone (LZ). The pipeline is designed to automate infrastructure provisioning, executing `terraform plan` and `terraform apply` whenever code is merged into the `main` branch.

To maintain security, separation of duties, and modularity, the pipeline is divided into distinct stages and utilizes dynamic child pipelines to manage multi-tenant infrastructure efficiently.

---

## Architecture & Design

### Authentication
All authentication from the GitLab instance to Google Cloud is handled securely through **Workload Identity Federation (WIF)**.
* GitLab authenticates via an OpenID Connect (OIDC) provider configured in Google Cloud.
* The WIF pool ID and prefix are passed as GitLab CI/CD variables to authorize the runner.
* This setup allows the pipeline to impersonate specific service accounts for each stage, ensuring strict separation of duties and least-privilege access.

### Pipeline Jobs & Stages
The pipeline is highly modular. Core infrastructural changes go through standard stages.

| Job Name | Description |
| :--- | :--- |
| `compliance` | Runs immediately after the Stage 1 plan. Cross-checks the plan against allowed YAML configurations to ensure no services outside the compliance catalog (or compliance COA decisions) are utilized. |
| `<Stage_number>-plan` | Runs for Stages 0-4. Previews infrastructure changes on Merge Requests and `main`. Downloads tools, tfvars, and providers. Saves the plan as a GitLab artifact. |
| `<Stage_number>-apply` | Executes **only** on the `main` branch. Uses the saved plan artifact from the previous step to provision approved changes. |

### Execution Flow & Dependencies
Because of the modular design, the pipeline intelligently determines which stages need to run based on the files changed:

* **Changes in Stage 0:** Runs only Stage 0.
* **Changes in Stage 1:** Runs Stage 1, 2, 3, 4, and 5.
* **Changes in Stage 2:** Runs Stage 2, 3, 4, and 5.
* **Changes in Stage 3:** Runs Stage 3 and 5.
* **Changes in Stage 4:** Runs Stage only stage 4.
* **Changes in stage 5 or `tenants.yml`:** Runs only Stage 5.

*(Note: The pipeline automatically triggers the **Plan** stage, but will pause and wait for a **manual trigger** before executing the **Apply** stage).*

---

## Setup & Integration Guide

The following steps guide you through bootstrapping a new environment so that the automated CI/CD pipeline can take over subsequent deployments.

> **Best Practices**
> * Keep variable names exactly the same as documented.
> * Maintain the exact format for variable values.

### 1. Local Configuration

Authenticate your local `gcloud` environment:
```bash
gcloud auth login
gcloud auth application-default login
```

Create and set up your `config.env` file (use `config.env.sample` for reference). Be sure to include the Workload Identity Federation variables:
```env
# Workload Identity Federation via GitLab
CI_PROJECT_PATH=google-cloud/enterprise-lz
# If deployment is for prod this should be main or the equivelent protected branch
CI_COMMIT_BRANCH=<Branch name you are testing on>
GITLAB_URL=[https://gitlab.example.com](https://gitlab.example.com)
```

Update the `tenants.yml` file located in the root directory to reflect the initial tenants you are deploying via `automation/tenant.sh`.

### 2. Initial Bootstrap (Stages 0 & 1)

To allow the CI/CD pipeline to assume control, you must manually deploy Stages 0 and 1 locally first. This establishes the Workload Identity Federation and impersonation service accounts.

**Run `./stellar-engine-deploy.sh`**
1. Go through all of stage 0
2. Run the through the first and second apply for stage one and update providers and migrate state, stop at the third apply without the bootstrap user.

🎉 **Success:** Workload Identity Federation should now be active. You can verify this by checking the `-il5-prod-iac` project in your GCP Console under **IAM > Workload Identity Federation**.

---

## GitLab Configuration

Now that WIF is set up in Google Cloud, you need to configure the connection variables in GitLab.

1. **Gather your WIF Provider Variable:**
Run the following command from the `1-assured-workload` directory to extract the exact WIF path:
```bash
cd fast/stages-aw/1-assured-workload
terraform output -json workload_identity_pool | jq -r '.providers."gitlab-fed".audiences[1] | sub("[https://iam.googleapis.com/](https://iam.googleapis.com/)"; "")'
```
*The output will look similar to: `projects/<project-ID>/locations/global/workloadIdentityPools/<WIF-pool-name>`*

2. **Set GitLab Variables:**
* Navigate to **Settings > CI/CD** in your GitLab repository and expand the **Variables** section.
* Edit the `PREFIX` variable and replace the value with your deployment's prefix.
* Edit the `GCP_WORKLOAD_IDENTITY_PROVIDER` variable and paste the filepath outputted from the `jq` command above.
* Click **Save Changes**.

---

## Usage

### Running the Pipeline
* Commits pushed to `fast/stages-aw` will trigger the pipeline automatically based on the dependency rules outlined in the Architecture section.
* To view a plan, click on the **logs** for the specific plan stage in the GitLab UI.
* To apply changes, click the **Play** button on the manual apply stage.
Loading