Skip to content

Fix firewall planning with unknown network inputs - #6536

Open
danehans wants to merge 5 commits into
GoogleCloudPlatform:developfrom
danehans:firewall-plan-count
Open

danehans wants to merge 5 commits into
GoogleCloudPlatform:developfrom
danehans:firewall-plan-count

Conversation

@danehans

@danehans danehans commented Oct 21, 2026 •

Copy link
Copy Markdown

Fresh deployments can fail with Invalid count argument when the firewall module receives VPC outputs that are unknown until apply. Select subnet lookup with a plan-time use_subnetwork_data boolean instead of testing those outputs for null. Also avoid interpolating a null subnet name in the Private Google Access error message.

Subnet lookup now defaults to enabled. As before, Private Google Access is required only when deriving a missing project or network value. Callers supplying project and network directly can set use_subnetwork_data: false to retain the previous skip behavior. Existing indexed resource addresses are preserved.

Related: #6334. This PR contains only the shared firewall fix, documentation, and regression tests.

Validation: a fresh agentgateway deployment passed through gcluster with the fix, including live Gemini and synthetic-provider synchronous/streaming/metrics tests and Cloud Logging. Reapplication with the final patch reported all four deployment groups already applied. HCL formatting, TFLint, documentation generation, and applicable non-Terraform pre-commit checks passed. Added targeted Terraform regression cases; they have not been executed because local repository instructions prohibit direct Terraform commands. Full make tests and coverage verification remain pending.

Live test cleanup completed successfully: the cluster, VPC, nodes and reserved addresses were removed; administrator-provisioned service accounts were preserved.

Submission Checklist

NOTE: Community submissions can take up to 2 weeks to be reviewed.

Please take the following actions before submitting this pull request.

  • Fork your PR branch from the Toolkit "develop" branch (not main)
  • Test all changes with pre-commit in a local branch #
  • Confirm that "make tests" passes all tests
  • Add or modify unit tests to cover code changes
  • Ensure that unit test coverage remains above 80%
  • Update all applicable documentation
  • Follow Cluster Toolkit Contribution guidelines #

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses deployment failures occurring when firewall modules receive VPC outputs that are unknown during the planning phase. By introducing an explicit control variable, the module now allows users to bypass automatic subnetwork lookups when necessary, ensuring robust planning even in fresh infrastructure deployments.

Highlights

  • New configuration parameter: Introduced a use_subnetwork_data boolean variable to explicitly control subnetwork lookups and Private Google Access checks, preventing planning errors when network outputs are unknown.
  • Refactored logic: Replaced local logic that inferred lookup behavior from null values with the new explicit use_subnetwork_data variable.
  • Improved error handling: Updated the Private Google Access check error message to avoid interpolating potentially null subnet names.
  • Regression testing: Added comprehensive Terraform test fixtures and integration tests to verify lookup behavior and failure conditions.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@github-actions github-actions Bot added the external PR from external contributor label Oct 21, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

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.

Code Review

This pull request introduces a new use_subnetwork_data input variable to the firewall-rules module, allowing users to bypass subnetwork lookups and Private Google Access checks when project and network details are explicitly provided. It also includes comprehensive integration tests and updated documentation. The feedback suggests removing nullable = false from the new variable definition to allow explicit null values without triggering default overrides, which aligns with Terraform best practices.

@danehans
danehans force-pushed the firewall-plan-count branch 3 times, most recently from 88dba26 to 4f0d983 Compare October 21, 2026 04:30
@aslam-quad

Copy link
Copy Markdown
Contributor

/gcbrun

Use an explicit subnet lookup switch to keep resource counts known during
planning. Avoid interpolating a null subnet name in validation errors.

Signed-off-by: Daneyon Hansen <daneyon.hansen@solo.io>
Signed-off-by: Daneyon Hansen <daneyon.hansen@solo.io>
@danehans
danehans force-pushed the firewall-plan-count branch from af4325a to 1afb5f4 Compare November 2, 2026 19:48
@danehans
danehans marked this pull request as ready for review November 2, 2026 20:28
@danehans
danehans requested a review from a team as a code owner November 2, 2026 20:28
@danehans

