Skip to content

Create IAP for nomad#2573

Closed
djeebus wants to merge 2 commits into
mainfrom
create-iap-for-nomad
Closed

Create IAP for nomad#2573
djeebus wants to merge 2 commits into
mainfrom
create-iap-for-nomad

Conversation

@djeebus

@djeebus djeebus commented May 5, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@cla-bot cla-bot Bot added the cla-signed label May 5, 2026
@cursor

cursor Bot commented May 5, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes load balancer access control for the Nomad UI and introduces new secret inputs; misconfiguration (missing secret or members) can break Terraform apply or unintentionally lock users out.

Overview
Adds optional IAP support for the nomad load balancer backend by wiring new variables (nomad_iap_oauth2_client_id/secret, nomad_iap_members) through the root and nomad-cluster modules, enabling the backend-service iap block when a client ID is set, and creating an IAP IAM binding to grant roles/iap.httpsResourceAccessor to the provided members.

Potential issues: IAP enablement only checks client_id != null, so a missing/empty nomad_iap_oauth2_client_secret can cause apply failures; enabling IAP with no nomad_iap_members skips the IAM binding and may lock out intended users.

Reviewed by Cursor Bugbot for commit 6c4296f. Bugbot is set up for automated code reviews on this repo. Configure here.

@codecov

codecov Bot commented May 5, 2026

Copy link
Copy Markdown

❌ 3 Tests Failed:

