Remove custom role and rely on conditions.
This commit is contained in:
parent
5c653638bc
commit
ceb611bb81
|
@ -171,12 +171,6 @@ module "organization" {
|
|||
"dns.networks.bindPrivateDNSZone",
|
||||
"resourcemanager.projects.get",
|
||||
]
|
||||
(var.custom_role_names.cloud_kms_key_editor) = [
|
||||
"cloudkms.cryptoKeys.get",
|
||||
"cloudkms.cryptoKeys.list",
|
||||
"cloudkms.cryptoKeys.getIamPolicy",
|
||||
"cloudkms.cryptoKeys.setIamPolicy"
|
||||
]
|
||||
}
|
||||
logging_sinks = {
|
||||
for name, attrs in var.log_sinks : name => {
|
||||
|
|
|
@ -85,12 +85,10 @@ variable "custom_role_names" {
|
|||
type = object({
|
||||
organization_iam_admin = string
|
||||
service_project_network_admin = string
|
||||
cloud_kms_key_editor = string
|
||||
})
|
||||
default = {
|
||||
organization_iam_admin = "organizationIamAdmin"
|
||||
service_project_network_admin = "serviceProjectNetworkAdmin"
|
||||
cloud_kms_key_editor = "cloudKmsKeyAdmin"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -288,22 +288,21 @@ Some references that might be useful in setting up this stage:
|
|||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [automation](variables.tf#L17) | Automation resources created by the bootstrap stage. | <code title="object({ outputs_bucket = string })">object({…})</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [billing_account](variables.tf#L25) | Billing account id and organization id ('nnnnnnnn' or null). | <code title="object({ id = string organization_id = number })">object({…})</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [folder_ids](variables.tf#L43) | Folder name => id mappings, the 'security' folder name must exist. | <code title="object({ security = string })">object({…})</code> | ✓ | | <code>01-resman</code> |
|
||||
| [organization](variables.tf#L100) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [prefix](variables.tf#L116) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [service_accounts](variables.tf#L89) | Automation service accounts that can assign the encrypt/decrypt roles on keys. | <code title="object({ data-platform-dev = string data-platform-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | ✓ | | <code>01-resman</code> |
|
||||
| [custom_roles](variables.tf#L34) | Custom roles defined at the org level, in key => id format. | <code title="object({ cloud_kms_key_editor = string })">object({…})</code> | | <code>null</code> | <code>00-bootstrap</code> |
|
||||
| [groups](variables.tf#L51) | Group names to grant organization-level permissions. | <code>map(string)</code> | | <code title="{ gcp-billing-admins = "gcp-billing-admins", gcp-devops = "gcp-devops", gcp-network-admins = "gcp-network-admins" gcp-organization-admins = "gcp-organization-admins" gcp-security-admins = "gcp-security-admins" gcp-support = "gcp-support" }">{…}</code> | <code>00-bootstrap</code> |
|
||||
| [kms_defaults](variables.tf#L66) | Defaults used for KMS keys. | <code title="object({ locations = list(string) rotation_period = string })">object({…})</code> | | <code title="{ locations = ["europe", "europe-west1", "europe-west3", "global"] rotation_period = "7776000s" }">{…}</code> | |
|
||||
| [kms_keys](variables.tf#L78) | KMS keys to create, keyed by name. Null attributes will be interpolated with defaults. | <code title="map(object({ iam = map(list(string)) labels = map(string) locations = list(string) rotation_period = string }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [outputs_location](variables.tf#L110) | Path where providers, tfvars files, and lists for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [vpc_sc_access_levels](variables.tf#L127) | VPC SC access level definitions. | <code title="map(object({ combining_function = string conditions = list(object({ ip_subnetworks = list(string) members = list(string) negate = bool regions = list(string) required_access_levels = list(string) })) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [vpc_sc_egress_policies](variables.tf#L142) | VPC SC egress policy defnitions. | <code title="map(object({ egress_from = object({ identity_type = string identities = list(string) }) egress_to = object({ operations = list(object({ method_selectors = list(string) service_name = string })) resources = list(string) }) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [vpc_sc_ingress_policies](variables.tf#L160) | VPC SC ingress policy defnitions. | <code title="map(object({ ingress_from = object({ identity_type = string identities = list(string) source_access_levels = list(string) source_resources = list(string) }) ingress_to = object({ operations = list(object({ method_selectors = list(string) service_name = string })) resources = list(string) }) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [vpc_sc_perimeter_access_levels](variables.tf#L180) | VPC SC perimeter access_levels. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpc_sc_perimeter_egress_policies](variables.tf#L190) | VPC SC egress policies per perimeter, values reference keys defined in the `vpc_sc_ingress_policies` variable. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpc_sc_perimeter_ingress_policies](variables.tf#L200) | VPC SC ingress policies per perimeter, values reference keys defined in the `vpc_sc_ingress_policies` variable. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpc_sc_perimeter_projects](variables.tf#L210) | VPC SC perimeter resources. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
| [folder_ids](variables.tf#L34) | Folder name => id mappings, the 'security' folder name must exist. | <code title="object({ security = string })">object({…})</code> | ✓ | | <code>01-resman</code> |
|
||||
| [organization](variables.tf#L91) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [prefix](variables.tf#L107) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [service_accounts](variables.tf#L80) | Automation service accounts that can assign the encrypt/decrypt roles on keys. | <code title="object({ data-platform-dev = string data-platform-prod = string project-factory-dev = string project-factory-prod = string })">object({…})</code> | ✓ | | <code>01-resman</code> |
|
||||
| [groups](variables.tf#L42) | Group names to grant organization-level permissions. | <code>map(string)</code> | | <code title="{ gcp-billing-admins = "gcp-billing-admins", gcp-devops = "gcp-devops", gcp-network-admins = "gcp-network-admins" gcp-organization-admins = "gcp-organization-admins" gcp-security-admins = "gcp-security-admins" gcp-support = "gcp-support" }">{…}</code> | <code>00-bootstrap</code> |
|
||||
| [kms_defaults](variables.tf#L57) | Defaults used for KMS keys. | <code title="object({ locations = list(string) rotation_period = string })">object({…})</code> | | <code title="{ locations = ["europe", "europe-west1", "europe-west3", "global"] rotation_period = "7776000s" }">{…}</code> | |
|
||||
| [kms_keys](variables.tf#L69) | KMS keys to create, keyed by name. Null attributes will be interpolated with defaults. | <code title="map(object({ iam = map(list(string)) labels = map(string) locations = list(string) rotation_period = string }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [outputs_location](variables.tf#L101) | Path where providers, tfvars files, and lists for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [vpc_sc_access_levels](variables.tf#L118) | VPC SC access level definitions. | <code title="map(object({ combining_function = string conditions = list(object({ ip_subnetworks = list(string) members = list(string) negate = bool regions = list(string) required_access_levels = list(string) })) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [vpc_sc_egress_policies](variables.tf#L133) | VPC SC egress policy defnitions. | <code title="map(object({ egress_from = object({ identity_type = string identities = list(string) }) egress_to = object({ operations = list(object({ method_selectors = list(string) service_name = string })) resources = list(string) }) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [vpc_sc_ingress_policies](variables.tf#L151) | VPC SC ingress policy defnitions. | <code title="map(object({ ingress_from = object({ identity_type = string identities = list(string) source_access_levels = list(string) source_resources = list(string) }) ingress_to = object({ operations = list(object({ method_selectors = list(string) service_name = string })) resources = list(string) }) }))">map(object({…}))</code> | | <code>{}</code> | |
|
||||
| [vpc_sc_perimeter_access_levels](variables.tf#L171) | VPC SC perimeter access_levels. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpc_sc_perimeter_egress_policies](variables.tf#L181) | VPC SC egress policies per perimeter, values reference keys defined in the `vpc_sc_ingress_policies` variable. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpc_sc_perimeter_ingress_policies](variables.tf#L191) | VPC SC ingress policies per perimeter, values reference keys defined in the `vpc_sc_ingress_policies` variable. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
| [vpc_sc_perimeter_projects](variables.tf#L201) | VPC SC perimeter resources. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
|
||||
locals {
|
||||
dev_kms_restricted_admins = [
|
||||
"serviceAccount:${var.service_accounts.project-factory-dev}"
|
||||
"serviceAccount:${var.service_accounts.project-factory-dev}",
|
||||
"serviceAccount:${var.service_accounts.data-platform-dev}"
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -27,7 +28,6 @@ module "dev-sec-project" {
|
|||
prefix = var.prefix
|
||||
billing_account = var.billing_account.id
|
||||
iam = {
|
||||
(local.custom_roles.cloud_kms_key_editor) = ["serviceAccount:${var.service_accounts.data-platform-dev}"]
|
||||
"roles/cloudkms.viewer" = local.dev_kms_restricted_admins
|
||||
}
|
||||
labels = { environment = "dev", team = "security" }
|
||||
|
@ -50,7 +50,6 @@ module "dev-sec-kms" {
|
|||
}
|
||||
|
||||
# TODO(ludo): add support for conditions to Fabric modules
|
||||
# TODO(ludo): grant delegated role at key instead of project level
|
||||
|
||||
resource "google_project_iam_member" "dev_key_admin_delegated" {
|
||||
for_each = toset(local.dev_kms_restricted_admins)
|
||||
|
@ -61,7 +60,7 @@ resource "google_project_iam_member" "dev_key_admin_delegated" {
|
|||
title = "kms_sa_delegated_grants"
|
||||
description = "Automation service account delegated grants."
|
||||
expression = format(
|
||||
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
|
||||
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s]) && resource.type == 'cloudkms.googleapis.com/CryptoKey'",
|
||||
join(",", formatlist("'%s'", [
|
||||
"roles/cloudkms.cryptoKeyEncrypterDecrypter",
|
||||
"roles/cloudkms.cryptoKeyEncrypterDecrypterViaDelegation"
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
|
||||
locals {
|
||||
prod_kms_restricted_admins = [
|
||||
"serviceAccount:${var.service_accounts.project-factory-prod}"
|
||||
"serviceAccount:${var.service_accounts.project-factory-prod}",
|
||||
"serviceAccount:${var.service_accounts.data-platform-prod}"
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -27,7 +28,6 @@ module "prod-sec-project" {
|
|||
prefix = var.prefix
|
||||
billing_account = var.billing_account.id
|
||||
iam = {
|
||||
(local.custom_roles.cloud_kms_key_editor) = ["serviceAccount:${var.service_accounts.data-platform-prod}"]
|
||||
"roles/cloudkms.viewer" = local.prod_kms_restricted_admins
|
||||
}
|
||||
labels = { environment = "prod", team = "security" }
|
||||
|
@ -60,7 +60,7 @@ resource "google_project_iam_member" "prod_key_admin_delegated" {
|
|||
title = "kms_sa_delegated_grants"
|
||||
description = "Automation service account delegated grants."
|
||||
expression = format(
|
||||
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
|
||||
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s]) && resource.type == 'cloudkms.googleapis.com/CryptoKey'",
|
||||
join(",", formatlist("'%s'", [
|
||||
"roles/cloudkms.cryptoKeyEncrypterDecrypter",
|
||||
"roles/cloudkms.cryptoKeyEncrypterDecrypterViaDelegation"
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
|
||||
locals {
|
||||
custom_roles = coalesce(var.custom_roles, {})
|
||||
kms_keys = {
|
||||
for k, v in var.kms_keys : k => {
|
||||
iam = coalesce(v.iam, {})
|
||||
|
|
|
@ -31,15 +31,6 @@ variable "billing_account" {
|
|||
})
|
||||
}
|
||||
|
||||
variable "custom_roles" {
|
||||
# tfdoc:variable:source 00-bootstrap
|
||||
description = "Custom roles defined at the org level, in key => id format."
|
||||
type = object({
|
||||
cloud_kms_key_editor = string
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "folder_ids" {
|
||||
# tfdoc:variable:source 01-resman
|
||||
description = "Folder name => id mappings, the 'security' folder name must exist."
|
||||
|
|
|
@ -170,19 +170,20 @@ You can find examples in the `[demo](../../../../examples/data-solutions/data-pl
|
|||
| [billing_account](variables.tf#L25) | Billing account id and organization id ('nnnnnnnn' or null). | <code title="object({ id = string organization_id = number })">object({…})</code> | ✓ | | <code>00-globals</code> |
|
||||
| [folder_ids](variables.tf#L64) | Folder to be used for the networking resources in folders/nnnn format. | <code title="object({ data-platform = string })">object({…})</code> | ✓ | | <code>01-resman</code> |
|
||||
| [host_project_ids](variables.tf#L82) | Shared VPC project ids. | <code title="object({ dev-spoke-0 = string })">object({…})</code> | ✓ | | <code>02-networking</code> |
|
||||
| [organization](variables.tf#L108) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>00-globals</code> |
|
||||
| [prefix](variables.tf#L124) | Unique prefix used for resource names. Not used for projects if 'project_create' is null. | <code>string</code> | ✓ | | <code>00-globals</code> |
|
||||
| [organization](variables.tf#L114) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>00-globals</code> |
|
||||
| [prefix](variables.tf#L130) | Unique prefix used for resource names. Not used for projects if 'project_create' is null. | <code>string</code> | ✓ | | <code>00-globals</code> |
|
||||
| [composer_config](variables.tf#L34) | | <code title="object({ node_count = number airflow_version = string env_variables = map(string) })">object({…})</code> | | <code title="{ node_count = 3 airflow_version = "composer-1.17.5-airflow-2.1.4" env_variables = {} }">{…}</code> | |
|
||||
| [data_catalog_tags](variables.tf#L47) | List of Data Catalog Policy tags to be created with optional IAM binging configuration in {tag => {ROLE => [MEMBERS]}} format. | <code>map(map(list(string)))</code> | | <code title="{ "3_Confidential" = null "2_Private" = null "1_Sensitive" = null }">{…}</code> | |
|
||||
| [data_force_destroy](variables.tf#L58) | Flag to set 'force_destroy' on data services like BigQery or Cloud Storage. | <code>bool</code> | | <code>false</code> | |
|
||||
| [groups](variables.tf#L72) | Groups. | <code>map(string)</code> | | <code title="{ data-analysts = "gcp-data-analysts" data-engineers = "gcp-data-engineers" data-security = "gcp-data-security" }">{…}</code> | |
|
||||
| [network_config_composer](variables.tf#L90) | Network configurations to use for Composer. | <code title="object({ cloudsql_range = string gke_master_range = string gke_pods_name = string gke_services_name = string web_server_range = string })">object({…})</code> | | <code title="{ cloudsql_range = "192.168.254.0/24" gke_master_range = "192.168.255.0/28" gke_pods_name = "pods" gke_services_name = "services" web_server_range = "192.168.255.16/28" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L118) | Path where providers, tfvars files, and lists for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [project_services](variables.tf#L130) | List of core services enabled on all projects. | <code>list(string)</code> | | <code title="[ "cloudresourcemanager.googleapis.com", "iam.googleapis.com", "serviceusage.googleapis.com", "stackdriver.googleapis.com" ]">[…]</code> | |
|
||||
| [region](variables.tf#L141) | Region used for regional resources. | <code>string</code> | | <code>"europe-west1"</code> | |
|
||||
| [service_encryption_keys](variables.tf#L147) | Cloud KMS to use to encrypt different services. Key location should match service region. | <code title="object({ bq = string composer = string dataflow = string storage = string pubsub = string })">object({…})</code> | | <code>null</code> | |
|
||||
| [subnet_self_links](variables.tf#L159) | Shared VPC subnet self links. | <code title="object({ dev-spoke-0 = map(string) })">object({…})</code> | | <code>null</code> | <code>02-networking</code> |
|
||||
| [vpc_self_links](variables.tf#L168) | Shared VPC self links. | <code title="object({ dev-spoke-0 = string })">object({…})</code> | | <code>null</code> | <code>02-networking</code> |
|
||||
| [location](variables.tf#L90) | Location used for multi-regional resources. | <code>string</code> | | <code>"eu"</code> | |
|
||||
| [network_config_composer](variables.tf#L96) | Network configurations to use for Composer. | <code title="object({ cloudsql_range = string gke_master_range = string gke_pods_name = string gke_services_name = string web_server_range = string })">object({…})</code> | | <code title="{ cloudsql_range = "192.168.254.0/24" gke_master_range = "192.168.255.0/28" gke_pods_name = "pods" gke_services_name = "services" web_server_range = "192.168.255.16/28" }">{…}</code> | |
|
||||
| [outputs_location](variables.tf#L124) | Path where providers, tfvars files, and lists for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
|
||||
| [project_services](variables.tf#L136) | List of core services enabled on all projects. | <code>list(string)</code> | | <code title="[ "cloudresourcemanager.googleapis.com", "iam.googleapis.com", "serviceusage.googleapis.com", "stackdriver.googleapis.com" ]">[…]</code> | |
|
||||
| [region](variables.tf#L147) | Region used for regional resources. | <code>string</code> | | <code>"europe-west1"</code> | |
|
||||
| [service_encryption_keys](variables.tf#L153) | Cloud KMS to use to encrypt different services. Key location should match service region. | <code title="object({ bq = string composer = string dataflow = string storage = string pubsub = string })">object({…})</code> | | <code>null</code> | |
|
||||
| [subnet_self_links](variables.tf#L165) | Shared VPC subnet self links. | <code title="object({ dev-spoke-0 = map(string) })">object({…})</code> | | <code>null</code> | <code>02-networking</code> |
|
||||
| [vpc_self_links](variables.tf#L174) | Shared VPC self links. | <code title="object({ dev-spoke-0 = string })">object({…})</code> | | <code>null</code> | <code>02-networking</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -23,9 +23,6 @@ module "stage" {
|
|||
id = "000000-111111-222222"
|
||||
organization_id = 123456789012
|
||||
}
|
||||
custom_roles = {
|
||||
cloud_kms_key_editor = "cloudKmsKeyAdmin"
|
||||
}
|
||||
folder_ids = {
|
||||
security = null
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue