Skip to content

feat(RHOAIENG-47026): add gcs resource#5

Merged
ktdreyer merged 2 commits intomainfrom
feat/add-gcs-bucket-
Apr 9, 2026
Merged

feat(RHOAIENG-47026): add gcs resource#5
ktdreyer merged 2 commits intomainfrom
feat/add-gcs-bucket-

Conversation

@syntaxsdev
Copy link
Copy Markdown
Contributor

@syntaxsdev syntaxsdev commented Apr 7, 2026

This adds a simple GCS resource to the IaS configuration.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 7, 2026

Walkthrough

Enables the Google Cloud Storage API and adds a new Terraform-managed GCS bucket ambient-code-pull-reviews with a 45-day object lifecycle, public read access, and write access for GitHub Actions via a workload identity principal.

Changes

Cohort / File(s) Summary
GCS API Enablement
gcp/apis.tf
Added google_project_service.storage to enable the storage.googleapis.com API for var.project_id with disable_on_destroy = false.
GCS Bucket & IAM
gcp/pull-reviews.tf
Added google_storage_bucket.pull_reviews with uniform bucket-level access and a 45-day delete lifecycle; google_storage_bucket_iam_member.pull_reviews_public_read binds roles/storage.objectViewer to allUsers; google_storage_bucket_iam_member.pull_reviews_gha_write binds roles/storage.objectCreator to a workload identity principal constrained to the ambient-code/platform repository via google_iam_workload_identity_pool.github_pool.name.

Sequence Diagram(s)

sequenceDiagram
    participant GH as GitHub Actions
    participant WI as Workload Identity Pool
    participant GCP as Google Cloud (IAM)
    participant GCS as Google Cloud Storage

    GH->>WI: Exchange OIDC token (repo attribute)
    WI->>GCP: Token validated, maps to service account principal
    GH->>GCS: Upload object (using mapped principal)
    GCS->>GCP: Check IAM binding (roles/storage.objectCreator)
    GCS-->>GH: Accept object
    GCS-->>Public Users: Objects served via public read (roles/storage.objectViewer)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(RHOAIENG-47026): add gcs resource' directly and clearly describes the main change: adding a Google Cloud Storage (GCS) resource to the infrastructure-as-code configuration, which matches the changeset content.
Description check ✅ Passed The description 'This adds a simple GCS resource to the IaS configuration' is directly related to the changeset, accurately describing the addition of Google Cloud Storage resources to the infrastructure configuration.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/add-gcs-bucket-

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@gcp/pull-reviews.tf`:
- Around line 7-22: Add an explicit dependency so the google_storage_bucket
"pull_reviews" waits for the storage API to be enabled; update the
google_storage_bucket resource (resource "google_storage_bucket" "pull_reviews")
to include a depends_on referencing the google_project_service resource that
enables the storage API (e.g., depends_on = [google_project_service.storage]) to
prevent the bucket creation from running before the API is available.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0980db37-beef-4ece-97b9-1f6deb5dd911

📥 Commits

Reviewing files that changed from the base of the PR and between 19cfc49 and 58b46f3.

📒 Files selected for processing (2)
  • gcp/apis.tf
  • gcp/pull-reviews.tf

Comment thread gcp/pull-reviews.tf
Comment on lines +7 to +22
resource "google_storage_bucket" "pull_reviews" {
project = var.project_id
name = "ambient-code-pull-reviews"
location = "US"

uniform_bucket_level_access = true

lifecycle_rule {
action {
type = "Delete"
}
condition {
age = 45
}
}
}
Copy link
Copy Markdown

@coderabbitai coderabbitai bot Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider adding explicit dependency on the storage API.

Without depends_on, Terraform may attempt to create this bucket before google_project_service.storage is fully enabled, causing failures on initial apply.

Proposed fix
 resource "google_storage_bucket" "pull_reviews" {
   project  = var.project_id
   name     = "ambient-code-pull-reviews"
   location = "US"

   uniform_bucket_level_access = true

   lifecycle_rule {
     action {
       type = "Delete"
     }
     condition {
       age = 45
     }
   }
+
+  depends_on = [google_project_service.storage]
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
resource "google_storage_bucket" "pull_reviews" {
project = var.project_id
name = "ambient-code-pull-reviews"
location = "US"
uniform_bucket_level_access = true
lifecycle_rule {
action {
type = "Delete"
}
condition {
age = 45
}
}
}
resource "google_storage_bucket" "pull_reviews" {
project = var.project_id
name = "ambient-code-pull-reviews"
location = "US"
uniform_bucket_level_access = true
lifecycle_rule {
action {
type = "Delete"
}
condition {
age = 45
}
}
depends_on = [google_project_service.storage]
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@gcp/pull-reviews.tf` around lines 7 - 22, Add an explicit dependency so the
google_storage_bucket "pull_reviews" waits for the storage API to be enabled;
update the google_storage_bucket resource (resource "google_storage_bucket"
"pull_reviews") to include a depends_on referencing the google_project_service
resource that enables the storage API (e.g., depends_on =
[google_project_service.storage]) to prevent the bucket creation from running
before the API is available.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai why would it do that? We don't want to add explicit deps on everything in gcp/apis.tf - that's noisy

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ktdreyer, fair point — you're right to push back. The concern was about a potential race condition on an initial terraform apply when the Storage API hasn't been enabled yet, but in practice:

  1. Google's own best-practice guidance favors implicit dependencies (e.g., project_id = module.project_services.project_id) over explicit depends_on, since referencing output attributes ensures Terraform waits for the upstream resource automatically.
  2. The Storage API is a foundational GCP service and is very likely already enabled on any non-brand-new project, making this a low-real-world-risk concern.
  3. Scattering depends_on = [google_project_service.*] across every resource in the codebase is noisy and adds maintenance overhead, as you noted.