Tests completed Failed Passed Skipped
2499 3 2496 7
View the full list of 3 ❄️ flaky test(s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/metrics::TestTeamMetrics

Flake rate in main: 50.00% (Passed 9 times, Failed 9 times)

Stack Traces | 1.33s run time
=== RUN   TestTeamMetrics
=== PAUSE TestTeamMetrics
=== CONT  TestTeamMetrics
    team_metrics_test.go:61: 
        	Error Trace:	.../api/metrics/team_metrics_test.go:61
        	Error:      	Should be true
        	Test:       	TestTeamMetrics
        	Messages:   	MaxConcurrentSandboxes should be >= 0
--- FAIL: TestTeamMetrics (1.33s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/sandboxes::TestUpdateNetworkConfig

Flake rate in main: 56.00% (Passed 11 times, Failed 14 times)

Stack Traces | 24.1s run time
=== RUN   TestUpdateNetworkConfig
=== PAUSE TestUpdateNetworkConfig
=== CONT  TestUpdateNetworkConfig
Executing command curl in sandbox id8shp39mofp18ga82u0d
--- FAIL: TestUpdateNetworkConfig (24.08s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/sandboxes::TestUpdateNetworkConfig/pause_resume_preserves_allow_internet_access_false

Flake rate in main: 50.00% (Passed 11 times, Failed 11 times)

Stack Traces | 0.69s run time
=== RUN   TestUpdateNetworkConfig/pause_resume_preserves_allow_internet_access_false
Executing command curl in sandbox iew3lo3jv5sxhcftwftea
    sandbox_network_update_test.go:372: Command [curl] output: event:{start:{pid:1365}}
    sandbox_network_update_test.go:372: Command [curl] output: event:{end:{exit_code:35 exited:true status:"exit status 35" error:"exit status 35"}}
Executing command curl in sandbox iew3lo3jv5sxhcftwftea
    sandbox_network_update_test.go:372: Command [curl] output: event:{start:{pid:1366}}
    sandbox_network_update_test.go:372: Command [curl] output: event:{end:{exit_code:35 exited:true status:"exit status 35" error:"exit status 35"}}
    sandbox_network_update_test.go:391: Command [curl] output: event:{start:{pid:1367}}
    sandbox_network_update_test.go:391: Command [curl] output: event:{data:{stdout:"HTTP/2 302 \r\nx-content-type-options: nosniff\r\nlocation: https://dns.google/\r\ndate: Tue, 05 May 2026 19:06:42 GMT\r\ncontent-type: text/html; charset=UTF-8\r\nserver: HTTP server (unknown)\r\ncontent-length: 216\r\nx-xss-protection: 0\r\nx-frame-options: SAMEORIGIN\r\nalt-svc: h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\r\n\r\n"}}
    sandbox_network_update_test.go:391: Command [curl] output: event:{end:{exited:true status:"exit status 0"}}
    sandbox_network_update_test.go:391: Command [curl] completed successfully in sandbox iew3lo3jv5sxhcftwftea
    sandbox_network_update_test.go:391: 
        	Error Trace:	.../api/sandboxes/sandbox_network_out_test.go:74
        	            				.../api/sandboxes/sandbox_network_update_test.go:60
        	            				.../api/sandboxes/sandbox_network_update_test.go:391
        	Error:      	An error is expected but got nil.
        	Test:       	TestUpdateNetworkConfig/pause_resume_preserves_allow_internet_access_false
        	Messages:   	https://8.8.8.8 should be blocked
--- FAIL: TestUpdateNetworkConfig/pause_resume_preserves_allow_internet_access_false (0.69s)

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@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

The IAP configuration for the Nomad backend and the associated IAM binding must validate the presence of both the OAuth2 client ID and client secret to prevent Terraform apply failures and ensure configuration consistency.

Comment on lines +94 to +97
iap = var.nomad_iap_oauth2_client_id != null ? {
oauth2_client_id = var.nomad_iap_oauth2_client_id
oauth2_client_secret = var.nomad_iap_oauth2_client_secret
} : null

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.

high

The IAP configuration for the Nomad backend only checks for the presence of the OAuth2 client ID. If a client ID is provided but the client secret is missing, the backend service resource will attempt to enable IAP with a null secret, which will cause a failure during the Terraform apply phase. The condition should ensure both the client ID and secret are present before enabling the IAP block.

      iap = (var.nomad_iap_oauth2_client_id != null && var.nomad_iap_oauth2_client_secret != null) ? {
        oauth2_client_id     = var.nomad_iap_oauth2_client_id
        oauth2_client_secret = var.nomad_iap_oauth2_client_secret
      } : null


# IAP IAM binding for Nomad backend
resource "google_iap_web_backend_service_iam_binding" "nomad_iap" {
count = var.nomad_iap_oauth2_client_id != null && length(var.nomad_iap_members) > 0 ? 1 : 0

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.

high

The IAM binding for IAP is created based on the presence of the client ID and a non-empty members list. However, if the client ID is provided but the client secret is missing, the backend service will fail to enable IAP (or fail to apply), leading to an inconsistent state where an IAM binding exists for a feature that is not correctly configured on the target resource. This condition should be updated to match the logic used for enabling IAP on the backend service.

  count = var.nomad_iap_oauth2_client_id != null && var.nomad_iap_oauth2_client_secret != null && length(var.nomad_iap_members) > 0 ? 1 : 0

Comment thread iac/provider-gcp/nomad-cluster/network/main.tf
enabled = true
oauth2_client_id = iap.value["oauth2_client_id"]
oauth2_client_secret = iap.value["oauth2_client_secret"]
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

IAP blocks Nomad API clients

High Severity

IAP is enabled on the same nomad.${domain} endpoint used by the Terraform nomad provider, but that provider is only configured with the Nomad ACL token. Once active, Terraform Nomad job management hits the IAP login barrier and fails.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 1db68f2. Configure here.

project = var.gcp_project_id
web_backend_service = google_compute_backend_service.default["nomad"].name
role = "roles/iap.httpsResourceAccessor"
members = var.nomad_iap_members

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

IAP can enable without access

Medium Severity

IAP turns on when nomad_iap_oauth2_client_id is set, but the access binding is skipped when nomad_iap_members is empty. That can apply successfully while leaving the Nomad UI with no Terraform-managed IAP users.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 1db68f2. Configure here.

web_backend_service = google_compute_backend_service.default["nomad"].name
role = "roles/iap.httpsResourceAccessor"
members = var.nomad_iap_members
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

IAP API is never enabled

Medium Severity

google_iap_web_backend_service_iam_binding uses the IAP API, but the GCP init module never enables iap.googleapis.com. Enabling Nomad IAP can fail at apply time in fresh projects.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 1db68f2. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 4 total unresolved issues (including 3 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6c4296f. Configure here.

iap = var.nomad_iap_oauth2_client_id != null ? {
oauth2_client_id = var.nomad_iap_oauth2_client_id
oauth2_client_secret = var.nomad_iap_oauth2_client_secret
} : null

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sensitive backend map breaks plans

High Severity

Including nomad_iap_oauth2_client_secret in the iap block within local.backends makes the collection sensitive. Terraform's for_each cannot process sensitive values when creating google_compute_backend_service resources, causing plan failures when Nomad IAP is enabled.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6c4296f. Configure here.

@djeebus

djeebus commented May 5, 2026

Copy link
Copy Markdown
Contributor Author

Turns out it's tedious to get nomad's terraform provider to communicate through IAP, and really tedious to convince terraform that IAP is optional, but not necessary. Going to punt on this.

@djeebus djeebus closed this May 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants