cloud-foundation-fabric/blueprints/serverless/cloud-run-corporate/main.tf

666 lines
19 KiB
HCL

/**
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
locals {
cloud_run_domain = "run.app."
service_name_cr1 = "cart"
service_name_cr2 = "checkout"
tf_id = (
var.tf_identity == null
? null
: (
length(regexall("iam.gserviceaccount.com", var.tf_identity)) > 0
? "serviceAccount:${var.tf_identity}"
: "user:${var.tf_identity}"
)
)
vpc_sc_create = (
(
length(module.project_prj1) > 0
&&
(var.access_policy != null || var.access_policy_create != null)
)
? 1
: 0
)
}
###############################################################################
# Projects #
###############################################################################
# Main project
module "project_main" {
source = "../../../modules/project"
name = var.prj_main_id
project_create = var.prj_main_create != null
billing_account = try(var.prj_main_create.billing_account_id, null)
parent = try(var.prj_main_create.parent, null)
# Enable Shared VPC by default, some use cases will use this project as host
shared_vpc_host_config = {
enabled = true
}
services = [
"run.googleapis.com",
"compute.googleapis.com",
"dns.googleapis.com",
"cloudresourcemanager.googleapis.com",
"accesscontextmanager.googleapis.com"
]
skip_delete = true
}
# Simulated onprem environment
module "project_onprem" {
source = "../../../modules/project"
count = var.prj_onprem_id != null ? 1 : 0
name = var.prj_onprem_id
project_create = var.prj_onprem_create != null
billing_account = try(var.prj_onprem_create.billing_account_id, null)
parent = try(var.prj_onprem_create.parent, null)
services = [
"compute.googleapis.com",
"dns.googleapis.com"
]
skip_delete = true
}
# Project 1
module "project_prj1" {
source = "../../../modules/project"
count = var.prj_prj1_id != null ? 1 : 0
name = var.prj_prj1_id
project_create = var.prj_prj1_create != null
billing_account = try(var.prj_prj1_create.billing_account_id, null)
parent = try(var.prj_prj1_create.parent, null)
services = [
"compute.googleapis.com",
"dns.googleapis.com"
]
skip_delete = true
}
# Service Project 1
module "project_svc1" {
source = "../../../modules/project"
count = var.prj_svc1_id != null ? 1 : 0
name = var.prj_svc1_id
project_create = var.prj_svc1_create != null
billing_account = try(var.prj_svc1_create.billing_account_id, null)
parent = try(var.prj_svc1_create.parent, null)
shared_vpc_service_config = {
host_project = module.project_main.project_id
service_identity_iam = {
"roles/compute.networkUser" = [
"vpcaccess"
],
"roles/editor" = [
"cloudservices"
]
}
}
services = [
"compute.googleapis.com",
"dns.googleapis.com",
"run.googleapis.com",
"vpcaccess.googleapis.com"
]
skip_delete = true
}
###############################################################################
# Cloud Run #
###############################################################################
# Cloud Run service in main project
module "cloud_run_hello" {
source = "../../../modules/cloud-run"
project_id = module.project_main.project_id
name = "hello"
region = var.region
containers = {
default = {
image = var.image
}
}
iam = {
"roles/run.invoker" = ["allUsers"]
}
ingress_settings = var.ingress_settings
}
# VPC Access connector in the service project.
# The Shared VPC Ingress feature needs a VPC connector. In the future,
# this need will be removed.
resource "google_vpc_access_connector" "connector" {
count = var.prj_svc1_id != null ? 1 : 0
name = "connector"
project = module.project_svc1[0].project_id
region = var.region
subnet {
name = module.vpc_main.subnets["${var.region}/subnet-vpc-access"].name
project_id = module.project_main.project_id
}
}
# Cloud Run service 1 in service project
module "cloud_run_cart" {
source = "../../../modules/cloud-run"
count = var.prj_svc1_id != null ? 1 : 0
project_id = module.project_svc1[0].project_id
name = local.service_name_cr1 # "cart"
region = var.region
containers = {
default = {
image = var.image
}
}
iam = {
"roles/run.invoker" = ["allUsers"]
}
ingress_settings = var.ingress_settings
revision_annotations = {
vpcaccess_connector = google_vpc_access_connector.connector[0].name
}
}
# Cloud Run service 2 in service project
module "cloud_run_checkout" {
source = "../../../modules/cloud-run"
count = var.prj_svc1_id != null ? 1 : 0
project_id = module.project_svc1[0].project_id
name = local.service_name_cr2 # "checkout"
region = var.region
containers = {
default = {
image = var.image
}
}
iam = {
"roles/run.invoker" = ["allUsers"]
}
ingress_settings = var.ingress_settings
revision_annotations = {
vpcaccess_connector = google_vpc_access_connector.connector[0].name
}
}
###############################################################################
# VPCs #
###############################################################################
# VPC in main project
module "vpc_main" {
source = "../../../modules/net-vpc"
project_id = module.project_main.project_id
name = "vpc-main"
subnets = [
{
ip_cidr_range = var.ip_ranges["main"].subnet
name = "subnet-main"
region = var.region
},
{
ip_cidr_range = var.ip_ranges["main"].subnet_vpc_access
name = "subnet-vpc-access"
region = var.region
}
]
subnets_proxy_only = [
{
ip_cidr_range = var.ip_ranges["main"].subnet_proxy
name = "subnet-proxy"
region = var.region
active = true
}
]
}
# Main VPC Firewall with default config, IAP for SSH enabled
module "firewall_main" {
source = "../../../modules/net-vpc-firewall"
project_id = module.project_main.project_id
network = module.vpc_main.name
default_rules_config = {
http_ranges = []
https_ranges = []
}
}
# VPC in simulated onprem environment
module "vpc_onprem" {
source = "../../../modules/net-vpc"
count = length(module.project_onprem)
project_id = module.project_onprem[0].project_id
name = "vpc-onprem"
subnets = [
{
ip_cidr_range = var.ip_ranges["onprem"].subnet
name = "subnet-onprem"
region = var.region
}
]
}
# Onprem VPC Firewall with default config, IAP for SSH enabled
module "firewall_onprem" {
source = "../../../modules/net-vpc-firewall"
count = length(module.project_onprem)
project_id = module.project_onprem[0].project_id
network = module.vpc_onprem[0].name
default_rules_config = {
http_ranges = []
https_ranges = []
}
}
# VPC in project 1
module "vpc_prj1" {
source = "../../../modules/net-vpc"
count = length(module.project_prj1)
project_id = module.project_prj1[0].project_id
name = "vpc-prj1"
subnets = [
{
ip_cidr_range = var.ip_ranges["prj1"].subnet
name = "subnet-prj1"
region = var.region
}
]
}
# Project 1 VPC Firewall with default config, IAP for SSH enabled
module "firewall_prj1" {
source = "../../../modules/net-vpc-firewall"
count = length(module.project_prj1)
project_id = module.project_prj1[0].project_id
network = module.vpc_prj1[0].name
default_rules_config = {
http_ranges = []
https_ranges = []
}
}
###############################################################################
# PSC #
###############################################################################
# PSC configured in the main project
module "psc_addr_main" {
source = "../../../modules/net-address"
project_id = module.project_main.project_id
psc_addresses = {
psc-addr = {
address = var.ip_ranges["main"].psc_addr
network = module.vpc_main.self_link
}
}
}
resource "google_compute_global_forwarding_rule" "psc_endpoint_main" {
provider = google-beta
project = module.project_main.project_id
name = "pscaddr"
network = module.vpc_main.self_link
ip_address = module.psc_addr_main.psc_addresses["psc-addr"].self_link
target = "vpc-sc"
load_balancing_scheme = ""
}
# PSC configured in project 1
module "psc_addr_prj1" {
source = "../../../modules/net-address"
count = length(module.project_prj1)
project_id = module.project_prj1[0].project_id
psc_addresses = {
psc-addr = {
address = var.ip_ranges["prj1"].psc_addr
network = module.vpc_prj1[0].self_link
}
}
}
resource "google_compute_global_forwarding_rule" "psc_endpoint_prj1" {
provider = google-beta
count = length(module.project_prj1)
project = module.project_prj1[0].project_id
name = "pscaddr"
network = module.vpc_prj1[0].self_link
ip_address = module.psc_addr_prj1[0].psc_addresses["psc-addr"].self_link
target = "vpc-sc"
load_balancing_scheme = ""
}
###############################################################################
# L7 ILB #
###############################################################################
module "ilb-l7" {
source = "../../../modules/net-lb-app-int"
count = var.custom_domain == null ? 0 : 1
project_id = module.project_main.project_id
name = "ilb-l7-cr"
region = var.region
backend_service_configs = {
default = {
project_id = module.project_svc1[0].project_id
backends = [{
group = "cr1"
}]
health_checks = []
}
cart = {
project_id = module.project_svc1[0].project_id
backends = [{
group = "cr1"
}]
health_checks = []
}
checkout = {
project_id = module.project_svc1[0].project_id
backends = [{
group = "cr2"
}]
health_checks = []
}
}
health_check_configs = {}
neg_configs = {
cr1 = {
project_id = module.project_svc1[0].project_id
cloudrun = {
region = var.region
target_service = {
name = local.service_name_cr1
}
}
}
cr2 = {
project_id = module.project_svc1[0].project_id
cloudrun = {
region = var.region
target_service = {
name = local.service_name_cr2
}
}
}
}
urlmap_config = {
default_service = "default"
host_rules = [{
hosts = ["*"]
path_matcher = "pathmap"
}]
path_matchers = {
pathmap = {
default_service = "default"
path_rules = [
{
paths = ["/cart", "/cart/*"]
service = local.service_name_cr1
},
{
paths = ["/checkout", "/checkout/*"]
service = local.service_name_cr2
}
]
}
}
}
vpc_config = {
network = module.vpc_main.self_link
subnetwork = module.vpc_main.subnet_self_links["${var.region}/subnet-main"]
}
}
###############################################################################
# VMs #
###############################################################################
module "vm_test_main" {
source = "../../../modules/compute-vm"
project_id = module.project_main.project_id
zone = "${var.region}-b"
name = "vm-test-main"
instance_type = "e2-micro"
network_interfaces = [{
network = module.vpc_main.self_link
subnetwork = module.vpc_main.subnet_self_links["${var.region}/subnet-main"]
}]
tags = ["ssh"]
}
module "vm_test_onprem" {
source = "../../../modules/compute-vm"
count = length(module.project_onprem)
project_id = module.project_onprem[0].project_id
zone = "${var.region}-b"
name = "vm-test-onprem"
instance_type = "e2-micro"
network_interfaces = [{
network = module.vpc_onprem[0].self_link
subnetwork = module.vpc_onprem[0].subnet_self_links["${var.region}/subnet-onprem"]
}]
tags = ["ssh"]
}
module "vm_test_prj1" {
source = "../../../modules/compute-vm"
count = length(module.project_prj1)
project_id = module.project_prj1[0].project_id
zone = "${var.region}-b"
name = "vm-test-prj1"
instance_type = "e2-micro"
network_interfaces = [{
network = module.vpc_prj1[0].self_link
subnetwork = module.vpc_prj1[0].subnet_self_links["${var.region}/subnet-prj1"]
}]
tags = ["ssh"]
}
module "vm_test_svc1" {
source = "../../../modules/compute-vm"
count = length(module.project_svc1)
project_id = module.project_svc1[0].project_id
zone = "${var.region}-b"
name = "vm-test-svc1"
instance_type = "e2-micro"
network_interfaces = [{
network = module.vpc_main.self_link
subnetwork = module.vpc_main.subnet_self_links["${var.region}/subnet-main"]
}]
tags = ["ssh"]
}
###############################################################################
# DNS #
###############################################################################
module "private_dns_main" {
source = "../../../modules/dns"
project_id = module.project_main.project_id
name = "dns-main"
zone_config = {
domain = local.cloud_run_domain
private = {
client_networks = [module.vpc_main.self_link]
}
}
recordsets = {
"A *" = { records = [module.psc_addr_main.psc_addresses["psc-addr"].address] }
}
}
module "private_dns_main_custom" {
source = "../../../modules/dns"
count = var.custom_domain == null ? 0 : 1
project_id = module.project_main.project_id
name = "dns-main-custom"
zone_config = {
domain = format("%s.", var.custom_domain)
private = {
client_networks = [module.vpc_main.self_link]
}
}
recordsets = {
"A " = { records = [module.ilb-l7[0].address] }
}
}
module "private_dns_onprem" {
source = "../../../modules/dns"
count = length(module.project_onprem)
project_id = module.project_onprem[0].project_id
name = "dns-onprem"
zone_config = {
domain = local.cloud_run_domain
private = {
client_networks = [module.vpc_onprem[0].self_link]
}
}
recordsets = {
"A *" = { records = [module.psc_addr_main.psc_addresses["psc-addr"].address] }
}
}
module "private_dns_prj1" {
source = "../../../modules/dns"
count = length(module.project_prj1)
project_id = module.project_prj1[0].project_id
name = "dns-prj1"
zone_config = {
domain = local.cloud_run_domain
private = {
client_networks = [module.vpc_prj1[0].self_link]
}
}
recordsets = {
"A *" = { records = [module.psc_addr_prj1[0].psc_addresses["psc-addr"].address] }
}
}
###############################################################################
# VPC SC #
###############################################################################
module "vpc_sc" {
source = "../../../modules/vpc-sc"
count = local.vpc_sc_create
access_policy = var.access_policy_create == null ? var.access_policy : null
access_policy_create = var.access_policy_create
ingress_policies = {
ingress-ids = {
from = {
identities = [local.tf_id]
access_levels = ["*"]
}
to = {
operations = [{ service_name = "*" }]
resources = ["*"]
}
}
}
service_perimeters_regular = {
cloudrun = {
status = {
resources = [
"projects/${module.project_main.number}",
"projects/${module.project_prj1[0].number}"
]
restricted_services = ["run.googleapis.com"]
ingress_policies = ["ingress-ids"]
}
}
}
}
###############################################################################
# VPN #
###############################################################################
# VPN between main project and "onprem" environment
module "vpn_main" {
source = "../../../modules/net-vpn-ha"
count = length(module.project_onprem)
project_id = module.project_main.project_id
region = var.region
network = module.vpc_main.self_link
name = "vpn-main-to-onprem"
peer_gateways = {
default = { gcp = module.vpn_onprem[0].self_link }
}
router_config = {
asn = 65001
custom_advertise = {
all_subnets = true
ip_ranges = {
(var.ip_ranges["main"].psc_addr) = "to-psc-endpoint"
}
}
}
tunnels = {
tunnel-0 = {
bgp_peer = {
address = "169.254.0.2"
asn = 65002
}
bgp_session_range = "169.254.0.1/30"
vpn_gateway_interface = 0
}
tunnel-1 = {
bgp_peer = {
address = "169.254.1.2"
asn = 65002
}
bgp_session_range = "169.254.1.1/30"
vpn_gateway_interface = 1
}
}
}
module "vpn_onprem" {
source = "../../../modules/net-vpn-ha"
count = length(module.project_onprem)
project_id = module.project_onprem[0].project_id
region = var.region
network = module.vpc_onprem[0].self_link
name = "vpn-onprem-to-main"
peer_gateways = {
default = { gcp = module.vpn_main[0].self_link }
}
router_config = { asn = 65002 }
tunnels = {
tunnel-0 = {
bgp_peer = {
address = "169.254.0.1"
asn = 65001
}
bgp_session_range = "169.254.0.2/30"
vpn_gateway_interface = 0
shared_secret = module.vpn_main[0].random_secret
}
tunnel-1 = {
bgp_peer = {
address = "169.254.1.1"
asn = 65001
}
bgp_session_range = "169.254.1.2/30"
vpn_gateway_interface = 1
shared_secret = module.vpn_main[0].random_secret
}
}
}