1-foundations/04-orchestration.tf (230 lines of code) (raw):

# Copyright 2022 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 # # https://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. # tfdoc:file:description Orchestration project and VPC. locals { orch_subnet = ( local.use_shared_vpc ? local.config.network_config.subnet_self_links.orchestration : values(module.orch-vpc.0.subnet_self_links)[0] ) orch_vpc = ( local.use_shared_vpc ? local.config.network_config.network_self_link : module.orch-vpc.0.self_link ) } module "orch-project" { source = "github.com/GoogleCloudPlatform/cloud-foundation-fabric//modules/project?ref=v36.0.1" deletion_policy = "ABANDON" parent = "folders/${local.config.folder-id}" billing_account = local.config.billing-account prefix = local.config.resource-prefix name = "orc${local.project_suffix}" iam_by_principals = { "group:${local.groups.data-engineers}" = [ "roles/bigquery.dataEditor", "roles/bigquery.jobUser", "roles/cloudbuild.builds.editor", "roles/composer.admin", "roles/composer.environmentAndStorageObjectAdmin", "roles/iap.httpsResourceAccessor", "roles/iam.serviceAccountUser", "roles/storage.objectAdmin", "roles/storage.admin", ] } iam = { "roles/bigquery.dataEditor" = [ module.load-sa-df-0.iam_email, module.transf-sa-df-0.iam_email ] "roles/bigquery.jobUser" = [ module.orch-sa-cmp-0.iam_email ] "roles/composer.worker" = [ module.orch-sa-cmp-0.iam_email ] "roles/iam.serviceAccountTokenCreator" = [ module.orch-sa-cmp-0.iam_email ] "roles/iam.serviceAccountUser" = [ module.orch-sa-cmp-0.iam_email ] "roles/storage.objectAdmin" = [ module.orch-sa-cmp-0.iam_email, "serviceAccount:${module.orch-project.service_agents.composer.email}" ] "roles/storage.objectViewer" = [ module.load-sa-df-0.iam_email ] } services = concat(local.config.core-services, [ "artifactregistry.googleapis.com", "bigquery.googleapis.com", "bigqueryreservation.googleapis.com", "bigquerystorage.googleapis.com", "cloudkms.googleapis.com", "composer.googleapis.com", "compute.googleapis.com", "container.googleapis.com", "containerregistry.googleapis.com", "dataflow.googleapis.com", "orgpolicy.googleapis.com", "pubsub.googleapis.com", "servicenetworking.googleapis.com", "storage.googleapis.com", "storage-component.googleapis.com", "cloudbuild.googleapis.com", "orgpolicy.googleapis.com", ]) # org_policies = { # "constraints/compute.requireOsLogin" = { # enforce = false # } # } /*service_encryption_key_ids = { "composer.googleapis.com" = [try(local.service_encryption_keys.composer, null)] "storage.googleapis.com" = [try(local.service_encryption_keys.storage, null)] }*/ shared_vpc_service_config = local.shared_vpc_project == null ? null : { attach = true host_project = local.shared_vpc_project } } # Cloud Storage module "orch-cs-0" { source = "github.com/GoogleCloudPlatform/cloud-foundation-fabric//modules/gcs?ref=v36.0.1" project_id = module.orch-project.project_id prefix = local.config.resource-prefix name = "orc-cs-0" location = local.config.region storage_class = "REGIONAL" encryption_key = try(local.service_encryption_keys.storage, null) } # internal VPC resources module "orch-vpc" { source = "github.com/GoogleCloudPlatform/cloud-foundation-fabric//modules/net-vpc?ref=v36.0.1" count = local.use_shared_vpc ? 0 : 1 project_id = module.orch-project.project_id name = "${local.config.resource-prefix}-default" subnets = [ { ip_cidr_range = "10.10.0.0/24" name = "default" region = local.config.region secondary_ip_ranges = { pods = "10.10.8.0/22" services = "10.10.12.0/24" } } ] } module "orch-vpc-firewall" { source = "github.com/GoogleCloudPlatform/cloud-foundation-fabric//modules/net-vpc-firewall?ref=v36.0.1" count = local.use_shared_vpc ? 0 : 1 project_id = module.orch-project.project_id network = module.orch-vpc.0.name default_rules_config = { admin_ranges = ["10.10.0.0/24"] } } module "orch-nat" { count = local.use_shared_vpc ? 0 : 1 source = "github.com/GoogleCloudPlatform/cloud-foundation-fabric//modules/net-cloudnat?ref=v36.0.1" project_id = module.orch-project.project_id name = "${local.config.resource-prefix}-default" region = local.config.region router_network = module.orch-vpc.0.name } module "orch-sa-cmp-0" { source = "github.com/GoogleCloudPlatform/cloud-foundation-fabric//modules/iam-service-account?ref=v36.0.1" project_id = module.orch-project.project_id prefix = local.config.resource-prefix name = "orc-cmp-0" display_name = "Data platform Composer service account" iam = { "roles/iam.serviceAccountTokenCreator" = [local.groups_iam.data-engineers] } } # resource "google_project_iam_member" "orch-sa-cmp-0" { # for_each = toset([ # "roles/iam.serviceAccountTokenCreator", # "roles/iam.serviceAccountUser", # "roles/composer.worker", # "roles/bigquery.jobUser" # ]) # project = module.main_project.id # role = each.key # member = "serviceAccount:${google_service_account.orc-cmp-sa-0.email}" # } resource "google_composer_environment" "orch-cmp-0" { # depends_on = [ google_service_account.load-cmp-sa-0 ] # count = 0 provider = google-beta project = module.orch-project.project_id name = "orc-cmp-0" region = local.config.region config { workloads_config { scheduler { cpu = 0.5 memory_gb = 2 storage_gb = 1 count = 1 } triggerer { cpu = 0.5 memory_gb = 1 count = 1 } dag_processor { cpu = 1 memory_gb = 2 storage_gb = 1 count = 1 } web_server { cpu = 0.5 memory_gb = 2 storage_gb = 1 } worker { cpu = 0.5 memory_gb = 2 storage_gb = 1 min_count = 1 max_count = 3 } } environment_size = "ENVIRONMENT_SIZE_SMALL" node_config { service_account = module.orch-sa-cmp-0.email tags = ["composer-worker", "http-server", "https-server"] } # private_environment_config { # enable_private_endpoint = "true" # cloud_sql_ipv4_cidr_block = try( # local.config.network_config.composer_ip_ranges.cloudsql, "10.20.10.0/24" # ) # master_ipv4_cidr_block = try( # local.config.network_config.composer_ip_ranges.gke_master, "10.20.11.0/28" # ) # web_server_ipv4_cidr_block = try( # local.config.network_config.composer_ip_ranges.web_server, "10.20.11.16/28" # ) # } software_config { image_version = local.config.composer.airflow_version # pypi_packages = { # PACKAGE_NAME = "EXTRAS_AND_VERSION" # } env_variables = merge( local.config.composer.env_variables, { BQ_LOCATION = local.config.location DATA_CAT_TAGS = try(jsonencode(module.common-datacatalog.tags), "{}") DF_KMS_KEY = try(local.config.encryption-keys.dataflow, "") DWH_LAND_PRJ = module.dwh-lnd-project.project_id DWH_LAND_BQ_DATASET = module.dwh-lnd-bq-0.dataset_id DWH_LAND_GCS = module.dwh-lnd-cs-0.url DWH_CURATED_PRJ = module.dwh-cur-project.project_id DWH_CURATED_BQ_DATASET = module.dwh-cur-bq-0.dataset_id DWH_CURATED_GCS = module.dwh-cur-cs-0.url DWH_CONFIDENTIAL_PRJ = module.dwh-conf-project.project_id DWH_CONFIDENTIAL_BQ_DATASET = module.dwh-conf-bq-0.dataset_id DWH_CONFIDENTIAL_GCS = module.dwh-conf-cs-0.url DWH_PLG_PRJ = module.dwh-plg-project.project_id DWH_PLG_BQ_DATASET = module.dwh-plg-bq-0.dataset_id DWH_PLG_GCS = module.dwh-plg-cs-0.url GCP_REGION = local.config.region LOD_PRJ = module.load-project.project_id LOD_SA = google_service_account.load-cmp-sa-0.email LOD_GCS_STAGING = module.load-cs-df-0.url LOD_NET_VPC = local.load_vpc LOD_NET_SUBNET = local.load_subnet LOD_BQ_DATASET = module.dwh-load-bq-0.dataset_id ORC_PRJ = module.orch-project.project_id ORC_GCS = module.orch-cs-0.url TRF_PRJ = module.transf-project.project_id TRF_GCS_STAGING = module.transf-cs-df-0.url TRF_NET_VPC = local.transf_vpc TRF_NET_SUBNET = local.transf_subnet TRF_SA_DF = module.transf-sa-df-0.email TRF_SA_BQ = module.transf-sa-bq-0.email } ) } # dynamic "encryption_config" { # for_each = ( # try(local.service_encryption_keys.composer != null, false) # ? { 1 = 1 } # : {} # ) # content { # kms_key_name = try(local.service_encryption_keys.composer, null) # } # } # dynamic "web_server_network_access_control" { # for_each = toset( # local.config.network_config.web_server_network_access_control == null # ? [] # : [local.config.network_config.web_server_network_access_control] # ) # content { # dynamic "allowed_ip_range" { # for_each = toset(web_server_network_access_control.key) # content { # value = allowed_ip_range.key # } # } # } # } } # depends_on = [ # google_project_iam_member.shared_vpc, # ] } resource "google_storage_bucket_object" "load-templated-dag-files" { depends_on = [google_composer_environment.orch-cmp-0] for_each = { for wf in local.workflows : wf.name => wf } name = "dags/api_workflow_${each.key}.py" bucket = replace(replace(google_composer_environment.orch-cmp-0.config[0].dag_gcs_prefix, "/dags", ""), "gs://", "") content = templatefile( "${path.root}/../airflow/dags_template/generic-api-service.py", { WORKFLOW_CONFIG = jsonencode(each.value), WORKFLOW_KEY = each.key } ) content_type = "text/x-python" }