1
0

feat: new iam-user module and secretsmanager-2025 module

This commit is contained in:
xpk
2026-04-25 21:42:02 +08:00
parent 5fd8aa807f
commit 2ef2ad1571
12 changed files with 473 additions and 140 deletions
@@ -1,27 +1,90 @@
resource "aws_iam_user" "iam-user" {
name = var.iam-user-name
/**
* # 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_access_key" "iam-user-access-key" {
count = var.create-access-key ? 1 : 0
user = aws_iam_user.iam-user.name
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_policy" "iam-user-policy" {
count = var.iam-user-policy != "" ? 1 : 0
name = var.iam-user-policy-name
user = aws_iam_user.iam-user.name
policy = var.iam-user-policy
resource "aws_iam_user_login_profile" "profile" {
count = var.enable_console_access ? 1 : 0
user = var.user_name
}
resource "aws_iam_user_policy" "iam-user-selfservice-policy" {
name = "SelfServicePermissions"
user = aws_iam_user.iam-user.name
policy = data.aws_iam_policy_document.user-policy.json
resource "aws_iam_policy" "policy" {
name_prefix = var.user_name
description = "Policy for ${var.user_name}"
policy = data.aws_iam_policy_document.policy.json
}
data "aws_iam_policy_document" "user-policy" {
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"
@@ -42,58 +105,4 @@ data "aws_iam_policy_document" "user-policy" {
effect = "Allow"
resources = ["arn:aws:iam::*:user/$${aws:username}"]
}
statement {
sid = "GetBasicUserInfo"
actions = [
"iam:GetAccountPasswordPolicy",
"iam:GetAccessKeyLastUsed",
"iam:GetUserPolicy"
]
effect = "Allow"
resources = ["*"]
}
}
resource "aws_iam_user_policy_attachment" "iam-user-managed-policies" {
count = length(var.add-to-groups) > 0 ? 0 : length(var.managed-policy-arns)
user = aws_iam_user.iam-user.name
policy_arn = var.managed-policy-arns[count.index]
}
resource "aws_iam_user_login_profile" "iam-user-profile" {
count = var.create-password ? 1 : 0
user = aws_iam_user.iam-user.name
password_length = 20
pgp_key = null
}
resource "random_id" "secrets-random-id" {
byte_length = 2
}
resource "aws_secretsmanager_secret" "secretmanager" {
count = var.create-access-key || var.create-password ? 1 : 0
name = "IamUserCredential-${random_id.secrets-random-id.dec}-${var.iam-user-name}"
description = "AWS resource credential"
}
resource "aws_secretsmanager_secret_version" "iam-user-secret" {
count = var.create-access-key || var.create-password ? 1 : 0
secret_id = aws_secretsmanager_secret.secretmanager[0].id
secret_string = jsonencode(
{
"ConsolePassword" : length(aws_iam_user_login_profile.iam-user-profile[0].password) > 0 ? aws_iam_user_login_profile.iam-user-profile[0].password : "NotSet",
"AccessKeyId" : length(aws_iam_access_key.iam-user-access-key) > 0 ? aws_iam_access_key.iam-user-access-key[0].id : "NotSet",
"KeySecret" : length(aws_iam_access_key.iam-user-access-key) > 0 ? aws_iam_access_key.iam-user-access-key[0].secret : "NotSet"
}
)
}
resource "aws_iam_group_membership" "group-membership" {
for_each = toset(var.add-to-groups)
name = "MembershipToExistingGroups"
group = each.value
users = [aws_iam_user.iam-user.name]
}
}