- こんにちは。熱い太陽光を浴びるとモリモリ元気が出る気がするCTO室のkazです。 今日は以前から社内から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.enechange.yell", "exp.enechange.ange", "exp.enechange.etoile", "exp.enechange.amor", "exp.enechange.macherie", "exp.enechange.whip", "exp.enechange.custerd", "exp.enechange.gelato", "exp.enechange.macaron", "exp.enechange.chocolat", "exp.enechange.parfait", ] } variable "aws_iam_group" { type = "list" default = [ "administrator", "development", "operators", ] }
- iam_user.tf
- シークレットキーはkeybaseを使用して暗号化し、ユーザIDと関連付けしてoutputさせています
resource "aws_iam_user" "enechange_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" "enechange_exp_login_profile" { count = "${length(var.aws_iam_user)}" user = "${element(var.aws_iam_user, count.index)}" pgp_key = "keybase:exp_enechange" password_reset_required = true password_length = "20" } resource "aws_iam_access_key" "enechange_exp_access_key" { count = "${length(var.aws_iam_user)}" user = "${element(var.aws_iam_user, count.index)}" pgp_key = "keybase:exp_enechange" } output "encrypted_secret" { value = "${join("\n", aws_iam_access_key.enechange_exp_access_key.*.encrypted_secret)}" } output "id" { value = "${join("\n", aws_iam_access_key.enechange_exp_access_key.*.id)}" } output "user" { value = "${join("\n", aws_iam_access_key.enechange_exp_access_key.*.user)}" }
- iam_group_membership.tf
resource "aws_iam_group_membership" "enechange_exp_group_membership" { count = "${length(var.aws_iam_user)}" name = "enechange_exp_group_membership" users = [ "${element(var.aws_iam_user, count.index)}", ] group = "${element(var.aws_iam_group, 0)}" } resource "aws_iam_group" "enechange_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.enechange.yell exp.enechange.ange exp.enechange.etoile exp.enechange.amor exp.enechange.macherie exp.enechange.whip exp.enechange.custerd exp.enechange.gelato exp.enechange.macaron exp.enechange.chocolat exp.enechange.parfait
- 作成したユーザ分のシークレットキーをoutputすることはできるんですが、outputにcount処理が使えなく、どのキーがどのユーザに紐付いてるのかわからず...、また、ユーザ分のシークレットキーを復号化する際は、
terraform output encrypted_secret | base64 --decode | keybase pgp decrypt
で処理するんですが、複数のoutputをうまく処理できなく困ってました... どう処理をぶん回すのが効率がいいか悩んでいたところ弊社が誇るRuby関西のFounderでもあるRubyistのcuzic (a.k.a Tomoya Kawanishi )が助けてくれました。(私の社内でのコードレビューの90%はcuzic...!) 「ちょっとまっとき〜」と言って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_enechange`.chomp} : v}.transpose].map{|a| a.join(",")}'
素敵やん...!
- 実行結果
user,id,encrypted_secret exp.enechange.yell,AKIA****************,Ya3R************************************ enechange.ange,AKIA****************,GYW7************************************ enechange.etoile,AKIA****************,bUpd************************************ exp.enechange.amor,AKIA****************,5lHm************************************ exp.enechange.macherie,AKIA****************,RyoM************************************ exp.enechange.whip,AKIA****************,r7EW************************************ exp.enechange.custerd,AKIA****************,CoBk************************************ exp.enechange.gelato,AKIA****************,FWYd************************************ exp.enechange.macaron,AKIA****************,4taL************************************ exp.enechange.chocolat,AKIA****************,4taL************************************ exp.enechange.parfait,AKIA****************,4taL************************************
最高やん...!
- これらをまとめてMFAを使うように手順も併せて配布すれば、きっと開発速度が向上し、技術的負債を熨斗付きで返済するようなイノベーションが発生するはず...!
お知らせ
弊社では下記職種で募集しています!
- エンジニア
- ディレクター
- コーポレート・スタッフ
- セールス
- マーケティング
- ライター
- コンサルタント・アナリスト
プロジェクトマネージャー www.wantedly.com
オフィス見学 www.wantedly.com