27
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

TerraformでIAMグループ・ユーザを作成する

Last updated at Posted at 2018-08-22
  • 今日は以前から社内からAWSの機能検証を気軽に実施できる環境がほしいというリクエストがあったため、新たにAWSアカウントを作成し、異なる権限をもったIAMグループを作成し、エンジニアごとに所属させたことを記事にしたいと思います。

作成するグループとそれに付与する管理ポリシー

  • グループ名:administrator
    • 管理ポリシー名:AdministratorAccess
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        }
    ]
}
  • グループ名:development
    • 管理ポリシー名:PowerUserAccess
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "NotAction": [
                "iam:*",
                "organizations:*"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreateServiceLinkedRole",
                "iam:DeleteServiceLinkedRole",
                "iam:ListRoles",
                "organizations:DescribeOrganization"
            ],
            "Resource": "*"
        }
    ]
}
  • グループ名:operators
    • 管理ポリシー名:未設定

作成するユーザ

  • 11ユーザ作成
    • administratorグループへ追加

設定ファイル構成

.
├── README.md
├── iam_group_membership.tf
├── iam_user.tf
├── main.tf
├── terraform_remote_state.tf
└── variables.tf
  • variables.tf
variable "aws_iam_user" {
  type = "list"

  default = [
    "exp.example.yell",
    "exp.example.ange",
    "exp.example.etoile",
    "exp.example.amor",
    "exp.example.macherie",
    "exp.example.whip",
    "exp.example.custerd",
    "exp.example.gelato",
    "exp.example.macaron",
    "exp.example.chocolat",
    "exp.example.parfait",

  ]
}

variable "aws_iam_group" {
  type = "list"

  default = [
    "administrator",
    "development",
    "operators",
  ]
}
  • iam_user.tf
    • シークレットキーはkeybaseを使用して暗号化し、ユーザIDと関連付けしてoutputさせています
resource "aws_iam_user" "example_exp" {
  count         = "${length(var.aws_iam_user)}"
  name          = "${element(var.aws_iam_user, count.index)}"
  path          = "/"
  force_destroy = true
}

resource "aws_iam_user_login_profile" "example_exp_login_profile" {
  count                   = "${length(var.aws_iam_user)}"
  user                    = "${element(var.aws_iam_user, count.index)}"
  pgp_key                 = "keybase:exp_example"
  password_reset_required = true
  password_length         = "20"
}

resource "aws_iam_access_key" "example_exp_access_key" {
  count   = "${length(var.aws_iam_user)}"
  user    = "${element(var.aws_iam_user, count.index)}"
  pgp_key = "keybase:exp_example"
}

output "encrypted_secret" {
  value = "${join("\n", aws_iam_access_key.example_exp_access_key.*.encrypted_secret)}"
}

output "id" {
  value = "${join("\n", aws_iam_access_key.example_exp_access_key.*.id)}"
}

output "user" {
  value = "${join("\n", aws_iam_access_key.example_exp_access_key.*.user)}"
}
  • iam_group_membership.tf
resource "aws_iam_group_membership" "example_exp_group_membership" {
  count = "${length(var.aws_iam_user)}"
  name  = "example_exp_group_membership"

  users = [
    "${element(var.aws_iam_user, count.index)}",
  ]

  group = "${element(var.aws_iam_group, 0)}"
}

resource "aws_iam_group" "example_exp_group" {
  count = "${length(var.aws_iam_group)}"
  name  = "${element(var.aws_iam_group, count.index)}"
}

resource "aws_iam_group_policy_attachment" "policy-attach" {
  group      = "${element(var.aws_iam_group, count.index)}"
  policy_arn = "arn:aws:iam::************:policy/administratoraccess"
}
  • output
$ terraform output
encrypted_secret = wcFMA615XJelCVO0ARAA(snip)
wcFMA615XJelCVO0ARAA(snip)
wcFMA615XJelCVO0ARAA(snip)
wcFMA615XJelCVO0ARAA(snip)
wcFMA615XJelCVO0ARAA(snip)
wcFMA615XJelCVO0ARAA(snip)
wcFMA615XJelCVO0ARAA(snip)
wcFMA615XJelCVO0ARAA(snip)
wcFMA615XJelCVO0ARAA(snip)
wcFMA615XJelCVO0ARAA(snip)
wcFMA615XJelCVO0ARAA(snip)
id = AKIA****************
AKIA****************
AKIA****************
AKIA****************
AKIA****************
AKIA****************
AKIA****************
AKIA****************
AKIA****************
AKIA****************
AKIA****************
AKIA****************
user =exp.example.yell
exp.example.ange
exp.example.etoile
exp.example.amor
exp.example.macherie
exp.example.whip
exp.example.custerd
exp.example.gelato
exp.example.macaron
exp.example.chocolat
exp.example.parfait
  • 作成したユーザ分のシークレットキーをoutputすることはできるんですが、outputにcount処理が使えなく、どのキーがどのユーザに紐付いてるのかわからず...、また、ユーザ分のシークレットキーを復号化する際は、terraform output encrypted_secret | base64 --decode | keybase pgp decryptで処理するんですが、複数のoutputをうまく処理できなく困ってました...
    どう処理をぶん回すのが効率がいいか悩んでいたところ弊社が誇るRuby関西のFounderでもあるRubyistのcuzic (a.k.a Tomoya Kawanishi )が助けてくれました。「ちょっとまっとき〜」と言って1時間後に下記ワンライナー付きでメンションがきました。
$ terraform output -json | ruby -rjson -ryaml -e 'json = JSON.load(ARGF); keys = %w(user id encrypted_secret); puts [keys, *keys.map{|key| v = json[key]["value"].split; key == "encrypted_secret" ? v.map{|s| `echo #{s} | base64 -d | keybase pgp decrypt -S exp_example`.chomp} : v}.transpose].map{|a| a.join(",")}'

素敵やん...!

  • 実行結果
user,id,encrypted_secret
exp.example.yell,AKIA****************,Ya3R************************************
example.ange,AKIA****************,GYW7************************************
example.etoile,AKIA****************,bUpd************************************
exp.example.amor,AKIA****************,5lHm************************************
exp.example.macherie,AKIA****************,RyoM************************************
exp.example.whip,AKIA****************,r7EW************************************
exp.example.custerd,AKIA****************,CoBk************************************
exp.example.gelato,AKIA****************,FWYd************************************
exp.example.macaron,AKIA****************,4taL************************************
exp.example.chocolat,AKIA****************,4taL************************************
exp.example.parfait,AKIA****************,4taL************************************

最高やん...!

  • これらをまとめてMFAを使うように手順も併せて配布すれば、きっと開発速度が向上し、技術的負債を熨斗付きで返済するようなイノベーションが発生するはず...!
27
13
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?