Skip to content

Commit

Permalink
adds support to multiple services project and the creation of a Share…
Browse files Browse the repository at this point in the history
…d VPC in a network project
  • Loading branch information
amandakarina committed Apr 24, 2023
1 parent 7744a6d commit afe6228
Show file tree
Hide file tree
Showing 21 changed files with 401 additions and 118 deletions.
14 changes: 7 additions & 7 deletions examples/secure_cloud_run_standalone/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ resource "random_id" "random_folder_suffix" {
}

module "secure_harness" {
source = "../../modules/secure-cloud-serverless-harness"
source = "../../modules/secure-serverless-harness"
billing_account = var.billing_account
security_project_name = "prj-kms-secure-cloud-run"
serverless_project_name = "prj-secure-cloud-run"
serverless_project_names = ["prj-secure-cloud-run"]
org_id = var.org_id
parent_folder_id = var.parent_folder_id
serverless_folder_suffix = random_id.random_folder_suffix.hex
Expand Down Expand Up @@ -65,18 +65,18 @@ module "secure_cloud_run" {
source = "../../modules/secure-cloud-run"
location = local.location
region = local.region
serverless_project_id = module.secure_harness.serverless_project_id
vpc_project_id = module.secure_harness.serverless_project_id
serverless_project_id = module.secure_harness.serverless_project_ids[0]
vpc_project_id = module.secure_harness.network_project_id[0]
kms_project_id = module.secure_harness.security_project_id
key_name = "key-secure-cloud-run"
keyring_name = "krg-secure-cloud-run"
service_name = "srv-secure-cloud-run"
image = "${local.location}-docker.pkg.dev/${module.secure_harness.security_project_id}/${module.secure_harness.artifact_registry_repository_name}/hello:latest"
cloud_run_sa = module.secure_harness.service_account_email
cloud_run_sa = module.secure_harness.service_account_email[module.secure_harness.serverless_project_ids[0]]
connector_name = "con-secure-cloud-run"
subnet_name = module.secure_harness.service_subnet
subnet_name = module.secure_harness.service_subnet[0]
create_subnet = false
shared_vpc_name = module.secure_harness.service_vpc.network_name
shared_vpc_name = module.secure_harness.service_vpc[0].network_name
ip_cidr_range = "10.0.0.0/28"
prevent_destroy = false
artifact_registry_repository_location = local.location
Expand Down
12 changes: 6 additions & 6 deletions examples/secure_cloud_run_standalone/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
*/

output "serverless_project_id" {
value = module.secure_harness.serverless_project_id
value = module.secure_harness.serverless_project_ids[0]
description = "The serverless project id."
}

output "serverless_project_number" {
value = module.secure_harness.serverless_project_number
value = module.secure_harness.serverless_project_numbers[module.secure_harness.serverless_project_ids[0]]
description = "The serverless project number."
}

Expand All @@ -35,22 +35,22 @@ output "security_project_number" {
}

output "service_account_email" {
value = module.secure_harness.service_account_email
value = module.secure_harness.service_account_email[module.secure_harness.serverless_project_ids[0]]
description = "The service account email created to be used by Cloud Run."
}

output "service_vpc_self_link" {
value = module.secure_harness.service_vpc.network.self_link
value = module.secure_harness.service_vpc[0].network.self_link
description = "The Network self-link created in harness."
}

output "service_vpc_name" {
value = module.secure_harness.service_vpc.network_name
value = module.secure_harness.service_vpc[0].network_name
description = "The Network self-link created in harness."
}

output "service_vpc_subnet_name" {
value = module.secure_harness.service_subnet
value = module.secure_harness.service_subnet[0]
description = "The sub-network name created in harness."
}

Expand Down
3 changes: 2 additions & 1 deletion modules/secure-cloud-run/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ module "vpc_project_apis" {
}

module "cloud_run_network" {
source = "../secure-cloud-serverless-net"
source = "../secure-serverless-net"

connector_name = var.connector_name
subnet_name = var.subnet_name
Expand All @@ -56,6 +56,7 @@ module "cloud_run_network" {
ip_cidr_range = var.ip_cidr_range
create_subnet = var.create_subnet
resource_names_suffix = var.resource_names_suffix
serverless_type = "CLOUD_RUN"

serverless_service_identity_email = google_project_service_identity.serverless_sa.email

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ module "secure_cloud_run_harness" {
| key\_rotation\_period | Period of key rotation in seconds. Default value is equivalent to 30 days. | `string` | `"2592000s"` | no |
| keyring\_name | Keyring name. | `string` | n/a | yes |
| location | The location where resources are going to be deployed. | `string` | n/a | yes |
| network\_project\_name | The name to give the shared vpc project. | `string` | `""` | no |
| org\_id | The organization ID. | `string` | n/a | yes |
| owners | List of comma-separated owners for each key declared in set\_owners\_for. | `list(string)` | `[]` | no |
| parent\_folder\_id | The ID of a folder to host the infrastructure created in this module. | `string` | `""` | no |
Expand All @@ -78,10 +79,11 @@ module "secure_cloud_run_harness" {
| region | The region in which the subnetwork will be created. | `string` | n/a | yes |
| security\_project\_name | The name to give the security project. | `string` | n/a | yes |
| serverless\_folder\_suffix | The suffix to be concat in the Serverless folder name fldr-serverless-<SUFFIX>. | `string` | `""` | no |
| serverless\_project\_name | The name to give the Cloud Run project. | `string` | n/a | yes |
| serverless\_project\_names | The name to give the Cloud Serverless project. | `list(string)` | n/a | yes |
| serverless\_type | The type of resource to be used. It supports only CLOUD\_RUN or CLOUD\_FUNCTION | `string` | n/a | yes |
| service\_account\_project\_roles | Common roles to apply to the Cloud Run service account in the serverless project. | `list(string)` | `[]` | no |
| service\_account\_project\_roles | Common roles to apply to the Cloud Serverless service account in the serverless project. | `map(list(string))` | `{}` | no |
| subnet\_ip | The CDIR IP range of the subnetwork. | `string` | n/a | yes |
| use\_shared\_vpc | Defines if the network created will be a single or shared vpc. | `bool` | `false` | no |
| vpc\_name | The name of the network. | `string` | n/a | yes |

## Outputs
Expand All @@ -90,17 +92,19 @@ module "secure_cloud_run_harness" {
|------|-------------|
| artifact\_registry\_repository\_id | The Artifact Registry Repository full identifier where the images should be stored. |
| artifact\_registry\_repository\_name | The Artifact Registry Repository last part of the repository name where the images should be stored. |
| cloud\_run\_service\_identity\_email | The Cloud Run Service Identity email. |
| cloud\_serverless\_service\_identity\_email | The Cloud Run Service Identity email. |
| cloudfunction\_source\_bucket | Cloud Function Source Bucket. |
| network\_project\_id | Project ID of the project created to host the Cloud Run Network. |
| restricted\_access\_level\_name | Access level name. |
| restricted\_service\_perimeter\_name | Service Perimeter name. |
| security\_project\_id | Project ID of the project created for KMS and Artifact Register. |
| security\_project\_number | Project number of the project created for KMS and Artifact Register. |
| serverless\_folder\_id | The folder created to alocate Serverless infra. |
| serverless\_project\_id | Project ID of the project created to deploy Cloud Run. |
| serverless\_project\_number | Project number of the project created to deploy Cloud Run. |
| service\_account\_email | The email of the Service Account created to be used by Cloud Run. |
| serverless\_project\_ids | Project ID of the projects created to deploy Cloud Run. |
| serverless\_project\_numbers | Project number of the projects created to deploy Cloud Run. |
| service\_account\_email | The email of the Service Account created to be used by Cloud Serverless. |
| service\_subnet | The sub-network name created in harness. |
| service\_vpc | The network created for Cloud Run. |
| service\_vpc | The network created for Cloud Serverless. |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,33 @@
*/

locals {
api = var.serverless_type == "CLOUD_RUN" ? "run" : "cloudfunctions"
serverless_apis = [
api = var.serverless_type == "CLOUD_FUNCTION" ? ["cloudfunctions.googleapis.com", "cloudbuild.googleapis.com", "eventarc.googleapis.com"] : []
serverless_apis = concat([
"vpcaccess.googleapis.com",
"compute.googleapis.com",
"container.googleapis.com",
"artifactregistry.googleapis.com",
"${local.api}.googleapis.com",
"run.googleapis.com",
"cloudkms.googleapis.com",
"dns.googleapis.com"
]
], local.api)
kms_apis = [
"cloudkms.googleapis.com",
"artifactregistry.googleapis.com"
]

decrypters = join(",", concat(["serviceAccount:${google_project_service_identity.artifact_sa.email}"], var.decrypters))
encrypters = join(",", concat(["serviceAccount:${google_project_service_identity.artifact_sa.email}"], var.encrypters))
network_apis = [
"vpcaccess.googleapis.com",
"compute.googleapis.com",
"dns.googleapis.com"
]

network_project_id = var.use_shared_vpc ? module.network_project[0].project_id : ""

eventarc_identities = [for project in module.serverless_project : "serviceAccount:${project.services_identities["eventarc"]}"]
gcs_identities = [for project in module.serverless_project : "serviceAccount:${project.services_identities["gcs"]}"]
decrypters = join(",", concat(["serviceAccount:${google_project_service_identity.artifact_sa.email}"], local.eventarc_identities, local.gcs_identities, var.decrypters))
encrypters = join(",", concat(["serviceAccount:${google_project_service_identity.artifact_sa.email}"], local.eventarc_identities, local.gcs_identities, var.encrypters))

}

Expand All @@ -40,82 +50,45 @@ resource "google_folder" "fld_serverless" {
parent = var.parent_folder_id == "" ? "organizations/${var.org_id}" : "folders/${var.parent_folder_id}"
}

module "security_project" {
module "network_project" {
count = var.use_shared_vpc ? 1 : 0
source = "terraform-google-modules/project-factory/google"
version = "~> 13.0"
version = "~> 14.2"
random_project_id = "true"
activate_apis = local.kms_apis
name = var.security_project_name
activate_apis = local.network_apis
name = var.network_project_name
org_id = var.org_id
billing_account = var.billing_account
folder_id = google_folder.fld_serverless.name

enable_shared_vpc_host_project = true
}

module "serverless_project" {
module "security_project" {
source = "terraform-google-modules/project-factory/google"
version = "~> 13.0"
version = "~> 14.2"
random_project_id = "true"
activate_apis = local.serverless_apis
name = var.serverless_project_name
activate_apis = local.kms_apis
name = var.security_project_name
org_id = var.org_id
billing_account = var.billing_account
folder_id = google_folder.fld_serverless.name
}

module "service_accounts" {
source = "terraform-google-modules/service-accounts/google"
version = "~> 3.0"
project_id = module.serverless_project.project_id
prefix = "sa"
names = ["serverless-${local.api}"]

depends_on = [
time_sleep.wait_90_seconds
]
}

resource "google_project_iam_member" "cloud_run_sa_roles" {
for_each = toset(var.service_account_project_roles)
project = module.serverless_project.project_id
role = each.value
member = module.service_accounts.iam_email

depends_on = [
time_sleep.wait_90_seconds
]
}

resource "google_project_service_identity" "serverless_sa" {
provider = google-beta

project = module.serverless_project.project_id
service = "${local.api}.googleapis.com"

depends_on = [
time_sleep.wait_90_seconds
]
}
module "serverless_project" {
source = "../service-project-factory"

resource "google_service_account_iam_member" "identity_service_account_user" {
service_account_id = module.service_accounts.service_account.id
role = "roles/iam.serviceAccountUser"
member = "serviceAccount:${google_project_service_identity.serverless_sa.email}"
for_each = toset(var.serverless_project_names)

depends_on = [
time_sleep.wait_90_seconds
]
billing_account = var.billing_account
serverless_type = var.serverless_type
org_id = var.org_id
activate_apis = local.serverless_apis
folder_name = google_folder.fld_serverless.name
project_name = each.value
service_account_project_roles = length(var.service_account_project_roles) > 0 ? var.service_account_project_roles[each.value] : []
}

resource "google_project_service_identity" "artifact_sa" {
provider = google-beta

project = module.security_project.project_id
service = "artifactregistry.googleapis.com"

depends_on = [
time_sleep.wait_90_seconds
]
}

resource "google_artifact_registry_repository" "repo" {
project = module.security_project.project_id
Expand All @@ -131,11 +104,12 @@ resource "google_artifact_registry_repository" "repo" {
}

resource "google_artifact_registry_repository_iam_member" "member" {
for_each = module.serverless_project
project = module.security_project.project_id
location = var.location
repository = google_artifact_registry_repository.repo.repository_id
role = "roles/artifactregistry.reader"
member = "serviceAccount:${google_project_service_identity.serverless_sa.email}"
member = "serviceAccount:${each.value.cloud_serverless_service_identity_email}"

depends_on = [
time_sleep.wait_90_seconds
Expand Down Expand Up @@ -164,3 +138,32 @@ module "artifact_registry_kms" {
time_sleep.wait_90_seconds
]
}

resource "google_project_service_identity" "artifact_sa" {
provider = google-beta

project = module.security_project.project_id
service = "artifactregistry.googleapis.com"

depends_on = [
time_sleep.wait_90_seconds
]
}

module "cloudfunction_source_bucket" {
for_each = var.serverless_type == "CLOUD_RUN" ? {} : module.serverless_project
source = "terraform-google-modules/cloud-storage/google//modules/simple_bucket"
version = "~>3.4"

project_id = each.value.project_id
name = "bkt-${var.location}-${each.value.project_number}-cfv2-zip-files"
location = var.location
storage_class = "REGIONAL"
force_destroy = true

encryption = {
default_kms_key_name = module.artifact_registry_kms.keys[var.key_name]
}

depends_on = [module.artifact_registry_kms]
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@

locals {
network_name = trimprefix(var.vpc_name, "vpc-") == var.vpc_name ? var.vpc_name : "vpc-${var.vpc_name}"
services_projects = var.use_shared_vpc ? { for key, project in module.serverless_project : key => project.project_id } : {}
network_projects = var.use_shared_vpc ? { for key, project in module.network_project : key => project.project_id } : { for key, project in module.serverless_project : key => project.project_id }
}
module "network" {
for_each = local.network_projects
source = "terraform-google-modules/network/google"
version = "~> 6.0"
project_id = module.serverless_project.project_id
version = "~> 7.0"
project_id = each.value
network_name = local.network_name
shared_vpc_host = "false"
shared_vpc_host = var.use_shared_vpc
delete_default_internet_gateway_routes = "true"

subnets = [
Expand Down Expand Up @@ -68,18 +72,28 @@ module "network" {
ports = ["443"]
}]

ranges = [module.private_service_connect.private_service_connect_ip]
ranges = [var.private_service_connect_ip]
target_tags = ["allow-google-apis", "vpc-connector"]
}
]
}

resource "google_compute_shared_vpc_service_project" "shared_vpc_attachment" {
for_each = local.services_projects

host_project = module.network[0].project_id
service_project = each.value
depends_on = [module.serverless_project]
}

resource "google_dns_policy" "default_policy" {
project = module.serverless_project.project_id
for_each = module.network

project = each.value.project_id
name = "dns-default-policy"
enable_inbound_forwarding = var.dns_enable_inbound_forwarding
enable_logging = var.dns_enable_logging
networks {
network_url = module.network.network_self_link
network_url = each.value.network_self_link
}
}
Loading

0 comments on commit afe6228

Please sign in to comment.