Update resman modules (#475)
* Make logging sinks in different resources use the same API * Split resman modules in multiple files. Add nullables where applicable
This commit is contained in:
@@ -140,7 +140,7 @@ module "folder-sink" {
|
||||
name = "my-folder"
|
||||
logging_sinks = {
|
||||
warnings = {
|
||||
type = "gcs"
|
||||
type = "storage"
|
||||
destination = module.gcs.name
|
||||
filter = "severity=WARNING"
|
||||
include_children = true
|
||||
@@ -215,26 +215,41 @@ module "folder2" {
|
||||
}
|
||||
# tftest modules=2 resources=6
|
||||
```
|
||||
|
||||
<!-- TFDOC OPTS files:1 -->
|
||||
<!-- BEGIN TFDOC -->
|
||||
|
||||
## Files
|
||||
|
||||
| name | description | resources |
|
||||
|---|---|---|
|
||||
| [firewal_policies.tf](./firewal_policies.tf) | None | <code>google_compute_firewall_policy</code> · <code>google_compute_firewall_policy_association</code> · <code>google_compute_firewall_policy_rule</code> |
|
||||
| [iam.tf](./iam.tf) | IAM bindings, roles and audit logging resources. | <code>google_folder_iam_binding</code> |
|
||||
| [logging.tf](./logging.tf) | Log sinks and supporting resources. | <code>google_bigquery_dataset_iam_member</code> · <code>google_logging_folder_exclusion</code> · <code>google_logging_folder_sink</code> · <code>google_project_iam_member</code> · <code>google_pubsub_topic_iam_member</code> · <code>google_storage_bucket_iam_member</code> |
|
||||
| [main.tf](./main.tf) | Module-level locals and resources. | <code>google_essential_contacts_contact</code> · <code>google_folder</code> |
|
||||
| [organization_policies.tf](./organization_policies.tf) | Folder-level organization policies. | <code>google_folder_organization_policy</code> |
|
||||
| [outputs.tf](./outputs.tf) | Module outputs. | |
|
||||
| [variables.tf](./variables.tf) | Module variables. | |
|
||||
| [versions.tf](./versions.tf) | Version pins. | |
|
||||
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [contacts](variables.tf#L17) | List of essential contacts for this resource. Must be in the form EMAIL -> [NOTIFICATION_TYPES]. Valid notification types are ALL, SUSPENSION, SECURITY, TECHNICAL, BILLING, LEGAL, PRODUCT_UPDATES | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [firewall_policies](variables.tf#L23) | Hierarchical firewall policies created in this folder. | <code title="map(map(object({ action = string description = string direction = string logging = bool ports = map(list(string)) priority = number ranges = list(string) target_resources = list(string) target_service_accounts = list(string) })))">map(map(object({…})))</code> | | <code>{}</code> |
|
||||
| [firewall_policy_association](variables.tf#L39) | The hierarchical firewall policy to associate to this folder. Must be either a key in the `firewall_policies` map or the id of a policy defined somewhere else. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [firewall_policy_factory](variables.tf#L45) | Configuration for the firewall policy factory. | <code title="object({ cidr_file = string policy_name = string rules_file = string })">object({…})</code> | | <code>null</code> |
|
||||
| [folder_create](variables.tf#L55) | Create folder. When set to false, uses id to reference an existing folder. | <code>bool</code> | | <code>true</code> |
|
||||
| [group_iam](variables.tf#L61) | Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [iam](variables.tf#L67) | IAM bindings in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [id](variables.tf#L73) | Folder ID in case you use folder_create=false | <code>string</code> | | <code>null</code> |
|
||||
| [logging_exclusions](variables.tf#L79) | Logging exclusions for this folder in the form {NAME -> FILTER}. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [logging_sinks](variables.tf#L85) | Logging sinks to create for this folder. | <code title="map(object({ destination = string type = string filter = string include_children = bool exclusions = map(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [name](variables.tf#L98) | Folder name. | <code>string</code> | | <code>null</code> |
|
||||
| [parent](variables.tf#L104) | Parent in folders/folder_id or organizations/org_id format. | <code>string</code> | | <code>null</code> |
|
||||
| [policy_boolean](variables.tf#L114) | Map of boolean org policies and enforcement value, set value to null for policy restore. | <code>map(bool)</code> | | <code>{}</code> |
|
||||
| [policy_list](variables.tf#L120) | Map of list org policies, status is true for allow, false for deny, null for restore. Values can only be used for allow or deny. | <code title="map(object({ inherit_from_parent = bool suggested_value = string status = bool values = list(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [firewall_policies](variables.tf#L24) | Hierarchical firewall policies created in this folder. | <code title="map(map(object({ action = string description = string direction = string logging = bool ports = map(list(string)) priority = number ranges = list(string) target_resources = list(string) target_service_accounts = list(string) })))">map(map(object({…})))</code> | | <code>{}</code> |
|
||||
| [firewall_policy_association](variables.tf#L41) | The hierarchical firewall policy to associate to this folder. Must be either a key in the `firewall_policies` map or the id of a policy defined somewhere else. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [firewall_policy_factory](variables.tf#L48) | Configuration for the firewall policy factory. | <code title="object({ cidr_file = string policy_name = string rules_file = string })">object({…})</code> | | <code>null</code> |
|
||||
| [folder_create](variables.tf#L58) | Create folder. When set to false, uses id to reference an existing folder. | <code>bool</code> | | <code>true</code> |
|
||||
| [group_iam](variables.tf#L64) | Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [iam](variables.tf#L71) | IAM bindings in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [id](variables.tf#L78) | Folder ID in case you use folder_create=false | <code>string</code> | | <code>null</code> |
|
||||
| [logging_exclusions](variables.tf#L84) | Logging exclusions for this folder in the form {NAME -> FILTER}. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [logging_sinks](variables.tf#L91) | Logging sinks to create for this folder. | <code title="map(object({ destination = string type = string filter = string include_children = bool exclusions = map(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [name](variables.tf#L112) | Folder name. | <code>string</code> | | <code>null</code> |
|
||||
| [parent](variables.tf#L118) | Parent in folders/folder_id or organizations/org_id format. | <code>string</code> | | <code>null</code> |
|
||||
| [policy_boolean](variables.tf#L128) | Map of boolean org policies and enforcement value, set value to null for policy restore. | <code>map(bool)</code> | | <code>{}</code> |
|
||||
| [policy_list](variables.tf#L135) | Map of list org policies, status is true for allow, false for deny, null for restore. Values can only be used for allow or deny. | <code title="map(object({ inherit_from_parent = bool suggested_value = string status = bool values = list(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
||||
40
modules/folder/iam.tf
Normal file
40
modules/folder/iam.tf
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
# tfdoc:file:description IAM bindings, roles and audit logging resources.
|
||||
|
||||
locals {
|
||||
group_iam_roles = distinct(flatten(values(var.group_iam)))
|
||||
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
|
||||
]
|
||||
}
|
||||
iam = {
|
||||
for role in distinct(concat(keys(var.iam), keys(local.group_iam))) :
|
||||
role => concat(
|
||||
try(var.iam[role], []),
|
||||
try(local.group_iam[role], [])
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_folder_iam_binding" "authoritative" {
|
||||
for_each = local.iam
|
||||
folder = local.folder.name
|
||||
role = each.key
|
||||
members = each.value
|
||||
}
|
||||
91
modules/folder/logging.tf
Normal file
91
modules/folder/logging.tf
Normal file
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
# tfdoc:file:description Log sinks and supporting resources.
|
||||
|
||||
locals {
|
||||
sink_bindings = {
|
||||
for type in ["bigquery", "pubsub", "logging", "storage"] :
|
||||
type => {
|
||||
for name, sink in var.logging_sinks :
|
||||
name => sink
|
||||
if sink.type == type
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_logging_folder_sink" "sink" {
|
||||
for_each = var.logging_sinks
|
||||
name = each.key
|
||||
#description = "${each.key} (Terraform-managed)"
|
||||
folder = local.folder.name
|
||||
destination = "${each.value.type}.googleapis.com/${each.value.destination}"
|
||||
filter = each.value.filter
|
||||
include_children = each.value.include_children
|
||||
|
||||
dynamic "exclusions" {
|
||||
for_each = each.value.exclusions
|
||||
iterator = exclusion
|
||||
content {
|
||||
name = exclusion.key
|
||||
filter = exclusion.value
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = [
|
||||
google_folder_iam_binding.authoritative
|
||||
]
|
||||
}
|
||||
|
||||
resource "google_storage_bucket_iam_member" "gcs-sinks-binding" {
|
||||
for_each = local.sink_bindings["storage"]
|
||||
bucket = each.value.destination
|
||||
role = "roles/storage.objectCreator"
|
||||
member = google_logging_folder_sink.sink[each.key].writer_identity
|
||||
}
|
||||
|
||||
resource "google_bigquery_dataset_iam_member" "bq-sinks-binding" {
|
||||
for_each = local.sink_bindings["bigquery"]
|
||||
project = split("/", each.value.destination)[1]
|
||||
dataset_id = split("/", each.value.destination)[3]
|
||||
role = "roles/bigquery.dataEditor"
|
||||
member = google_logging_folder_sink.sink[each.key].writer_identity
|
||||
}
|
||||
|
||||
resource "google_pubsub_topic_iam_member" "pubsub-sinks-binding" {
|
||||
for_each = local.sink_bindings["pubsub"]
|
||||
project = split("/", each.value.destination)[1]
|
||||
topic = split("/", each.value.destination)[3]
|
||||
role = "roles/pubsub.publisher"
|
||||
member = google_logging_folder_sink.sink[each.key].writer_identity
|
||||
}
|
||||
|
||||
resource "google_project_iam_member" "bucket-sinks-binding" {
|
||||
for_each = local.sink_bindings["logging"]
|
||||
project = split("/", each.value.destination)[1]
|
||||
role = "roles/logging.bucketWriter"
|
||||
member = google_logging_folder_sink.sink[each.key].writer_identity
|
||||
# TODO(jccb): use a condition to limit writer-identity only to this
|
||||
# bucket
|
||||
}
|
||||
|
||||
resource "google_logging_folder_exclusion" "logging-exclusion" {
|
||||
for_each = var.logging_exclusions
|
||||
name = each.key
|
||||
folder = local.folder.name
|
||||
description = "${each.key} (Terraform-managed)"
|
||||
filter = each.value
|
||||
}
|
||||
@@ -15,34 +15,6 @@
|
||||
*/
|
||||
|
||||
locals {
|
||||
group_iam_roles = distinct(flatten(values(var.group_iam)))
|
||||
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
|
||||
]
|
||||
}
|
||||
iam = {
|
||||
for role in distinct(concat(keys(var.iam), keys(local.group_iam))) :
|
||||
role => concat(
|
||||
try(var.iam[role], []),
|
||||
try(local.group_iam[role], [])
|
||||
)
|
||||
}
|
||||
logging_sinks = coalesce(var.logging_sinks, {})
|
||||
sink_type_destination = {
|
||||
gcs = "storage.googleapis.com"
|
||||
bigquery = "bigquery.googleapis.com"
|
||||
pubsub = "pubsub.googleapis.com"
|
||||
logging = "logging.googleapis.com"
|
||||
}
|
||||
sink_bindings = {
|
||||
for type in ["gcs", "bigquery", "pubsub", "logging"] :
|
||||
type => {
|
||||
for name, sink in local.logging_sinks :
|
||||
name => sink
|
||||
if sink.type == type
|
||||
}
|
||||
}
|
||||
folder = (
|
||||
var.folder_create
|
||||
? try(google_folder.folder.0, null)
|
||||
@@ -61,149 +33,6 @@ resource "google_folder" "folder" {
|
||||
parent = var.parent
|
||||
}
|
||||
|
||||
resource "google_folder_iam_binding" "authoritative" {
|
||||
for_each = local.iam
|
||||
folder = local.folder.name
|
||||
role = each.key
|
||||
members = each.value
|
||||
}
|
||||
|
||||
resource "google_folder_organization_policy" "boolean" {
|
||||
for_each = var.policy_boolean
|
||||
folder = local.folder.name
|
||||
constraint = each.key
|
||||
|
||||
dynamic "boolean_policy" {
|
||||
for_each = each.value == null ? [] : [each.value]
|
||||
iterator = policy
|
||||
content {
|
||||
enforced = policy.value
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "restore_policy" {
|
||||
for_each = each.value == null ? [""] : []
|
||||
content {
|
||||
default = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_folder_organization_policy" "list" {
|
||||
for_each = var.policy_list
|
||||
folder = local.folder.name
|
||||
constraint = each.key
|
||||
|
||||
dynamic "list_policy" {
|
||||
for_each = each.value.status == null ? [] : [each.value]
|
||||
iterator = policy
|
||||
content {
|
||||
inherit_from_parent = policy.value.inherit_from_parent
|
||||
suggested_value = policy.value.suggested_value
|
||||
dynamic "allow" {
|
||||
for_each = policy.value.status ? [""] : []
|
||||
content {
|
||||
values = (
|
||||
try(length(policy.value.values) > 0, false)
|
||||
? policy.value.values
|
||||
: null
|
||||
)
|
||||
all = (
|
||||
try(length(policy.value.values) > 0, false)
|
||||
? null
|
||||
: true
|
||||
)
|
||||
}
|
||||
}
|
||||
dynamic "deny" {
|
||||
for_each = policy.value.status ? [] : [""]
|
||||
content {
|
||||
values = (
|
||||
try(length(policy.value.values) > 0, false)
|
||||
? policy.value.values
|
||||
: null
|
||||
)
|
||||
all = (
|
||||
try(length(policy.value.values) > 0, false)
|
||||
? null
|
||||
: true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "restore_policy" {
|
||||
for_each = each.value.status == null ? [true] : []
|
||||
content {
|
||||
default = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_logging_folder_sink" "sink" {
|
||||
for_each = local.logging_sinks
|
||||
name = each.key
|
||||
#description = "${each.key} (Terraform-managed)"
|
||||
folder = local.folder.name
|
||||
destination = "${local.sink_type_destination[each.value.type]}/${each.value.destination}"
|
||||
filter = each.value.filter
|
||||
include_children = each.value.include_children
|
||||
|
||||
dynamic "exclusions" {
|
||||
for_each = each.value.exclusions
|
||||
iterator = exclusion
|
||||
content {
|
||||
name = exclusion.key
|
||||
filter = exclusion.value
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = [
|
||||
google_folder_iam_binding.authoritative
|
||||
]
|
||||
}
|
||||
|
||||
resource "google_storage_bucket_iam_member" "gcs-sinks-binding" {
|
||||
for_each = local.sink_bindings["gcs"]
|
||||
bucket = each.value.destination
|
||||
role = "roles/storage.objectCreator"
|
||||
member = google_logging_folder_sink.sink[each.key].writer_identity
|
||||
}
|
||||
|
||||
resource "google_bigquery_dataset_iam_member" "bq-sinks-binding" {
|
||||
for_each = local.sink_bindings["bigquery"]
|
||||
project = split("/", each.value.destination)[1]
|
||||
dataset_id = split("/", each.value.destination)[3]
|
||||
role = "roles/bigquery.dataEditor"
|
||||
member = google_logging_folder_sink.sink[each.key].writer_identity
|
||||
}
|
||||
|
||||
resource "google_pubsub_topic_iam_member" "pubsub-sinks-binding" {
|
||||
for_each = local.sink_bindings["pubsub"]
|
||||
project = split("/", each.value.destination)[1]
|
||||
topic = split("/", each.value.destination)[3]
|
||||
role = "roles/pubsub.publisher"
|
||||
member = google_logging_folder_sink.sink[each.key].writer_identity
|
||||
}
|
||||
|
||||
resource "google_project_iam_member" "bucket-sinks-binding" {
|
||||
for_each = local.sink_bindings["logging"]
|
||||
project = split("/", each.value.destination)[1]
|
||||
role = "roles/logging.bucketWriter"
|
||||
member = google_logging_folder_sink.sink[each.key].writer_identity
|
||||
# TODO(jccb): use a condition to limit writer-identity only to this
|
||||
# bucket
|
||||
}
|
||||
|
||||
resource "google_logging_folder_exclusion" "logging-exclusion" {
|
||||
for_each = coalesce(var.logging_exclusions, {})
|
||||
name = each.key
|
||||
folder = local.folder.name
|
||||
description = "${each.key} (Terraform-managed)"
|
||||
filter = each.value
|
||||
}
|
||||
|
||||
resource "google_essential_contacts_contact" "contact" {
|
||||
provider = google-beta
|
||||
for_each = var.contacts
|
||||
|
||||
90
modules/folder/organization_policies.tf
Normal file
90
modules/folder/organization_policies.tf
Normal file
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
# tfdoc:file:description Folder-level organization policies.
|
||||
|
||||
resource "google_folder_organization_policy" "boolean" {
|
||||
for_each = var.policy_boolean
|
||||
folder = local.folder.name
|
||||
constraint = each.key
|
||||
|
||||
dynamic "boolean_policy" {
|
||||
for_each = each.value == null ? [] : [each.value]
|
||||
iterator = policy
|
||||
content {
|
||||
enforced = policy.value
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "restore_policy" {
|
||||
for_each = each.value == null ? [""] : []
|
||||
content {
|
||||
default = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_folder_organization_policy" "list" {
|
||||
for_each = var.policy_list
|
||||
folder = local.folder.name
|
||||
constraint = each.key
|
||||
|
||||
dynamic "list_policy" {
|
||||
for_each = each.value.status == null ? [] : [each.value]
|
||||
iterator = policy
|
||||
content {
|
||||
inherit_from_parent = policy.value.inherit_from_parent
|
||||
suggested_value = policy.value.suggested_value
|
||||
dynamic "allow" {
|
||||
for_each = policy.value.status ? [""] : []
|
||||
content {
|
||||
values = (
|
||||
try(length(policy.value.values) > 0, false)
|
||||
? policy.value.values
|
||||
: null
|
||||
)
|
||||
all = (
|
||||
try(length(policy.value.values) > 0, false)
|
||||
? null
|
||||
: true
|
||||
)
|
||||
}
|
||||
}
|
||||
dynamic "deny" {
|
||||
for_each = policy.value.status ? [] : [""]
|
||||
content {
|
||||
values = (
|
||||
try(length(policy.value.values) > 0, false)
|
||||
? policy.value.values
|
||||
: null
|
||||
)
|
||||
all = (
|
||||
try(length(policy.value.values) > 0, false)
|
||||
? null
|
||||
: true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "restore_policy" {
|
||||
for_each = each.value.status == null ? [true] : []
|
||||
content {
|
||||
default = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ variable "contacts" {
|
||||
description = "List of essential contacts for this resource. Must be in the form EMAIL -> [NOTIFICATION_TYPES]. Valid notification types are ALL, SUSPENSION, SECURITY, TECHNICAL, BILLING, LEGAL, PRODUCT_UPDATES"
|
||||
type = map(list(string))
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "firewall_policies" {
|
||||
@@ -33,13 +34,15 @@ variable "firewall_policies" {
|
||||
target_resources = list(string)
|
||||
target_service_accounts = list(string)
|
||||
})))
|
||||
default = {}
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "firewall_policy_association" {
|
||||
description = "The hierarchical firewall policy to associate to this folder. Must be either a key in the `firewall_policies` map or the id of a policy defined somewhere else."
|
||||
type = map(string)
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "firewall_policy_factory" {
|
||||
@@ -62,12 +65,14 @@ variable "group_iam" {
|
||||
description = "Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable."
|
||||
type = map(list(string))
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "iam" {
|
||||
description = "IAM bindings in {ROLE => [MEMBERS]} format."
|
||||
type = map(list(string))
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "id" {
|
||||
@@ -80,6 +85,7 @@ variable "logging_exclusions" {
|
||||
description = "Logging exclusions for this folder in the form {NAME -> FILTER}."
|
||||
type = map(string)
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "logging_sinks" {
|
||||
@@ -92,7 +98,15 @@ variable "logging_sinks" {
|
||||
# TODO exclusions also support description and disabled
|
||||
exclusions = map(string)
|
||||
}))
|
||||
default = {}
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for k, v in(var.logging_sinks == null ? {} : var.logging_sinks) :
|
||||
contains(["bigquery", "logging", "pubsub", "storage"], v.type)
|
||||
])
|
||||
error_message = "Type must be one of 'bigquery', 'logging', 'pubsub', 'storage'."
|
||||
}
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
@@ -115,6 +129,7 @@ variable "policy_boolean" {
|
||||
description = "Map of boolean org policies and enforcement value, set value to null for policy restore."
|
||||
type = map(bool)
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "policy_list" {
|
||||
@@ -125,5 +140,6 @@ variable "policy_list" {
|
||||
status = bool
|
||||
values = list(string)
|
||||
}))
|
||||
default = {}
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
terraform {
|
||||
required_version = ">= 1.0.0"
|
||||
required_version = ">= 1.1.0"
|
||||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
|
||||
@@ -243,11 +243,11 @@ module "org" {
|
||||
|
||||
| name | description | resources |
|
||||
|---|---|---|
|
||||
| [firewall-policy.tf](./firewall-policy.tf) | Hierarchical firewall policies. | <code>google_compute_firewall_policy</code> · <code>google_compute_firewall_policy_association</code> · <code>google_compute_firewall_policy_rule</code> |
|
||||
| [firewall_policies.tf](./firewall_policies.tf) | Hierarchical firewall policies. | <code>google_compute_firewall_policy</code> · <code>google_compute_firewall_policy_association</code> · <code>google_compute_firewall_policy_rule</code> |
|
||||
| [iam.tf](./iam.tf) | IAM bindings, roles and audit logging resources. | <code>google_organization_iam_audit_config</code> · <code>google_organization_iam_binding</code> · <code>google_organization_iam_custom_role</code> · <code>google_organization_iam_member</code> · <code>google_organization_iam_policy</code> |
|
||||
| [logging.tf](./logging.tf) | Log sinks and supporting resources. | <code>google_bigquery_dataset_iam_member</code> · <code>google_logging_organization_exclusion</code> · <code>google_logging_organization_sink</code> · <code>google_project_iam_member</code> · <code>google_pubsub_topic_iam_member</code> · <code>google_storage_bucket_iam_member</code> |
|
||||
| [main.tf](./main.tf) | Module-level locals and resources. | <code>google_essential_contacts_contact</code> |
|
||||
| [org-policy.tf](./org-policy.tf) | Organization policies. | <code>google_organization_policy</code> |
|
||||
| [organization_policies.tf](./organization_policies.tf) | Organization-level organization policies. | <code>google_organization_policy</code> |
|
||||
| [outputs.tf](./outputs.tf) | Module outputs. | |
|
||||
| [variables.tf](./variables.tf) | Module variables. | |
|
||||
| [versions.tf](./versions.tf) | Version pins. | |
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
# tfdoc:file:description Organization policies.
|
||||
# tfdoc:file:description Organization-level organization policies.
|
||||
|
||||
resource "google_organization_policy" "boolean" {
|
||||
for_each = var.policy_boolean
|
||||
@@ -108,7 +108,7 @@ module "project-host" {
|
||||
parent = "folders/1234567890"
|
||||
logging_sinks = {
|
||||
warnings = {
|
||||
type = "gcs"
|
||||
type = "storage"
|
||||
destination = module.gcs.name
|
||||
filter = "severity=WARNING"
|
||||
iam = false
|
||||
@@ -184,49 +184,49 @@ module "project" {
|
||||
| [iam.tf](./iam.tf) | Generic and OSLogin-specific IAM bindings and roles. | <code>google_project_iam_binding</code> · <code>google_project_iam_custom_role</code> · <code>google_project_iam_member</code> |
|
||||
| [logging.tf](./logging.tf) | Log sinks and supporting resources. | <code>google_bigquery_dataset_iam_member</code> · <code>google_logging_project_exclusion</code> · <code>google_logging_project_sink</code> · <code>google_project_iam_member</code> · <code>google_pubsub_topic_iam_member</code> · <code>google_storage_bucket_iam_member</code> |
|
||||
| [main.tf](./main.tf) | Module-level locals and resources. | <code>google_compute_project_metadata_item</code> · <code>google_essential_contacts_contact</code> · <code>google_monitoring_monitored_project</code> · <code>google_project</code> · <code>google_project_service</code> · <code>google_resource_manager_lien</code> |
|
||||
| [organization-policies.tf](./organization-policies.tf) | Project-level organization policies. | <code>google_project_organization_policy</code> |
|
||||
| [organization_policies.tf](./organization_policies.tf) | Project-level organization policies. | <code>google_project_organization_policy</code> |
|
||||
| [outputs.tf](./outputs.tf) | Module outputs. | |
|
||||
| [service_accounts.tf](./service_accounts.tf) | Service identities and supporting resources. | <code>google_kms_crypto_key_iam_member</code> · <code>google_project_service_identity</code> |
|
||||
| [shared_vpc.tf](./shared_vpc.tf) | Shared VPC project-level configuration. | <code>google_compute_shared_vpc_host_project</code> · <code>google_compute_shared_vpc_service_project</code> |
|
||||
| [variables.tf](./variables.tf) | Module variables. | |
|
||||
| [versions.tf](./versions.tf) | Version pins. | |
|
||||
| [vpc-sc.tf](./vpc-sc.tf) | VPC-SC project-level perimeter configuration. | <code>google_access_context_manager_service_perimeter_resource</code> |
|
||||
| [vpc_sc.tf](./vpc_sc.tf) | VPC-SC project-level perimeter configuration. | <code>google_access_context_manager_service_perimeter_resource</code> |
|
||||
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [name](variables.tf#L109) | Project name and id suffix. | <code>string</code> | ✓ | |
|
||||
| [name](variables.tf#L125) | Project name and id suffix. | <code>string</code> | ✓ | |
|
||||
| [auto_create_network](variables.tf#L17) | Whether to create the default network for the project | <code>bool</code> | | <code>false</code> |
|
||||
| [billing_account](variables.tf#L23) | Billing account id. | <code>string</code> | | <code>null</code> |
|
||||
| [contacts](variables.tf#L29) | List of essential contacts for this resource. Must be in the form EMAIL -> [NOTIFICATION_TYPES]. Valid notification types are ALL, SUSPENSION, SECURITY, TECHNICAL, BILLING, LEGAL, PRODUCT_UPDATES | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [custom_roles](variables.tf#L35) | Map of role name => list of permissions to create in this project. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [descriptive_name](variables.tf#L41) | Name of the project name. Used for project name instead of `name` variable | <code>string</code> | | <code>null</code> |
|
||||
| [group_iam](variables.tf#L47) | Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [iam](variables.tf#L53) | IAM bindings in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [iam_additive](variables.tf#L59) | IAM additive bindings in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [iam_additive_members](variables.tf#L65) | IAM additive bindings in {MEMBERS => [ROLE]} format. This might break if members are dynamic values. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [labels](variables.tf#L71) | Resource labels. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [lien_reason](variables.tf#L77) | If non-empty, creates a project lien with this description. | <code>string</code> | | <code>""</code> |
|
||||
| [logging_exclusions](variables.tf#L83) | Logging exclusions for this project in the form {NAME -> FILTER}. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [logging_sinks](variables.tf#L89) | Logging sinks to create for this project. | <code title="map(object({ destination = string type = string filter = string iam = bool unique_writer = bool exclusions = map(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [metric_scopes](variables.tf#L103) | List of projects that will act as metric scopes for this project. | <code>list(string)</code> | | <code>null</code> |
|
||||
| [oslogin](variables.tf#L114) | Enable OS Login. | <code>bool</code> | | <code>false</code> |
|
||||
| [oslogin_admins](variables.tf#L120) | List of IAM-style identities that will be granted roles necessary for OS Login administrators. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [oslogin_users](variables.tf#L126) | List of IAM-style identities that will be granted roles necessary for OS Login users. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [parent](variables.tf#L132) | Parent folder or organization in 'folders/folder_id' or 'organizations/org_id' format. | <code>string</code> | | <code>null</code> |
|
||||
| [policy_boolean](variables.tf#L142) | Map of boolean org policies and enforcement value, set value to null for policy restore. | <code>map(bool)</code> | | <code>{}</code> |
|
||||
| [policy_list](variables.tf#L148) | Map of list org policies, status is true for allow, false for deny, null for restore. Values can only be used for allow or deny. | <code title="map(object({ inherit_from_parent = bool suggested_value = string status = bool values = list(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [prefix](variables.tf#L159) | Prefix used to generate project id and name. | <code>string</code> | | <code>null</code> |
|
||||
| [project_create](variables.tf#L165) | Create project. When set to false, uses a data source to reference existing project. | <code>bool</code> | | <code>true</code> |
|
||||
| [service_config](variables.tf#L171) | Configure service API activation. | <code title="object({ disable_on_destroy = bool disable_dependent_services = bool })">object({…})</code> | | <code title="{ disable_on_destroy = true disable_dependent_services = true }">{…}</code> |
|
||||
| [service_encryption_key_ids](variables.tf#L183) | Cloud KMS encryption key in {SERVICE => [KEY_URL]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [service_perimeter_bridges](variables.tf#L190) | Name of VPC-SC Bridge perimeters to add project into. See comment in the variables file for format. | <code>list(string)</code> | | <code>null</code> |
|
||||
| [service_perimeter_standard](variables.tf#L197) | Name of VPC-SC Standard perimeter to add project into. See comment in the variables file for format. | <code>string</code> | | <code>null</code> |
|
||||
| [services](variables.tf#L203) | Service APIs to enable. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [shared_vpc_host_config](variables.tf#L209) | Configures this project as a Shared VPC host project (mutually exclusive with shared_vpc_service_project). | <code title="object({ enabled = bool service_projects = list(string) })">object({…})</code> | | <code title="{ enabled = false service_projects = [] }">{…}</code> |
|
||||
| [shared_vpc_service_config](variables.tf#L221) | Configures this project as a Shared VPC service project (mutually exclusive with shared_vpc_host_config). | <code title="object({ attach = bool host_project = string })">object({…})</code> | | <code title="{ attach = false host_project = "" }">{…}</code> |
|
||||
| [skip_delete](variables.tf#L233) | Allows the underlying resources to be destroyed without destroying the project itself. | <code>bool</code> | | <code>false</code> |
|
||||
| [custom_roles](variables.tf#L36) | Map of role name => list of permissions to create in this project. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [descriptive_name](variables.tf#L43) | Name of the project name. Used for project name instead of `name` variable | <code>string</code> | | <code>null</code> |
|
||||
| [group_iam](variables.tf#L49) | Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [iam](variables.tf#L56) | IAM bindings in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [iam_additive](variables.tf#L63) | IAM additive bindings in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [iam_additive_members](variables.tf#L70) | IAM additive bindings in {MEMBERS => [ROLE]} format. This might break if members are dynamic values. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [labels](variables.tf#L76) | Resource labels. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [lien_reason](variables.tf#L83) | If non-empty, creates a project lien with this description. | <code>string</code> | | <code>""</code> |
|
||||
| [logging_exclusions](variables.tf#L89) | Logging exclusions for this project in the form {NAME -> FILTER}. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [logging_sinks](variables.tf#L96) | Logging sinks to create for this project. | <code title="map(object({ destination = string type = string filter = string iam = bool unique_writer = bool exclusions = map(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [metric_scopes](variables.tf#L118) | List of projects that will act as metric scopes for this project. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [oslogin](variables.tf#L130) | Enable OS Login. | <code>bool</code> | | <code>false</code> |
|
||||
| [oslogin_admins](variables.tf#L136) | List of IAM-style identities that will be granted roles necessary for OS Login administrators. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [oslogin_users](variables.tf#L144) | List of IAM-style identities that will be granted roles necessary for OS Login users. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [parent](variables.tf#L151) | Parent folder or organization in 'folders/folder_id' or 'organizations/org_id' format. | <code>string</code> | | <code>null</code> |
|
||||
| [policy_boolean](variables.tf#L161) | Map of boolean org policies and enforcement value, set value to null for policy restore. | <code>map(bool)</code> | | <code>{}</code> |
|
||||
| [policy_list](variables.tf#L168) | Map of list org policies, status is true for allow, false for deny, null for restore. Values can only be used for allow or deny. | <code title="map(object({ inherit_from_parent = bool suggested_value = string status = bool values = list(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [prefix](variables.tf#L180) | Prefix used to generate project id and name. | <code>string</code> | | <code>null</code> |
|
||||
| [project_create](variables.tf#L186) | Create project. When set to false, uses a data source to reference existing project. | <code>bool</code> | | <code>true</code> |
|
||||
| [service_config](variables.tf#L192) | Configure service API activation. | <code title="object({ disable_on_destroy = bool disable_dependent_services = bool })">object({…})</code> | | <code title="{ disable_on_destroy = true disable_dependent_services = true }">{…}</code> |
|
||||
| [service_encryption_key_ids](variables.tf#L204) | Cloud KMS encryption key in {SERVICE => [KEY_URL]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [service_perimeter_bridges](variables.tf#L211) | Name of VPC-SC Bridge perimeters to add project into. See comment in the variables file for format. | <code>list(string)</code> | | <code>null</code> |
|
||||
| [service_perimeter_standard](variables.tf#L218) | Name of VPC-SC Standard perimeter to add project into. See comment in the variables file for format. | <code>string</code> | | <code>null</code> |
|
||||
| [services](variables.tf#L224) | Service APIs to enable. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [shared_vpc_host_config](variables.tf#L230) | Configures this project as a Shared VPC host project (mutually exclusive with shared_vpc_service_project). | <code title="object({ enabled = bool service_projects = list(string) })">object({…})</code> | | <code title="{ enabled = false service_projects = [] }">{…}</code> |
|
||||
| [shared_vpc_service_config](variables.tf#L243) | Configures this project as a Shared VPC service project (mutually exclusive with shared_vpc_host_config). | <code title="object({ attach = bool host_project = string })">object({…})</code> | | <code title="{ attach = false host_project = "" }">{…}</code> |
|
||||
| [skip_delete](variables.tf#L256) | Allows the underlying resources to be destroyed without destroying the project itself. | <code>bool</code> | | <code>false</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
||||
@@ -17,28 +17,21 @@
|
||||
# tfdoc:file:description Log sinks and supporting resources.
|
||||
|
||||
locals {
|
||||
logging_sinks = coalesce(var.logging_sinks, {})
|
||||
sink_bindings = {
|
||||
for type in ["gcs", "bigquery", "pubsub", "logging"] :
|
||||
for type in ["bigquery", "pubsub", "logging", "storage"] :
|
||||
type => {
|
||||
for name, sink in local.logging_sinks :
|
||||
for name, sink in var.logging_sinks :
|
||||
name => sink if sink.iam && sink.type == type
|
||||
}
|
||||
}
|
||||
sink_type_destination = {
|
||||
gcs = "storage.googleapis.com"
|
||||
bigquery = "bigquery.googleapis.com"
|
||||
pubsub = "pubsub.googleapis.com"
|
||||
logging = "logging.googleapis.com"
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_logging_project_sink" "sink" {
|
||||
for_each = local.logging_sinks
|
||||
for_each = var.logging_sinks
|
||||
name = each.key
|
||||
#description = "${each.key} (Terraform-managed)"
|
||||
project = local.project.project_id
|
||||
destination = "${local.sink_type_destination[each.value.type]}/${each.value.destination}"
|
||||
destination = "${each.value.type}.googleapis.com/${each.value.destination}"
|
||||
filter = each.value.filter
|
||||
unique_writer_identity = each.value.unique_writer
|
||||
|
||||
@@ -58,7 +51,7 @@ resource "google_logging_project_sink" "sink" {
|
||||
}
|
||||
|
||||
resource "google_storage_bucket_iam_member" "gcs-sinks-binding" {
|
||||
for_each = local.sink_bindings["gcs"]
|
||||
for_each = local.sink_bindings["storage"]
|
||||
bucket = each.value.destination
|
||||
role = "roles/storage.objectCreator"
|
||||
member = google_logging_project_sink.sink[each.key].writer_identity
|
||||
@@ -90,7 +83,7 @@ resource "google_project_iam_member" "bucket-sinks-binding" {
|
||||
}
|
||||
|
||||
resource "google_logging_project_exclusion" "logging-exclusion" {
|
||||
for_each = coalesce(var.logging_exclusions, {})
|
||||
for_each = var.logging_exclusions
|
||||
name = each.key
|
||||
project = local.project.project_id
|
||||
description = "${each.key} (Terraform-managed)"
|
||||
|
||||
@@ -89,7 +89,7 @@ resource "google_essential_contacts_contact" "contact" {
|
||||
|
||||
resource "google_monitoring_monitored_project" "primary" {
|
||||
provider = google-beta
|
||||
for_each = toset(coalesce(var.metric_scopes, []))
|
||||
for_each = toset(var.metric_scopes)
|
||||
metrics_scope = each.value
|
||||
name = local.project.project_id
|
||||
}
|
||||
|
||||
@@ -30,12 +30,14 @@ variable "contacts" {
|
||||
description = "List of essential contacts for this resource. Must be in the form EMAIL -> [NOTIFICATION_TYPES]. Valid notification types are ALL, SUSPENSION, SECURITY, TECHNICAL, BILLING, LEGAL, PRODUCT_UPDATES"
|
||||
type = map(list(string))
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "custom_roles" {
|
||||
description = "Map of role name => list of permissions to create in this project."
|
||||
type = map(list(string))
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "descriptive_name" {
|
||||
@@ -48,18 +50,21 @@ variable "group_iam" {
|
||||
description = "Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable."
|
||||
type = map(list(string))
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "iam" {
|
||||
description = "IAM bindings in {ROLE => [MEMBERS]} format."
|
||||
type = map(list(string))
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "iam_additive" {
|
||||
description = "IAM additive bindings in {ROLE => [MEMBERS]} format."
|
||||
type = map(list(string))
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "iam_additive_members" {
|
||||
@@ -72,6 +77,7 @@ variable "labels" {
|
||||
description = "Resource labels."
|
||||
type = map(string)
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "lien_reason" {
|
||||
@@ -84,6 +90,7 @@ variable "logging_exclusions" {
|
||||
description = "Logging exclusions for this project in the form {NAME -> FILTER}."
|
||||
type = map(string)
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "logging_sinks" {
|
||||
@@ -97,13 +104,22 @@ variable "logging_sinks" {
|
||||
# TODO exclusions also support description and disabled
|
||||
exclusions = map(string)
|
||||
}))
|
||||
default = {}
|
||||
validation {
|
||||
condition = alltrue([
|
||||
for k, v in(var.logging_sinks == null ? {} : var.logging_sinks) :
|
||||
contains(["bigquery", "logging", "pubsub", "storage"], v.type)
|
||||
])
|
||||
error_message = "Type must be one of 'bigquery', 'logging', 'pubsub', 'storage'."
|
||||
}
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "metric_scopes" {
|
||||
description = "List of projects that will act as metric scopes for this project."
|
||||
type = list(string)
|
||||
default = null
|
||||
default = []
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
@@ -121,12 +137,15 @@ variable "oslogin_admins" {
|
||||
description = "List of IAM-style identities that will be granted roles necessary for OS Login administrators."
|
||||
type = list(string)
|
||||
default = []
|
||||
nullable = false
|
||||
|
||||
}
|
||||
|
||||
variable "oslogin_users" {
|
||||
description = "List of IAM-style identities that will be granted roles necessary for OS Login users."
|
||||
type = list(string)
|
||||
default = []
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "parent" {
|
||||
@@ -143,6 +162,7 @@ variable "policy_boolean" {
|
||||
description = "Map of boolean org policies and enforcement value, set value to null for policy restore."
|
||||
type = map(bool)
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "policy_list" {
|
||||
@@ -153,7 +173,8 @@ variable "policy_list" {
|
||||
status = bool
|
||||
values = list(string)
|
||||
}))
|
||||
default = {}
|
||||
default = {}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
@@ -216,6 +237,7 @@ variable "shared_vpc_host_config" {
|
||||
enabled = false
|
||||
service_projects = []
|
||||
}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "shared_vpc_service_config" {
|
||||
@@ -228,6 +250,7 @@ variable "shared_vpc_service_config" {
|
||||
attach = false
|
||||
host_project = ""
|
||||
}
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "skip_delete" {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
terraform {
|
||||
required_version = ">= 1.0.0"
|
||||
required_version = ">= 1.1.0"
|
||||
required_providers {
|
||||
google = {
|
||||
source = "hashicorp/google"
|
||||
|
||||
@@ -18,7 +18,7 @@ def test_sinks(plan_runner):
|
||||
"Test folder-level sinks."
|
||||
logging_sinks = """ {
|
||||
warning = {
|
||||
type = "gcs"
|
||||
type = "storage"
|
||||
destination = "mybucket"
|
||||
filter = "severity=WARNING"
|
||||
iam = true
|
||||
|
||||
@@ -19,7 +19,7 @@ def test_sinks(plan_runner):
|
||||
"Test folder-level sinks."
|
||||
logging_sinks = """ {
|
||||
warning = {
|
||||
type = "gcs"
|
||||
type = "storage"
|
||||
destination = "mybucket"
|
||||
filter = "severity=WARNING"
|
||||
iam = true
|
||||
|
||||
Reference in New Issue
Block a user