Day 16/30: Mastering AWS IAM User Management with Terraform

Published: (December 11, 2025 at 08:43 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

Architecture

Architecture diagram

IAM is the cornerstone for managing users and permissions in large organizations. This demo shows how to manage IAM users, groups, and memberships with Terraform—an AWS‑centric analogue of Azure AD user management—while demonstrating Terraform’s iteration constructs (for_each, for expressions, conditional filtering).

What This Demo Does

  • Retrieves AWS Account Information – Gets the current AWS Account ID.
  • Reads User Data from CSV – Loads user information from a CSV file.
  • Creates IAM Users – Automatically creates users with a consistent naming convention.
  • Sets Up Login Profiles – Configures console access with mandatory password reset.
  • Creates IAM Groups – Sets up organizational groups (Education, Managers, Engineers).
  • Manages Group Memberships – Assigns users to groups based on their attributes.

Mini Project Overview

Goal: Bulk‑create 26 IAM users (based on users.csv).

Key Features

  • Dynamic group assignment (Education, Engineers, Managers).
  • Console login with temporary passwords.
  • S3 remote backend for state management.
  • Username format: first initial + last name (e.g., Michael Scott → mscott).

What Gets Created

  • 26 IAM Users with console access.
  • 3 IAM Groups (Education, Managers, Engineers).
  • Group memberships derived from user attributes.
  • User tags containing metadata (DisplayName, Department, JobTitle).

Project Setup

day16/
├── backend.tf          # S3 backend configuration for state
├── provider.tf         # AWS provider configuration
├── versions.tf         # Terraform version and required providers
├── main.tf             # Main user creation logic
├── groups.tf           # IAM groups and membership management
├── users.csv           # User data source

CSV Processing

Terraform’s csvdecode() function converts the CSV file into a list of maps, which can be iterated over.

CSV format

first_name,last_name,department,job_title
Michael,Scott,Education,Regional Manager
Dwight,Schrute,Sales,Assistant to the Regional Manager

Local variable

locals {
  users = csvdecode(file("users.csv"))
}

Place users.csv in the same directory as the Terraform configuration.

IAM User Creation

resource "aws_iam_user" "users" {
  for_each = { for user in local.users : user.first_name => user }

  name = lower("${substr(each.value.first_name, 0, 1)}${each.value.last_name}")
  path = "/users/"

  tags = {
    DisplayName = "${each.value.first_name} ${each.value.last_name}"
    Department  = each.value.department
    JobTitle    = each.value.job_title
  }
}
  • Username: {first_initial}{last_name} (lower‑cased).
  • Tags propagate department and job title for later group filtering.

Console Login Profiles

resource "aws_iam_user_login_profile" "users" {
  for_each = aws_iam_user.users

  user                     = each.value.name
  password_reset_required = true

  lifecycle {
    ignore_changes = [password_reset_required, password_length]
  }
}

Creates console login profiles with a forced password reset on first login. The lifecycle block prevents unnecessary recreation when the password changes.

Create Groups and Memberships

Create IAM Groups

resource "aws_iam_group" "education" {
  name = "Education"
  path = "/groups/"
}

resource "aws_iam_group_membership" "education_members" {
  name  = "education-group-membership"
  group = aws_iam_group.education.name

  users = [
    for user in aws_iam_user.users : user.name
    if user.tags.Department == "Education"
  ]
}

Similar blocks can be created for Engineers and Managers. The for expression with an if clause filters users based on the Department tag.

Manager Group Logic (Advanced)

resource "aws_iam_group_membership" "managers_members" {
  name  = "managers-group-membership"
  group = aws_iam_group.managers.name

  users = [
    for user in aws_iam_user.users :
    user.name
    if contains(keys(user.tags), "JobTitle") &&
       can(regex("Manager|CEO", user.tags.JobTitle))
  ]
}

The can() function safely checks for the JobTitle key and matches titles containing “Manager” or “CEO”, assigning those users to the Managers group.

Execution Commands

# Initialize Terraform (download providers, configure backend)
terraform init

# Review the planned changes
terraform plan

# Apply the configuration
terraform apply

Running the configuration provisions 58 resources in total:

  • 26 IAM Users
  • 26 IAM User Login Profiles
  • 3 IAM Groups
  • 3 IAM Group Memberships

Happy Terraforming!

Back to Blog

Related posts

Read more »