やりたいこと
TerraformでまとめてIAMユーザーをバーッと作り、ユーザーグループへバスンと放り込んで大勝利!🤗
きっかけ
アカウントの払い出しや棚卸しを安全かつ楽に実施したい
→ 手始めにIAMユーザーの作成(とユーザーグループへの追加)をTerraformでやってみる
IAMユーザーの数だけTerraformリソース(aws_iam_user
とaws_iam_group_membership
)が必要になる?やだな〜と思ってましたが、module
とfor_each/each
を使うとすっきり書けて嬉しかった
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_group_membership
環境と構成
Terraformのバージョンやファイル構成は下記の通りです
❯ terraform version
Terraform v1.0.8
on darwin_amd64
terraform/
├ envs/
│ └ test/
│ ├ main.tf
│ ├ outputs.tf
│ ├ variables.tf
│ └ provider.tf
├ modules/
│ └ iam/
│ ├ main.tf
│ ├ outputs.tf
│ └ variables.tf
└ src/
└ user.yml
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "3.62.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
関連リソース
ユーザー
ここではdev
とops
という2つのロール(IAMのロールではない)があると仮定して、各ロールのユーザーを3人ずつ作成します
以下のようなyamlファイルにロールとユーザー名を書きます
dev:
- dev_tarou_1st
- dev_tarou_2nd
- dev_tarou_3rd
ops:
- ops_hanako_1st
- ops_hanako_2nd
- ops_hanako_3rd
ユーザーグループ
今回は作成済みのユーザーグループへユーザーを追加していきます
dev
ロールのユーザーはdev_member_group
, ops
ロールのメンバーはops_member_group
にといった感じで何も考えずぶち込みます
locals {
users = yamldecode(file("../../src/user.yaml"))
dev_users = local.users.dev
ops_users = local.users.ops
dev_groupname = "dev_member_group"
dev_membership_name = "dev_members"
ops_groupname = "ops_member_group"
ops_membership_name = "ops_members"
}
module "dev" {
source = "../../modules/iam"
group_users = toset(local.dev_users)
membership_name = local.dev_membership_name
groupname = local.dev_groupname
}
module "ops" {
source = "../../modules/iam"
group_users = toset(local.ops_users)
membership_name = local.ops_membership_name
groupname = local.ops_groupname
}
resource "aws_iam_user" "user" {
for_each = var.group_users
name = each.value
}
resource "aws_iam_group_membership" "group_assotiation" {
depends_on = [aws_iam_user.user]
name = var.membership_name
users = var.group_users
group = var.groupname
}
variable "group_users" {}
variable "groupname" {}
variable "membership_name" {}
ユーザー作成は各ロールのユーザーごとにeach
でループさせ、ユーザーグループへの追加はtoset
を使ってユーザー名のコレクション(set)を渡します
ユーザーがいないとグループ追加がこけるので、depends_on
で明示的に依存関係を書きます
terraform plan
してみます
terraform plan実行結果
❯ terraform plan
Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# module.dev.aws_iam_group_membership.group_assotiation will be created
+ resource "aws_iam_group_membership" "group_assotiation" {
+ group = "dev_member_group"
+ id = (known after apply)
+ name = "dev_members"
+ users = [
+ "dev_tarou_1st",
+ "dev_tarou_2nd",
+ "dev_tarou_3rd",
]
}
# module.dev.aws_iam_user.user["dev_tarou_1st"] will be created
+ resource "aws_iam_user" "user" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "dev_tarou_1st"
+ path = "/"
+ tags_all = (known after apply)
+ unique_id = (known after apply)
}
# module.dev.aws_iam_user.user["dev_tarou_2nd"] will be created
+ resource "aws_iam_user" "user" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "dev_tarou_2nd"
+ path = "/"
+ tags_all = (known after apply)
+ unique_id = (known after apply)
}
# module.dev.aws_iam_user.user["dev_tarou_3rd"] will be created
+ resource "aws_iam_user" "user" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "dev_tarou_3rd"
+ path = "/"
+ tags_all = (known after apply)
+ unique_id = (known after apply)
}
# module.ops.aws_iam_group_membership.group_assotiation will be created
+ resource "aws_iam_group_membership" "group_assotiation" {
+ group = "ops_member_group"
+ id = (known after apply)
+ name = "ops_members"
+ users = [
+ "ops_hanako_1st",
+ "ops_hanako_2nd",
+ "ops_hanako_3rd",
]
}
# module.ops.aws_iam_user.user["ops_hanako_1st"] will be created
+ resource "aws_iam_user" "user" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "ops_hanako_1st"
+ path = "/"
+ tags_all = (known after apply)
+ unique_id = (known after apply)
}
# module.ops.aws_iam_user.user["ops_hanako_2nd"] will be created
+ resource "aws_iam_user" "user" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "ops_hanako_2nd"
+ path = "/"
+ tags_all = (known after apply)
+ unique_id = (known after apply)
}
# module.ops.aws_iam_user.user["ops_hanako_3rd"] will be created
+ resource "aws_iam_user" "user" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "ops_hanako_3rd"
+ path = "/"
+ tags_all = (known after apply)
+ unique_id = (known after apply)
}
Plan: 8 to add, 0 to change, 0 to destroy.
良さそう!!!!!!!!!!applyすっぞ!!!!!!!!!!!!
terraform apply
まとめ
やりたかったことができてにっこりです
が、初期パスワードの設定などほかにも色々必要なのでたくさん頑張ります