02-security
This commit is contained in:
parent
7e9843d445
commit
ca186054df
|
@ -285,27 +285,29 @@ Some references that might be useful in setting up this stage:
|
|||
|
||||
| name | description | type | required | default | producer |
|
||||
|---|---|:---:|:---:|:---:|:---:|
|
||||
| [billing_account_id](variables.tf#L17) | Billing account id. | <code>string</code> | ✓ | | <code>bootstrap</code> |
|
||||
| [folder_id](variables.tf#L23) | Folder to be used for the networking resources in folders/nnnn format. | <code>string</code> | ✓ | | <code>resman</code> |
|
||||
| [organization](variables.tf#L73) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>bootstrap</code> |
|
||||
| [prefix](variables.tf#L89) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [groups](variables.tf#L29) | 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>bootstrap</code> |
|
||||
| [kms_defaults](variables.tf#L44) | 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#L56) | 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> | |
|
||||
| [kms_restricted_admins](variables.tf#L67) | Map of environment => [identities] who can assign the encrypt/decrypt roles on keys. | <code>map(list(string))</code> | | <code>{}</code> | |
|
||||
| [outputs_location](variables.tf#L83) | 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#L100) | 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#L115) | 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#L133) | 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#L153) | 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#L163) | 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#L173) | 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#L183) | VPC SC perimeter resources. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
| [billing_account](variables.tf#L17) | 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#L26) | Folder name => id mappings, the 'security' folder name must exist. | <code title="object({ security = string })">object({…})</code> | ✓ | | <code>01-resman</code> |
|
||||
| [organization](variables.tf#L81) | Organization details. | <code title="object({ domain = string id = number customer_id = string })">object({…})</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [prefix](variables.tf#L97) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
|
||||
| [service_accounts](variables.tf#L72) | Automation service accounts that can assign the encrypt/decrypt roles on keys. | <code title="object({ project-factory-dev = string project-factory-prod = string })">object({…})</code> | ✓ | | <code>01-resman</code> |
|
||||
| [groups](variables.tf#L34) | 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#L49) | 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#L61) | 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#L91) | 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#L108) | 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#L123) | 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#L141) | 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#L161) | 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#L171) | 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#L181) | 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#L191) | VPC SC perimeter resources. | <code title="object({ dev = list(string) landing = list(string) prod = list(string) })">object({…})</code> | | <code>null</code> | |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive | consumers |
|
||||
|---|---|:---:|---|
|
||||
| [stage_perimeter_projects](outputs.tf#L37) | Security project numbers. They can be added to perimeter resources. | | |
|
||||
| [kms_keys](outputs.tf#L52) | KMS key ids. | | |
|
||||
| [stage_perimeter_projects](outputs.tf#L57) | Security project numbers. They can be added to perimeter resources. | | |
|
||||
| [tfvars](outputs.tf#L67) | Terraform variable files for the following stages. | ✓ | |
|
||||
|
||||
<!-- END TFDOC -->
|
||||
|
|
|
@ -14,14 +14,20 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
locals {
|
||||
dev_kms_restricted_admins = [
|
||||
"serviceAccount:${var.service_accounts.project-factory-dev}"
|
||||
]
|
||||
}
|
||||
|
||||
module "dev-sec-project" {
|
||||
source = "../../../modules/project"
|
||||
name = "dev-sec-core-0"
|
||||
parent = var.folder_id
|
||||
parent = var.folder_ids.security
|
||||
prefix = var.prefix
|
||||
billing_account = var.billing_account_id
|
||||
billing_account = var.billing_account.id
|
||||
iam = {
|
||||
"roles/cloudkms.viewer" = try(var.kms_restricted_admins.dev, [])
|
||||
"roles/cloudkms.viewer" = local.dev_kms_restricted_admins
|
||||
}
|
||||
labels = { environment = "dev", team = "security" }
|
||||
services = local.project_services
|
||||
|
@ -46,7 +52,7 @@ module "dev-sec-kms" {
|
|||
# TODO(ludo): grant delegated role at key instead of project level
|
||||
|
||||
resource "google_project_iam_member" "dev_key_admin_delegated" {
|
||||
for_each = toset(try(var.kms_restricted_admins.dev, []))
|
||||
for_each = toset(local.dev_kms_restricted_admins)
|
||||
project = module.dev-sec-project.project_id
|
||||
role = "roles/cloudkms.admin"
|
||||
member = each.key
|
||||
|
|
|
@ -14,14 +14,20 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
locals {
|
||||
prod_kms_restricted_admins = [
|
||||
"serviceAccount:${var.service_accounts.project-factory-prod}"
|
||||
]
|
||||
}
|
||||
|
||||
module "prod-sec-project" {
|
||||
source = "../../../modules/project"
|
||||
name = "prod-sec-core-0"
|
||||
parent = var.folder_id
|
||||
parent = var.folder_ids.security
|
||||
prefix = var.prefix
|
||||
billing_account = var.billing_account_id
|
||||
billing_account = var.billing_account.id
|
||||
iam = {
|
||||
"roles/cloudkms.viewer" = try(var.kms_restricted_admins.prod, [])
|
||||
"roles/cloudkms.viewer" = local.prod_kms_restricted_admins
|
||||
}
|
||||
labels = { environment = "prod", team = "security" }
|
||||
services = local.project_services
|
||||
|
@ -45,7 +51,7 @@ module "prod-sec-kms" {
|
|||
# TODO(ludo): add support for conditions to Fabric modules
|
||||
|
||||
resource "google_project_iam_member" "prod_key_admin_delegated" {
|
||||
for_each = toset(try(var.kms_restricted_admins.prod, []))
|
||||
for_each = toset(local.prod_kms_restricted_admins)
|
||||
project = module.prod-sec-project.project_id
|
||||
role = "roles/cloudkms.admin"
|
||||
member = each.key
|
||||
|
|
|
@ -14,26 +14,46 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
# optionally generate files for subsequent stages
|
||||
|
||||
resource "local_file" "dev_sec_kms" {
|
||||
for_each = var.outputs_location == null ? {} : { 1 = 1 }
|
||||
filename = "${pathexpand(var.outputs_location)}/yamls/02-security-kms-dev-keys.yaml"
|
||||
content = yamlencode({
|
||||
for k, m in module.dev-sec-kms : k => m.key_ids
|
||||
})
|
||||
locals {
|
||||
_output_kms_keys = concat(
|
||||
flatten([
|
||||
for location, mod in module.dev-sec-kms : [
|
||||
for name, id in mod.key_ids : {
|
||||
key = "dev:${name}:${location}"
|
||||
id = id
|
||||
}
|
||||
]
|
||||
]),
|
||||
flatten([
|
||||
for location, mod in module.prod-sec-kms : [
|
||||
for name, id in mod.key_ids : {
|
||||
key = "prod:${name}:${location}"
|
||||
id = id
|
||||
}
|
||||
]
|
||||
])
|
||||
)
|
||||
output_kms_keys = { for k in local._output_kms_keys : k.key => k.id }
|
||||
}
|
||||
|
||||
resource "local_file" "prod_sec_kms" {
|
||||
for_each = var.outputs_location == null ? {} : { 1 = 1 }
|
||||
filename = "${pathexpand(var.outputs_location)}/yamls/02-security-kms-prod-keys.yaml"
|
||||
content = yamlencode({
|
||||
for k, m in module.prod-sec-kms : k => m.key_ids
|
||||
# optionally generate files for subsequent stages
|
||||
|
||||
resource "local_file" "tfvars" {
|
||||
for_each = var.outputs_location == null ? {} : { 1 = 1 }
|
||||
file_permission = "0644"
|
||||
filename = "${pathexpand(var.outputs_location)}/tfvars/02-security.auto.tfvars.json"
|
||||
content = jsonencode({
|
||||
kms_keys = local.output_kms_keys
|
||||
})
|
||||
}
|
||||
|
||||
# outputs
|
||||
|
||||
output "kms_keys" {
|
||||
description = "KMS key ids."
|
||||
value = local.output_kms_keys
|
||||
}
|
||||
|
||||
output "stage_perimeter_projects" {
|
||||
description = "Security project numbers. They can be added to perimeter resources."
|
||||
value = {
|
||||
|
@ -41,3 +61,13 @@ output "stage_perimeter_projects" {
|
|||
prod = ["projects/${module.prod-sec-project.number}"]
|
||||
}
|
||||
}
|
||||
|
||||
# ready to use variable values for subsequent stages
|
||||
|
||||
output "tfvars" {
|
||||
description = "Terraform variable files for the following stages."
|
||||
sensitive = true
|
||||
value = {
|
||||
kms_keys = local.output_kms_keys
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,20 +14,25 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
variable "billing_account_id" {
|
||||
# tfdoc:variable:source bootstrap
|
||||
description = "Billing account id."
|
||||
type = string
|
||||
variable "billing_account" {
|
||||
# tfdoc:variable:source 00-bootstrap
|
||||
description = "Billing account id and organization id ('nnnnnnnn' or null)."
|
||||
type = object({
|
||||
id = string
|
||||
organization_id = number
|
||||
})
|
||||
}
|
||||
|
||||
variable "folder_id" {
|
||||
# tfdoc:variable:source resman
|
||||
description = "Folder to be used for the networking resources in folders/nnnn format."
|
||||
type = string
|
||||
variable "folder_ids" {
|
||||
# tfdoc:variable:source 01-resman
|
||||
description = "Folder name => id mappings, the 'security' folder name must exist."
|
||||
type = object({
|
||||
security = string
|
||||
})
|
||||
}
|
||||
|
||||
variable "groups" {
|
||||
# tfdoc:variable:source bootstrap
|
||||
# tfdoc:variable:source 00-bootstrap
|
||||
description = "Group names to grant organization-level permissions."
|
||||
type = map(string)
|
||||
# https://cloud.google.com/docs/enterprise/setup-checklist
|
||||
|
@ -64,14 +69,17 @@ variable "kms_keys" {
|
|||
default = {}
|
||||
}
|
||||
|
||||
variable "kms_restricted_admins" {
|
||||
description = "Map of environment => [identities] who can assign the encrypt/decrypt roles on keys."
|
||||
type = map(list(string))
|
||||
default = {}
|
||||
variable "service_accounts" {
|
||||
# tfdoc:variable:source 01-resman
|
||||
description = "Automation service accounts that can assign the encrypt/decrypt roles on keys."
|
||||
type = object({
|
||||
project-factory-dev = string
|
||||
project-factory-prod = string
|
||||
})
|
||||
}
|
||||
|
||||
variable "organization" {
|
||||
# tfdoc:variable:source bootstrap
|
||||
# tfdoc:variable:source 00-bootstrap
|
||||
description = "Organization details."
|
||||
type = object({
|
||||
domain = string
|
||||
|
|
Loading…
Reference in New Issue