IAMユーザーの払い出しを自動化してみた

記事タイトルとURLをコピーする

はじめに

釣りが好きなCS部CS2課オールドルーキー有川です。 アオリイカを釣りに伊豆に行きたい。イカチョップしたい。

参考:イカチョップとは https://www.youtube.com/watch?v=z-FoT6QFU9g&t=20s

※釣ったイカの神経を断つことで鮮度を保ち、美味しくいただくための方法。 〆用の刃物などもあるが、家の鍵でもいい。動画の通りチョップでも〆ることが出来ます

この記事では何を得ることが出来る?

さて、本記事ではLambdaとS3を用いて、IAMuserの作成を自動化してみました。 CSVリストにあるユーザーを一気に作成するためのLambdaで用いるPythonスクリプトと関連する権限設定について記載しています。

  • AWS Lambda+S3を用いたIAMユーザーの作成の自動化の方式
  • 自動化出来た暁には大量のIAMユーザー作成業務からの解放

構成図

再帰読込による無限ループ発生を防ぐため、入力用のS3と、作業終了したS3は別のバケットで管理します。 同一バケットでの入出力も可能ですが、上記の危険がありアンチパターンです。 以下の記事で紹介するように無限ループの自動検出機能もありますが、設計段階で排除できる危険は排除したいところです。

blog.serverworks.co.jp

前提

  1. 検証時は、Lambda内のPython3.12を用いました
  2. 参加するIAMグループは事前に作成が必要です
  3. 作成したユーザーへの通知は手動です(イケてない・・・)
  4. 作成したユーザーは初回ログイン時にご自身でのパスワード変更が必要です

※3の通知はSES連携やSNSでSlackと連携するなどを実装することで自動化できます

実際にどういう運用手順になるか

  1. 作成対象者をリスト化したCSVを作成する
  2. 作成したCSVをS3にアップロードする
  3. マネコンやCLIにて、IAM上にユーザーが作成されている事を確認
  4. 対象者にログイン確認&パスワード変更を実施頂く通知を実施

構築手順

手順1:S3バケットの用意

1-1. S3バケットの用意(ソース用と処理済み格納用の2種)

  • バケット名に指定はありません。その他の設定もデフォルトで良いです。

※既存のバケット使用でも構いませんが、src側のバケットに.csvがアップロードされるたびにLambdaが走るので新規作成をお勧めします。

※1つのバケットで設定する事も可能ですが、再帰呼び出しの可能性を含むためアンチパターンです。最悪超高額なLambda料金の請求が来ますのでお勧めしません。

手順2:Lambdaの準備

2-1. Lambdaを作成します

以下のコードを用いてLambdaを作成します

import boto3
import io
import csv
import datetime

# ご自身の環境に合わせて変更してください
SRC_BUCKET_NAME="YOURBACKETPREFIX-iam-useradd-src"
DST_BUCKET_NAME="YOURBACKETPREFIX-iam-useradd-dst"
SRC_OBJECT_KEY_NAME="iam_useradd.csv"
SRC_FILE_ENCODING="utf-8"

s3 = boto3.resource('s3')
s3c = boto3.client("s3")
iam = boto3.resource('iam')
client = boto3.client('iam')
dt_now = datetime.datetime.now()



t = str(dt_now.strftime("%Y%m%d-%H:%M:%S"))
dst_f = t + "_" + SRC_OBJECT_KEY_NAME +".done"
dst = "added/" + dst_f



#S3上のファイルリネームを関数化
def s3_move_object(s3c, *, BucketFrom: str, BucketTo: str | None = None, KeyFrom: str, KeyTo: str):
    if BucketTo is None:
        BucketTo = BucketFrom
    s3c.copy_object(Bucket=BucketTo, Key=KeyTo, CopySource={"Bucket": BucketFrom, "Key": KeyFrom})
    s3c.delete_object(Bucket=BucketFrom, Key=KeyFrom)


#処理部
def lambda_handler(event, context):
  
  src_obj = s3.Object(
    SRC_BUCKET_NAME,
    SRC_OBJECT_KEY_NAME
  )
  body_in = src_obj.get()['Body'].read().decode(SRC_FILE_ENCODING)

  st = io.StringIO()
  st.write(body_in)
  st.seek(0)
  csv_f =csv.reader(st)

  for row in csv_f:
    #print('ユーザ名:{}'.format(row[0]))
  
    response = client.create_user(
      UserName=row[0]
    )

    response = client.create_login_profile(
      UserName=row[0],
      Password=row[2],
      PasswordResetRequired=True
    )
    
    waiter = client.get_waiter('user_exists')
    waiter.wait(
      UserName=row[0],
      WaiterConfig={
        'Delay': 5,
        'MaxAttempts': 5
      }
    )
   

    user = iam.User(row[0])
    response = user.add_group(
      GroupName=row[1]
    )
    response = user.attach_policy(
      PolicyArn='arn:aws:iam::aws:policy/IAMUserChangePassword'
    )
  else:
    s3_move_object(s3c, BucketFrom=SRC_BUCKET_NAME, BucketTo=DST_BUCKET_NAME, KeyFrom=SRC_OBJECT_KEY_NAME, KeyTo=dst)

※ソース作成に当たり、以下のサイト記述を参考にしています

docs.aws.amazon.com

qiita.com

qiita.com

2-2. Lambda実行ロールに以下の許可を与えます

以下のユーザーポリシーを作成し、ロールにアタッチを行ってください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:AttachUserPolicy",
                "iam:DetachUserPolicy",
                "iam:AddUserToGroup",
                "iam:RemoveUserFromGroup",
                "iam:Get*",
                "iam:List*",
                "iam:CreateUser",
                "iam:CreateLoginProfile",
                "s3:Get*",
                "s3:List*",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": "*"
        }
    ]
}

2-3. Lambdaの実行時間タイムアウトを30秒程度に伸ばします

ここは実際の作業ボリュームに合わせて適宜変更してください。私の環境では、3名作成するのに7秒程度必要でした。

2-4. Lambdaのトリガーに1-1で作成したバケット「すべてのオブジェクト作製イベント」を設定します

手順3:CSVファイルを用意

3-1. カラム構成は以下のようにする

ユーザー名 参加グループ名 仮パスワード
TEST_USER_001 TEST_GROUP_001 TEST_PaSsWoRd01!
TEST_USER_002 TEST_GROUP_002 TEST_PaSsWoRd02!

※実際のCSVにタイトル行は不要です

動作確認

  • 作成したCSVを、1-1で作成したソース用S3バケットにアップロードしてください。

  • IAM画面で、想定通りのユーザーが作成されているか確認をしてください。

  • アップロードしたファイルがリネームされ、DST_BUCKET_NAME/added/に移動している事を確認してください。

ファイル移動の確認

  • 作成したユーザーと仮パスワードでログインを試行し、本パスワードへの変更が実施可能かを確認してください。

注意事項

・エラー制御の考慮がありません。例えば既に同一ユーザー名がいた場合、Lambdaはエラーで終了します。

・削除は手動で実施する想定です。(自動で消すのはなんか怖い・・・)

・アクセスキーなど関連設定の付与は考慮していません。

・グループに付与した権限が付与されるのみで、個別のアクセス権限はパスワード変更以外の考慮はありません。

まとめ

4月に入ると、IAMユーザーを一斉に作成する作業で半日終わる、なんて嘆く方も多いのではないでしょうか。 本手順が皆様の運用負荷を下げる一助となれば幸いです。

ありかわ りゅうた(執筆記事の一覧)

カスタマーサクセス部 CS2課

2024年11月中途入社
自動車、釣り、キャンプ、ギターが趣味です。
経験こそ至高と思っているので、趣味的な事柄は何でも手を出します。
妻(パート)と娘(小学低学年)と息子(小学高学年)と犬(ゴールデンレトリバー)と猫(ミックス)で暮らす日々が煩わしくてうるさくて面倒くさいのに、かけがえの無いものなのが不思議です。