The comment was already marked as a nitpick/trivial and was overly cautious. I'll drop it — no change needed here.


📝 Learnings were identified and not saved (knowledge base disabled). Enable

@ktdreyer ktdreyer self-requested a review April 7, 2026 17:11
Comment thread gcp/pull-reviews.tf Outdated
resource "google_storage_bucket_iam_member" "pull_reviews_gha_write" {
bucket = google_storage_bucket.pull_reviews.name
role = "roles/storage.objectCreator"
member = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.github_pool.name}/attribute.repository/ambient-code/pull-reviews"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we need principalSet to point at ambient-code/platform instead, if the actions will run under that repo?

I'm not sure how WIF authz works when we're including one action in another repo.

Comment thread gcp/apis.tf
service = "storage.googleapis.com"
disable_on_destroy = false
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part LGTM

@ktdreyer ktdreyer changed the title feat: add gcs resource feat(RHOAIENG-47026): add gcs resource Apr 7, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
gcp/pull-reviews.tf (1)

34-38: ⚠️ Potential issue | 🟠 Major

Verify the WIF repository claim matches the actual caller workflow repo.

Line 37 restricts writes to attribute.repository/ambient-code/platform. For reusable workflows, GitHub OIDC standard claims describe the calling workflow repo; if uploads are triggered from another caller (for example ambient-code/pull-reviews), this binding will 403 at runtime.

In GitHub Actions reusable workflows, does the OIDC `repository` claim represent the calling workflow repository or the called reusable workflow repository? Please include the official GitHub docs reference.

