When your project runs inside a VPC service control perimeter, Google Cloud Pub/Sub push subscriptions are not support. In this blog I will introduce you to a simple egress proxy, which will allow you to work-around this restriction.
According to the VPC service control documentation, Google Pub/Sub is a fully supported product. With an exception for push subscriptions. Push subscriptions can only target Google Cloud Run services. An existing push subscriptions will continue to work, but if you try to create a new one you will receive the error: Request is prohibited by organization's policy.
To work around this problem, we have created a simple https proxy in go. When you change your push subscription to target this proxy, it will forward the requests to the original destination.
deploy the proxy
To deploy the proxy, use the following Terraform snippet:
resource "google_cloud_run_service" "push_subscription_proxy" {
name = "push-subscription-proxy"
location = data.google_client_config.current.region
template {
spec {
service_account_name = google_service_account.push_subscription_proxy.email
containers {
image = "gcr.io/binx-io-public/simple-egress-proxy:0.1.0"
args = [ "--target-url", "https://httpbin.org/anything/event"]
}
}
}
}
Of course you have to change the URL to your original destination.
change the push subscription
Next, you change the push subscription to point to the egress proxy:
resource "google_pubsub_subscription" "proxied_push_subscription" {
name = "proxied-push-subscription"
topic = google_pubsub_topic.notifications.name
push_config {
push_endpoint = google_cloud_run_service.push_subscription_proxy.status[0].url
oidc_token {
service_account_email = google_service_account.push_subscription_proxy.email
}
}
}
To ensure that the service can only be invoked by this subscription, create a separate service account and use the following policy:
resource "google_service_account" "push_subscription_proxy" {
account_id = "push-subscription-proxy"
display_name = "Pub/Sub push subscription proxy"
}
resource "google_cloud_run_service_iam_binding" "push_subscription_proxy_run_invokers" {
location = google_cloud_run_service.push_subscription_proxy.location
project = google_cloud_run_service.push_subscription_proxy.project
service = google_cloud_run_service.push_subscription_proxy.name
role = "roles/run.invoker"
members = [
format("serviceAccount:%s", google_service_account.push_subscription_proxy.email)
]
depends_on = [google_cloud_run_service.push_subscription_proxy]
}
Checkout the terraform demo template for a full working version.
Conclusion
The simple egress proxy is written with just a few lines of code using the standard golang proxy library. It provides a quick work-around for the restriction on Google Pub/Sub push notifications inside a VPC service control perimeter.
Image by Екатерина Гусева from Pixabay