Skip to content

Commit

Permalink
Create a networking module for provisioning a Cloud Run compatible ne…
Browse files Browse the repository at this point in the history
…twork. (#6)

This creates a module suitable for provisioning a network and regional
subnets suitable for use with Cloud Run's direct VPC egress feature (in
preview).

Signed-off-by: Matt Moore <[email protected]>
  • Loading branch information
mattmoor authored Dec 10, 2023
1 parent ed2041c commit ac834c4
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 9 deletions.
1 change: 1 addition & 0 deletions .github/workflows/documentation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jobs:
- authorize-private-service
- cloudevent-broker
- cloudevent-trigger
- networking

steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
Expand Down
18 changes: 12 additions & 6 deletions cloudevent-broker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,27 @@ This module provisions a regionalizied Broker abstraction akin to the Knative
events is something like this:

```hcl
// Create a network with several regional subnets
module "networking" {
source = "chainguard-dev/glue/cloudrun//networking"
name = "my-networking"
project_id = var.project_id
regions = [...]
}
// Create the Broker abstraction.
module "cloudevent-broker" {
source = "chainguard-dev/glue/cloudrun//cloudevent-broker"
name = "my-broker"
project_id = var.project_id
regions = local.region-to-networking
regions = module.networking.regional-networks
}
// Authorize the "foo" service account to publish events.
module "foo-emits-events" {
for_each = local.region-to-networking
for_each = module.networking.regional-networks
source = "chainguard-dev/glue/cloudrun//authorize-private-service"
Expand All @@ -31,7 +40,7 @@ module "foo-emits-events" {
// Run a cloud run service as the "foo" service account, and pass in the address
// of the regional ingress endpoint.
resource "google_cloud_run_v2_service" "foo-service" {
for_each = local.region-to-networking
for_each = module.networking.regional-networks
project = var.project_id
name = "foo"
Expand Down Expand Up @@ -62,9 +71,6 @@ resource "google_cloud_run_v2_service" "foo-service" {
}
}
}
// TODO(mattmoor): Put together an example showing how to set up
// local.region-to-networking with the appropriate pieces.
```

<!-- BEGIN_TF_DOCS -->
Expand Down
15 changes: 12 additions & 3 deletions cloudevent-trigger/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,27 @@ is captured by the sibling `cloudevent-broker` module. The intended usage of
this module for consuming events is something like this:

