Deployment strategies for Google Cloud Identity and Access Management using Terragrunt. lets get on the same page with our terminology: - [Terraform](https://www.terraform.io/) - a popular ~~open source~~ Infrastructure as code tool. - [Terragrunt](https://terragrunt.gruntwork.io/) - a powerful and popular tool for managing terraform environments and module versions. - Terragrunt hcl - Terragrunt's hashicorp configuration language files. - [Google Cloud IAM](https://cloud.google.com/iam) - Fine-grained access control and visibility for centrally managing cloud resources in Google Cloud. <br> ### What Informs our decision ##### Google Cloud Hierarchy Google Cloud allows you to assign roles at 4 different layers. ![[Google_IAM_hierarchy.png]] As the diagram shows, if you assign a role at the Organisation level, this will be inherited by all resources. If you assign a role the Project level then they will only be inherited by the resources in that project. Simple. <br> ##### Google Cloud API Split The apis called when making IAM changes is split differently. With all resource IAM being managed in their respective api. With Organisation, Folder and Project IAM being managed within the separate `iam.googleapis.com` api. ![[Google_Cloud_api_split.png]] This is reflected in the Google Cloud Provider Terraform resources hierarchy too. | Resource specific Terraform resources under the resources heading (in this example Cloud Run) | Organisation, Folder and Project placed under the Cloud Platform heading | | --- | --- | | ![[Google_Cloud_cloud_run_Terraform.png]] | ![[Google_Cloud_cloud_platform_Terraform.png]] | <br> ##### Project as the default boundary Projects in Google Cloud are 1st class citizens. They are the foundation of many companies use of Google Cloud. Many assignments are here for convenience when building out infrastructure. Google Cloud themselves treat it as the default IAM boundary, with [Default Service Accounts](https://cloud.google.com/iam/docs/service-account-types#default) being assigned `role/Editor` at the Project level by out of the box. <br> ##### Identity Types Google Cloud identities can be broadly divided into 2 types. 1. <mark style="background: #ADCCFFA6;">User</mark> - a User identity is one that is attached to a living breathing human and it represents them. When an action is logged against these accounts, we assume it was a non automated action instigated by the named owner. 2. <mark style="background: #ADCCFFA6;">Service</mark> - a Service identity is an identity attached to an application or compute workload. Actions logged to these identities should be attributed to the automated actions of the application or compute workload they are attached to. <br> ### The service / user split In the first instance we can begin to organise what IAM configuration goes where by splitting along the Identity type. #### Service Identity Assignments Starting with the simpler, all assignments that provide an application its access should be kept alongside the application terraform within its module. The makes it easier to manage the service as a whole. And gives engineers the ability to make informed decisions regarding the application being adding into Google Cloud. ```plaintext └── app_module ├── main.tf │ ├── outputs.tf │ ├── variables.tf │ └── iam.tf ``` #### User Identity Assignments All assignments that provide users with access in Google Cloud should be collected together. I think it makes most sense to have it form part of your infrastructure Terraform. > <mark style="background: #ADCCFFA6;">Why with infrastructure?</mark> I see the Google Cloud Terraform modules as part of the platform teams Google Cloud offering to their developers. The access to this offering is a core part of it and therefore makes sense to sit alongside it. Depending on how you structure Terragrunt, will impact what variables that are provided when applied. So some thought should go into where in the infrastructure Terragrunt you place it. <br> ### User Identity IAM Organised With Terragrunt One of the many goals of importing User IAM into terraform is to create a source of truth and a simple location for developers and admin to manage the changing assignments. Unfortunately organising your User IAM using into terragrunt structure requires us to make some design choices. Deciding if we prioritise adhering to the infrastructure hierarchy or if we try and group all the User assignments together, distancing it from the other infrastructure. My design choices will be rationalised below and I will use the example layout (shown below) taken from the Terragrunt [documentation](https://terragrunt.gruntwork.io/docs/features/keep-your-terraform-code-dry/) on "Keep your Terraform DRY". ```plaintext └── google_cloud ├── prod │ ├── app │ │ └── terragrunt.hcl │ ├── mysql │ │ └── terragrunt.hcl │ └── vpc │ └── terragrunt.hcl ├── qa │ ├── app │ │ └── terragrunt.hcl │ ├── mysql │ │ └── terragrunt.hcl │ └── vpc │ └── terragrunt.hcl └── stage ├── app │ └── terragrunt.hcl ├── mysql │ └── terragrunt.hcl └── vpc └── terragrunt.hcl ``` <br> #### Merging Project and Resource Assignments One of my more contentious choices includes merging Project and Resource assignments into a single IAM directory in the projects terragrunt directory. ``` └── google_cloud ├── prod │ ├── app │ │ └── terragrunt.hcl │ ├── mysql │ │ └── terragrunt.hcl │ ├── vpc │ │ └── terragrunt.hcl │ └── iam │ ├── project │ │ └── terragrunt.hcl │ ├── storage │ │ └── terragrunt.hcl │ └── compute │ └── terragrunt.hcl ... ``` This is an important merge as it brings together the popular and [[Google Cloud IAM Architecture using Terragrunt#Project as the default boundary| default]] Project assigned IAM. With the granular and purposeful Resource assigned IAM. This draws a line between the convenience of keeping as much of the User IAM in one place, whilst sticking to the hierarchical structure of Google Cloud and Terragrunt Configuration. <br> #### Folder and Organisation Assignments I have less of an opinion on the placement of Organisation and Folder IAM assignments as they arent used or changed as often. I have 2 suggestions and theydepend a lot on how much your organisation has adopted Folders into your environment and where you keep other Organisation level configuration <br> ##### Following the hierarchy If you have organised your Google Cloud using folders and replicated this in your terragrunt, it might make sense to adhere to this structure with here too. Which would put a single IAM directory at the Organisation level, Folder level and then a final one with both Resource and Project in the Project level. ``` └── google_cloud ├── live │ ├── prod │ │ ├── app │ │ │ └── terragrunt.hcl │ │ ├── mysql │ │ │ └── terragrunt.hcl │ │ ├── vpc │ │ │ └── terragrunt.hcl │ │ └── iam │ │ ├── project │ │ │ └── terragrunt.hcl │ │ ├── storage │ │ │ └── terragrunt.hcl │ │ └── compute │ │ └── terragrunt.hcl │ │ │ ├── iam │ │ └── terragrunt.hcl │ ... │ ├── iam │ └── terragrunt.hcl │ ... ``` <br> ##### Folder and Organisation Merge I suspect a number of companies with a smaller or flatter Google Cloud hierarchy will be tempted to merge Folder and Organisation IAM assignments together. ```plaintext └── company_wide └── google_cloud ├── iam │ ├── organisation │ │ └── terragrunt.hcl │ └── folder │ └── terragrunt.hcl ├── live │ ├── ... │ ... │ ... ``` In this example we have a `company_wide` directory that contains `google_cloud` configuration. and within `google_cloud` we have both organisation and folder hcl files in a IAM directory. Even though this sorta breaks the terragrunt hierarchy schema, it keeps all the non project/resource IAM together. <br> #### How does it all look? I visualise things better when I can see all the parts. So how does this look in its entirety? ##### Folder and Organisation Merge ```plaintext └── company_wide ├── google_cloud │ ├── iam │ │ ├── organisation │ │ │ └── terragrunt.hcl │ │ └── folder │ │ └── terragrunt.hcl │ └── live │ ├── prod │ │ ├── app │ │ │ └── terragrunt.hcl │ │ ├── mysql │ │ │ └── terragrunt.hcl │ │ ├── vpc │ │ │ └── terragrunt.hcl │ │ └── iam │ │ ├── project │ │ │ └── terragrunt.hcl │ │ ├── storage │ │ │ └── terragrunt.hcl │ │ └── compute │ │ └── terragrunt.hcl │ ├── qa │ │ ├── app │ │ │ └── terragrunt.hcl │ │ ├── mysql │ │ │ └── terragrunt.hcl │ │ ├── vpc │ │ │ └── terragrunt.hcl │ │ └── iam │ │ ├── project │ │ │ └── terragrunt.hcl │ │ ├── storage │ │ │ └── terragrunt.hcl │ │ └── compute │ │ └── terragrunt.hcl │ └── stage │ ├── app │ │ └── terragrunt.hcl │ ├── mysql │ │ └── terragrunt.hcl │ ├── vpc │ │ └── terragrunt.hcl │ └── iam │ ├── project │ │ └── terragrunt.hcl │ ├── storage │ │ └── terragrunt.hcl │ └── compute │ └── terragrunt.hcl │ │ │ │ │ └── cicd └── terragrunt.hcl ``` ##### Follow the Hierarchy ```plaintext └── company_wide ├── google_cloud │ ├── iam │ │ └── terragrunt.hcl │ └── live │ ├── iam │ │ └── terragrunt.hcl │ ├── prod │ │ ├── app │ │ │ └── terragrunt.hcl │ │ ├── mysql │ │ │ └── terragrunt.hcl │ │ ├── vpc │ │ │ └── terragrunt.hcl │ │ └── iam │ │ ├── project │ │ │ └── terragrunt.hcl │ │ ├── storage │ │ │ └── terragrunt.hcl │ │ └── compute │ │ └── terragrunt.hcl │ ├── qa │ │ ├── app │ │ │ └── terragrunt.hcl │ │ ├── mysql │ │ │ └── terragrunt.hcl │ │ ├── vpc │ │ │ └── terragrunt.hcl │ │ └── iam │ │ ├── project │ │ │ └── terragrunt.hcl │ │ ├── storage │ │ │ └── terragrunt.hcl │ │ └── compute │ │ └── terragrunt.hcl │ └── stage │ ├── app │ │ └── terragrunt.hcl │ ├── mysql │ │ └── terragrunt.hcl │ ├── vpc │ │ └── terragrunt.hcl │ └── iam │ ├── project │ │ └── terragrunt.hcl │ ├── storage │ │ └── terragrunt.hcl │ └── compute │ └── terragrunt.hcl │ │ │ │ │ └── cicd └── terragrunt.hcl ``` <br> ### Conclusion Thats it! I think deciding between those 2 depends on how big your organisation is and how much you have invested in your Google Cloud folder structure. I would lean towards [[Google Cloud IAM Architecture using Terragrunt#Folder and Organisation Merge| Folder and Organisation merge method]] as I prefer keeping the assignments in as few places as possible. Thanks for reading :)