Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 2 additions & 59 deletions google_permissions/ADDING_NEW_ROLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,67 +6,10 @@ For most things, it is assumed that you'll start with the [core resource set](./

### TL;DR

- update local list matching your role `folder_additional_roles` or `project_additional_roles` in [variables.tf](./variables.tf)
- add appropriate resource block to [other_roles.tf](./other_roles.tf)
Add new role to `local.allowed_folder_roles`, `local.allowed_nonprod_roles`, and/or `local.allowed_prod_roles` in [other_roles.tf](./other_roles.tf) depending on the desired scope of the role.

### Adding New Role

You will work with two files in adding a resource: `variables.tf` and `other_roles.tf`.

In [variables.tf](./variables.tf), you want to add your new role to one of the locals->*_additional_roles variable depending on the role type itself (folder or project):

```hcl
locals {
// This is a list of all the roles that we support in this module
// IN ADDITION to the roles added via the core rules in main.tf
// and that already have have existing supporting resource definitions.
folder_additional_roles = [
"roles/bigquery.jobUser",
]
project_additional_roles = [
"roles/automl.editor",
"roles/cloudtranslate.editor",
"roles/storage.objectAdmin",
"roles/translationhub.admin",
"roles/storage.admin",
"roles/cloudsql.admin"
]
}
```

That's it for that file. We use this list to validate user input.
### Implementation details

The other thing to notice here is that three types of input lists are declared - folder, prod, and non_prod. This will allow the module user to set which role but also at which level of permissions. Why?

This gets a little convoluted as they represent two different things -- folder level roles and project level roles (of two types: prod and non-prod -- or at least those are the two arbitrary types that we use.). However, the roles provided by Google Cloud fall into those same two distinctions: hierarchy where folders contain projects and roles are available at folder or project level. So, in setting them in our environments, we have to understand which are folder level and which are project level. Fortunately, as we define or update our other roles available in [the file](./other_roles.tf), we'll see this explicitly called out.

We see the resource declared here as type `google_folder_iam_binding`, and we create this role by checking if it was in the input list `var.folder_roles`. We also have to use the appropriate folder_id.

```hcl
resource "google_folder_iam_binding" "bq_job_user" {
count = contains(var.folder_roles, "roles/bigquery.jobUser") && !var.admin_only ? 1 : 0
folder = var.google_folder_id
role = "roles/bigquery.jobUser"
members = setunion(
module.viewers_workgroup.members,
module.developers_workgroup.members
)
}
```

Similarly, a project role is of type `google_project_iam_binding`. Additionally, this requires another piece of information - which environment. This then corresponds to which variable list to check it against. In the case below, we see we check the role name against the `var.nonprod_roles` list. Also, we apply it to the variable input named `var.google_nonprod_project_id`

```hcl
resource "google_project_iam_binding" "editor_nonprod" {
count = contains(var.nonprod_roles, "roles/editor") && !var.admin_only && var.google_nonprod_project_id != "" ? 1 : 0
project = var.google_nonprod_project_id
role = "roles/editor"
members = module.developers_workgroup.members
}
```






45 changes: 45 additions & 0 deletions google_permissions/other_roles.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,51 @@
//
*/

locals {
allowed_folder_roles = [
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there's a high probability we keep these lists synced it makes sense to deduplicate here. But that gets into the general structure of this module which is not a topic we want to get into.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think as part of the refactoring of existing roles into using local.allowed_folder_roles, local.allowed_nonprod_roles, and local.allowed_prod_roles that would be a good time to remove this list

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Er whoops, misread the context. I kept the original design where roles could be allowed at separate levels

"roles/datastore.user",
]
allowed_nonprod_roles = [
"roles/datastore.user",
]
allowed_prod_roles = [
"roles/datastore.user",
]
}

resource "google_folder_iam_binding" "developers_folder_roles" {
for_each = setintersection(
local.allowed_folder_roles,
[for role in var.folder_roles : role if !var.admin_only],
)

folder = var.google_folder_id
role = each.value
members = module.developers_workgroup.members
}

resource "google_project_iam_binding" "developers_nonprod_roles" {
for_each = setintersection(
local.allowed_nonprod_roles,
[for role in var.nonprod_roles : role if !var.admin_only && var.google_nonprod_project_id != ""],
)

project = var.google_nonprod_project_id
role = each.value
members = module.developers_workgroup.members
}

resource "google_project_iam_binding" "developers_prod_roles" {
for_each = setintersection(
local.allowed_prod_roles,
[for role in var.prod_roles : role if !var.admin_only && var.google_prod_project_id != ""],
)

project = var.google_prod_project_id
role = each.value
members = module.developers_workgroup.members
}

resource "google_folder_iam_binding" "bq_job_user" {
//
// NOTE: this uses bq_data_viewer as well as the next resource block so that those we grant data viewer
Expand Down
6 changes: 3 additions & 3 deletions google_permissions/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ output "validate_folder_roles" {
value = null
precondition {
condition = alltrue([
for x in var.folder_roles : contains(local.folder_additional_roles, x)
for x in var.folder_roles : contains(local.folder_additional_roles, x) || contains(local.allowed_folder_roles, x)
])
error_message = "You have specified an invalid folder role."
}
Expand All @@ -52,7 +52,7 @@ output "validate_prod_roles" {
value = null
precondition {
condition = alltrue([
for x in var.prod_roles : contains(local.project_additional_roles, x)
for x in var.prod_roles : contains(local.project_additional_roles, x) || contains(local.allowed_prod_roles, x)
])
error_message = "You have specified an invalid prod role."
}
Expand All @@ -62,7 +62,7 @@ output "validate_nonprod_roles" {
value = null
precondition {
condition = alltrue([
for x in var.nonprod_roles : contains(local.project_additional_roles, x)
for x in var.nonprod_roles : contains(local.project_additional_roles, x) || contains(local.allowed_nonprod_roles, x)
])
error_message = "You have specified an invalid nonprod role."
}
Expand Down
Loading