A few months ago, I was working on a Terraform module to manage all the roles and their permissions in our AWS accounts. This on the surface seems like a straight forward project, but there was a curveball that required some research, trial & error, and finesse to address.

The teams/permissions were not consistent across the AWS accounts. TeamA might have read/write access to s3 in account A, but only have read access to s3 in account B. Team A does not even exist in account C. Multiply this conundrum by 10+ teams across 10+ accounts.

In thinking about how to best tackle this issue, there were a couple bad ways to solve this that immediately come to mind:

  • Brute force — define the permission for every team in every environment.

This approach is horrible. It would have been tedious, hard to maintain, and the amount of repeated code would have been astronomical, but it would have worked.

  • Ask the business to standardize permissions.

This on the surface seems reasonable but it is not. First, your code is dictating business logic/function. Secondly, the principle of least privilege means that you should only allow enough access to perform the required job. Third, there are AWS accounts which certain teams should not have access to (e.g. secops, networking, & IT accounts). Last, the business would never agree to it.


The right approach needed to something that could account for all the variability across the accounts. Additionally, the end result needed to be clean, easy to maintain/update, and easy to use without requiring a deep understanding of how the module worked.

What I envisioned was something that allowed me to define the permissions as part of the config. This design addressed the variability issues across the accounts by allowing me to define the permissions per iteration of the module. Additionally, it was easy to understand and manage (even if you didn’t know what the module was doing).

This looked something like:

module usermap {
  source = "../modules/example-module"

  role_map_aws_policies = {
    TeamA = ["AdministratorAccess"]
    TeamB = ["AmazonS3FullAccess", "AmazonEC2FullAccess"]
    TeamC = ["AdministratorAccess"]
    TeamD = ["ReadOnlyAccess", "AmazonInspectorFullAccess"]
  }
}

#aws #aws-iam #automating-aws-iam #terraform #terraform-modules

Terraform: Iterating through a Map of Lists To Define AWS Roles and Permissions
2.75 GEEK