Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

deploy: route control-plane services through the VPC NAT for a stable egress IP - #3044

#3044
Merged
skord merged 1 commit into
masterestuary/flow:masterfrom
mdanko/cloud-run-vpc-egressestuary/flow:mdanko/cloud-run-vpc-egressCopy head branch name to clipboard
Jun 18, 2026
Merged

deploy: route control-plane services through the VPC NAT for a stable egress IP#3044
skord merged 1 commit into
masterestuary/flow:masterfrom
mdanko/cloud-run-vpc-egressestuary/flow:mdanko/cloud-run-vpc-egressCopy head branch name to clipboard

Conversation

@skord

@skord skord commented Jun 17, 2026

Copy link
Copy Markdown
Member

Description:

Routes the control-plane Cloud Run services through a Cloud NAT in the data-plane-controller VPC so they egress from a stable IP instead of Cloud Run's dynamic Google IPs. agent-api and oidc-discovery-server use a dedicated control-plane-api-sn1 subnet with its own NAT IP, kept separate from the data-plane-controller-service egress IP; that service stays on its existing subnet.

Adds flags: '--network=… --subnet=… --vpc-egress=all-traffic' to:

  • deploy-agent-api.yaml (subnet control-plane-api-sn1; new VPC egress)
  • deploy-oidc-discovery-server.yaml (subnet control-plane-api-sn1; new VPC egress)
  • deploy-data-plane-controller.yaml (subnet data-plane-controller-sn1; backfill of config previously set out-of-band, so it survives a full replace)

Supporting infra: the control-plane-api-sn1 subnet, its reserved NAT IP, and a dedicated Cloud NAT (with the existing NAT scoped to only data-plane-controller-sn1) are already provisioned. This PR only adds the deploy-time egress flags.

Workflow steps:

  • Merge, then run each deploy workflow (workflow_dispatch) to apply. This is a real egress behavior change for agent-api and oidc-discovery-server: all of their outbound traffic begins flowing through the NAT, so roll out deliberately and watch service health and Cloud NAT metrics.

Notes for reviewers:

  • No application code; CI/deploy config only.
  • After redeploy, gcloud run services describe <svc> --region us-central1 --project estuary-control --format="yaml(spec.template.metadata.annotations)" shows run.googleapis.com/network-interfaces (control-plane-api-sn1) and vpc-access-egress: all-traffic.
  • agent-api is the high-volume service; its dedicated NAT has dynamic port allocation enabled.

@skord
skord requested a review from a team June 17, 2026 14:24
@skord skord self-assigned this Jun 17, 2026
@skord
skord force-pushed the mdanko/cloud-run-vpc-egress branch from d48122e to 1053de8 Compare June 17, 2026 14:32
@skord
skord marked this pull request as draft June 17, 2026 15:02
@skord
skord force-pushed the mdanko/cloud-run-vpc-egress branch from 1053de8 to d0c0907 Compare June 17, 2026 15:04
@skord skord changed the title deploy: route control-plane services through the VPC NAT for static egress deploy: route control-plane services through the VPC NAT for a stable egress IP Jun 17, 2026
@skord
skord marked this pull request as ready for review June 17, 2026 15:16
… egress IP

Add direct VPC egress to the agent-api and oidc-discovery-server Cloud Run
deploys via a dedicated control-plane-api subnet on the data-plane-controller
VPC, so they egress through their own Cloud NAT IP (separate from the
data-plane-controller egress IP) instead of dynamic Google IPs. Also backfill
the same flags onto data-plane-controller-service, whose VPC egress was set
out-of-band, so it is declared in code.
@skord
skord force-pushed the mdanko/cloud-run-vpc-egress branch from d0c0907 to 9f4b934 Compare June 17, 2026 18:31

@jgraettinger jgraettinger left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

Would be nice to rename the VPC but 🤷

