Skip to content

Commit

Permalink
Allow specifying arbitrary project roles for service accounts in proj…
Browse files Browse the repository at this point in the history
…ect factory (#1814)

* allow specifying arbitrary project roles for service accounts in project factory

* tfdoc
  • Loading branch information
ludoo authored Oct 26, 2023
1 parent 062ef1b commit 30d7126
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 25 deletions.
18 changes: 11 additions & 7 deletions blueprints/factories/project-factory/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ module "project-factory" {
data_path = "data"
}
}
# tftest modules=6 resources=15 files=prj-app-1,prj-app-2
# tftest modules=6 resources=17 files=prj-app-1,prj-app-2
```

```yaml
Expand All @@ -74,8 +74,12 @@ service_encryption_key_ids:
services:
- storage.googleapis.com
service_accounts:
app-1-be: {}
app-1-fe: {}
app-1-be:
iam_project_roles:
- roles/logging.logWriter
- roles/monitoring.metricWriter
app-1-fe:
display_name: "Test app 1 frontend."

# tftest-file id=prj-app-1 path=data/prj-app-1.yaml
```
Expand Down Expand Up @@ -104,10 +108,10 @@ shared_vpc_service_config:

| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [factory_data](variables.tf#L85) | Project data from either YAML files or externally parsed data. | <code title="object&#40;&#123;&#10; data &#61; optional&#40;map&#40;any&#41;&#41;&#10; data_path &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> || |
| [data_defaults](variables.tf#L17) | Optional default values used when corresponding project data from files are missing. | <code title="object&#40;&#123;&#10; billing_account &#61; optional&#40;string&#41;&#10; contacts &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; metric_scopes &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; parent &#61; optional&#40;string&#41;&#10; prefix &#61; optional&#40;string&#41;&#10; service_encryption_key_ids &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_perimeter_bridges &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; service_perimeter_standard &#61; optional&#40;string&#41;&#10; services &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; shared_vpc_service_config &#61; optional&#40;object&#40;&#123;&#10; host_project &#61; string&#10; service_identity_iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_iam_grants &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; &#125;&#41;, &#123; host_project &#61; null &#125;&#41;&#10; tag_bindings &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; service_accounts &#61; optional&#40;map&#40;object&#40;&#123;&#10; default_roles &#61; optional&#40;bool, true&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [data_merges](variables.tf#L45) | Optional values that will be merged with corresponding data from files. Combines with `data_defaults`, file data, and `data_overrides`. | <code title="object&#40;&#123;&#10; contacts &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; metric_scopes &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; service_encryption_key_ids &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_perimeter_bridges &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; services &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; tag_bindings &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; service_accounts &#61; optional&#40;map&#40;object&#40;&#123;&#10; default_roles &#61; optional&#40;bool, true&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [data_overrides](variables.tf#L64) | Optional values that override corresponding data from files. Takes precedence over file data and `data_defaults`. | <code title="object&#40;&#123;&#10; billing_account &#61; optional&#40;string&#41;&#10; contacts &#61; optional&#40;map&#40;list&#40;string&#41;&#41;&#41;&#10; parent &#61; optional&#40;string&#41;&#10; prefix &#61; optional&#40;string&#41;&#10; service_encryption_key_ids &#61; optional&#40;map&#40;list&#40;string&#41;&#41;&#41;&#10; service_perimeter_bridges &#61; optional&#40;list&#40;string&#41;&#41;&#10; service_perimeter_standard &#61; optional&#40;string&#41;&#10; tag_bindings &#61; optional&#40;map&#40;string&#41;&#41;&#10; services &#61; optional&#40;list&#40;string&#41;&#41;&#10; service_accounts &#61; optional&#40;map&#40;object&#40;&#123;&#10; default_roles &#61; optional&#40;bool, true&#41;&#10; &#125;&#41;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [factory_data](variables.tf#L88) | Project data from either YAML files or externally parsed data. | <code title="object&#40;&#123;&#10; data &#61; optional&#40;map&#40;any&#41;&#41;&#10; data_path &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> || |
| [data_defaults](variables.tf#L17) | Optional default values used when corresponding project data from files are missing. | <code title="object&#40;&#123;&#10; billing_account &#61; optional&#40;string&#41;&#10; contacts &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; metric_scopes &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; parent &#61; optional&#40;string&#41;&#10; prefix &#61; optional&#40;string&#41;&#10; service_encryption_key_ids &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_perimeter_bridges &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; service_perimeter_standard &#61; optional&#40;string&#41;&#10; services &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; shared_vpc_service_config &#61; optional&#40;object&#40;&#123;&#10; host_project &#61; string&#10; service_identity_iam &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_iam_grants &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; &#125;&#41;, &#123; host_project &#61; null &#125;&#41;&#10; tag_bindings &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; service_accounts &#61; optional&#40;map&#40;object&#40;&#123;&#10; display_name &#61; optional&#40;string, &#34;Terraform-managed.&#34;&#41;&#10; iam_project_roles &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [data_merges](variables.tf#L46) | Optional values that will be merged with corresponding data from files. Combines with `data_defaults`, file data, and `data_overrides`. | <code title="object&#40;&#123;&#10; contacts &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; metric_scopes &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; service_encryption_key_ids &#61; optional&#40;map&#40;list&#40;string&#41;&#41;, &#123;&#125;&#41;&#10; service_perimeter_bridges &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; services &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; tag_bindings &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; service_accounts &#61; optional&#40;map&#40;object&#40;&#123;&#10; display_name &#61; optional&#40;string, &#34;Terraform-managed.&#34;&#41;&#10; iam_project_roles &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [data_overrides](variables.tf#L66) | Optional values that override corresponding data from files. Takes precedence over file data and `data_defaults`. | <code title="object&#40;&#123;&#10; billing_account &#61; optional&#40;string&#41;&#10; contacts &#61; optional&#40;map&#40;list&#40;string&#41;&#41;&#41;&#10; parent &#61; optional&#40;string&#41;&#10; prefix &#61; optional&#40;string&#41;&#10; service_encryption_key_ids &#61; optional&#40;map&#40;list&#40;string&#41;&#41;&#41;&#10; service_perimeter_bridges &#61; optional&#40;list&#40;string&#41;&#41;&#10; service_perimeter_standard &#61; optional&#40;string&#41;&#10; tag_bindings &#61; optional&#40;map&#40;string&#41;&#41;&#10; services &#61; optional&#40;list&#40;string&#41;&#41;&#10; service_accounts &#61; optional&#40;map&#40;object&#40;&#123;&#10; display_name &#61; optional&#40;string, &#34;Terraform-managed.&#34;&#41;&#10; iam_project_roles &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |

## Outputs

Expand Down
7 changes: 4 additions & 3 deletions blueprints/factories/project-factory/factory.tf
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,10 @@ locals {
service_accounts = flatten([
for k, v in local.projects : [
for name, opts in v.service_accounts : {
project = k
name = name
options = opts
project = k
name = name
display_name = try(opts.display_name, "Terraform-managed.")
iam_project_roles = try(opts.iam_project_roles, null)
}
]
])
Expand Down
18 changes: 6 additions & 12 deletions blueprints/factories/project-factory/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,10 @@ module "service-accounts" {
for_each = {
for k in local.service_accounts : "${k.project}-${k.name}" => k
}
name = each.value.name
project_id = module.projects[each.value.project].project_id
iam_project_roles = (
try(each.value.options.default_roles, null) == null
? {}
: {
(module.projects[each.value.project].project_id) = [
"roles/logging.logWriter",
"roles/monitoring.metricWriter"
]
}
)
project_id = module.projects[each.value.project].project_id
name = each.value.name
display_name = each.value.display_name
iam_project_roles = each.value.iam_project_roles == null ? {} : {
(module.projects[each.value.project].project_id) = each.value.iam_project_roles
}
}
9 changes: 6 additions & 3 deletions blueprints/factories/project-factory/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ variable "data_defaults" {
tag_bindings = optional(map(string), {})
# non-project resources
service_accounts = optional(map(object({
default_roles = optional(bool, true)
display_name = optional(string, "Terraform-managed.")
iam_project_roles = optional(list(string))
})), {})
})
nullable = false
Expand All @@ -54,7 +55,8 @@ variable "data_merges" {
tag_bindings = optional(map(string), {})
# non-project resources
service_accounts = optional(map(object({
default_roles = optional(bool, true)
display_name = optional(string, "Terraform-managed.")
iam_project_roles = optional(list(string))
})), {})
})
nullable = false
Expand All @@ -75,7 +77,8 @@ variable "data_overrides" {
services = optional(list(string))
# non-project resources
service_accounts = optional(map(object({
default_roles = optional(bool, true)
display_name = optional(string, "Terraform-managed.")
iam_project_roles = optional(list(string))
})))
})
nullable = false
Expand Down

0 comments on commit 30d7126

Please sign in to comment.