danehans commented Nov 2, 2026

Copy link
Copy Markdown
Author

@aslam-quad can you /gcbrun?

@saara-tyagi27

Copy link
Copy Markdown
Contributor

/gcbrun

@danehans

danehans commented Nov 2, 2026

Copy link
Copy Markdown
Author

The PR-validation (hpc-toolkit-dev) failure appears to be unrelated to the changes in this PR:

...
Step #1 - "make-tests": testing community/examples/hpc-build-slurm-image.yaml in /tmp/tmp.mjev4sR1jf
Step #1 - "make-tests": neither packer nor terraform found in folder clou-yxns/_modules/. Skipping.
Step #1 - "make-tests": neither packer nor terraform found in folder hpc-r1jf/_modules/. Skipping.
Step #1 - "make-tests": 
Step #1 - "make-tests": Error: Failed to install provider
Step #1 - "make-tests": 
Step #1 - "make-tests": Error while installing hashicorp/archive v2.8.1: releases.hashicorp.com: Get
Step #1 - "make-tests": "https://releases.hashicorp.com/terraform-provider-archive/2.8.1/terraform-provider-archive_2.8.1_linux_amd64.zip":
Step #1 - "make-tests": read tcp 192.168.10.2:39182->52.85.129.12:443: read: connection reset by peer
Step #1 - "make-tests": *** ERROR: terraform init failed for community/examples/hpc-build-slurm-image.yaml, logs in /tmp/tmp.mjev4sR1jf/hpc-r1jf/demo-cluster

Comment thread modules/network/firewall-rules/main.tf Resolved
@saara-tyagi27 saara-tyagi27 added the release-bugfix Added to release notes under the "Bug fixes" heading. label Nov 3, 2026
Signed-off-by: Daneyon Hansen <daneyon.hansen@solo.io>
@danehans

danehans commented Nov 3, 2026

Copy link
Copy Markdown
Author

@saara-tyagi27 can you rerun /gcbrun?

@deepakrajk-quad

Copy link
Copy Markdown
Contributor

/gcbrun

Comment on lines +15 to +17
terraform {
required_version = ">= 1.12.2"
}

@shubpal07 shubpal07 Nov 4, 2026 •

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.

[Major] Because this test fixture does not list google under required_providers, terraform test does not bind mock_provider "google" from tests/subnetwork_lookup.tftest.hcl to the child firewall modules. Instead, it initializes the real hashicorp/google provider and tries to load Application Default Credentials (you can reproduce this on an authenticated machine with GOOGLE_APPLICATION_CREDENTIALS=/nonexistent terraform test).

Please add google to required_providers here (and update tests/fixtures/new-network/README.md) so the test uses the mock provider:

Suggested change
terraform {
required_version = ">= 1.12.2"
}
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.64"
}
}
required_version = ">= 1.12.2"
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks for reproducing this. I added google to the fixture requirements and regenerated its README.

Comment on lines +140 to +145
}
}
expect_failures = [terraform_data.pga_check]
}

run "new_network_values_unknown_until_apply" {

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.

[Minor] During command = plan, the outputs from terraform_data.network are still unknown, so the variable checks, subnet read, and Private Google Access check are all postponed until apply.

Once google is added to required_providers in tests/fixtures/new-network/main.tf, you can switch this test to command = apply with an assertion so those postponed checks are verified too:

Suggested change
}
}
expect_failures = [terraform_data.pga_check]
}
run "new_network_values_unknown_until_apply" {
run "new_network_values_unknown_until_apply" {
command = apply
module {
source = "./tests/fixtures/new-network"
}
assert {
condition = terraform_data.network.output.project == "test-project" && terraform_data.network.output.name == "test-network"
error_message = "New network outputs must resolve and apply cleanly."
}
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Switched the new-network case to apply and added the assertion for the resolved project and network.

Comment on lines +35 to +49
run "missing_project_without_lookup" {
command = plan
variables {
project_id = null
}
expect_failures = [var.use_subnetwork_data]
}

run "empty_network_without_lookup" {
command = plan
variables {
network_name = ""
}
expect_failures = [var.use_subnetwork_data]
}

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.

[Minor] These two tests cover project_id = null and network_name = "" when use_subnetwork_data = false, but they do not test project_id = "" or network_name = null. Consider adding those two cases so all four parts of the input check in variables.tf are covered:

Suggested change
run "missing_project_without_lookup" {
command = plan
variables {
project_id = null
}
expect_failures = [var.use_subnetwork_data]
}
run "empty_network_without_lookup" {
command = plan
variables {
network_name = ""
}
expect_failures = [var.use_subnetwork_data]
}
run "missing_project_without_lookup" {
command = plan
variables {
project_id = null
}
expect_failures = [var.use_subnetwork_data]
}
run "empty_project_without_lookup" {
command = plan
variables {
project_id = ""
}
expect_failures = [var.use_subnetwork_data]
}
run "missing_network_without_lookup" {
command = plan
variables {
network_name = null
}
expect_failures = [var.use_subnetwork_data]
}
run "empty_network_without_lookup" {
command = plan
variables {
network_name = ""
}
expect_failures = [var.use_subnetwork_data]
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Added both cases. Null and empty values are now covered for each input.

Comment thread modules/network/firewall-rules/main.tf Outdated
# the google_compute_network data source does not allow identification by
# self_link, which uniquely identifies subnet, project, and network
data "google_compute_subnetwork" "subnetwork" {
# Only instantiate this data source 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.

[Nit] With this change, the subnet is read whenever var.use_subnetwork_data is true (even when project_id and network_name are already provided, such as when a blueprint uses use: [network]). Let's update this comment so it matches the new behavior:

Suggested change
# Only instantiate this data source if needed
# Look up the subnetwork when enabled by use_subnetwork_data

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Updated the comment to match the lookup switch.

Comment on lines +6 to +9
By default, this module looks up `subnetwork_self_link` to derive missing project
and network values. When either value is omitted, it also verifies that Private
Google Access is enabled. The subnet can be created in the same deployment group;
its lookup waits until it exists.

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.

[Nit] When use_subnetwork_data is true (the default), the module still looks up subnetwork_self_link even if both project_id and network_name are passed (for example, via use: [network]), and only uses the looked-up values when either input is missing. Making that explicit here helps clarify when the subnet read happens:

Suggested change
By default, this module looks up `subnetwork_self_link` to derive missing project
and network values. When either value is omitted, it also verifies that Private
Google Access is enabled. The subnet can be created in the same deployment group;
its lookup waits until it exists.
By default (`use_subnetwork_data: true`), this module looks up `subnetwork_self_link`
and uses it to fill in any missing `project_id` or `network_name` value. When either
value is omitted, it also verifies that Private Google Access is enabled. The subnet
can be created in the same deployment group; its lookup waits until it exists.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Clarified the default lookup behavior in the README.

@shubpal07 shubpal07 left a comment •

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.

The firewall module changes look good.

Running terraform test locally showed one Major issue in the new test fixture (tests/fixtures/new-network/main.tf is missing google in required_providers, so the test fails without live GCP credentials), plus a few small test and comment suggestions below.

Signed-off-by: Daneyon Hansen <daneyon.hansen@solo.io>
shubpal07
shubpal07 previously approved these changes Nov 6, 2026

@shubpal07 shubpal07 left a comment

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.

Thanks for addressing the suggestions!!

Signed-off-by: Daneyon Hansen <daneyon.hansen@solo.io>
@danehans

danehans commented Nov 6, 2026

Copy link
Copy Markdown
Author

The https://github.com/GoogleCloudPlatform/cluster-toolkit/actions/runs/41898092853/job/127659083551?pr=6536 and https://github.com/GoogleCloudPlatform/cluster-toolkit/actions/runs/41898092853/job/127659083935?pr=6536 pre-commit jobs failed because TFLint flagged the Google provider declaration needed by the mock test. I added the same lint ignore used elsewhere in the repo in f19de27.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

external PR from external contributor release-bugfix Added to release notes under the "Bug fixes" heading.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add an agentgateway-based multi-provider AI gateway blueprint for GKE

7 participants