@skord
skord merged commit 869845a into master Jun 18, 2026
11 checks passed
mdibaiee added a commit to estuary/homebrew-flowctl that referenced this pull request Jul 15, 2026
## What's Changed
* runtime: periodically store primary FSMHints of V2 shards by @williamhbaker in estuary/flow#3027
* mise build:flowctl for a local flowctl binary by @mdibaiee in estuary/flow#3031
* go.mod: bump gazette to latest by @williamhbaker in estuary/flow#3033
* data-plane-controller: dns and s3 passthroughs by @qaoj in estuary/flow#3022
* Self-service private-link configuration by @jshearer in estuary/flow#2944
* supabase: scoped refresh tokens so CI writes via PostgREST instead of direct psql by @skord in estuary/flow#3013
* docs: Describe SQL Server replica suport by @willdonnelly in estuary/flow#3040
* proto-gazette: regenerate to pick up SUSPEND_KEEP by @williamhbaker in estuary/flow#3041
* docs: correct custom-column-types backfill behavior for DDL changes by @jwhartley in estuary/flow#3036
* Refresh token GraphQL operations and token exchange endpoint by @GregorShear in estuary/flow#3020
* docs: shopify stream & resource config additions by @Alex-Bair in estuary/flow#3034
* validation/collection: exclude `flow://inferred-schema` from the managed-defs redact check by @jshearer in estuary/flow#3046
* docs: update Bigtable connector permissions example by @mwillman-estuary in estuary/flow#3045
* docs: disable auto-discover for multi-binding file source captures by @jwhartley in estuary/flow#3037
* docs: add streams and API pinning details to stripe-native by @nicolaslazo in estuary/flow#3055
* data-plane-controller: restart setting by @qaoj in estuary/flow#3048
* deploy: route control-plane services through the VPC NAT for a stable egress IP by @skord in estuary/flow#3044
* docs: document the Exclude Flow Document (no_flow_document) materialization option by @jwhartley in estuary/flow#3018
* oidc-discovery-server: survive direct VPC egress cold-start on deploy by @skord in estuary/flow#3062
* docs: clarify retain_existing_data_on_backfill requires allow_existing_tables_for_new_bindings by @jwhartley in estuary/flow#3049
* data-plane-controller: restart on ansiblehost by @qaoj in estuary/flow#3066
* flow-web: Bump version to release by @jshearer in estuary/flow#3068
* ops-catalog: misc updates by @williamhbaker in estuary/flow#3067
* proto-flow: tolerate unknown JSON fields in connector protocols by @williamhbaker in estuary/flow#3059
* flowctl: add raw split-shards to scale out V2 tasks by @williamhbaker in estuary/flow#3021
* supabase: qualify replace_data_plane_releases DELETE for PostgREST by @skord in estuary/flow#3076
* docs: kcat recipes for testing a Dekaf topic by @jwhartley in estuary/flow#3072
* Docs: document per-prefix alert scoping and configurable thresholds by @jwhartley in estuary/flow#3039
* notifications: trial bucket retention is 20 days, not 30 by @jwhartley in estuary/flow#3074
* runtime/container: use ops::decode::Decoder for log lines by @williamhbaker in estuary/flow#3091
* data-plane-controller: remove restart flag by @qaoj in estuary/flow#3087
* runtime-next: durably seed initial connector state as {} to match V1 by @williamhbaker in estuary/flow#3081
* runtime-next: don't abandon the final capture transaction on connector EOF by @jgraettinger in estuary/flow#3090
* Docs: Remove an IP address from GCP allowed list by @jwhartley in estuary/flow#3080
* docs: remove static data plane IP list, reference dashboard by @jwhartley in estuary/flow#3097
* dekaf: improve logging by @williamhbaker in estuary/flow#3078
* agent: make startup logging consistent by @williamhbaker in estuary/flow#3098
* shuffle: make the shuffle disk limit configurable per-task by @jgraettinger in estuary/flow#3096
* runtime-next: automatically split journals under sustained append-rate throttling by @dgreer-dev in estuary/flow#3029
* billing: add tenant billing contact fields and per-tenant controller by @jshearer in estuary/flow#2902
* flowctl-go(api test): raise test-shard readiness window from ~3s to ~30s by @jshearer in estuary/flow#3101
* runtime: strip the V2 committed-close marker for derivations by @williamhbaker in estuary/flow#3100
* deps: bump aws-lc-sys and lz4_flex for security advisories by @skord in estuary/flow#2875
* data-plane-controller: fix db timeout by @qaoj in estuary/flow#3105
* agent-api: survive direct VPC egress cold-start on instance startup by @skord in estuary/flow#3109
* docs: avoiding backfills during a database failover or host change by @jwhartley in estuary/flow#3086
* docs: clarify column-level SELECT grants unsupported for MySQL/MariaDB CDC by @jwhartley in estuary/flow#3085
* json: require RFC3339 'T' separator in date-time format validator by @jacobmarble in estuary/flow#3116
* control-plane: reserve privileged tenant names by @jwhartley in estuary/flow#3083
* agent-api: harden startup and shutdown on Cloud Run by @skord in estuary/flow#3114
* Incidental fixes: gazette Append retry, connector-init image, materialize tear-down by @jgraettinger in estuary/flow#3121
* agent: flag to create new captures as runtime-v2 by @williamhbaker in estuary/flow#3107
* runtime-next: add minimum interval for post-txn triggers by @dgreer-dev in estuary/flow#3110
* flowctl: chunk API requests by url size rather than fixed count by @mdibaiee in estuary/flow#3123
* dekaf: use projection_constraints only, no constraints by @mdibaiee in estuary/flow#3124
* flowctl: normalize --prefix trailing slash to avoid misleading PermissionDenied by @GregorShear in estuary/flow#3075
* docs: retain_existing_data_on_backfill no longer requires allow_existing_tables_for_new_bindings by @jwhartley in estuary/flow#3125
* Restart Materializations sessions before IAM token expiry by @dgreer-dev in estuary/flow#3130
* docs: add "bring your own app" instructions for source-quickbooks by @nicolaslazo in estuary/flow#3135
* flowctl: re-tool `preview` on the runtime-next stack by @jgraettinger in estuary/flow#3117
* Adding support for updating the quotas when payment info changes by @bbartman in estuary/flow#3127
* control-plane-api: add unauthenticated publicDataPlanes GraphQL query by @GregorShear in estuary/flow#3129
* go/bindings: update snapshots for materialize-sqlite ser_policy by @dgreer-dev in estuary/flow#3142
* Revert "flowctl: replace `preview` with the runtime-next implementation" by @jgraettinger in estuary/flow#3141
* local: per-checkout stacks — every checkout runs its own isolated stack by @jgraettinger in estuary/flow#3137
* dekaf: log tls handshake eof instead of returning as error by @danielnelson in estuary/flow#3143
* Updating migrations to better support testing. by @bbartman in estuary/flow#3146
* shuffle: raise causal-hint stall timeout to 15m; lower prune horizon to 2GB by @jgraettinger in estuary/flow#3148
* ci: fix Platform Build by packaging Go binaries from per-checkout $GOBIN by @jgraettinger in estuary/flow#3149
* capture+materialize: Support Nonsensitive Field Overlays by @willdonnelly in estuary/flow#3119
* Docs: The Great Description-ing by @aeluce in estuary/flow#3057
* runtime: fix recursive read-lock deadlock in capture-v2 buildJoin by @jgraettinger in estuary/flow#3156
* validation: surface write-schema redact annotations on projections of split-schema collections by @GregorShear in estuary/flow#3147
* control-plane-api: retry Stripe customer search on index-lag misses by @jgraettinger in estuary/flow#3157
* flowctl: multi-shard --fixture for raw preview-next by @mdibaiee in estuary/flow#3154
* dekaf: prevent cached `TimeoutNoData` fetch responses from incorrectly signaling EOF by @jshearer in estuary/flow#3153
* mise: remove Lima VM host share and other VM tweaks by @jgraettinger in estuary/flow#3163
* docs: document connecting Azure Private Link to native Azure resources by @jwhartley in estuary/flow#3138
* docs: explain why exclusiveCollectionFilter needs few enabled bindings by @jwhartley in estuary/flow#3126

## New Contributors
* @bbartman made their first contribution in estuary/flow#3127

**Full Changelog**: estuary/flow@v0.6.10...v0.6.11

Co-authored-by: mdibaiee <mdibaiee@users.noreply.github.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

Morty Proxy This is a proxified and sanitized view of the page, visit original site.