Use Fabric modules when possibile

This commit is contained in:
Wiktor Niesiobędzki 2024-02-14 19:54:32 +00:00 committed by Wiktor Niesiobędzki
parent d158aecba1
commit 19be54a72f
7 changed files with 245 additions and 315 deletions

View File

@ -74,7 +74,7 @@ Before we deploy the architecture, you will need the following information:
4. Copy the following command into a console and replace __[consumer-project-id]__ and __[producer-a-project-id]__ and __[producer-b-project-id]__ with your projects IDs. Then run the following command to run the terraform script and create all relevant resources for this architecture:
terraform apply -var consumer_project_id=[consumer-project-id] -var producer_a_project_id=[producer-a-project-id] -var producer_b_project_id=[producer-b-project-id]
terraform apply -var consumer_project_id=[consumer-project-id] -var producer_a_project_id=[producer-a-project-id] -var producer_b_project_id=[producer-b-project-id] -var region=[gcp-region]
The resource creation will take a few minutes… but when its complete, you should see an output stating the command completed successfully with a list of the created resources.
@ -85,13 +85,13 @@ __Congratulations__! You have successfully deployed an HTTP Load Balancer with C
You can simply invoke the service by calling
Check the default path (producer A):
curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -H "Content-Type: application/json" http://$LB_IP/anything
curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -H "Content-Type: application/json" http://$(terraform output -raw lb_ip)/uuid
Specifically call the producer A path:
curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -H "Content-Type: application/json" http://$LB_IP/anything/a/*
curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -H "Content-Type: application/json" http://$(terraform output -raw lb_ip)/a/uuid
Specifically call the producer B path:
curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -H "Content-Type: application/json" http://$LB_IP/anything/b/*
curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -H "Content-Type: application/json" http://$(terraform output -raw lb_ip)/b/uuid
## Cleaning up your environment
@ -106,12 +106,11 @@ The above command will delete the associated resources so there will be no billa
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [consumer_project_id](variables.tf#L17) | The consumer project, in which the GCLB and Cloud Armor should be created. | <code>string</code> | ✓ | |
| [prefix](variables.tf#L22) | Prefix used for resource names. | <code>string</code> | ✓ | |
| [producer_a_project_id](variables.tf#L31) | The producer A project, in which the LB, PSC Service Attachment and Cloud Run service should be created. | <code>string</code> | ✓ | |
| [producer_b_project_id](variables.tf#L36) | The producer B project, in which the LB, PSC Service Attachment and Cloud Run service should be created. | <code>string</code> | ✓ | |
| [project_create](variables.tf#L41) | Create project instead of using an existing one. | <code>bool</code> | | <code>false</code> |
| [region](variables.tf#L47) | The GCP region in which the resources should be deployed. | <code>string</code> | | <code>&#34;europe-west1&#34;</code> |
| [zone](variables.tf#L53) | The GCP zone for the VM. | <code>string</code> | | <code>&#34;europe-west1-b&#34;</code> |
| [producer_a_project_id](variables.tf#L28) | The producer A project, in which the LB, PSC Service Attachment and Cloud Run service should be created. | <code>string</code> | ✓ | |
| [producer_b_project_id](variables.tf#L33) | The producer B project, in which the LB, PSC Service Attachment and Cloud Run service should be created. | <code>string</code> | ✓ | |
| [region](variables.tf#L47) | The GCP region in which the resources should be deployed. | <code>string</code> | ✓ | |
| [prefix](variables.tf#L22) | Prefix used for resource names. | <code>string</code> | | <code>&#34;&#34;</code> |
| [project_create_config](variables.tf#L38) | Create project instead of using an existing one. | <code title="object&#40;&#123;&#10; billing_account &#61; string&#10; parent &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
## Outputs
@ -123,12 +122,15 @@ The above command will delete the associated resources so there will be no billa
```hcl
module "psc-glb-and-armor-test" {
source = "./fabric/blueprints/networking/psc-glb-and-armor"
prefix = "test"
project_create = true
source = "./fabric/blueprints/networking/psc-glb-and-armor"
prefix = "test"
project_create_config = {
billing_account = var.billing_account_id
}
consumer_project_id = "project-1"
producer_a_project_id = "project-2"
producer_b_project_id = "project-3"
region = "europe-west2"
}
# tftest modules=6 resources=57
# tftest modules=14 resources=57
```

View File

@ -1,5 +1,5 @@
/**
* Copyright 2023 Google LLC
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,95 +14,131 @@
* limitations under the License.
*/
module "consumer_project" {
module "consumer-project" {
source = "../../../modules/project"
name = var.consumer_project_id
project_create = var.project_create
project_create = var.project_create_config != null
billing_account = try(var.project_create_config.billing_account)
parent = try(var.project_create_config.parent)
prefix = var.prefix
services = [
"iam.googleapis.com",
"compute.googleapis.com",
]
}
module "producer_a_project" {
source = "./modules/producer"
producer_project_id = var.producer_a_project_id
project_create = var.project_create
module "producer-a" {
source = "./modules/producer"
consumer_project_id = module.consumer-project.project_id
prefix = var.prefix
producer_project_id = var.producer_a_project_id
project_create_config = var.project_create_config
}
module "producer_b_project" {
source = "./modules/producer"
producer_project_id = var.producer_b_project_id
project_create = var.project_create
module "producer-b" {
source = "./modules/producer"
consumer_project_id = module.consumer-project.project_id
prefix = var.prefix
producer_project_id = var.producer_b_project_id
project_create_config = var.project_create_config
}
resource "google_compute_region_network_endpoint_group" "psc_neg_a" {
name = "psc-neg-a"
region = var.region
project = module.consumer_project.project_id
network_endpoint_type = "PRIVATE_SERVICE_CONNECT"
psc_target_service = module.producer_a_project.psc_ilb_service_attachment.self_link
module "consumer-vpc" {
source = "../../../modules/net-vpc"
network = "default"
subnetwork = "default"
name = "consumer"
project_id = module.consumer-project.project_id
subnets = [
{
ip_cidr_range = "10.0.0.0/24"
name = "consumer"
region = var.region
},
]
}
resource "google_compute_region_network_endpoint_group" "psc_neg_b" {
name = "psc-neg-b"
region = var.region
project = module.consumer_project.project_id
network_endpoint_type = "PRIVATE_SERVICE_CONNECT"
psc_target_service = module.producer_b_project.psc_ilb_service_attachment.self_link
network = "default"
subnetwork = "default"
}
resource "google_compute_global_forwarding_rule" "default" {
project = module.consumer_project.project_id
name = "global-rule"
load_balancing_scheme = "EXTERNAL_MANAGED"
target = google_compute_target_http_proxy.default.id
port_range = "80"
}
resource "google_compute_target_http_proxy" "default" {
project = module.consumer_project.project_id
name = "target-proxy"
description = "a description"
url_map = google_compute_url_map.default.id
}
resource "google_compute_url_map" "default" {
project = module.consumer_project.project_id
name = "url-map-target-proxy"
description = "A simple URL Map, routing all traffic to the PSC NEG"
default_service = google_compute_backend_service.backend-a.id
host_rule {
hosts = ["*"]
path_matcher = "allpaths"
}
path_matcher {
name = "allpaths"
default_service = google_compute_backend_service.backend-a.id
path_rule {
paths = ["/anything/b/*"]
service = google_compute_backend_service.backend-b.id
module "glb" {
source = "./../../../modules/net-lb-app-ext"
name = "glb"
project_id = module.consumer-project.project_id
use_classic_version = false
backend_service_configs = {
default = {
backends = [
{ backend = "neg-a" }
]
health_checks = []
protocol = "HTTPS"
security_policy = google_compute_security_policy.cloud-armor-policy.name
}
path_rule {
paths = ["/anything/a/*"]
service = google_compute_backend_service.backend-a.id
other = {
backends = [
{ backend = "neg-b" }
]
health_checks = []
protocol = "HTTPS"
security_policy = google_compute_security_policy.cloud-armor-policy.name
}
}
# with a single serverless NEG the implied default health check is not needed
health_check_configs = {}
neg_configs = {
neg-a = {
psc = {
region = var.region
target_service = module.producer-a.exposed_service_psc_attachment.self_link
network = module.consumer-vpc.id
subnetwork = module.consumer-vpc.subnet_ids["${var.region}/consumer"]
}
}
neg-b = {
psc = {
region = var.region
target_service = module.producer-b.exposed_service_psc_attachment.self_link
network = module.consumer-vpc.id
subnetwork = module.consumer-vpc.subnet_ids["${var.region}/consumer"]
}
}
}
urlmap_config = {
default_service = "default"
host_rules = [{
hosts = ["*"]
path_matcher = "pathmap"
}]
path_matchers = {
pathmap = {
default_service = "default"
path_rules = [
{
paths = ["/b/*"]
service = "other"
route_action = {
url_rewrite = {
path_prefix = "/" # rewrite "/b/*" to "/*"
}
}
},
{
paths = ["/a/*"]
service = "default"
route_action = {
url_rewrite = {
path_prefix = "/" # rewrite "/b/*" to "/*"
}
}
},
]
}
}
}
}
resource "google_compute_security_policy" "policy" {
resource "google_compute_security_policy" "cloud-armor-policy" {
provider = google-beta
project = module.consumer_project.project_id
project = module.consumer-project.project_id
name = "ddos-protection"
adaptive_protection_config {
layer_7_ddos_defense_config {
@ -110,29 +146,3 @@ resource "google_compute_security_policy" "policy" {
}
}
}
resource "google_compute_backend_service" "backend-a" {
provider = google-beta
project = module.consumer_project.project_id
name = "backend-a"
load_balancing_scheme = "EXTERNAL_MANAGED"
protocol = "HTTPS"
backend {
group = google_compute_region_network_endpoint_group.psc_neg_a.id
balancing_mode = "UTILIZATION"
capacity_scaler = 1.0
}
}
resource "google_compute_backend_service" "backend-b" {
provider = google-beta
project = module.consumer_project.project_id
name = "backend-b"
load_balancing_scheme = "EXTERNAL_MANAGED"
protocol = "HTTPS"
backend {
group = google_compute_region_network_endpoint_group.psc_neg_b.id
balancing_mode = "UTILIZATION"
capacity_scaler = 1.0
}
}

View File

@ -1,5 +1,5 @@
/**
* Copyright 2023 Google LLC
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,10 +14,14 @@
* limitations under the License.
*/
module "producer_project" {
module "producer-project" {
source = "../../../../../modules/project"
name = var.producer_project_id
project_create = var.project_create
project_create = var.project_create_config != null
billing_account = try(var.project_create_config.billing_account)
parent = try(var.project_create_config.parent)
prefix = var.prefix
services = [
"iam.googleapis.com",
"run.googleapis.com",
@ -25,90 +29,66 @@ module "producer_project" {
]
}
resource "google_service_account" "app" {
project = module.producer_project.project_id
account_id = "example-app"
display_name = "Example App Service Account"
module "app" {
source = "../../../../../modules/cloud-run-v2"
name = "example-app"
project_id = module.producer-project.project_id
region = var.region
containers = {
hello = {
image = "kennethreitz/httpbin:latest"
ports = {
http = { container_port = 80 }
}
}
}
ingress = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER"
service_account_create = true
}
resource "google_cloud_run_service" "app" {
name = "example-app"
location = var.region
project = module.producer_project.project_id
module "producer-ilb" {
source = "../../../../../modules/net-lb-app-int"
name = "example-app"
project_id = module.producer-project.project_id
region = var.region
template {
spec {
containers {
image = "kennethreitz/httpbin:latest"
ports {
container_port = 80
backend_service_configs = {
default = {
backends = [{
group = "my-neg"
}]
health_checks = []
}
}
global_access = true
health_check_configs = {}
neg_configs = {
my-neg = {
cloudrun = {
region = var.region
target_service = {
name = module.app.service_name
}
}
service_account_name = google_service_account.app.email
}
}
autogenerate_revision_name = true
traffic {
percent = 100
latest_revision = true
}
metadata {
annotations = {
"run.googleapis.com/ingress" = "internal-and-cloud-load-balancing"
protocol = "HTTPS"
ssl_certificates = {
create_configs = {
default = {
# certificate and key could also be read via file() from external files
certificate = tls_self_signed_cert.example.cert_pem
private_key = tls_private_key.example.private_key_pem
}
}
}
}
resource "google_compute_region_network_endpoint_group" "neg" {
name = "example-app-neg"
network_endpoint_type = "SERVERLESS"
region = var.region
project = module.producer_project.project_id
cloud_run {
service = google_cloud_run_service.app.name
vpc_config = {
network = module.producer-vpc.self_link
subnetwork = module.producer-vpc.subnets["${var.region}/ilb-subnetwork"].self_link
}
}
resource "google_compute_forwarding_rule" "psc_ilb_target_service" {
name = "producer-forwarding-rule"
region = var.region
project = module.producer_project.project_id
depends_on = [google_compute_subnetwork.proxy_subnet]
load_balancing_scheme = "INTERNAL_MANAGED"
port_range = "443"
allow_global_access = true
target = google_compute_region_target_https_proxy.default.id
network = google_compute_network.psc_ilb_network.name
subnetwork = google_compute_subnetwork.ilb_subnetwork.name
}
resource "google_compute_region_target_https_proxy" "default" {
name = "l7-ilb-target-http-proxy"
provider = google-beta
region = var.region
project = module.producer_project.project_id
url_map = google_compute_region_url_map.default.id
ssl_certificates = [google_compute_region_ssl_certificate.default.id]
}
resource "google_compute_region_ssl_certificate" "default" {
region = var.region
project = module.producer_project.project_id
name = "my-certificate"
private_key = tls_private_key.example.private_key_pem
certificate = tls_self_signed_cert.example.cert_pem
}
resource "google_compute_region_url_map" "default" {
name = "l7-ilb-regional-url-map"
provider = google-beta
region = var.region
project = module.producer_project.project_id
default_service = google_compute_region_backend_service.producer_service_backend.id
}
resource "tls_private_key" "example" {
algorithm = "RSA"
rsa_bits = 2048
@ -130,114 +110,48 @@ resource "tls_self_signed_cert" "example" {
"server_auth",
]
}
resource "google_compute_region_backend_service" "producer_service_backend" {
name = "producer-service"
region = var.region
project = module.producer_project.project_id
load_balancing_scheme = "INTERNAL_MANAGED"
protocol = "HTTPS"
backend {
group = google_compute_region_network_endpoint_group.neg.id
balancing_mode = "UTILIZATION"
capacity_scaler = 1.0
}
module "producer-vpc" {
source = "../../../../../modules/net-vpc"
project_id = module.producer-project.project_id
name = "psc-ilb-network"
subnets = [
{
ip_cidr_range = "10.0.0.0/24"
name = "ilb-subnetwork"
region = var.region
},
]
subnets_proxy_only = [
{
ip_cidr_range = "10.0.1.0/24"
name = "l7-ilb-proxy-subnet"
region = var.region
active = true
},
]
subnets_psc = [
{
ip_cidr_range = "10.3.0.0/16"
name = "psc-private-subnetwork"
region = var.region
}
]
}
resource "google_compute_network" "psc_ilb_network" {
name = "psc-ilb-network"
auto_create_subnetworks = false
project = module.producer_project.project_id
}
resource "google_compute_subnetwork" "ilb_subnetwork" {
name = "ilb-subnetwork"
region = var.region
project = module.producer_project.project_id
network = google_compute_network.psc_ilb_network.id
ip_cidr_range = "10.0.0.0/24"
role = "ACTIVE"
}
# proxy-only subnet
resource "google_compute_subnetwork" "proxy_subnet" {
name = "l7-ilb-proxy-subnet"
provider = google-beta
ip_cidr_range = "10.0.1.0/24"
region = var.region
project = module.producer_project.project_id
purpose = "REGIONAL_MANAGED_PROXY"
role = "ACTIVE"
network = google_compute_network.psc_ilb_network.id
}
resource "google_compute_subnetwork" "psc_private_subnetwork" {
name = "psc-private-subnetwork"
region = var.region
project = module.producer_project.project_id
network = google_compute_network.psc_ilb_network.id
ip_cidr_range = "10.3.0.0/16"
purpose = "PRIVATE"
role = "ACTIVE"
}
resource "google_compute_subnetwork" "psc_ilb_nat" {
name = "psc-ilb-nat"
region = var.region
project = module.producer_project.project_id
network = google_compute_network.psc_ilb_network.id
purpose = "PRIVATE_SERVICE_CONNECT"
ip_cidr_range = "10.1.0.0/16"
}
resource "google_compute_subnetwork" "vms" {
name = "vms"
region = var.region
project = module.producer_project.project_id
network = google_compute_network.psc_ilb_network.id
ip_cidr_range = "10.4.0.0/16"
}
resource "google_compute_service_attachment" "psc_ilb_service_attachment" {
name = "my-psc-ilb"
resource "google_compute_service_attachment" "exposed-psc-service" {
name = "producer-app"
region = var.region
project = module.producer_project.project_id
project = module.producer-project.project_id
description = "A service attachment configured with Terraform"
enable_proxy_protocol = false
connection_preference = "ACCEPT_AUTOMATIC"
nat_subnets = [google_compute_subnetwork.psc_ilb_nat.id]
target_service = google_compute_forwarding_rule.psc_ilb_target_service.id
connection_preference = "ACCEPT_MANUAL"
nat_subnets = [module.producer-vpc.subnets_psc["${var.region}/psc-private-subnetwork"].id]
target_service = module.producer-ilb.id
consumer_accept_lists {
connection_limit = 10
project_id_or_num = var.consumer_project_id
}
}
resource "google_service_account" "noop" {
project = module.producer_project.project_id
account_id = "noop-sa"
display_name = "Service Account for NOOP VM"
}
resource "google_compute_instance" "noop-vm" {
project = module.producer_project.project_id
name = "noop-ilb-vm"
machine_type = "e2-medium"
zone = var.zone
boot_disk {
initialize_params {
image = "debian-cloud/debian-11"
}
}
network_interface {
network = google_compute_network.psc_ilb_network.id
subnetwork = google_compute_subnetwork.vms.id
}
service_account {
email = google_service_account.noop.email
scopes = []
}
}

View File

@ -13,6 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
output "psc_ilb_service_attachment" {
value = google_compute_service_attachment.psc_ilb_service_attachment
output "exposed_service_psc_attachment" {
value = google_compute_service_attachment.exposed-psc-service
}

View File

@ -14,15 +14,32 @@
* limitations under the License.
*/
variable "consumer_project_id" {
description = "The producer project, in which the LB, PSC Service Attachment and Cloud Run service should be created."
type = string
}
variable "prefix" {
description = "Prefix used for resource names."
type = string
validation {
condition = var.prefix != ""
error_message = "Prefix cannot be empty."
}
}
variable "producer_project_id" {
description = "The producer project, in which the LB, PSC Service Attachment and Cloud Run service should be created."
type = string
}
variable "project_create" {
variable "project_create_config" {
description = "Create project instead of using an existing one."
type = bool
default = false
type = object({
billing_account = string
parent = optional(string)
})
default = null
}
variable "region" {
@ -30,9 +47,3 @@ variable "region" {
type = string
default = "europe-west1"
}
variable "zone" {
description = "The GCP zone for the VM."
type = string
default = "europe-west1-b"
}

View File

@ -1,5 +1,5 @@
/**
* Copyright 2023 Google LLC
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,5 +16,5 @@
output "lb_ip" {
description = "Load balancer IP address."
value = google_compute_global_forwarding_rule.default.ip_address
value = module.glb.address
}

View File

@ -1,5 +1,5 @@
/**
* Copyright 2023 Google LLC
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -22,10 +22,7 @@ variable "consumer_project_id" {
variable "prefix" {
description = "Prefix used for resource names."
type = string
validation {
condition = var.prefix != ""
error_message = "Prefix cannot be empty."
}
default = ""
}
variable "producer_a_project_id" {
@ -38,20 +35,16 @@ variable "producer_b_project_id" {
type = string
}
variable "project_create" {
variable "project_create_config" {
description = "Create project instead of using an existing one."
type = bool
default = false
type = object({
billing_account = string
parent = optional(string)
})
default = null
}
variable "region" {
description = "The GCP region in which the resources should be deployed."
type = string
default = "europe-west1"
}
variable "zone" {
description = "The GCP zone for the VM."
type = string
default = "europe-west1-b"
}