【AWS CLI】IAM Groupに所属するIAM Userを一覧抽出したい

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

はじめに

こんにちは。技術1課の三木宏昭です。

最近、HADESというアクションゲームをNintendo Switchで購入しました。
ギリシャ神話が元となった世界観というのもあり、楽しいです。(ギリシャ神話って、なんかいいですよね。)

store-jp.nintendo.com

目次


IAM Groupに関連する情報をテキスト出力したい

様々な事情で、テキストファイルに出力したいことありますよね。
今回は、そんな時に役立つ情報を提供します。

なお、WindowsPowershellを利用します。

IAM Groupと所属IAM Userの一覧出力

アカウントに存在する、全IAM Groupに対して、所属ユーザを抽出します。 ユーザが存在しない場合、[]のみが表示されます。

コマンド

@(aws iam list-groups --query 'Groups[*].[GroupName]' --output text)| ForEach-Object {aws iam get-group --group-name $PSItem --query '[Group.{group:GroupName},Users[*].{user:UserName}]' }

実行結果

[
    {
        "group": "test-source"
    },
    [
        {
            "user": "test1"
        }
    ]
]

[
    {
        "group": "test-target"
    },
    []
]

IAM Groupとアタッチされたマネージドポリシーの一覧出力

アカウントに存在する、全IAM Groupに対して、アタッチされてるマネージドポリシーを出力します。

コマンド

@(aws iam list-groups --query 'Groups[*].[GroupName]' --output text)| ForEach-Object {
echo $PSItem
aws iam list-attached-group-policies --group-name $PSItem --query 'AttachedPolicies[*].{PolicyName:PolicyName}'
}

実行結果

test-source
[
    {
        "PolicyName": "AWSHealthFullAccess"
    },
    {
        "PolicyName": "IAMFullAccess"
    },
    {
        "PolicyName": "AdministratorAccess"
    },
    {
        "PolicyName": "AWSCertificateManagerFullAccess"
    }
]

test-target
[
    {
        "PolicyName": "IAMFullAccess"
    },
    {
        "PolicyName": "Billing"
    },
    {
        "PolicyName": "SystemAdministrator"
    },
    {
        "PolicyName": "AWSSupportAccess"
    }
]

IAM Groupとアタッチされたインラインポリシーの一覧出力

アカウントに存在する、全IAM Groupに対して、アタッチされてるインラインポリシーを出力します。

コマンド

@(aws iam list-groups --query 'Groups[*].[GroupName]' --output text)| ForEach-Object {
echo $PSItem
aws iam list-group-policies --group-name $PSItem
}

実行結果

test-source
{
    "PolicyNames": [
        "EC2InstanceConnect",
        "IAM_UpdateUser"
    ]
}

test-target
{
    "PolicyNames": [
        "MFA"
    ]
}

コマンドの解説

全てのコマンドを解説するのは難しいので、以下のコマンドのみ解説します。

@(aws iam list-groups --query 'Groups[*].[GroupName]' --output text)| ForEach-Object {aws iam get-group --group-name $PSItem --query '[Group.{group:GroupName},Users[*].{user:UserName}]' }

といっても、考え方は全てのコマンドで共通です。

基本的には
①IAM Groupの一覧を配列として作成
②それをパイプラインで渡して、 "ForEach-Object"コマンドを使ってIAM Userを抽出
という仕組みです。

f:id:swx-miki:20210702200109p:plain

全体の流れは以下になります。

f:id:swx-miki:20210702211809p:plain

なお、Powershellの配列についての詳細は以下のドキュメントを参照してください。

docs.microsoft.com

前半部分

@(aws iam list-groups --query 'Groups[*].[GroupName]' --output text)

の解説となります。

@() とは

配列です。以下をみて頂ければお分かりいただけるかと思います。

PS> $data = @('Zero','One','Two','Three')
PS> $data.count
4

PS> $data
Zero
One
Two
Three

今回は@()の中に以下のaws cliコマンドを入れています。

aws iam list-groups --query 'Groups[*].[GroupName]' --output text

このコマンドによって、以下が配列として格納されます。

test-source
test-target

aws iam list-groups コマンド

aws iam list-groupsコマンドはAWSアカウント内のIAMGroupを一覧表示するコマンドです。
そのまま出力すると、以下のように出力されます。

PS> aws iam list-groups
{
    "Groups": [
        {
            "Path": "/",
            "GroupName": "test-source",
            "GroupId": "AGPXXXXXXXXXXXXXXXXXX",
            "Arn": "arn:aws:iam::123456789012:group/test-sorce",
            "CreateDate": "2021-04-14T05:27:25+00:00"
        },
        {
            "Path": "/",
            "GroupName": "test-target",
            "GroupId": "AGPXXXXXXXXXXXXXXX",
            "Arn": "arn:aws:iam::123456789012:group/test-target",
            "CreateDate": "2021-04-14T05:24:42+00:00"
        }
    ]
}

今回はIAM Group名だけあれば良いので、これを --query コマンドで絞り込みます。

aws iam list-groups --query 'Groups[*].[GroupName]'

--query コマンドの使い方は長くなるので割愛しますが、コマンドの以下部分を取得していると思ってください。

f:id:swx-miki:20210702204400p:plain

また、出力形式をテキストにするため、最後に --output text オプションを付けています。
従って、このコマンドの出力は、以下のようになります。

PS> aws iam list-groups --query 'Groups[*].[GroupName]' --output text
test-source
test-target

参考

jmespath.org

docs.aws.amazon.com

後半部分

後半部分となる、以下の解説です。

| ForEach-Object {aws iam get-group --group-name $PSItem --query '[Group.{group:GroupName},Users[*].{user:UserName}]' }

ForEach-Object

前半部分の出力結果("test-source"と"test-target")を元に、それぞれのIAM Groupに所属するIAM Userを出力させようとしています。
ここで使っているのがForEach-Objectです。これも事例を挙げてみます。

PS> 30000, 56798, 12432 | ForEach-Object -Process {$PSItem/1024}

29.296875
55.466796875
12.140625

この事例では、前半部分の配列に対して、それぞれ1024で除算した結果を出力しています。
このように、配列の中身1つ1つに処理を行う時に利用できるコマンドです。
因みに、受け取りは$PSItem変数を利用します。("$_"でもOKです。)

docs.microsoft.com ※英語になります

aws iam get-group コマンド

aws iam get-group コマンドは指定したIAM Groupの情報を取得するコマンドです。
前半部分で使用した list-groups コマンドとの違いは、明示的にグループを指定する必要がある点になります。

出力は以下のようになります。

PS> aws iam get-group --group-name test-source
{
    "Users": [
        {
            "Path": "/",
            "UserName": "test1",
            "UserId": "AIDAXXXXXXXXXXXXXX",
            "Arn": "arn:aws:iam::123456789012:user/test1",
            "CreateDate": "2020-09-16T02:22:02+00:00"
        }
    ],
    "Group": {
        "Path": "/",
        "GroupName": "test-source",
        "GroupId": "AGPAXXXXXXXXXXXXXXXXX",
        "Arn": "arn:aws:iam::123456789012:group/test-sorce",
        "CreateDate": "2021-04-14T05:27:25+00:00"
    }
}

今回はIAM Group名とIAM User名だけあれば良いので、これを --query コマンドで絞り込みます。
しかし、前半部分と同様の書き方だと少々困ったことが起きます。

PS> aws iam get-group --group-name test-source--query '[Group.GroupName,Users[*].UserName] --output text'
[
    "test-source",
    [
        "test1"
    ]
]

ご覧の通り、出力だけではどちらがグループ名でどちらがユーザ名なのか分かりません。
そこで、分かるように"group"と"user"という表記を付け加えることにしました。

PS> aws iam get-group --group-name test-source --query '[Group.{group:GroupName},Users[*].{user:UserName}]'

[
    {
        "group": "test-sorce"
    },
    [
        {
            "user": "test1"
        }
    ]
]

パイプライン

後半部分で解説した要素を使い、前半部分の配列に対してaws iam get-groupコマンドを実行させます。

| ForEach-Object {aws iam get-group --group-name $PSItem --query '[Group.{group:GroupName},Users[*].{user:UserName}]' }

ForEach-Objectコマンドによって、配列の中身1つ1つに対してカッコ内のコマンドが実行されます。
なお、配列の中身は $PSItem 変数で渡されます。


おわりに

いかがでしたでしょうか。 要件によって、いろいろとやりたいことがあるかと思います。
このブログと以下のリンクが参考になれば幸いです。

docs.aws.amazon.com

三木 宏昭 (執筆記事の一覧)

クラウドインテグレーション部 技術1課

紅茶と親子丼とAWSが好き

2021年の目標:毎日リングフィットアドベンチャーのコントローラーを持つ

2021 APN ALL AWS Certifications Engineers