155 lines
5.3 KiB
HCL
155 lines
5.3 KiB
HCL
/**
|
|
* Copyright 2024 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 {
|
|
# group mapping from checklist to ours
|
|
_cl_groups = {
|
|
BILLING_ADMINS = local.principals.gcp-billing-admins
|
|
DEVOPS = local.principals.gcp-devops
|
|
# LOGGING_ADMINS
|
|
# MONITORING_ADMINS
|
|
NETWORK_ADMINS = local.principals.gcp-network-admins
|
|
ORG_ADMINS = local.principals.gcp-organization-admins
|
|
SECURITY_ADMINS = local.principals.gcp-security-admins
|
|
}
|
|
# parse raw data from JSON files if they exist
|
|
_cl_data_raw = (
|
|
var.factories_config.checklist_data == null
|
|
? null
|
|
: jsondecode(file(pathexpand(var.factories_config.checklist_data)))
|
|
)
|
|
_cl_org_raw = (
|
|
var.factories_config.checklist_org_iam == null
|
|
? null
|
|
: jsondecode(file(pathexpand(var.factories_config.checklist_org_iam)))
|
|
)
|
|
# check that files are for the correct organization and ignore them if not
|
|
_cl_data = (
|
|
try(local._cl_data_raw.cloud_setup_config.organization.id, null) != tostring(var.organization.id)
|
|
? null
|
|
: local._cl_data_raw.cloud_setup_config
|
|
)
|
|
_cl_org = (
|
|
try(local._cl_org_raw.cloud_setup_org_iam.organization.id, null) != tostring(var.organization.id)
|
|
? null
|
|
: local._cl_org_raw.cloud_setup_org_iam
|
|
)
|
|
# do a first pass on IAM bindings to identify groups and normalize
|
|
_cl_org_iam_bindings = {
|
|
for b in try(local._cl_org.iam_bindings, []) :
|
|
lookup(local._cl_groups, b.group_id, b.principal) => {
|
|
additive = [
|
|
for r in b.role : r if !contains(local.iam_roles_authoritative, r)
|
|
]
|
|
authoritative = [
|
|
for r in b.role : r if contains(local.iam_roles_authoritative, r)
|
|
]
|
|
roles = b.role
|
|
is_group = lookup(local._cl_groups, b.group_id, null) != null
|
|
}
|
|
}
|
|
# compile the final data structure we will consume from various places
|
|
checklist = {
|
|
billing_account = try(local._cl_data.billing_account, null)
|
|
iam_principals = {
|
|
for k, v in local._cl_org_iam_bindings :
|
|
k => v.authoritative if v.is_group && length(v.authoritative) > 0
|
|
}
|
|
iam = {
|
|
for k, v in local._cl_org_iam_bindings :
|
|
k => v.authoritative if !v.is_group && length(v.authoritative) > 0
|
|
}
|
|
iam_bindings = concat(flatten([
|
|
for k, v in local._cl_org_iam_bindings : [
|
|
for r in v.additive : [
|
|
{
|
|
key = "${r}-${k}"
|
|
member = k
|
|
role = r
|
|
}
|
|
]
|
|
]
|
|
]))
|
|
location = try(local._cl_data.logging.sinks[0].destination.location, null)
|
|
}
|
|
uses_checklist = (
|
|
var.factories_config.checklist_data != null
|
|
||
|
|
var.factories_config.checklist_org_iam != null
|
|
)
|
|
}
|
|
check "checklist" {
|
|
# checklist data files don't need to be both present so we check independently
|
|
# version mismatch might be ok, we just alert users
|
|
assert {
|
|
condition = (
|
|
var.factories_config.checklist_data == null ||
|
|
try(local._cl_data_raw.cloud_setup_config.version, null) == "0.1.0"
|
|
)
|
|
error_message = "Checklist data version mismatch."
|
|
}
|
|
assert {
|
|
condition = (
|
|
var.factories_config.checklist_org_iam == null ||
|
|
try(local._cl_org_raw.cloud_setup_org_iam.version, null) == "0.1.0"
|
|
)
|
|
error_message = "Checklist org IAM version mismatch."
|
|
}
|
|
# wrong org id forces us to ignore the files, but we also alert users
|
|
assert {
|
|
condition = (
|
|
var.factories_config.checklist_data == null ||
|
|
try(local._cl_data_raw.cloud_setup_config.organization.id, null) == tostring(var.organization.id)
|
|
)
|
|
error_message = "Checklist data organization id mismatch, file ignored."
|
|
}
|
|
assert {
|
|
condition = (
|
|
var.factories_config.checklist_org_iam == null ||
|
|
try(local._cl_org_raw.cloud_setup_org_iam.organization.id, null) == tostring(var.organization.id)
|
|
)
|
|
error_message = "Checklist org IAM organization id mismatch, file ignored."
|
|
}
|
|
}
|
|
|
|
# checklist files bucket
|
|
|
|
module "automation-tf-checklist-gcs" {
|
|
source = "../../../modules/gcs"
|
|
count = local.uses_checklist ? 1 : 0
|
|
project_id = module.automation-project.project_id
|
|
name = "iac-core-checklist-0"
|
|
prefix = local.prefix
|
|
location = local.locations.gcs
|
|
storage_class = local.gcs_storage_class
|
|
versioning = true
|
|
depends_on = [module.organization]
|
|
}
|
|
|
|
resource "google_storage_bucket_object" "checklist_data" {
|
|
count = var.factories_config.checklist_data != null ? 1 : 0
|
|
bucket = module.automation-tf-checklist-gcs[0].name
|
|
name = "checklist/data.tfvars.json"
|
|
source = var.factories_config.checklist_data
|
|
}
|
|
|
|
resource "google_storage_bucket_object" "checklist_org_iam" {
|
|
count = var.factories_config.checklist_org_iam != null ? 1 : 0
|
|
bucket = module.automation-tf-checklist-gcs[0].name
|
|
name = "checklist/org-iam.tfvars.json"
|
|
source = var.factories_config.checklist_org_iam
|
|
}
|