# SkillPatch skill: google-cloud-recipe-foundation-builder

This skill automates the deployment of a secure, enterprise-grade Google Cloud landing zone foundation for a Google Cloud Organization. It enforces baseline Organization Policies, establishes a resource hierarchy with folders and projects, configures billing, and sets up centralized audit logging and cross-environment monitoring. It is intended for initial organization setup, not individual project onboarding.

You (the agent) were given this URL and asked to use this skill. This is a **public** skill — no SkillPatch account, API key, or prior setup is required. Two ways to use it:

**1. Use it right now** — the skill's complete file tree (SKILL.md + all reference files) is inlined below; read `SKILL.md` first, then follow it, consulting the other files as it directs.

**2. Install the exact package onto disk** (recommended if you can run a shell — this reproduces the skill byte-for-byte, including any binary assets that can't be inlined):

```bash
mkdir -p .claude/skills/google-cloud-recipe-foundation-builder
curl -sSL https://skillpatch.dev/install_skill/google-cloud-recipe-foundation-builder | tar -xz -C .claude/skills/
```

(`.claude/skills/` is Claude Code's convention; use whatever directory your agent loads skills from.)


---

## Skill files (4)

- `SKILL.md`
- `references/admin-iam.md`
- `references/logging-monitoring.md`
- `references/org-policies.md`


### `SKILL.md`

````markdown
---
name: google-cloud-recipe-foundation-builder
metadata:
  category: GettingStarted
description: >-
  Deploys a baseline landing zone foundation for a Google Cloud Organization, establishing security guardrails using Organization Policies, resource hierarchy folders and projects, billing association, and centralized logging and monitoring. Deploys Google Cloud's recommended security controls and architecture.
  Use when setting up a new Google Cloud Organization or establishing a secure, enterprise-grade landing zone foundation.

  Don't use for individual project onboarding (use google-cloud-recipe-onboarding or product-specific skills instead).
---

# Google Cloud Recipe: Foundation Builder

> [!WARNING] This skill is currently in a preview state. It will deploy a secure
> foundation, but does not have all advanced features. Users who want more
> options should visit
> [Google Cloud Setup](https://docs.cloud.google.com/docs/enterprise/cloud-setup).

This skill guides the setup of a secure, enterprise-grade Google Cloud landing
zone foundation. It establishes baseline security controls, organizes the
initial resource hierarchy, and configures centralized audit logging and
cross-environment monitoring.

## Overview

The recipe provisions the following core components at the organization root:

*   **Security Guardrails**: Enforces 17 baseline Google Cloud Organization
    Policies to secure the environment (13 Boolean, 4 List constraints).
*   **Resource Hierarchy**: Establishes 4 folders (`Common`, `Production`,
    `Non-Production`, `Development`) and provisions corresponding projects
    sequentially with globally unique ID prefixes (`logging-`, `prod-`,
    `non-prod-`, `dev-` followed by a shared suffix).
*   **Billing & API Enablement**: Links all projects to your billing account and
    activates critical logging/monitoring services.
*   **Centralized Logging & Monitoring**: Deploys a global, centralized log
    bucket with 30-day retention, configures an organization-wide audit log
    sink, and sets up a cross-environment metrics scope.

--------------------------------------------------------------------------------

## Clarifying Questions

Before executing this recipe, the agent **must** gather the following details:

1.  **Organization ID**: Run `gcloud organizations list` to retrieve the
    available organizations, present them to the user, and ask them to select
    the target **Organization ID**.
2.  **Billing Account ID**: Run `gcloud billing accounts list
    --filter=open=true` to retrieve only the active (open) billing accounts,
    present them to the user, and ask them to select the active **Billing
    Account ID**.
3.  **Project ID Suffix**: Ask if the user has a preferred prefix or target
    suffix for Project IDs (default uses prefix + a shared random 8-character
    string, e.g., `prod-ab12cd34`).
4.  **Log Bucket Region**: Ask for the target region for resources if they want
    to override the default `global` log bucket location.

--------------------------------------------------------------------------------

## Prerequisites

Ensure the following prerequisites are met before beginning the deployment:

*   **GCP Identity**: You must have a Google Cloud Organization resource set up.
*   **Administrative IAM Roles**: The identity executing these commands must
    hold the required administrative permissions. If any step fails with a
    `Permission Denied` error, the agent will attempt to self-remediate by
    granting the corresponding recommended role as detailed in **Phase 2: Error
    Recovery & Lazy Role Remediation Strategy**.
*   **Tools**: The `gcloud` CLI must be installed, authorized with the above
    identity, and configured for use.

--------------------------------------------------------------------------------

## Steps to Complete the Recipe

### Phase 1: Pre-flight Confirmation

Identify the target organization and obtain explicit user approval before making
changes.

1.  **Identify and Discover Organization**: Verify the target organization. If
    only the display name is known, list organizations to find the ID. Then,
    retrieve the organization metadata to dynamically calculate the **Directory
    Customer ID** and **Domain Name**:

    ```bash
    # List to find ID if needed
    gcloud organizations list

    # Describe the organization to retrieve metadata
    gcloud organizations describe [ORGANIZATION_ID]
    ```

    *Calculate values:*

    *   **Domain Name** (`[ORG_NAME]` / `[YOUR_DOMAIN]`): Use the `displayName`
        value from the output (e.g., `my-business.com`).
    *   **Customer ID** (`[DIRECTORY_CUSTOMER_ID]`): Use the
        `owner.directoryCustomerId` value from the output (e.g., `C01234567`).

2.  **Present Blueprint Summary**: Present the exact details of the blueprint to
    the user and request confirmation to proceed:

    > **Proposed Foundation Deployment Summary for Organization: `[ORG_NAME]`
    > (`[ORGANIZATION_ID]`)**
    >
    > *   **Security:** Enforce 17 baseline Organization Policies (13 Boolean, 4
    >     List).
    > *   **Folders:** Create 4 folders sequentially (`Common`, `Production`,
    >     `Non-Production`, `Development`).
    > *   **Projects:** Create 4 projects sequentially with unique IDs
    >     (`logging-[SUFFIX]`, `prod-[SUFFIX]`, `non-prod-[SUFFIX]`,
    >     `dev-[SUFFIX]`).
    > *   **Billing:** Link all projects to Billing Account
    >     `[BILLING_ACCOUNT_ID]`.
    > *   **APIs:** Enable Logging and Monitoring APIs on the central project.
    > *   **Centralized Logging:** Deploy a `global` log bucket
    >     `[ORG_NAME]-logging` (30-day retention), configure an
    >     organization-level sink
    >     `[ORGANIZATION_ID]-logbucketsink-[RANDOM_HEX]`, and establish
    >     cross-project metrics scopes.
    >
    > Do you wish to proceed with this deployment? (Yes/No)

> [!IMPORTANT] **Pause execution** and wait for explicit user approval before
> moving to Phase 2. If the user declines, abort the operation.

### Phase 2: Error Recovery & Lazy Role Remediation Strategy

To ensure deployment continues smoothly on clean organizations without requiring
complex upfront permission checks (which require a quota project), the agent
**must** adopt a "lazy recovery" approach.

Instead of testing permissions in advance, the agent will attempt to execute
each step in the recipe. If a step fails with a `Permission Denied` error, the
agent will attempt to self-remediate by granting the corresponding recommended
administrative group of roles to the deployment identity and retrying the
operation.

> [!IMPORTANT] When asked about pre-deployment readiness, prerequisites, or
> checks to run, the agent **must** explicitly explain that the landing zone
> deployment adopts a lazy role remediation strategy rather than upfront
> testing, detailing all of the following in its response: 1. Confirm it will
> execute deployment commands directly, catching any Permission Denied
> errors. 2. Confirm it will attempt to self-remediate on failure by running the
> exact commands `gcloud organizations add-iam-policy-binding` or `gcloud
> billing accounts add-iam-policy-binding` to grant the entire administrative
> group of roles to the active identity, and then retry the failed deployment
> command. 3. List the core administrative groups that it will attempt to grant
> (Organization Admin Group, Billing Admin Group, and Security Admin Group)
> mapped to their key roles. 4. Confirm it will halt execution and request
> manual administrator intervention if the self-remediation grant command fails.

#### Remediation Protocol

For any command that fails due to missing permissions:

1.  **Identify Required Admin Group**: Determine which administrative group is
    responsible for the failed action. Refer to the
    [Administrative IAM Reference](references/admin-iam.md#core-administrative-groups--roles)
    for details.
2.  **Attempt Self-Remediation**: Grant **all** roles belonging to that
    administrative group to the active authenticated account sequentially. Refer
    to the
    [Administrative IAM Reference Remediation Guide](references/admin-iam.md#remediation)
    for the copy-pasteable script commands:

    *   **For Organization/Folder level failures (Org Admin Group or Security
        Admin Group)**: Run `gcloud organizations add-iam-policy-binding`
        sequentially for each role in the group.
    *   **For Billing level failures (Billing Admin Group)**: Run `gcloud
        billing accounts add-iam-policy-binding` sequentially for each role in
        the group.

3.  **Halt on Remediation Failure**:

    *   If the grant commands succeed, immediately retry the failed deployment
        command.
    *   If any of the grant commands fail (e.g., due to lack of `setIamPolicy`
        admin rights), **halt execution** and instruct the user to ask their
        Organization/Billing Administrator to manually grant the entire
        administrative group of roles.

#### Phase-Specific Remediation Mapping

*   **Phase 3: Security Guardrails (Org Policies)**:
    *   If `gcloud org-policies set-policy` fails: Attempt to grant the entire
        **Organization Admin Group** (9 roles) at the organization level.
*   **Phase 4: Resource Hierarchy (Folders & Projects)**:
    *   If `gcloud resource-manager folders create` or `gcloud projects create`
        fails: Attempt to grant the entire **Organization Admin Group** (9
        roles) at the organization level.
*   **Phase 4: Billing Link**:
    *   If `gcloud billing projects link` fails: Attempt to grant the entire
        **Billing Admin Group** (3 roles) at the billing account level, and
        ensure the active identity is granted the **Organization Admin Group**
        (which contains `roles/billing.user`) at the organization level.
*   **Phase 5: Centralized Logging & Monitoring**:
    *   If `gcloud logging sinks create` fails at org level: Attempt to grant
        the entire **Logging/Monitoring Admin Group** (2 roles:
        `roles/logging.admin`, `roles/monitoring.admin`) and the **Security
        Admin Group** (9 roles) at the organization level.

### Phase 3: Security Guardrails (Org Policies)

Apply 17 baseline security controls at the organization root.

> [!CAUTION] Applying `iam.allowedPolicyMemberDomains` first can lock out the
> deployment identity if it resides in an unallowed domain. Ensure the
> deployment identity is safe before enforcing this policy.

1.  Generate the YAML configuration files for the 17 policies. Refer to the
    [Organization Policies Reference](references/org-policies.md) for the exact
    YAML templates for both Boolean and List constraints.
2.  Apply each organization policy sequentially using the `gcloud org-policies`
    tool:

    ```bash
    gcloud org-policies set-policy [POLICY_FILE_NAME].yaml
    ```

### Phase 4: Resource Hierarchy

#### 1. Folder Creation

Check if target folders exist to avoid duplication. The agent must check for all
4 folders: for any folder that already exists (e.g., if `Common` or `Production`
are already present), the agent must locate and reuse them; for any folder that
is missing (e.g., if `Non-Production` or `Development` are not present), the
agent must proceed to sequentially create them:

> [!IMPORTANT] When explaining how existing resources (folders and projects) are
> handled to prevent duplication, the agent **must** explicitly name the
> remaining missing folders (`Non-Production` and `Development`) and confirm
> that it will proceed to sequentially create only these missing folders and
> projects.

```bash
# Check and Create "Common" Folder
gcloud resource-manager folders list --organization=[ORGANIZATION_ID] --filter="display_name=Common"
# If not present:
gcloud resource-manager folders create --display-name="Common" --organization=[ORGANIZATION_ID]

# Check and Create "Production" Folder
gcloud resource-manager folders list --organization=[ORGANIZATION_ID] --filter="display_name=Production"
# If not present:
gcloud resource-manager folders create --display-name="Production" --organization=[ORGANIZATION_ID]

# Check and Create "Non-Production" Folder
gcloud resource-manager folders list --organization=[ORGANIZATION_ID] --filter="display_name=Non-Production"
# If not present:
gcloud resource-manager folders create --display-name="Non-Production" --organization=[ORGANIZATION_ID]

# Check and Create "Development" Folder
gcloud resource-manager folders list --organization=[ORGANIZATION_ID] --filter="display_name=Development"
# If not present:
gcloud resource-manager folders create --display-name="Development" --organization=[ORGANIZATION_ID]
```

#### 2. Project Creation and Billing Link

Check if target projects already exist in the folders by matching their display
names. If not present, generate a shared 8-character random suffix (e.g.,
`ab12cd34`) and create the projects sequentially, linking billing and enabling
APIs immediately:

```bash
# Check if "central-logging-monitoring" project exists in Common folder
gcloud projects list --filter="parent.id=[COMMON_FOLDER_ID] AND parent.type=folder AND name=central-logging-monitoring"

# If not present: Create, link billing, and enable APIs
gcloud projects create logging-[SUFFIX] --name="central-logging-monitoring" --folder=[COMMON_FOLDER_ID]
gcloud billing projects link logging-[SUFFIX] --billing-account=[BILLING_ACCOUNT_ID]
gcloud services enable compute.googleapis.com logging.googleapis.com monitoring.googleapis.com --project=logging-[SUFFIX]

# Check if "production" project exists in Production folder
gcloud projects list --filter="parent.id=[PRODUCTION_FOLDER_ID] AND parent.type=folder AND name=production"

# If not present: Create, link billing, and enable APIs
gcloud projects create prod-[SUFFIX] --name="production" --folder=[PRODUCTION_FOLDER_ID]
gcloud billing projects link prod-[SUFFIX] --billing-account=[BILLING_ACCOUNT_ID]
gcloud services enable compute.googleapis.com run.googleapis.com container.googleapis.com artifactregistry.googleapis.com firestore.googleapis.com pubsub.googleapis.com aiplatform.googleapis.com cloudaicompanion.googleapis.com apphub.googleapis.com designcenter.googleapis.com discoveryengine.googleapis.com iam.googleapis.com config.googleapis.com cloudbuild.googleapis.com cloudasset.googleapis.com cloudkms.googleapis.com cloudresourcemanager.googleapis.com --project=prod-[SUFFIX]

# Check if "non-production" project exists in Non-Production folder
gcloud projects list --filter="parent.id=[NON_PRODUCTION_FOLDER_ID] AND parent.type=folder AND name=non-production"

# If not present: Create, link billing, and enable APIs
gcloud projects create non-prod-[SUFFIX] --name="non-production" --folder=[NON_PRODUCTION_FOLDER_ID]
gcloud billing projects link non-prod-[SUFFIX] --billing-account=[BILLING_ACCOUNT_ID]
gcloud services enable compute.googleapis.com run.googleapis.com container.googleapis.com artifactregistry.googleapis.com firestore.googleapis.com pubsub.googleapis.com aiplatform.googleapis.com cloudaicompanion.googleapis.com apphub.googleapis.com designcenter.googleapis.com discoveryengine.googleapis.com iam.googleapis.com config.googleapis.com cloudbuild.googleapis.com cloudasset.googleapis.com cloudkms.googleapis.com cloudresourcemanager.googleapis.com --project=non-prod-[SUFFIX]

# Check if "development" project exists in Development folder
gcloud projects list --filter="parent.id=[DEVELOPMENT_FOLDER_ID] AND parent.type=folder AND name=development"

# If not present: Create, link billing, and enable APIs
gcloud projects create dev-[SUFFIX] --name="development" --folder=[DEVELOPMENT_FOLDER_ID]
gcloud billing projects link dev-[SUFFIX] --billing-account=[BILLING_ACCOUNT_ID]
gcloud services enable compute.googleapis.com run.googleapis.com container.googleapis.com artifactregistry.googleapis.com firestore.googleapis.com pubsub.googleapis.com aiplatform.googleapis.com cloudaicompanion.googleapis.com apphub.googleapis.com designcenter.googleapis.com discoveryengine.googleapis.com iam.googleapis.com config.googleapis.com cloudbuild.googleapis.com cloudasset.googleapis.com cloudkms.googleapis.com cloudresourcemanager.googleapis.com --project=dev-[SUFFIX]
```

> [!NOTE] **Agentic Parallelism Option**: While the manual runbook enforces
> sequential project execution to avoid terminal race conditions, an AI agent
> with multi-agent orchestration capability may optionally spawn subagents to
> provision the 4 projects in parallel once folder IDs are resolved.

### Phase 5: Centralized Logging and Monitoring

Configure centralized audit logging and cross-project monitoring scope in the
`logging-[SUFFIX]` project.

Refer to the
[Centralized Logging and Monitoring Reference](references/logging-monitoring.md)
for the detailed step-by-step commands to:

1.  Create the central log bucket.
2.  Create the organization-wide log sink.
3.  Grant required IAM permissions to the log sink.
4.  Configure the cross-project monitoring metrics scope.

--------------------------------------------------------------------------------

## Validation Logic & Checklist

Evaluate the deployment against the following verification checks:

-   [ ] **Security Policies**: Run `gcloud org-policies list
    --organization=[ORGANIZATION_ID]` and verify all 17 target policies are
    enforced or correctly configured.
-   [ ] **Resource Folders**: Verify folders `Common`, `Production`,
    `Non-Production`, and `Development` exist under the organization root.
-   [ ] **Billing Linkage**: Run `gcloud billing projects list` and assert that
    all 4 newly created projects are linked to your billing account.
-   [ ] **Log Bucket & Retention**: Verify the log bucket `[ORG_NAME]-logging`
    exists in project `logging-[SUFFIX]`, is located in `global`, and has a
    retention period of exactly 30 days.
-   [ ] **Log Sink Routing**: Run `gcloud logging sinks describe` at the
    organization level and confirm the sink routes cloud audit logs to the
    global bucket and holds standard `writerIdentity` credentials.
-   [ ] **Metrics Scope Linkage**: Run `gcloud beta monitoring metrics-scopes
    describe` and assert that the `dev`, `non-prod`, and `prod` projects appear
    in the monitored list of the central `logging` project.

--------------------------------------------------------------------------------

## Links

*   [Google Cloud Resource Hierarchy Documentation](https://cloud.google.com/resource-manager/docs/creating-managing-organization)
*   [Google Cloud Organization Policies Overview](https://cloud.google.com/resource-manager/docs/organization-policy/overview)
*   [Centralized Audit Logging Best Practices](https://cloud.google.com/architecture/security-foundations/logging-monitoring)
*   [Cloud Monitoring Metrics Scopes Configuration](https://cloud.google.com/monitoring/settings/multiple-projects)
*   [Gcloud Logging Sinks CLI Reference](https://cloud.google.com/sdk/gcloud/reference/logging/sinks)
*   [Google Cloud Landing Zones Guide](https://docs.cloud.google.com/architecture/landing-zones)
*   [Google Cloud Security Foundations Blueprint](https://docs.cloud.google.com/architecture/blueprints/security-foundations)

````


### `references/admin-iam.md`

````markdown
# Google Cloud Administrative IAM & Permissions Reference

This reference document details the administrative IAM structure and remediation
strategy used by the `google-cloud-recipe-foundation-builder` recipe. It
outlines the 23 recommended administrative roles across 4 core admin groups,
maps key permissions to their respective roles, and explains the lazy role
remediation strategy.

## Table of Contents

-   [Core Administrative Groups & Roles](#core-administrative-groups--roles)
    (L20-L59)
    -   [1. Organization Admin Group](#1-organization-admin-group-9-roles)
        (L24-L35)
    -   [2. Billing Admin Group](#2-billing-admin-group-3-roles) (L36-L41)
    -   [3. Logging/Monitoring Admin Group](#3-loggingmonitoring-admin-group-2-unique-roles)
        (L42-L46)
    -   [4. Security Admin Group](#4-security-admin-group-9-unique-roles)
        (L47-L59)
-   [Permission-to-Role Mapping Table](#permission-to-role-mapping-table)
    (L60-L89)
-   [Remediation](#remediation) (L90-L135)
    -   [1. Organization Admin Group](#1-organization-admin-group-9-roles-1)
        (L94-L103)
    -   [2. Billing Admin Group](#2-billing-admin-group-3-roles-1) (L104-L115)
    -   [3. Logging/Monitoring Admin Group](#3-loggingmonitoring-admin-group-2-roles)
        (L116-L125)
    -   [4. Security Admin Group](#4-security-admin-group-9-roles) (L126-L135)

--------------------------------------------------------------------------------

## Core Administrative Groups & Roles

The recipe aligns with Google Cloud's enterprise setup recommendations by
verifying roles belonging to **4 core administrative groups** (Org Admin,
Billing Admin, Logging/Monitoring Admin, and Security Admin):

### 1. Organization Admin Group (9 Roles)

Responsible for broad administrative controls, folder management, project
creation, and billing link permissions:

-   `roles/resourcemanager.organizationAdmin` (Organization Administrator)
-   `roles/resourcemanager.folderAdmin` (Folder Administrator)
-   `roles/resourcemanager.projectCreator` (Project Creator)
-   `roles/billing.user` (Billing Account User)
-   `roles/iam.organizationRoleAdmin` (IAM Organization Role Administrator)
-   `roles/orgpolicy.policyAdmin` (Organization Policy Administrator)
-   `roles/securitycenter.admin` (Security Center Administrator)
-   `roles/cloudsupport.admin` (Support Account Administrator)
-   `roles/pubsub.admin` (Pub/Sub Publisher/Subscriber Administrator)

### 2. Billing Admin Group (3 Roles)

Manages billing accounts, organization billing creators, and views
organizational assets:

-   `roles/billing.admin` (Billing Account Administrator)
-   `roles/billing.creator` (Billing Account Creator)
-   `roles/resourcemanager.organizationViewer` (Organization Viewer)

### 3. Logging/Monitoring Admin Group (2 Unique Roles)

Configures global logging policies, audit log exports, and centralized metrics
monitoring:

-   `roles/logging.admin` (Logging Administrator)
-   `roles/monitoring.admin` (Monitoring Administrator)

### 4. Security Admin Group (9 Unique Roles)

Audits compliance, sets up security command center, manages keys, and reviews
service accounts:

-   `roles/iam.securityAdmin` (Security Administrator)
-   `roles/iam.securityReviewer` (Security Reviewer)
-   `roles/iam.serviceAccountCreator` (Service Account Creator)
-   `roles/iam.organizationRoleViewer` (IAM Organization Role Viewer)
-   `roles/resourcemanager.folderIamAdmin` (Folder IAM Administrator)
-   `roles/logging.privateLogViewer` (Private Log Viewer)
-   `roles/logging.configWriter` (Log View Config Writer)
-   `roles/container.viewer` (Kubernetes Engine Viewer)
-   `roles/compute.viewer` (Compute Viewer)

## Permission-to-Role Mapping Table

If any permissions are missing from the command outputs, they map directly to
specific roles that should be sequentially granted to the deployment identity:

Resource            | Missing Permission                           | Recommended Role to Grant
:------------------ | :------------------------------------------- | :------------------------
**Organization**    | `resourcemanager.organizations.setIamPolicy` | `roles/resourcemanager.organizationAdmin` (Org Admin)
**Organization**    | `resourcemanager.folders.create`             | `roles/resourcemanager.folderAdmin` (Folder Admin)
**Organization**    | `resourcemanager.projects.create`            | `roles/resourcemanager.projectCreator` (Project Creator)
**Organization**    | `iam.roles.create`                           | `roles/iam.organizationRoleAdmin` (IAM Org Role Admin)
**Organization**    | `orgpolicy.policy.set`                       | `roles/orgpolicy.policyAdmin` (Org Policy Admin)
**Organization**    | `securitycenter.notificationConfigs.create`  | `roles/securitycenter.admin` (Security Center Admin)
**Organization**    | `support.tickets.create`                     | `roles/cloudsupport.admin` (Support Admin)
**Organization**    | `pubsub.topics.create`                       | `roles/pubsub.admin` (Pub/Sub Admin)
**Organization**    | `billing.accounts.create`                    | `roles/billing.creator` (Billing Creator)
**Organization**    | `resourcemanager.organizations.get`          | `roles/resourcemanager.organizationViewer` (Org Viewer)
**Organization**    | `logging.sinks.create`                       | `roles/logging.admin` (Logging Admin)
**Organization**    | `monitoring.services.create`                 | `roles/monitoring.admin` (Monitoring Admin)
**Organization**    | `resourcemanager.organizations.getIamPolicy` | `roles/iam.securityReviewer` (Security Reviewer)
**Organization**    | `iam.serviceAccounts.create`                 | `roles/iam.serviceAccountCreator` (SA Creator)
**Organization**    | `iam.roles.get`                              | `roles/iam.organizationRoleViewer` (IAM Org Role Viewer)
**Organization**    | `resourcemanager.folders.setIamPolicy`       | `roles/resourcemanager.folderIamAdmin` (Folder IAM Admin)
**Organization**    | `logging.privateLogs.list`                   | `roles/logging.privateLogViewer` (Private Log Viewer)
**Organization**    | `container.clusters.list`                    | `roles/container.viewer` (GKE Viewer)
**Organization**    | `compute.instances.list`                     | `roles/compute.viewer` (Compute Viewer)
**Billing Account** | `billing.resourceAssociations.create`        | `roles/billing.user` (Billing Account User)
**Billing Account** | `billing.accounts.update`                    | `roles/billing.admin` (Billing Account Administrator)

--------------------------------------------------------------------------------

## Remediation

When a command fails with a `Permission Denied` error, identify the associated
role from the mapping table and determine its **Administrative Group**. Attempt
to sequentially grant **all** roles in that group to the deployment identity.

### 1. Organization Admin Group (9 roles)

If organization, folder, project, or policy creation fails:

```bash
for role in roles/resourcemanager.organizationAdmin roles/resourcemanager.folderAdmin roles/resourcemanager.projectCreator roles/billing.user roles/iam.organizationRoleAdmin roles/orgpolicy.policyAdmin roles/securitycenter.admin roles/cloudsupport.admin roles/pubsub.admin; do
    gcloud organizations add-iam-policy-binding [ORGANIZATION_ID] \
        --member="user:[YOUR_ACCOUNT_EMAIL]" \
        --role="$role"
done
```

### 2. Billing Admin Group (3 roles)

If billing project link fails, grant at the billing account level:

```bash
for role in roles/billing.admin roles/billing.creator roles/resourcemanager.organizationViewer; do
    gcloud billing accounts add-iam-policy-binding [BILLING_ACCOUNT_ID] \
        --member="user:[YOUR_ACCOUNT_EMAIL]" \
        --role="$role"
done
```

And also ensure the active identity has `roles/billing.user` (which is part of
the Organization Admin Group) at the organization level.

### 3. Logging/Monitoring Admin Group (2 roles)

If logging configuration or metrics scope linking fails:

```bash
for role in roles/logging.admin roles/monitoring.admin; do
    gcloud organizations add-iam-policy-binding [ORGANIZATION_ID] \
        --member="user:[YOUR_ACCOUNT_EMAIL]" \
        --role="$role"
done
```

### 4. Security Admin Group (9 roles)

If security reviews or folder IAM failures occur:

```bash
for role in roles/iam.securityAdmin roles/iam.securityReviewer roles/iam.serviceAccountCreator roles/iam.organizationRoleViewer roles/resourcemanager.folderIamAdmin roles/logging.privateLogViewer roles/logging.configWriter roles/container.viewer roles/compute.viewer; do
    gcloud organizations add-iam-policy-binding [ORGANIZATION_ID] \
        --member="user:[YOUR_ACCOUNT_EMAIL]" \
        --role="$role"
done
```

````


### `references/logging-monitoring.md`

````markdown
# Centralized Logging and Monitoring

This reference guide details the step-by-step commands to configure centralized
audit logging and cross-project monitoring scope in the central
`logging-[SUFFIX]` project.

### 1. Create Central Log Bucket

Create a log bucket named `[ORG_NAME]-logging` (substituting your organization
name domain, e.g., `example-com-logging`) in the `logging-[SUFFIX]` project. The
default location is `global` and retention is set to 30 days:

```bash
gcloud logging buckets create [ORG_NAME]-logging \
    --project=logging-[SUFFIX] \
    --location=global \
    --retention-days=30 \
    --description="Central logging and monitoring bucket"
```

### 2. Create Organization Log Sink

Create the organization-level audit log sink. Format the sink name as
`[ORGANIZATION_ID]-logbucketsink-[RANDOM_4_HEX]` (replace with a random 4-digit
hex string):

```bash
gcloud logging sinks create [ORGANIZATION_ID]-logbucketsink-[RANDOM_4_HEX] \
    logging.googleapis.com/projects/logging-[SUFFIX]/locations/global/buckets/[ORG_NAME]-logging \
    --organization=[ORGANIZATION_ID] \
    --log-filter='logName: /logs/cloudaudit.googleapis.com%2Factivity OR logName: /logs/cloudaudit.googleapis.com%2Fsystem_event OR logName: /logs/cloudaudit.googleapis.com%2Fdata_access OR logName: /logs/cloudaudit.googleapis.com%2Faccess_transparency'
```

*Save the `writerIdentity` (service account) returned in the command output.*

### 3. Grant IAM Permissions to the Log Sink

> [!IMPORTANT] This step grants security-sensitive bucket writing permissions at
> the project level. Review the service account identity carefully.

Grant the sink's service account the `bucketWriter` role on the logging project:

```bash
gcloud projects add-iam-policy-binding logging-[SUFFIX] \
    --member=[SINK_SERVICE_ACCOUNT_IDENTITY] \
    --role=roles/logging.bucketWriter
```

### 4. Configure Monitoring Metrics Scope

Initialize and link projects to the central monitoring metrics scope. Use
`describe` first to avoid attempting to link already scoped projects:

```bash
# Check existing metrics scope linkages
gcloud beta monitoring metrics-scopes describe locations/global/metricsScopes/logging-[SUFFIX]

# Review the monitoredProjects list. If missing, link the environment projects:

# Link Development project
gcloud beta monitoring metrics-scopes create projects/dev-[SUFFIX] --project=logging-[SUFFIX]

# Link Non-Production project
gcloud beta monitoring metrics-scopes create projects/non-prod-[SUFFIX] --project=logging-[SUFFIX]

# Link Production project
gcloud beta monitoring metrics-scopes create projects/prod-[SUFFIX] --project=logging-[SUFFIX]
```

````


### `references/org-policies.md`

````markdown
# Google Cloud Organization Policies Reference

This reference document details the baseline Organization Policies enforced by
the `google-cloud-recipe-foundation-builder` recipe. It provides the specific
constraint names, whether they are Boolean or List types, their target
configurations, and standard YAML templates for deployment.

## Table of Contents

-   [Overview of Constraints](#overview-of-constraints) (L20-L24)
-   [Enforced Boolean Constraints](#enforced-boolean-constraints) (L26-L101)
-   [List Constraints](#list-constraints) (L102-L173)
    -   [VM External IP Access](#vm-external-ip-access-deny-all) (L108-L120)
    -   [Restrict Protocol Forwarding Creation](#restrict-protocol-forwarding-creation-allow-internal)
        (L121-L136)
    -   [Allowed Policy Member Domains](#allowed-policy-member-domains-allow-customer-id)
        (L137-L155)
    -   [Allowed Contact Domains](#allowed-contact-domains-allow-org-domain)
        (L156-L171)
-   [Deployment Directive](#deployment-directive) (L174-L186)

--------------------------------------------------------------------------------

## Overview of Constraints

The baseline security posture enforces Boolean constraints (set to Enforced) and
List constraints (restricting allowed or denied values).

--------------------------------------------------------------------------------

## Enforced Boolean Constraints

These policies are binary and are set to `enforce: true`.

### Target YAML Structure

For all Boolean constraints, use the following YAML template. Replace
`[ORGANIZATION_ID]` and `[CONSTRAINT_NAME]` accordingly.

```yaml
name: organizations/[ORGANIZATION_ID]/policies/[CONSTRAINT_NAME]
spec:
  rules:
  - enforce: true
```

### List of Boolean Constraints

1.  **Disable Automatic IAM Grants for Default Service Accounts**
    *   **Constraint:** `iam.automaticIamGrantsForDefaultServiceAccounts`
    *   **Description:** Prevents the default App Engine and Compute Engine
        service accounts from automatically being granted the Editor role on
        your projects.
2.  **Public Access Prevention**
    *   **Constraint:** `storage.publicAccessPrevention`
    *   **Description:** Enforces public access prevention on all Cloud Storage
        buckets in the organization, blocking public access via IAM policies.
3.  **Set New Project Default to Zonal DNS Only**
    *   **Constraint:** `compute.setNewProjectDefaultToZonalDNSOnly`
    *   **Description:** Ensures that new projects use only zonal DNS names for
        Compute Engine instances, preventing internal DNS name leakage across
        zones.
4.  **Uniform Bucket-Level Access**
    *   **Constraint:** `storage.uniformBucketLevelAccess`
    *   **Description:** Enforces uniform bucket-level access on all Cloud
        Storage buckets, disabling fine-grained ACLs and relying solely on IAM.
5.  **Restrict Public IP Access for Cloud SQL**
    *   **Constraint:** `sql.restrictPublicIp`
    *   **Description:** Prevents Cloud SQL instances from being created with
        public IP addresses, enforcing private IP connectivity.
6.  **Disable Service Account Key Creation**
    *   **Constraint:** `iam.disableServiceAccountKeyCreation`
    *   **Description:** Prevents users from creating new external service
        account keys, reducing the risk of credential leakage.
7.  **Disable Serial Port Access**
    *   **Constraint:** `compute.disableSerialPortAccess`
    *   **Description:** Disables serial port access to all Compute Engine
        virtual machine instances, securing the console access.
8.  **Restrict Shared VPC Project Lien Removal**
    *   **Constraint:** `compute.restrictXpnProjectLienRemoval`
    *   **Description:** Restricts the removal of liens on host projects for
        Shared VPC, preventing accidental deletion of critical networking
        projects.
9.  **Disable VPC External IPv6**
    *   **Constraint:** `compute.disableVpcExternalIpv6`
    *   **Description:** Prevents the allocation of external IPv6 addresses to
        VPC subnets and resources, limiting external exposure.
10. **Disable Nested Virtualization**
    *   **Constraint:** `compute.disableNestedVirtualization`
    *   **Description:** Disables hardware-assisted nested virtualization on
        Compute Engine VMs, mitigating side-channel attack vectors.
11. **Disable Service Account Key Upload**
    *   **Constraint:** `iam.disableServiceAccountKeyUpload`
    *   **Description:** Prevents users from uploading public keys to service
        accounts, blocking external key association.
12. **Require OS Login**
    *   **Constraint:** `compute.requireOsLogin`
    *   **Description:** Enforces OS Login on all Compute Engine instances,
        linking VM SSH access to the user's Google identity.
13. **Restrict Authorized Networks for Cloud SQL**
    *   **Constraint:** `sql.restrictAuthorizedNetworks`
    *   **Description:** Blocks the addition of non-private IP ranges to the
        authorized networks list of Cloud SQL instances.

--------------------------------------------------------------------------------

## List Constraints

List constraints define specific allowed or denied values. Use the specific
templates below for each policy.

### VM External IP Access (Deny All)

*   **Constraint:** `compute.vmExternalIpAccess`
*   **Description:** Prevents Compute Engine VMs from being assigned external
    (public) IP addresses.
*   **YAML Template:**

    ```yaml
    name: organizations/[ORGANIZATION_ID]/policies/compute.vmExternalIpAccess
    spec:
      rules:
      - denyAll: true
    ```

### Restrict Protocol Forwarding Creation (Allow INTERNAL)

*   **Constraint:** `compute.restrictProtocolForwardingCreationForTypes`
*   **Description:** Restricts protocol forwarding rule creation to internal
    targets only.
*   **YAML Template:**

    ```yaml
    name: organizations/[ORGANIZATION_ID]/policies/compute.restrictProtocolForwardingCreationForTypes
    spec:
      rules:
      - values:
          allowedValues:
          - INTERNAL
    ```

### Allowed Policy Member Domains (Allow Customer ID)

*   **Constraint:** `iam.allowedPolicyMemberDomains`
*   **Description:** Restricts the domain identities that can be added to IAM
    policies to your specific Google Workspace or Cloud Identity customer ID.
*   **YAML Template:**

    ```yaml
    name: organizations/[ORGANIZATION_ID]/policies/iam.allowedPolicyMemberDomains
    spec:
      rules:
      - values:
          allowedValues:
          - [DIRECTORY_CUSTOMER_ID] # Replace with your numeric customer ID (e.g., C01234567)
    ```

    *(Note: Alternatively, you can use the principal set format:
    `principalSet://iam.googleapis.com/organizations/[ORGANIZATION_ID]`)*

### Allowed Contact Domains (Allow Org Domain)

*   **Constraint:** `essentialcontacts.allowedContactDomains`
*   **Description:** Restricts the domains that can be registered as essential
    contacts for the organization to your official domain.
*   **YAML Template:**

    ```yaml
    name: organizations/[ORGANIZATION_ID]/policies/essentialcontacts.allowedContactDomains
    spec:
      rules:
      - values:
          allowedValues:
          - @[YOUR_DOMAIN] # Replace with your organization's domain (e.g., @example.com)
    ```

--------------------------------------------------------------------------------

## Deployment Directive

Apply these policies sequentially using the `gcloud org-policies set-policy`
command:

```bash
gcloud org-policies set-policy [POLICY_FILE_NAME].yaml
```

> [!CAUTION] Applying `iam.allowedPolicyMemberDomains` first can lock out the
> deployment identity if it resides in an unallowed domain. Ensure the
> deployment identity is safe before enforcing this policy.

````
