add support for service account IAM variables to pf (#2130)
This commit is contained in:
parent
81cf47c785
commit
39139e2fa1
|
@ -43,18 +43,21 @@ Some examples on where to use each of the three sets are [provided below](#examp
|
||||||
|
|
||||||
Service accounts can be managed as part of each project's YAML configuration. This allows creation of default service accounts used for GCE instances, in firewall rules, or for application-level credentials without resorting to a separate Terraform configuration.
|
Service accounts can be managed as part of each project's YAML configuration. This allows creation of default service accounts used for GCE instances, in firewall rules, or for application-level credentials without resorting to a separate Terraform configuration.
|
||||||
|
|
||||||
Each service account is represented by one key and a set of optional key/value pairs in the `service_accounts` top-level YAML map, like in this example:
|
Each service account is represented by one key and a set of optional key/value pairs in the `service_accounts` top-level YAML map, which expose most of the variables available in the `iam-service-account` module:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
service_accounts:
|
service_accounts:
|
||||||
be-0: {}
|
be-0: {}
|
||||||
fe-1:
|
fe-1:
|
||||||
display_name: GCE frontend service account.
|
display_name: GCE frontend service account.
|
||||||
iam_project_roles:
|
iam_self_roles:
|
||||||
- roles/storage.objectViewer
|
- roles/storage.objectViewer
|
||||||
|
iam_project_roles:
|
||||||
|
my-host-project:
|
||||||
|
- roles/compute.networkUser
|
||||||
```
|
```
|
||||||
|
|
||||||
Both the `display_name` and `iam_project_roles` attributes are optional.
|
Both the `display_name` and `iam_self_roles` attributes are optional.
|
||||||
|
|
||||||
### Billing budgets
|
### Billing budgets
|
||||||
|
|
||||||
|
@ -122,7 +125,7 @@ module "project-factory" {
|
||||||
projects_data_path = "data/projects"
|
projects_data_path = "data/projects"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# tftest modules=8 resources=35 files=prj-app-1,prj-app-2,prj-app-3,budget-test-100 inventory=example.yaml
|
# tftest modules=8 resources=37 files=prj-app-1,prj-app-2,prj-app-3,budget-test-100
|
||||||
```
|
```
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
@ -140,11 +143,17 @@ services:
|
||||||
- storage.googleapis.com
|
- storage.googleapis.com
|
||||||
service_accounts:
|
service_accounts:
|
||||||
app-1-be:
|
app-1-be:
|
||||||
iam_project_roles:
|
iam_self_roles:
|
||||||
- roles/logging.logWriter
|
- roles/logging.logWriter
|
||||||
- roles/monitoring.metricWriter
|
- roles/monitoring.metricWriter
|
||||||
|
iam_project_roles:
|
||||||
|
my-host-project:
|
||||||
|
- roles/compute.networkUser
|
||||||
app-1-fe:
|
app-1-fe:
|
||||||
display_name: "Test app 1 frontend."
|
display_name: "Test app 1 frontend."
|
||||||
|
iam_project_roles:
|
||||||
|
my-host-project:
|
||||||
|
- roles/compute.networkUser
|
||||||
billing_budgets:
|
billing_budgets:
|
||||||
- test-100
|
- test-100
|
||||||
# tftest-file id=prj-app-1 path=data/projects/prj-app-1.yaml
|
# tftest-file id=prj-app-1 path=data/projects/prj-app-1.yaml
|
||||||
|
@ -223,9 +232,9 @@ update_rules:
|
||||||
| name | description | type | required | default |
|
| name | description | type | required | default |
|
||||||
|---|---|:---:|:---:|:---:|
|
|---|---|:---:|:---:|:---:|
|
||||||
| [factories_config](variables.tf#L91) | Path to folder with YAML resource description data files. | <code title="object({ projects_data_path = string budgets = optional(object({ billing_account = string budgets_data_path = string notification_channels = optional(map(any), {}) })) })">object({…})</code> | ✓ | |
|
| [factories_config](variables.tf#L91) | Path to folder with YAML resource description data files. | <code title="object({ projects_data_path = string budgets = optional(object({ billing_account = string budgets_data_path = string notification_channels = optional(map(any), {}) })) })">object({…})</code> | ✓ | |
|
||||||
| [data_defaults](variables.tf#L17) | Optional default values used when corresponding project data from files are missing. | <code title="object({ billing_account = optional(string) contacts = optional(map(list(string)), {}) labels = optional(map(string), {}) metric_scopes = optional(list(string), []) parent = optional(string) prefix = optional(string) service_encryption_key_ids = optional(map(list(string)), {}) service_perimeter_bridges = optional(list(string), []) service_perimeter_standard = optional(string) services = optional(list(string), []) shared_vpc_service_config = optional(object({ host_project = string network_users = optional(list(string), []) service_identity_iam = optional(map(list(string)), {}) service_identity_subnet_iam = optional(map(list(string)), {}) service_iam_grants = optional(list(string), []) network_subnet_users = optional(map(list(string)), {}) }), { host_project = null }) tag_bindings = optional(map(string), {}) service_accounts = optional(map(object({ display_name = optional(string, "Terraform-managed.") iam_project_roles = optional(list(string)) })), {}) })">object({…})</code> | | <code>{}</code> |
|
| [data_defaults](variables.tf#L17) | Optional default values used when corresponding project data from files are missing. | <code title="object({ billing_account = optional(string) contacts = optional(map(list(string)), {}) labels = optional(map(string), {}) metric_scopes = optional(list(string), []) parent = optional(string) prefix = optional(string) service_encryption_key_ids = optional(map(list(string)), {}) service_perimeter_bridges = optional(list(string), []) service_perimeter_standard = optional(string) services = optional(list(string), []) shared_vpc_service_config = optional(object({ host_project = string network_users = optional(list(string), []) service_identity_iam = optional(map(list(string)), {}) service_identity_subnet_iam = optional(map(list(string)), {}) service_iam_grants = optional(list(string), []) network_subnet_users = optional(map(list(string)), {}) }), { host_project = null }) tag_bindings = optional(map(string), {}) service_accounts = optional(map(object({ display_name = optional(string, "Terraform-managed.") iam_self_roles = optional(list(string)) })), {}) })">object({…})</code> | | <code>{}</code> |
|
||||||
| [data_merges](variables.tf#L49) | Optional values that will be merged with corresponding data from files. Combines with `data_defaults`, file data, and `data_overrides`. | <code title="object({ contacts = optional(map(list(string)), {}) labels = optional(map(string), {}) metric_scopes = optional(list(string), []) service_encryption_key_ids = optional(map(list(string)), {}) service_perimeter_bridges = optional(list(string), []) services = optional(list(string), []) tag_bindings = optional(map(string), {}) service_accounts = optional(map(object({ display_name = optional(string, "Terraform-managed.") iam_project_roles = optional(list(string)) })), {}) })">object({…})</code> | | <code>{}</code> |
|
| [data_merges](variables.tf#L49) | Optional values that will be merged with corresponding data from files. Combines with `data_defaults`, file data, and `data_overrides`. | <code title="object({ contacts = optional(map(list(string)), {}) labels = optional(map(string), {}) metric_scopes = optional(list(string), []) service_encryption_key_ids = optional(map(list(string)), {}) service_perimeter_bridges = optional(list(string), []) services = optional(list(string), []) tag_bindings = optional(map(string), {}) service_accounts = optional(map(object({ display_name = optional(string, "Terraform-managed.") iam_self_roles = optional(list(string)) })), {}) })">object({…})</code> | | <code>{}</code> |
|
||||||
| [data_overrides](variables.tf#L69) | Optional values that override corresponding data from files. Takes precedence over file data and `data_defaults`. | <code title="object({ billing_account = optional(string) contacts = optional(map(list(string))) parent = optional(string) prefix = optional(string) service_encryption_key_ids = optional(map(list(string))) service_perimeter_bridges = optional(list(string)) service_perimeter_standard = optional(string) tag_bindings = optional(map(string)) services = optional(list(string)) service_accounts = optional(map(object({ display_name = optional(string, "Terraform-managed.") iam_project_roles = optional(list(string)) }))) })">object({…})</code> | | <code>{}</code> |
|
| [data_overrides](variables.tf#L69) | Optional values that override corresponding data from files. Takes precedence over file data and `data_defaults`. | <code title="object({ billing_account = optional(string) contacts = optional(map(list(string))) parent = optional(string) prefix = optional(string) service_encryption_key_ids = optional(map(list(string))) service_perimeter_bridges = optional(list(string)) service_perimeter_standard = optional(string) tag_bindings = optional(map(string)) services = optional(list(string)) service_accounts = optional(map(object({ display_name = optional(string, "Terraform-managed.") iam_self_roles = optional(list(string)) }))) })">object({…})</code> | | <code>{}</code> |
|
||||||
|
|
||||||
## Outputs
|
## Outputs
|
||||||
|
|
||||||
|
|
|
@ -103,11 +103,7 @@ locals {
|
||||||
var.data_defaults.tag_bindings
|
var.data_defaults.tag_bindings
|
||||||
)
|
)
|
||||||
# non-project resources
|
# non-project resources
|
||||||
service_accounts = coalesce(
|
service_accounts = try(v.service_accounts, {})
|
||||||
var.data_overrides.service_accounts,
|
|
||||||
try(v.service_accounts, null),
|
|
||||||
var.data_defaults.service_accounts
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
service_accounts = flatten([
|
service_accounts = flatten([
|
||||||
|
@ -115,8 +111,23 @@ locals {
|
||||||
for name, opts in v.service_accounts : {
|
for name, opts in v.service_accounts : {
|
||||||
project = k
|
project = k
|
||||||
name = name
|
name = name
|
||||||
display_name = try(opts.display_name, "Terraform-managed.")
|
display_name = coalesce(
|
||||||
iam_project_roles = try(opts.iam_project_roles, null)
|
try(var.data_overrides.service_accounts.display_name, null),
|
||||||
|
try(opts.display_name, null),
|
||||||
|
try(var.data_defaults.service_accounts.display_name, null),
|
||||||
|
"Terraform-managed."
|
||||||
|
)
|
||||||
|
iam_billing_roles = try(opts.iam_billing_roles, {})
|
||||||
|
iam_organization_roles = try(opts.iam_organization_roles, {})
|
||||||
|
iam_sa_roles = try(opts.iam_sa_roles, {})
|
||||||
|
iam_project_roles = try(opts.iam_project_roles, {})
|
||||||
|
iam_self_roles = distinct(concat(
|
||||||
|
try(var.data_overrides.service_accounts.iam_self_roles, []),
|
||||||
|
try(opts.iam_self_roles, []),
|
||||||
|
try(var.data_defaults.service_accounts.iam_self_roles, []),
|
||||||
|
))
|
||||||
|
iam_storage_roles = try(opts.iam_storage_roles, {})
|
||||||
|
opts = opts
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
])
|
])
|
||||||
|
|
|
@ -67,14 +67,17 @@ module "projects" {
|
||||||
module "service-accounts" {
|
module "service-accounts" {
|
||||||
source = "../iam-service-account"
|
source = "../iam-service-account"
|
||||||
for_each = {
|
for_each = {
|
||||||
for k in local.service_accounts : "${k.project}-${k.name}" => k
|
for k in local.service_accounts : "${k.project}/${k.name}" => k
|
||||||
}
|
}
|
||||||
project_id = module.projects[each.value.project].project_id
|
project_id = module.projects[each.value.project].project_id
|
||||||
name = each.value.name
|
name = each.value.name
|
||||||
display_name = each.value.display_name
|
display_name = each.value.display_name
|
||||||
iam_project_roles = each.value.iam_project_roles == null ? {} : {
|
iam_project_roles = merge(
|
||||||
(module.projects[each.value.project].project_id) = each.value.iam_project_roles
|
each.value.iam_project_roles,
|
||||||
|
each.value.iam_self_roles == null ? {} : {
|
||||||
|
(module.projects[each.value.project].project_id) = each.value.iam_self_roles
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
module "billing-account" {
|
module "billing-account" {
|
||||||
|
|
|
@ -21,7 +21,6 @@ output "projects" {
|
||||||
|
|
||||||
output "service_accounts" {
|
output "service_accounts" {
|
||||||
description = "Service account emails."
|
description = "Service account emails."
|
||||||
# TODO: group by project
|
|
||||||
value = {
|
value = {
|
||||||
for k, v in module.service-accounts : k => v.email
|
for k, v in module.service-accounts : k => v.email
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ variable "data_defaults" {
|
||||||
# non-project resources
|
# non-project resources
|
||||||
service_accounts = optional(map(object({
|
service_accounts = optional(map(object({
|
||||||
display_name = optional(string, "Terraform-managed.")
|
display_name = optional(string, "Terraform-managed.")
|
||||||
iam_project_roles = optional(list(string))
|
iam_self_roles = optional(list(string))
|
||||||
})), {})
|
})), {})
|
||||||
})
|
})
|
||||||
nullable = false
|
nullable = false
|
||||||
|
@ -59,7 +59,7 @@ variable "data_merges" {
|
||||||
# non-project resources
|
# non-project resources
|
||||||
service_accounts = optional(map(object({
|
service_accounts = optional(map(object({
|
||||||
display_name = optional(string, "Terraform-managed.")
|
display_name = optional(string, "Terraform-managed.")
|
||||||
iam_project_roles = optional(list(string))
|
iam_self_roles = optional(list(string))
|
||||||
})), {})
|
})), {})
|
||||||
})
|
})
|
||||||
nullable = false
|
nullable = false
|
||||||
|
@ -81,7 +81,7 @@ variable "data_overrides" {
|
||||||
# non-project resources
|
# non-project resources
|
||||||
service_accounts = optional(map(object({
|
service_accounts = optional(map(object({
|
||||||
display_name = optional(string, "Terraform-managed.")
|
display_name = optional(string, "Terraform-managed.")
|
||||||
iam_project_roles = optional(list(string))
|
iam_self_roles = optional(list(string))
|
||||||
})))
|
})))
|
||||||
})
|
})
|
||||||
nullable = false
|
nullable = false
|
||||||
|
|
|
@ -13,6 +13,44 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
values:
|
values:
|
||||||
|
module.project-factory.module.billing-account[0].google_billing_budget.default["test-100"]:
|
||||||
|
all_updates_rule:
|
||||||
|
- disable_default_iam_recipients: true
|
||||||
|
pubsub_topic: null
|
||||||
|
schema_version: '1.0'
|
||||||
|
amount:
|
||||||
|
- last_period_amount: null
|
||||||
|
specified_amount:
|
||||||
|
- nanos: null
|
||||||
|
units: '100'
|
||||||
|
billing_account: 123456-123456-123456
|
||||||
|
budget_filter:
|
||||||
|
- calendar_period: null
|
||||||
|
credit_types_treatment: INCLUDE_ALL_CREDITS
|
||||||
|
custom_period: []
|
||||||
|
projects:
|
||||||
|
- projects/test-pf-prj-app-1
|
||||||
|
resource_ancestors:
|
||||||
|
- folders/1234567890
|
||||||
|
display_name: 100 dollars in current spend
|
||||||
|
threshold_rules:
|
||||||
|
- spend_basis: CURRENT_SPEND
|
||||||
|
threshold_percent: 0.5
|
||||||
|
- spend_basis: CURRENT_SPEND
|
||||||
|
threshold_percent: 0.75
|
||||||
|
timeouts: null
|
||||||
|
module.project-factory.module.billing-account[0].google_monitoring_notification_channel.default["billing-default"]:
|
||||||
|
description: null
|
||||||
|
display_name: Budget email notification billing-default.
|
||||||
|
enabled: true
|
||||||
|
force_delete: false
|
||||||
|
labels:
|
||||||
|
email_address: gcp-billing-admins@example.com
|
||||||
|
project: foo-billing-audit
|
||||||
|
sensitive_labels: []
|
||||||
|
timeouts: null
|
||||||
|
type: email
|
||||||
|
user_labels: null
|
||||||
module.project-factory.module.projects["prj-app-1"].data.google_storage_project_service_account.gcs_sa[0]:
|
module.project-factory.module.projects["prj-app-1"].data.google_storage_project_service_account.gcs_sa[0]:
|
||||||
project: test-pf-prj-app-1
|
project: test-pf-prj-app-1
|
||||||
user_project: null
|
user_project: null
|
||||||
|
@ -74,6 +112,25 @@ values:
|
||||||
host_project: foo-host
|
host_project: foo-host
|
||||||
service_project: test-pf-prj-app-2
|
service_project: test-pf-prj-app-2
|
||||||
timeouts: null
|
timeouts: null
|
||||||
|
? module.project-factory.module.projects["prj-app-2"].google_compute_subnetwork_iam_member.shared_vpc_host_robots["europe-west1:prod-default-ew1:cloudservices"]
|
||||||
|
: condition: []
|
||||||
|
project: foo-host
|
||||||
|
region: europe-west1
|
||||||
|
role: roles/compute.networkUser
|
||||||
|
subnetwork: prod-default-ew1
|
||||||
|
? module.project-factory.module.projects["prj-app-2"].google_compute_subnetwork_iam_member.shared_vpc_host_robots["europe-west1:prod-default-ew1:container-engine"]
|
||||||
|
: condition: []
|
||||||
|
project: foo-host
|
||||||
|
region: europe-west1
|
||||||
|
role: roles/compute.networkUser
|
||||||
|
subnetwork: prod-default-ew1
|
||||||
|
? module.project-factory.module.projects["prj-app-2"].google_compute_subnetwork_iam_member.shared_vpc_host_subnets_iam["europe-west1:prod-default-ew1:group:team-1@example.com"]
|
||||||
|
: condition: []
|
||||||
|
member: group:team-1@example.com
|
||||||
|
project: foo-host
|
||||||
|
region: europe-west1
|
||||||
|
role: roles/compute.networkUser
|
||||||
|
subnetwork: prod-default-ew1
|
||||||
module.project-factory.module.projects["prj-app-2"].google_essential_contacts_contact.contact["admin@example.com"]:
|
module.project-factory.module.projects["prj-app-2"].google_essential_contacts_contact.contact["admin@example.com"]:
|
||||||
email: admin@example.com
|
email: admin@example.com
|
||||||
language_tag: en
|
language_tag: en
|
||||||
|
@ -81,6 +138,23 @@ values:
|
||||||
- ALL
|
- ALL
|
||||||
parent: projects/test-pf-prj-app-2
|
parent: projects/test-pf-prj-app-2
|
||||||
timeouts: null
|
timeouts: null
|
||||||
|
? module.project-factory.module.projects["prj-app-2"].google_org_policy_policy.default["compute.restrictSharedVpcSubnetworks"]
|
||||||
|
: dry_run_spec: []
|
||||||
|
name: projects/test-pf-prj-app-2/policies/compute.restrictSharedVpcSubnetworks
|
||||||
|
parent: projects/test-pf-prj-app-2
|
||||||
|
spec:
|
||||||
|
- inherit_from_parent: null
|
||||||
|
reset: null
|
||||||
|
rules:
|
||||||
|
- allow_all: null
|
||||||
|
condition: []
|
||||||
|
deny_all: null
|
||||||
|
enforce: null
|
||||||
|
values:
|
||||||
|
- allowed_values:
|
||||||
|
- projects/foo-host/regions/europe-west1/subnetworks/prod-default-ew1
|
||||||
|
denied_values: null
|
||||||
|
timeouts: null
|
||||||
module.project-factory.module.projects["prj-app-2"].google_project.project[0]:
|
module.project-factory.module.projects["prj-app-2"].google_project.project[0]:
|
||||||
auto_create_network: false
|
auto_create_network: false
|
||||||
billing_account: 123456-123456-123456
|
billing_account: 123456-123456-123456
|
||||||
|
@ -110,18 +184,6 @@ values:
|
||||||
: condition: []
|
: condition: []
|
||||||
project: foo-host
|
project: foo-host
|
||||||
role: roles/vpcaccess.user
|
role: roles/vpcaccess.user
|
||||||
? module.project-factory.module.projects["prj-app-2"].google_compute_subnetwork_iam_member.shared_vpc_host_robots["europe-west1:prod-default-ew1:cloudservices"]
|
|
||||||
: condition: [ ]
|
|
||||||
project: foo-host
|
|
||||||
role: roles/compute.networkUser
|
|
||||||
? module.project-factory.module.projects["prj-app-2"].google_compute_subnetwork_iam_member.shared_vpc_host_robots["europe-west1:prod-default-ew1:container-engine"]
|
|
||||||
: condition: [ ]
|
|
||||||
project: foo-host
|
|
||||||
role: roles/compute.networkUser
|
|
||||||
? module.project-factory.module.projects["prj-app-2"].google_compute_subnetwork_iam_member.shared_vpc_host_subnets_iam["europe-west1:prod-default-ew1:group:team-1@example.com"]
|
|
||||||
: condition: [ ]
|
|
||||||
project: foo-host
|
|
||||||
role: roles/compute.networkUser
|
|
||||||
module.project-factory.module.projects["prj-app-2"].google_project_service.project_services["compute.googleapis.com"]:
|
module.project-factory.module.projects["prj-app-2"].google_project_service.project_services["compute.googleapis.com"]:
|
||||||
disable_dependent_services: false
|
disable_dependent_services: false
|
||||||
disable_on_destroy: false
|
disable_on_destroy: false
|
||||||
|
@ -152,21 +214,6 @@ values:
|
||||||
project: test-pf-prj-app-2
|
project: test-pf-prj-app-2
|
||||||
service: storage.googleapis.com
|
service: storage.googleapis.com
|
||||||
timeouts: null
|
timeouts: null
|
||||||
module.project-factory.module.projects["prj-app-2"].google_org_policy_policy.default["compute.restrictSharedVpcSubnetworks"]:
|
|
||||||
name: projects/test-pf-prj-app-2/policies/compute.restrictSharedVpcSubnetworks
|
|
||||||
parent: projects/test-pf-prj-app-2
|
|
||||||
spec:
|
|
||||||
- inherit_from_parent: null
|
|
||||||
reset: null
|
|
||||||
rules:
|
|
||||||
- allow_all: null
|
|
||||||
condition: [ ]
|
|
||||||
deny_all: null
|
|
||||||
enforce: null
|
|
||||||
values:
|
|
||||||
- allowed_values:
|
|
||||||
- projects/foo-host/regions/europe-west1/subnetworks/prod-default-ew1
|
|
||||||
denied_values: null
|
|
||||||
module.project-factory.module.projects["prj-app-3"].data.google_storage_project_service_account.gcs_sa[0]:
|
module.project-factory.module.projects["prj-app-3"].data.google_storage_project_service_account.gcs_sa[0]:
|
||||||
project: test-pf-prj-app-3
|
project: test-pf-prj-app-3
|
||||||
user_project: null
|
user_project: null
|
||||||
|
@ -210,33 +257,44 @@ values:
|
||||||
project: test-pf-prj-app-3
|
project: test-pf-prj-app-3
|
||||||
service: storage.googleapis.com
|
service: storage.googleapis.com
|
||||||
timeouts: null
|
timeouts: null
|
||||||
? module.project-factory.module.service-accounts["prj-app-1-app-1-be"].google_project_iam_member.project-roles["test-pf-prj-app-1-roles/logging.logWriter"]
|
? module.project-factory.module.service-accounts["prj-app-1/app-1-be"].google_project_iam_member.project-roles["my-host-project-roles/compute.networkUser"]
|
||||||
|
: condition: []
|
||||||
|
project: my-host-project
|
||||||
|
role: roles/compute.networkUser
|
||||||
|
? module.project-factory.module.service-accounts["prj-app-1/app-1-be"].google_project_iam_member.project-roles["test-pf-prj-app-1-roles/logging.logWriter"]
|
||||||
: condition: []
|
: condition: []
|
||||||
project: test-pf-prj-app-1
|
project: test-pf-prj-app-1
|
||||||
role: roles/logging.logWriter
|
role: roles/logging.logWriter
|
||||||
? module.project-factory.module.service-accounts["prj-app-1-app-1-be"].google_project_iam_member.project-roles["test-pf-prj-app-1-roles/monitoring.metricWriter"]
|
? module.project-factory.module.service-accounts["prj-app-1/app-1-be"].google_project_iam_member.project-roles["test-pf-prj-app-1-roles/monitoring.metricWriter"]
|
||||||
: condition: []
|
: condition: []
|
||||||
project: test-pf-prj-app-1
|
project: test-pf-prj-app-1
|
||||||
role: roles/monitoring.metricWriter
|
role: roles/monitoring.metricWriter
|
||||||
module.project-factory.module.service-accounts["prj-app-1-app-1-be"].google_service_account.service_account[0]:
|
module.project-factory.module.service-accounts["prj-app-1/app-1-be"].google_service_account.service_account[0]:
|
||||||
account_id: app-1-be
|
account_id: app-1-be
|
||||||
|
create_ignore_already_exists: null
|
||||||
description: null
|
description: null
|
||||||
disabled: false
|
disabled: false
|
||||||
display_name: null
|
display_name: Terraform-managed.
|
||||||
project: test-pf-prj-app-1
|
project: test-pf-prj-app-1
|
||||||
timeouts: null
|
timeouts: null
|
||||||
module.project-factory.module.service-accounts["prj-app-1-app-1-fe"].google_service_account.service_account[0]:
|
? module.project-factory.module.service-accounts["prj-app-1/app-1-fe"].google_project_iam_member.project-roles["my-host-project-roles/compute.networkUser"]
|
||||||
|
: condition: []
|
||||||
|
project: my-host-project
|
||||||
|
role: roles/compute.networkUser
|
||||||
|
module.project-factory.module.service-accounts["prj-app-1/app-1-fe"].google_service_account.service_account[0]:
|
||||||
account_id: app-1-fe
|
account_id: app-1-fe
|
||||||
|
create_ignore_already_exists: null
|
||||||
description: null
|
description: null
|
||||||
disabled: false
|
disabled: false
|
||||||
display_name: Test app 1 frontend.
|
display_name: Test app 1 frontend.
|
||||||
project: test-pf-prj-app-1
|
project: test-pf-prj-app-1
|
||||||
timeouts: null
|
timeouts: null
|
||||||
module.project-factory.module.service-accounts["prj-app-2-app-2-be"].google_service_account.service_account[0]:
|
module.project-factory.module.service-accounts["prj-app-2/app-2-be"].google_service_account.service_account[0]:
|
||||||
account_id: app-2-be
|
account_id: app-2-be
|
||||||
|
create_ignore_already_exists: null
|
||||||
description: null
|
description: null
|
||||||
disabled: false
|
disabled: false
|
||||||
display_name: null
|
display_name: Terraform-managed.
|
||||||
project: test-pf-prj-app-2
|
project: test-pf-prj-app-2
|
||||||
timeouts: null
|
timeouts: null
|
||||||
|
|
||||||
|
@ -249,11 +307,11 @@ counts:
|
||||||
google_monitoring_notification_channel: 1
|
google_monitoring_notification_channel: 1
|
||||||
google_org_policy_policy: 1
|
google_org_policy_policy: 1
|
||||||
google_project: 3
|
google_project: 3
|
||||||
google_project_iam_member: 4
|
google_project_iam_member: 6
|
||||||
google_project_service: 11
|
google_project_service: 11
|
||||||
google_service_account: 3
|
google_service_account: 3
|
||||||
google_storage_project_service_account: 3
|
google_storage_project_service_account: 3
|
||||||
modules: 8
|
modules: 8
|
||||||
resources: 35
|
resources: 37
|
||||||
|
|
||||||
outputs: {}
|
outputs: {}
|
||||||
|
|
Loading…
Reference in New Issue