
Naming Terraform resources is quite a challenge. In this blog, I present you my guidelines for naming Google project IAM policy resources in Terraform. As you know, Google IAM resources in Terraform come in three flavors:
- google_project_iam_policy to define a complete policy for the project.
- google_project_iam_binding to define all the members of a single role.
- google_project_iam_member to define a single role binding for a single principal.
In this blog I will present a naming convention for each of these.
naming convention for google_project_iam_policy
This IAM policy for a Google project is a singleton. Choose a name which reflects this, we recommend to use default
:
resource "google_project_iam_policy" "default" {
policy_data = ...
}
naming convention for google_project_iam_binding
The name for a google_project_iam_binding is the name of the role, minus the roles prefix and converted to snake case. For instance:
resource "google_project_iam_binding" "iap_tunnel_resource_accessor" {
role = "roles/iap.tunnelResourceAccessor"
members = [
...
]
}
As a google_project_iam_binding is always for a specific role, the roles prefix does not add any information.
naming convention for google_project_iam_member
The name for a google_project_iam_member is the name of the principal, converted to snake case. The following table shows a number of examples:
principal | resource name |
---|---|
allUsers | all_users |
allAuthenticatedUsers | all_authenticated_users |
domain:binx.io | binx_io |
domain:xebia.com | xebia_com |
group:admin@binx.io | admin_binx_io |
group:admin@xebia.com | admin_xebia_com |
user:mark@binx.io | mark_binx_io |
user:mark@xebia.com | mark_xebia_com |
serviceAccount:iap-accessor@my-project.iam-gserviceaccount.com | iap_accessor |
serviceAccount:iap-accessor@other-project.iam-gserviceaccount.com | iap_accessor_other_project |
If there is a name space conflict, prefix the type name. For instance if there is a user admin
and a service account with the same name, use user_admin
and service_account_admin
. Furthermore, we use the for_each construct to bind the roles to minimizes clutter. as shown in the examples below:
resource "google_project_iam_member" "mark_van_holsteijn_binx_io" {
for_each = toset([
"roles/iap.tunnelResourceAccessor",
"roles/compute.osLogin",
])
member = "user:markvanholsteijn@binx.io"
role = each.key
}
resource "google_project_iam_member" "iap_accessor" {
for_each = toset([
"roles/iap.tunnelResourceAccessor",
"roles/compute.osLogin",
])
member = "serviceAccount:iap-accessor@my-project.iam.gserviceaccount.com"
role = each.key
}
As a google_project_iam_member is always for a specific principal, it is nice to have the name of the principal as identifier for the resource.
naming convention for a single google_project_iam_member
If you want to specify a single member binding, you use the name of the principal followed by the role name converted to snake case. For instance:
resource "google_project_iam_member" "iap_accessor_iap_tunnel_resource_accessor" {
member = "serviceAccount:iap-accessor@my-project.iam.gserviceaccount.com"
role = "roles/iap.tunnelResourceAccessor"
}
We recommend against this form, as it is very verbose. Furthermore, it is highly unlikely that a principal will only need to be bound to a single role.
Which resource to use?
So, which resource do you use in practice? Of course, the google_project_iam_policy is the most secure and definite specification. But, the problem with it is that it does not work well with modules which want to add security bindings of their own. The same problem may occurs to a lesser extend with the google_project_iam_binding. Therefore, we recommend to use the resource google_project_iam_member to define the google IAM policies in your project.
Conclusion
We recommend to use the google_project_iam_member resource to define your IAM policy definitions in Terraform. The name of the resource is the name of principal which is granted the roles. The roles are bound using the for_each construct.
Image by PublicDomainPictures from Pixabay