```hcl
// Create a network with several regional subnets
module "networking" {
source = "chainguard-dev/glue/cloudrun//networking"
name = "my-networking"
project_id = var.project_id
regions = [...]
}
// Create the Broker abstraction.
module "cloudevent-broker" {
source = "chainguard-dev/glue/cloudrun//cloudevent-broker"
name = "my-broker"
project_id = var.project_id
regions = local.region-to-networking
regions = module.networking.regional-networks
}
// Run a cloud run service "bar" to consume events from the Broker above.
resource "google_cloud_run_v2_service" "bar-service" {
for_each = local.region-to-networking
for_each = module.networking.regional-networks
project = var.project_id
name = "bar"
Expand Down Expand Up @@ -49,7 +58,7 @@ resource "google_cloud_run_v2_service" "bar-service" {
// Set up regionalized triggers to deliver filtered events from our regionalized
// brokers to our regionalized consumer services.
module "cloudevent-trigger" {
for_each = var.regions
for_each = module.networking.regional-networks
source = "chainguard-dev/glue/cloudrun//cloudevent-trigger"
Expand Down
70 changes: 70 additions & 0 deletions networking/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# `networking`

This module sets up GCP networking suitable for operating Cloud Run services
utilizing the preview [Direct VPC egress](https://cloud.google.com/run/docs/configuring/vpc-direct-vpc)
feature to talk to other "internal ingress" Cloud Run services, and access other
GCP resources that live within or are accessible via the provisioned network.
The intended usage of this module:

```hcl
// Create a network with several regional subnets
module "networking" {
source = "chainguard-dev/glue/cloudrun//networking"
name = "my-networking"
project_id = var.project_id
// These are all of the regions where direct VPC egress is
// supported in preview.
regions = [
"us-east1",
"us-central1",
"europe-west1",
"europe-west3",
"asia-northeast1",
]
}
```

<!-- BEGIN_TF_DOCS -->
## Requirements

No requirements.

## Providers

| Name | Version |
|------|---------|
| <a name="provider_google"></a> [google](#provider\_google) | n/a |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [google_compute_network.this](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_network) | resource |
| [google_compute_subnetwork.regional](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_subnetwork) | resource |
| [google_dns_managed_zone.cloud-run-internal](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/dns_managed_zone) | resource |
| [google_dns_managed_zone.private-google-apis](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/dns_managed_zone) | resource |
| [google_dns_record_set.cloud-run-cname](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/dns_record_set) | resource |
| [google_dns_record_set.private-googleapis-a-record](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/dns_record_set) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_cidr"></a> [cidr](#input\_cidr) | n/a | `string` | `"10.0.0.0/8"` | no |
| <a name="input_name"></a> [name](#input\_name) | n/a | `string` | n/a | yes |
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | n/a | `string` | n/a | yes |
| <a name="input_regions"></a> [regions](#input\_regions) | The list of regions in which to provision subnets suitable for use with Cloud Run direct VPC egress. | `list(string)` | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_network_id"></a> [network\_id](#output\_network\_id) | n/a |
| <a name="output_regional-networks"></a> [regional-networks](#output\_regional-networks) | n/a |
<!-- END_TF_DOCS -->
60 changes: 60 additions & 0 deletions networking/dns.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Create a special DNS zone attached to the network in which
// we will operate our services that reroutes *.run.app to records
// that we control.
resource "google_dns_managed_zone" "cloud-run-internal" {
project = var.project_id
name = "cloud-run-internal"
dns_name = "run.app."
description = "This reroutes run.app requests to private.googleapis.com"

visibility = "private"

private_visibility_config {
networks {
network_url = google_compute_network.this.id
}
}
}

// Create a record for *.run.app that points to private.googleapis.com
resource "google_dns_record_set" "cloud-run-cname" {
project = var.project_id
name = "*.run.app."
managed_zone = google_dns_managed_zone.cloud-run-internal.name
type = "CNAME"
ttl = 60

rrdatas = ["private.googleapis.com."]
}

// Create a special DNS zone attached to the network in which
// we will operate our services that reroutes private.googleapis.com
// to records that we control.
resource "google_dns_managed_zone" "private-google-apis" {
project = var.project_id
name = "private-google-apis"
dns_name = "private.googleapis.com."
description = "This maps DNS for private.googleapis.com"

visibility = "private"

private_visibility_config {
networks {
network_url = google_compute_network.this.id
}
}
}

// Create a record for private.googleapis.com that points to
// the documented internal IP addresses for the Google APIs.
resource "google_dns_record_set" "private-googleapis-a-record" {
project = var.project_id
name = "private.googleapis.com."
managed_zone = google_dns_managed_zone.private-google-apis.name
type = "A"
ttl = 60

// This IP range is documented here:
// https://cloud.google.com/vpc/docs/configure-private-google-access-hybrid
rrdatas = [for x in range(8, 12) : "199.36.153.${x}"]
}
25 changes: 25 additions & 0 deletions networking/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Create a global network in which to place our resources.
resource "google_compute_network" "this" {
name = var.name
auto_create_subnetworks = false
routing_mode = "GLOBAL"
project = var.project_id
delete_default_routes_on_create = true
}

// Create regional subnets in each of the specified regions,
// which we will use to operate Cloud Run services.
resource "google_compute_subnetwork" "regional" {
for_each = {
for region in var.regions : region => 1 + index(var.regions, region)
}

name = "${var.name}-${each.key}"

// This is needed in order to interact with Google APIs like Pub/Sub.
private_ip_google_access = true

network = google_compute_network.this.id
region = each.key
ip_cidr_range = cidrsubnet(var.cidr, 8, each.value)
}
12 changes: 12 additions & 0 deletions networking/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
output "network_id" {
value = google_compute_network.this.id
}

output "regional-networks" {
value = {
for region in var.regions : region => {
network = google_compute_network.this.id
subnet = google_compute_subnetwork.regional[region].name
}
}
}
16 changes: 16 additions & 0 deletions networking/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
variable "name" {
type = string
}

variable "project_id" {
type = string
}

variable "regions" {
type = list(string)
description = "The list of regions in which to provision subnets suitable for use with Cloud Run direct VPC egress."
}

variable "cidr" {
default = "10.0.0.0/8"
}

0 comments on commit ac834c4

Please sign in to comment.