cloud-foundation-fabric/examples/factories/project-factory/main.tf

154 lines
6.2 KiB
Terraform
Raw Normal View History

2022-01-14 01:29:09 -08:00
/**
* 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
*
* 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 {
_gke_iam_hsau = try(var.vpc.gke_setup.enable_host_service_agent, false) ? {
"roles/container.hostServiceAgentUser" = "serviceAccount:${module.project.service_accounts.robots.container-engine}"
} : {}
2022-01-14 01:29:09 -08:00
_gke_iam_securityadmin = try(var.vpc.gke_setup.enable_security_admin, false) ? {
"roles/compute.securityAdmin" = "serviceAccount:${module.project.service_accounts.robots.container-engine}"
} : {}
2022-01-14 01:29:09 -08:00
_group_iam = {
for r in local._group_iam_roles : r => [
for k, v in var.group_iam : "group:${k}" if try(index(v, r), null) != null
]
}
_group_iam_roles = distinct(flatten(values(var.group_iam)))
_service_accounts_iam = {
for r in local._service_accounts_iam_roles : r => [
for k, v in var.service_accounts : "serviceAccount:${k}@${var.project_id}.iam.gserviceaccount.com" if try(index(v, r), null) != null
]
}
_service_accounts_iam_roles = distinct(flatten(values(var.service_accounts)))
_services = concat([
"billingbudgets.googleapis.com",
"essentialcontacts.googleapis.com"
],
length(var.dns_zones) > 0 ? ["dns.googleapis.com"] : [],
try(var.vpc.gke_setup, null) != null ? ["container.googleapis.com"] : [],
var.vpc != null ? ["compute.googleapis.com"] : [],
)
_services_iam_roles = distinct(flatten(values(var.services_iam)))
_services_iam = {
for r in local._services_iam_roles : r => [
for k, v in var.services_iam : "serviceAccount:${module.project.service_accounts.robots[k]}" if try(index(v, r), null) != null
2022-01-14 01:29:09 -08:00
]
}
billing_account_id = coalesce(var.billing_account_id, try(var.defaults.billing_account_id, ""))
billing_alert = var.billing_alert == null ? try(var.defaults.billing_alert, null) : var.billing_alert
2022-01-14 01:29:09 -08:00
essential_contacts = concat(try(var.defaults.essential_contacts, []), var.essential_contacts)
host_project_bindings = merge(
local._gke_iam_hsau,
local._gke_iam_securityadmin
)
2022-01-14 01:29:09 -08:00
iam = {
for role in distinct(concat(
keys(var.iam),
keys(local._group_iam),
keys(local._service_accounts_iam),
keys(local._services_iam),
)) :
role => concat(
try(var.iam[role], []),
try(local._group_iam[role], []),
try(local._service_accounts_iam[role], []),
try(local._services_iam[role], []),
)
}
labels = merge(coalesce(var.labels, {}), coalesce(try(var.defaults.labels, {}), {}))
2022-01-14 01:29:09 -08:00
network_user_service_accounts = concat(
contains(local.services, "compute.googleapis.com") ? [
"serviceAccount:${module.project.service_accounts.robots.compute}"
] : [],
contains(local.services, "container.googleapis.com") ? [
"serviceAccount:${module.project.service_accounts.robots.container-engine}",
"serviceAccount:${module.project.service_accounts.cloud_services}"
] : [],
2022-01-14 01:29:09 -08:00
[])
services = distinct(concat(var.services, local._services))
2022-01-14 01:29:09 -08:00
vpc_host_project = try(var.vpc.host_project, var.defaults.vpc_host_project)
vpc_setup = var.vpc != null
}
module "billing-alert" {
for_each = local.billing_alert == null ? {} : { 1 = 1 }
source = "../../../modules/billing-budget"
2022-01-14 01:29:09 -08:00
billing_account = local.billing_account_id
name = "${module.project.project_id} budget"
amount = local.billing_alert.amount
thresholds = local.billing_alert.thresholds
credit_treatment = local.billing_alert.credit_treatment
notification_channels = var.defaults.notification_channels
projects = ["projects/${module.project.number}"]
email_recipients = {
project_id = module.project.project_id
emails = local.essential_contacts
}
}
module "dns" {
source = "../../../modules/dns"
2022-01-14 01:29:09 -08:00
for_each = toset(var.dns_zones)
project_id = module.project.project_id
type = "private"
name = each.value
domain = "${each.value}.${var.defaults.environment_dns_zone}"
client_networks = [var.defaults.shared_vpc_self_link]
}
module "project" {
source = "../../../modules/project"
2022-01-14 01:29:09 -08:00
billing_account = local.billing_account_id
name = var.project_id
prefix = var.prefix
2022-01-14 01:29:09 -08:00
contacts = { for c in local.essential_contacts : c => ["ALL"] }
iam = local.iam
labels = local.labels
parent = var.folder_id
policy_boolean = try(var.org_policies.policy_boolean, {})
policy_list = try(var.org_policies.policy_list, {})
service_encryption_key_ids = var.kms_service_agents
services = local.services
shared_vpc_service_config = {
attach = local.vpc_setup
host_project = local.vpc_host_project
}
}
module "service-accounts" {
source = "../../../modules/iam-service-account"
2022-01-14 01:29:09 -08:00
for_each = var.service_accounts
name = each.key
project_id = module.project.project_id
}
# TODO(jccb): we should probably change this to non-authoritative bindings
2022-01-14 01:29:09 -08:00
resource "google_compute_subnetwork_iam_binding" "binding" {
for_each = local.vpc_setup ? coalesce(var.vpc.subnets_iam, {}) : {}
project = local.vpc_host_project
subnetwork = "projects/${local.vpc_host_project}/regions/${split("/", each.key)[0]}/subnetworks/${split("/", each.key)[1]}"
region = split("/", each.key)[0]
role = "roles/compute.networkUser"
members = concat(each.value, local.network_user_service_accounts)
}
resource "google_project_iam_member" "host_project_bindings" {
for_each = local.host_project_bindings
project = local.vpc_host_project
role = each.key
member = each.value
}