How to create a Static Outbound IP for Google Cloud Functions using Terraform

GCF with static outbound IP

Most of us have created a server-less function which generates a dynamic IP addresses. In some cases, you might want traffic originating from your function to be associated with a static IP address. It is mostly required when we want to whitelist a specific IP address when integrating with our APIs.
To have a static outbound IP address, we need to make sure we have the following things setup.

  • Create a VPC
  • Setup a Serverless VPC Access Connector
  • Deploy the Cloud Function
  • Setup a specific IP Address
  • Configure a Cloud Router
  • Create a Cloud NAT Gateway
  • Link all the steps to be used by the cloud function

Now that we know what are the things that we need, let’s setup the cloud function by linking them all. I have assumed that you have the gcloud cli already setup.

Step 1 : Create a VPC

You can configure an existing VPC network or create a new one using this terraform code.

resource "google_compute_network" "vpc_network" {
project = "demo-project"
name = "demo-vpc"
auto_create_subnetworks = false
mtu = 1460
}
resource "google_compute_subnetwork" "subnets" {
name = "public-subnet"
ip_cidr_range = "192.168.1.0/24"
region = "us-west1"
network = google_compute_network.vpc_network.id
}

Step 2: Create Serverless VPC Access Connector

Cloud Functions need a Serverless VPC Access connector to route traffic into your VPC network.

resource "google_vpc_access_connector" "connector" {
name = "demo-vpc-access-connector"
region = "us-west1"
ip_cidr_range = "192.168.8.0/28"
network = google_compute_network.vpc_network.name
}

Step 3: Deploy the cloud Function

Now, we need to recreate the required function and link it to the VPC Connector. I have attached a dummy function code below which runs a helloworld function in the google cloud function. This is just for reference, you may have your own function.

  1. Here, we have a function and we assigned the environment variables, networking, timeouts and more.
  2. In the Connections section, under Egress settings, we used the Serverless VPC Access connector created above and Route All_TRAFFIC through the VPC connector.
resource "google_cloudfunctions_function" "google_cloud_function" {
name = "gcf-demo-cloud-function"
description = "gcf-demo-cloud-function"
runtime = "nodejs16"
available_memory_mb = 256

source_archive_bucket = "gcf-bucket"
source_archive_object = "helloworld.zip"
environment_variables = {
PROJECT = "DEMO"
}
vpc_connector = google_vpc_access_connector.connector.name
vpc_connector_egress_settings = "ALL_TRAFFIC"
event_trigger {
event_type = "google.pubsub.topic.publish"
resource = "demo-topic"
}
lifecycle {
ignore_changes = [
entry_point,
labels,
min_instances,
]
}
}

Step 4: Create a Cloud NAT Gateway

Following the deployment of the function, all traffic coming from our function is routed through the VPC network and follows the VPC network’s regulations. Note that until Cloud NAT is configured, the function will be unable to access the public internet. In order to include the connector’s subnet in the mapping, Cloud NAT must map all primary and secondary IP ranges for all subnets to the NAT gateway. In some cases, while associating function egress with a static IP address, we want the traffic originating from our function to be associated with a static IP address. For example, this is useful if we are calling an external service that only allows requests from explicitly specified IP addresses.

  1. Specify a static IP address.
  2. Create a cloud router with specific vpc network as created above.
  3. Set up Cloud NAT for the subnet associated with the function’s Serverless VPC Access connector. As stated above, we need our Cloud NAT to map all primary and secondary IP ranges for all subnets to the NAT gateway, in order to include the connector’s subnet in the mapping.
resource "google_compute_address" "nat-ip" {
name = "demo-gcf-nat-gateway"
}

resource "google_compute_router" "router" {
name = "demo-gcf-router"
region = "us-west1"
network = google_compute_network.vpc_network.name
}

resource "google_compute_router_nat" "nat" {
name = "demo-gcf-router-nat"
router = google_compute_router.router.name
region = google_compute_router.router.region

nat_ip_allocate_option = "MANUAL_ONLY"
nat_ips = google_compute_address.nat-ip.*.self_link
source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"

log_config {
enable = true
filter = "ERRORS_ONLY"
}
}

Conclusion

The outgoing IP Address will always be a static IP Address that was established in Step 4 while running the google compute address.

Congratulations! Everything is finally completed. You may now have a static IP and let that IP be whitelisted in your firewall.

Enjoy!

References

https://cloud.google.com/functions/docs/networking/network-settings#associate-static-ip

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store