長期間使用されていないIAMユーザーをリストアップする

会社や組織で使用するAWSアカウントでは、IAMユーザーをたくさん作っていたりしますよね。
異動のタイミングできちんと都度削除できていればいいのですが、対応を忘れていたりしませんか?

ずっと使っていないのに残っているIAMユーザーはセキュリティ的によくありません。
パスワードは変更されていないでしょうし、悪用されても気づき辛いです。

なので、きちんと棚卸しをすべく、AWS Lambdaにて自動化してしまいましょう!

使用例

このページのLambdaと他のAWSサービスを使用することで以下のようなことが実現できます。
  • 任意のタイミングで特定の期間以上使用していないIAMユーザーのリストアップ
  • Amazon EventBridgeと組み合わせてで特定の期間以上使用していないIAMユーザーのリストアップ
  • プログラムに自動削除や無効化コードを追加して、使っていないIAMユーザーの自動削除や無効化
  • Amazon SNSと組み合わせて運用担当者へ特定の期間以上使用していないIAMユーザーのリストアップ結果をメールで送信
※本ページではリストアップするLambdaのご紹介のみです。
 各サービスとの連携はAWSのサービスドキュメントを確認しながら実装してください。

構成図

本ページにて紹介するLambdaにて、IAMユーザーを検索します。
boto3関数は、IAMの「list_users」と「get_login_profile」を使用します。
この関数にて、AWSアカウント内の全IAMユーザーを検査し、最終ログイン日が規定の日数以上前のものを長期間使用していないIAMユーザーとしてリストアップします。

オプションとして、このLambdaを定期実行するようにAmazon EventBridgeを連携させたり、Amazon SNSと連携させれば結果をメール送信することも可能です。

Lambdaソースコード

import boto3
from datetime import datetime, timedelta, timezone

iam_client = boto3.client('iam')
def lambda_handler(event, context):
    targetDay = datetime.now(timezone.utc) - timedelta(days=)
    iamUserList=iam_client.list_users()['Users']

    for i in range(len(iamUserList)):
        try:
            iam_client.get_login_profile(UserName=iamUserList[i]["UserName"])
        except iam_client.exceptions.NoSuchEntityException as e:
            continue
        
        if ("PasswordLastUsed" in iamUserList[i]):
            if iamUserList[i]['PasswordLastUsed'] < targetDay:
                print(iamUserList[i]['UserName'])
        else:
            if iamUserList[i]['CreateDate'] < targetDay:
                print(iamUserList[i]['UserName'])
        
    return 0

▼基本設定

期間(日)*

棚卸し対象とする日数を設定してください。
180と入力した場合は、
180日以上使われていないIAMユーザーがリストアップされます。

権限(IAMロール設定)

Lambdaに付与するIAMロールに「iam:ListUsers」と「iam:GetLoginProfile」の権限を付与してください。

解説

紹介したLambdaのフローは以下の通りです。
  1. リスト対象とする日付の設定
  2. IAMユーザーの一覧取得
  3. 取得したIAMユーザーのログインプロファイル有無確認
    ない場合は、コンソールログインしないIAMユーザーなのでスキップ
  4. 最終ログイン日時有無確認
    ない場合は、作成されてから一度もログインしていないユーザーなので作成日時を確認
  5. 作成日時確認
今回の関数では、最終ログイン日時と作成日時は日付(例:2000,1,1,12,30,45)で返ってきます。
なので、targetDay変数に設定した日にちだけ前の日付を設定し、関数から返ってきた日付と比較できるようにしています。

次にlist_users関数でAWSアカウント内の全IAMユーザーを取得します。
ただ、ここで取得するIAMユーザーはログインプロファイル(AWSマネジメントコンソールへのログイン設定)の有無にかかわらず取得されます。
マネジメントコンソールにログインしないユーザーについては、ログイン日時による棚卸しができませんので対象外としてスキップします。

ログインプロファイルが設定されているかの確認には、get_login_profile関数を使用します。
この関数によりIAMユーザーのログインプロファイルの情報を取得しますが、設定されていない場合は「NoSuchEntityException」のエラーがでます。
Try-Exceptionによりエラーが出た場合は、ログイン日時の有無をスキップするようにcontinueを入れいています。

また、list_users関数では、各IAMユーザーの最終ログイン日時と作成日時の情報が取得できますが、一度もログインしていないユーザーについては最終ログイン日時が入っておりません。
なので、最終ログイン日時がない場合は作成日時を参照し、作成されてから既定の期間以上ログインされていない場合はリスト対象としています。