modules/itar-hpc-workload/main.tf (266 lines of code) (raw):

/** * 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. */ data "google_project" "primary" { project_id = var.project_id } module "storage_kms" { source = "terraform-google-modules/kms/google" version = "2.2.1" project_id = var.cmek_project_id keyring = var.gcs_kms_ring_name location = var.gcs_location keys = [var.gcs_kms_key_name] purpose = "ENCRYPT_DECRYPT" # if keys can be destroyed by Terraform prevent_destroy = var.kms_prevent_destroy } # The code is for creating gcs buckets with locational endpoints module "gcs_locational_endpoints" { source = "../gcs-locational-endpoints" project_id = var.project_id cmek_project_id = var.cmek_project_id location_endpoint = var.gcs_location gcs_kms_ring_name = module.storage_kms.keyring_name gcs_kms_key_name = keys(module.storage_kms.keys)[0] input_bucket_name = var.input_bucket_name output_bucket_name = var.output_bucket_name lifecycle_file = var.bucket_lifecycle_file } module "gce_kms" { source = "terraform-google-modules/kms/google" version = "2.2.1" project_id = var.cmek_project_id keyring = var.gce_keyring_name location = var.region # if keys can be destroyed by Terraform prevent_destroy = var.kms_prevent_destroy } # Create a VPC to deploy the HPC ready vm module "hpc_vpc" { source = "terraform-google-modules/network/google" version = "~> 6.0" project_id = var.project_id network_name = var.hpc_network_name shared_vpc_host = false subnets = var.hpc_subnets } #Create a NAT gateway module "hpc_nat_gateway" { source = "terraform-google-modules/cloud-router/google" version = "~> 4.0" project = var.project_id name = var.hpc_router_name network = module.hpc_vpc.network_self_link region = var.hpc_router_region nats = [{ name = var.hpc_nat_name source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES" }] } #Create a HPC ready VM module "hpc_vm" { source = "../compute-engine-hpc" project_id = var.project_id cmek_project_id = var.cmek_project_id instance_prefix = var.hpc_instance_prefix region = var.region tags = var.hpc_tags network = module.hpc_vpc.network_self_link subnetwork = module.hpc_vpc.subnets_names[0] disk_size_gb = var.hpc_disk_size machine_type = var.hpc_machine_type num_instances = var.hpc_num_instances instance_name = var.hpc_instance_name source_image_family = var.hpc_source_image source_image_project = var.hpc_source_image_project deletion_protection = var.hpc_deletion_protection sa_prefix = var.sa_prefix zone = var.hpc_zone use_existing_keyring = var.hpc_use_existing_keyring keyring_name = var.hpc_use_existing_keyring ? var.hpc_keyring_name : "" key_rotation_period = var.key_rotation_period depends_on = [module.hpc_nat_gateway] } # Deploy Confidential Postgress SQL VM module "compute_engine_database_primary" { source = "../compute-engine-db" project_id = var.project_id cmek_project_id = var.cmek_project_id instance_prefix = var.db_instance_prefix region = var.region tags = var.db_tags disk_size_gb = var.db_disk_size_gb machine_type = var.db_machine_type num_instances = var.db_num_instances instance_name = var.db_instance_name source_image = var.db_source_image source_image_project = var.db_source_image_project deletion_protection = var.db_deletion_protection sa_prefix = var.sa_prefix zone = var.db_zone network = module.hpc_vpc.network_self_link subnetwork = module.hpc_vpc.subnets_names[1] use_existing_keyring = var.db_use_existing_keyring keyring_name = var.db_use_existing_keyring ? var.db_keyring_name : "" key_rotation_period = var.key_rotation_period depends_on = [module.hpc_nat_gateway] } #Enable firewall rules that allow users to access HPC VM and Postgress module "firewall_allow_db" { source = "terraform-google-modules/network/google//modules/firewall-rules" version = "~> 6.0" project_id = var.project_id network_name = module.hpc_vpc.network_self_link rules = [ { name = "hpc-firewall01" description = "hpc firewall rules" direction = "INGRESS" source_tags = ["hpc-vm"] target_tags = ["db-vm"] source_service_accounts = null target_service_accounts = null priority = null ranges = null deny = [] allow = [{ protocol = "tcp" ports = ["5432"] }] log_config = null }] depends_on = [ module.compute_engine_database_primary ] } #Create a DMZ VPC to deploy compute engine for accessing HPC VM module "dmz_vpc" { source = "terraform-google-modules/network/google" version = "~> 6.0" project_id = var.project_id network_name = var.dmz_network_name shared_vpc_host = false subnets = var.dmz_subnets } module "dmz_nat_gateway" { source = "terraform-google-modules/cloud-router/google" version = "~> 4.0" project = var.project_id name = var.dmz_router_name network = module.dmz_vpc.network_self_link region = var.dmz_router_region nats = [{ name = var.dmz_nat_name source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES" }] } #Create a confidential compute engine in DMZ network module "compute_engine_dmz" { source = "../compute-engine-dmz" project_id = var.project_id cmek_project_id = var.cmek_project_id instance_prefix = var.dmz_instance_prefix region = var.region tags = var.dmz_tags disk_size_gb = var.dmz_disk_size_gb machine_type = var.dmz_machine_type num_instances = var.dmz_num_instances instance_name = var.dmz_instance_name source_image = var.dmz_source_image source_image_project = var.dmz_source_image_project deletion_protection = var.dmz_deletion_protection sa_prefix = var.sa_prefix zone = var.dmz_zone network = module.dmz_vpc.network_self_link subnetwork = module.dmz_vpc.subnets_names[0] use_existing_keyring = var.dmz_use_existing_keyring keyring_name = var.dmz_use_existing_keyring ? var.dmz_keyring_name : "" key_rotation_period = var.key_rotation_period depends_on = [module.dmz_nat_gateway] } #Peer HPC VPC and DMZ VPC module "dmz_hpc_peering" { source = "terraform-google-modules/network/google//modules/network-peering" version = "~> 6.0" local_network = module.dmz_vpc.network_self_link peer_network = module.hpc_vpc.network_self_link } module "firewall_allow_dmz" { source = "terraform-google-modules/network/google//modules/firewall-rules" version = "~> 6.0" project_id = var.project_id network_name = module.hpc_vpc.network_self_link rules = [ { name = "dmz-firewall01" description = "dmz firewall rules" direction = "INGRESS" ranges = [module.dmz_vpc.subnets_ips[0]] destination_ranges = null source_tags = null target_tags = null source_service_accounts = null target_service_accounts = null priority = null allow = [{ protocol = "tcp" ports = ["22"] }] deny = [] log_config = null }] depends_on = [ module.dmz_hpc_peering ] } #Ensure Storage apis are secured with Private service connect module "vpc_servicecontrol" { source = "../vpc-sc" parent_id = var.parent_id policy_name = var.policy_name protected_project_numbers = [data.google_project.primary.number] scopes = ["projects/${data.google_project.primary.number}"] members = concat(var.members, ["serviceAccount:${data.google_project.primary.number}-compute@developer.gserviceaccount.com"]) access_level_name = var.access_level_name perimeter_name = var.perimeter_name # ingress_policies = var.vpc_sc_ingress_policies depends_on = [module.dmz_hpc_peering] } #Create private service connect so HPC cluster can connect with input and output buckets module "private_service_connect" { source = "../privateserviceconnect" project_id = var.project_id network_self_link = module.hpc_vpc.network_self_link private_service_connect_name = var.private_service_connect_name private_service_connect_ip = var.private_service_connect_ip forwarding_rule_name = var.private_service_forwarding_rule depends_on = [module.hpc_vpc, module.vpc_servicecontrol] } #Configure IAP firewalls to access the compute engine module "iap" { source = "../iap-tunnel" project_id = var.project_id name = var.iap_name network = module.dmz_vpc.network_self_link instance_name = module.compute_engine_dmz.instances_self_links[0] zone = var.iap_zone members = var.iap_members depends_on = [module.private_service_connect] } # The deny-compute-unsecur-api rule make sure that ITAR customers cannot suspend/resume instances and cannot use GetSerialPortOutput and GetScreenshot APIs resource "google_iam_deny_policy" "token_deny" { provider = google-beta name = var.deny_policy_name parent = urlencode("cloudresourcemanager.googleapis.com/projects/${var.project_id}") rules { description = "deny-token-creator-rule" deny_rule { denied_principals = ["principalSet://goog/public:all"] denied_permissions = ["iam.googleapis.com/serviceAccounts.getAccessToken", "iam.googleapis.com/serviceAccounts.getOpenIdToken", "iam.googleapis.com/serviceAccounts.implicitDelegation", "iam.googleapis.com/serviceAccounts.signBlob", "iam.googleapis.com/serviceAccounts.signJwt"] } } rules { description = "deny_compute_unsecure_api" deny_rule { denied_principals = ["principalSet://goog/public:all"] denied_permissions = ["compute.googleapis.com/instances.suspend", "compute.googleapis.com/instances.resume", "compute.googleapis.com/instances.getSerialPortOutput", "compute.googleapis.com/instances.getScreenshot"] } } }