/** * # iam-user module * Creates iam user. If new group will be created for this user, use custom_iam_policy_json to * attach iam policy to the group. You can also use attach_iam_policies to attach AWS-managed policies. * * ## Security requirements * IAM policies must be attached to iam group, not directly to iam user. * This module requires a new group be created, or an existing group for the user to be added to. * * User credentials are saved in secretsmanager, which must be encrypted with CMK */ resource "aws_iam_group" "group" { count = var.create_group_name != null ? 1 : 0 name = var.create_group_name } resource "aws_iam_user" "user" { name = var.user_name force_destroy = true } resource "aws_iam_group_membership" "membership" { group = coalesce(var.create_group_name, var.existing_group_name) users = [aws_iam_user.user.name] name = "${var.user_name} membership" lifecycle { precondition { condition = var.create_group_name != null || var.existing_group_name != null error_message = "You must provide either 'create_group_name' or 'existing_group_name'." } precondition { condition = !(var.create_group_name != null && var.existing_group_name != null) error_message = "You cannot provide both 'create_group_name' and 'existing_group_name' at the same time." } } } resource "aws_iam_user_login_profile" "profile" { count = var.enable_console_access ? 1 : 0 user = var.user_name } resource "aws_iam_policy" "policy" { name_prefix = var.user_name description = "Policy for ${var.user_name}" policy = data.aws_iam_policy_document.policy.json } resource "aws_iam_group_policy_attachment" "policy" { depends_on = [aws_iam_group.group] # attach policy only to new group group = var.create_group_name policy_arn = aws_iam_policy.policy.arn } resource "aws_iam_group_policy_attachment" "ManagedPolicies" { for_each = toset(var.attach_iam_policies) group = coalesce(var.create_group_name, var.existing_group_name) policy_arn = each.value } resource "aws_iam_access_key" "AccessKey" { count = var.create_access_key ? 1 : 0 user = aws_iam_user.user.name } module "UserCredentials" { source = "../secretsmanager-2025" name = "${var.user_name}-IamUser-Credentials" description = "Credentials for iam user ${var.user_name}" generate_secret = false secret = jsonencode( { "ConsolePassword" : var.enable_console_access ? aws_iam_user_login_profile.profile[0].password : "NotSet" "AccessKeyId" : var.create_access_key ? aws_iam_access_key.AccessKey[0].id : "NotSet" "SecretKey" : var.create_access_key ? aws_iam_access_key.AccessKey[0].secret : "NotSet" } ) kms_key_id = var.secretsmanager_kms_arn } data "aws_iam_policy_document" "policy" { source_policy_documents = [var.custom_iam_policy_json] statement { sid = "ManageOwnCredentials" actions = [ "iam:ChangePassword", "iam:UpdateLoginProfile", "iam:CreateAccessKey", "iam:DeleteAccessKey", "iam:ListAccessKeys", "iam:CreateVirtualMFADevice", "iam:EnableMFADevice", "iam:ListMFA*", "iam:ListVirtualMFA*", "iam:ResyncMFADevice", "iam:GetUser" ] effect = "Allow" resources = ["arn:aws:iam::*:user/$${aws:username}"] } }