As per coding guidelines, "Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@gcp/pull-reviews.tf` around lines 34 - 38, The IAM binding in
google_storage_bucket_iam_member.pull_reviews_gha_write currently restricts
writes to attribute.repository/ambient-code/platform which will 403 if the OIDC
token's repository claim is the calling workflow repo (e.g.,
ambient-code/pull-reviews); update the member principal to match the actual
caller repo or broaden it (for example
attribute.repository/ambient-code/pull-reviews or
attribute.repository/ambient-code/*) after verifying which repository initiates
the uploads, and re-run tests to confirm the
principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.github_pool.name}/attribute.repository/...
value matches the real GitHub Actions caller.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@gcp/pull-reviews.tf`:
- Line 9: Replace the hardcoded bucket name "ambient-code-pull-reviews" with a
project-scoped name to avoid global collisions: build the name using the project
identifier (e.g., var.project_id or data.google_project.current.project_id) and
optional environment suffix (e.g., format("%s-ambient-code-pull-reviews-%s",
var.project_id, var.env) or using substr(hash,…) for length), update the
resource that contains name = "ambient-code-pull-reviews" to use that
expression, and ensure any other references to the bucket use the same computed
value (extract into a variable or local like local.pull_reviews_bucket_name if
needed).

---

Duplicate comments:
In `@gcp/pull-reviews.tf`:
- Around line 34-38: The IAM binding in
google_storage_bucket_iam_member.pull_reviews_gha_write currently restricts
writes to attribute.repository/ambient-code/platform which will 403 if the OIDC
token's repository claim is the calling workflow repo (e.g.,
ambient-code/pull-reviews); update the member principal to match the actual
caller repo or broaden it (for example
attribute.repository/ambient-code/pull-reviews or
attribute.repository/ambient-code/*) after verifying which repository initiates
the uploads, and re-run tests to confirm the
principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.github_pool.name}/attribute.repository/...
value matches the real GitHub Actions caller.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4adfce13-37dc-4a35-a02e-345623f2930d

📥 Commits

Reviewing files that changed from the base of the PR and between 58b46f3 and 3a86c45.

📒 Files selected for processing (1)
  • gcp/pull-reviews.tf

Comment thread gcp/pull-reviews.tf

resource "google_storage_bucket" "pull_reviews" {
project = var.project_id
name = "ambient-code-pull-reviews"
Copy link
Copy Markdown

@coderabbitai coderabbitai bot Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use a project-scoped bucket name to avoid global-name collisions.

Line 9 uses a globally fixed GCS bucket name. Because bucket names are global (not project-scoped), this can break applies in other environments/projects and makes reuse brittle.

Proposed fix
 resource "google_storage_bucket" "pull_reviews" {
   project  = var.project_id
-  name     = "ambient-code-pull-reviews"
+  name     = "${var.project_id}-ambient-code-pull-reviews"
   location = "US"

As per coding guidelines, "Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
name = "ambient-code-pull-reviews"
resource "google_storage_bucket" "pull_reviews" {
project = var.project_id
name = "${var.project_id}-ambient-code-pull-reviews"
location = "US"
uniform_bucket_level_access = true
lifecycle_rule {
action {
type = "Delete"
}
condition {
age = 45
}
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@gcp/pull-reviews.tf` at line 9, Replace the hardcoded bucket name
"ambient-code-pull-reviews" with a project-scoped name to avoid global
collisions: build the name using the project identifier (e.g., var.project_id or
data.google_project.current.project_id) and optional environment suffix (e.g.,
format("%s-ambient-code-pull-reviews-%s", var.project_id, var.env) or using
substr(hash,…) for length), update the resource that contains name =
"ambient-code-pull-reviews" to use that expression, and ensure any other
references to the bucket use the same computed value (extract into a variable or
local like local.pull_reviews_bucket_name if needed).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai hard-coding works for simplicity.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ktdreyer, understood — a fixed name is simpler to reason about and reference externally. I'll defer to your judgement here.


📝 Learnings were identified and not saved (knowledge base disabled). Enable

Copy link
Copy Markdown
Contributor

@ktdreyer ktdreyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

principalSet looks right now

@ktdreyer ktdreyer merged commit 1f2903a into main Apr 9, 2026
6 checks passed
ktdreyer added a commit that referenced this pull request Apr 10, 2026
The pull-reviews GCS bucket (#5) requires CI to manage its
IAM bindings on subsequent applies. The bucket itself was
bootstrapped with a local "tofu apply" because
"storage.buckets.create" is a project-level permission that
CI does not have.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ktdreyer added a commit that referenced this pull request Apr 10, 2026
The pull-reviews GCS bucket (#5) requires CI to manage its IAM bindings
on subsequent applies.

I bootstrapped the bucket itself by running `tofu apply` on my computer.
The "storage.buckets.create" permission is project-level, and I did not
want to grant that to CI in order to limit the blast radius.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants