🐶
Terraform

Terraform: Assign Multiple IAM Roles to Service Account

By Ondřej Dolanský on 12/19/2024

Learn how to efficiently assign multiple Google Cloud IAM roles to a service account using Terraform for streamlined infrastructure management.

Terraform: Assign Multiple IAM Roles to Service Account

Table of Contents

Introduction

Managing roles and permissions for service accounts across multiple projects is a common task in Google Cloud Platform. Terraform provides a powerful way to automate this process. This article demonstrates how to use Terraform to efficiently assign multiple roles to a service account across different Google Cloud projects.

Step-by-Step Guide

  1. Define roles in a variable:
variable "project_roles" {
  type = map(list(string))
  default = {
    "project-id-1" = ["roles/storage.objectViewer", "roles/compute.networkViewer"]
    "project-id-2" = ["roles/pubsub.subscriber"]
  }
}
  1. Iterate through projects and roles:
resource "google_project_iam_member" "project_roles" {
  for_each = { for project, roles in var.project_roles : project => roles }
  project  = each.key
  role    = each.value
  member  = "serviceAccount:your-service-account@project-id.iam.gserviceaccount.com"
}

This code snippet iterates through the project_roles map and creates a google_project_iam_member resource for each role in each project.

Explanation:

  • We define a variable project_roles as a map, where keys are project IDs and values are lists of roles.
  • We use for_each to iterate over the project_roles map.
  • For each project and its associated roles, we create a google_project_iam_member resource.
  • The project argument is set to the project ID (the key of the map).
  • The role argument is set to the current role in the iteration.
  • The member argument specifies the service account and is constructed using the service account email format.

This approach allows you to assign multiple roles to a service account across different projects in a concise and manageable way.

Code Example

This Terraform code defines a variable to store project IDs and corresponding IAM roles. It then creates a Google service account and iterates through the variable to assign the specified roles to the service account for each project. This allows you to manage IAM permissions for a service account across multiple projects using a single configuration.

# Define the project roles variable
variable "project_roles" {
  type = map(list(string))
  default = {
    "project-id-1" = ["roles/storage.objectViewer", "roles/compute.networkViewer"]
    "project-id-2" = ["roles/pubsub.subscriber"]
  }
}

# Replace with your actual service account email
resource "google_service_account" "default" {
  account_id   = "sa-iam-example"
  disabled     = false
  display_name = "Example Service Account"
}

# Iterate through projects and roles
resource "google_project_iam_member" "project_roles" {
  for_each = { for project, roles in var.project_roles : project => roles }
  project  = each.key
  role    = each.value
  member  = "serviceAccount:${google_service_account.default.email}"
}

Explanation:

  1. Variable Definition:

    • The project_roles variable is defined as a map where:
      • Keys are project IDs (e.g., "project-id-1").
      • Values are lists of IAM role names (e.g., ["roles/storage.objectViewer", "roles/compute.networkViewer"]).
  2. Service Account:

    • This code assumes you have a service account created. Replace "serviceAccount:your-service-account@project-id.iam.gserviceaccount.com" with the actual email address of your service account.
  3. Resource Iteration:

    • The google_project_iam_member resource uses for_each to iterate over the project_roles map.
    • each.key represents the project ID (the key of the map).
    • each.value represents the list of roles associated with that project.
  4. Resource Configuration:

    • For each project and role combination, a google_project_iam_member resource is created.
    • project: Set to the current project ID (each.key).
    • role: Set to the current role being iterated (each.value).
    • member: Set to the service account that needs the roles assigned.

How to Use:

  1. Replace Placeholders:

    • Update the project_roles variable with your desired project IDs and roles.
    • Replace the service account placeholder with your actual service account email.
  2. Deploy with Terraform:

    • Run terraform apply to create the IAM bindings.

This code will efficiently grant the specified roles to your service account across the defined projects.

Additional Notes

Code Structure and Best Practices:

  • Modularity: For larger projects, consider splitting the code into separate modules for better organization and reusability. You could have a module for defining the project_roles variable and another for creating the IAM bindings.
  • Dynamic Service Account: Instead of hardcoding the service account email, you can make it more dynamic by using the google_service_account.default.email attribute if you're creating the service account within the same Terraform code.
  • Descriptive Naming: Use clear and descriptive names for variables and resources to improve code readability. For example, project_iam_roles could be a more informative name than project_roles.

Security Considerations:

  • Principle of Least Privilege: Always follow the principle of least privilege. Grant only the necessary roles to the service account and avoid overly permissive roles.
  • Service Account Key Management: If you're using a service account key, store it securely using tools like HashiCorp Vault or Google Cloud Secret Manager. Avoid hardcoding keys in your code.

Alternative Approaches:

  • google_project_iam_binding: Instead of google_project_iam_member, you can use google_project_iam_binding to assign roles to a group of members (users, service accounts) at once. This can be useful if you have multiple service accounts that need the same set of roles.
  • Terraform Workspaces: If you're managing multiple environments (e.g., development, staging, production), use Terraform workspaces to isolate your infrastructure changes and avoid conflicts.

Troubleshooting:

  • Terraform State: Ensure your Terraform state file is properly managed and backed up. Any accidental modifications to the state file can lead to unexpected behavior.
  • Error Messages: Pay close attention to Terraform error messages. They often provide valuable information for debugging issues.
  • Google Cloud Console: Use the Google Cloud Console to verify the IAM bindings and troubleshoot any permission problems.

Additional Tips:

  • Terraform Documentation: Refer to the official Terraform documentation for detailed information on the resources and features used in this code.
  • Google Cloud IAM Documentation: Familiarize yourself with Google Cloud IAM concepts and best practices for managing access control.
  • Version Control: Use a version control system like Git to track changes to your Terraform code and collaborate with others.

Summary

This code snippet demonstrates how to efficiently assign multiple IAM roles to a service account across different Google Cloud projects using Terraform.

Key Components:

  • project_roles Variable: A map variable defines project IDs as keys and a list of desired roles as values. This allows for a clear and organized way to manage role assignments across projects.
  • google_project_iam_member Resource: This resource grants IAM roles to members (in this case, a service account) at the project level.
  • for_each Meta-Argument: Used within the google_project_iam_member resource, it iterates through the project_roles map, dynamically creating a resource for each role in each project.

Functionality:

  1. The code iterates through each project ID and its corresponding list of roles defined in the project_roles variable.
  2. For each role within a project, it creates a google_project_iam_member resource.
  3. This resource assigns the specified role to the defined service account within the target project.

Benefits:

  • Concise and Manageable: Simplifies role assignment by defining all roles and projects in a single variable.
  • Dynamic and Scalable: Easily add or remove projects and roles by modifying the project_roles variable.
  • Improved Readability: The code is easier to understand and maintain compared to manually creating individual resources for each role assignment.

Conclusion

By using this Terraform configuration, you can streamline the process of managing IAM roles for service accounts across multiple Google Cloud projects, ensuring efficient and scalable management of permissions within your cloud environment. Remember to replace placeholder values with your specific details and follow security best practices for managing service accounts and their keys. This approach simplifies infrastructure management, improves code readability, and reduces the risk of errors compared to manual configuration.

References

Were You Able to Follow the Instructions?

😍Love it!
😊Yes
😐Meh-gical
😞No
🤮Clickbait