Blog

How to configure a Google Pub/Sub push subscription within a VPC Service control perimeter

17 Oct, 2021
Xebia Background Header Wave

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

Mark van Holsteijn
Mark van Holsteijn is a senior software systems architect at Xebia Cloud-native solutions. He is passionate about removing waste in the software delivery process and keeping things clear and simple.
Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts