BioErrorLog Tech Blog

試行錯誤の記録

特定のIAM RoleがアタッチされたEC2インスタンスを列挙する | AWS CLI

AWS CLIを用いて、特定のIAM RoleがアタッチされたEC2インスタンスを列挙する方法の備忘録です。


はじめに

おはよう。@bioerrorlogです。

あるEC2インスタンスにアタッチされたIAM Roleは、AWSマネジメントコンソールからも簡単に確認することが出来ます。

では逆に、特定のIAM Roleがアタッチされた全てのEC2インスタンスを列挙するにはどうすればいいか?

今回は、AWS CLIを用いてやる方法をメモします。


特定のIAM RoleがアタッチされたEC2を列挙する

やり方

まず結論から、以下のコマンドを実行します。

aws ec2 describe-instances \
    --filters Name=iam-instance-profile.arn,Values=<対象IAM Roleのインスタンスプロファイル> \
    --query 'Reservations[*].Instances[*].{Instance:InstanceId,Name:Tags[?Key==`Name`]|[0].Value}' \
    --output table


上記コマンドを実行すると、以下のように対象IAM RoleがアタッチされたEC2インスタンス情報を取得できます。

----------------------------------
|        DescribeInstances       |
+----------------------+---------+
|       Instance       |  Name   |
+----------------------+---------+
|  i-06f7c25f664d1e9ee |  Test1  |
|  i-06aacb6d35a8c4753 |  Test2  |
+----------------------+---------+


以下、上記コマンドを一つ一つ解説していきます。


解説

ec2 describe-instances

aws ec2 describe-instances

まずはこちら、AWS CLIの ec2 describe-instancesを利用しています。

このコマンドでは、特定のインスタンス、または条件で指定した複数のインスタンス情報が取得できます。


--filters

--filters Name=iam-instance-profile.arn,Values=<対象IAM Roleのインスタンスプロファイル>

続いて、フィルタ条件--filtersで、対象のインスタンスを抽出します。 対象IAM Roleのインスタンスプロファイルを指定することで、そのIAM RoleがアタッチされたEC2インスタンスをすべて取得することが出来ます。

"インスタンスプロファイル"とは、IAM Roleが格納される箱のようなもので、IAM RoleがEC2インスタンスにアタッチされる際の仲介者のような役割をもちます。

Using instance profiles - AWS Identity and Access Management

IAM Roleのインスタンスプロファイルは、マネジメントコンソールからも確認することが出来ます。

f:id:BioErrorLog:20201208231117p:plain
IAM Roleインスタンスプロファイルをマネジメントコンソールから確認する

ここで確認したIAM Roleのインスタンスプロファイルを、上記コマンドの<対象IAM Roleのインスタンスプロファイル>に置き換えます。

例)

--filters Name=iam-instance-profile.arn,Values=arn:aws:iam::123456789012:instance-profile/EC2TestRole


--query

--query 'Reservations[*].Instances[*].{Instance:InstanceId,Name:Tags[?Key==`Name`]|[0].Value}'

次は、--queryオプションで表示する情報を抽出しています。

仮に何も--queryに指定せず全ての情報を表示した場合、取得された情報の全体像のイメージは例えば以下のようになっています。

例)

{
    "Reservations": [
        {
        "Instances": [
                {
                    "AmiLaunchIndex": 0,
                    "ImageId": "ami-0abcdef1234567890",
                    "InstanceId": "i-1234567890abcdef0",
                    "InstanceType": "t2.micro",
                    "KeyName": "MyKeyPair",
                    "LaunchTime": "2018-05-10T08:05:20.000Z",
                    "Monitoring": {
                        "State": "disabled"
                    },
                    "Placement": {
                        "AvailabilityZone": "us-east-2a",
                        "GroupName": "",
                        "Tenancy": "default"
                    },
                    "PrivateDnsName": "ip-10-0-0-157.us-east-2.compute.internal",
                    "PrivateIpAddress": "10.0.0.157",
                    "ProductCodes": [],
                    "PublicDnsName": "",
                    "State": {
                        "Code": 0,
                        "Name": "pending"
                    },
                    "StateTransitionReason": "",
                    "SubnetId": "subnet-04a636d18e83cfacb",
                    "VpcId": "vpc-1234567890abcdef0",
                    "Architecture": "x86_64",
                    "BlockDeviceMappings": [],
                    "ClientToken": "",
                    "EbsOptimized": false,
                    "Hypervisor": "xen",
                    "NetworkInterfaces": [
                        {
                            "Attachment": {
                                "AttachTime": "2018-05-10T08:05:20.000Z",
                                "AttachmentId": "eni-attach-0e325c07e928a0405",
                                "DeleteOnTermination": true,
                                "DeviceIndex": 0,
                                "Status": "attaching"
                            },
                            "Description": "",
                            "Groups": [
                                {
                                    "GroupName": "MySecurityGroup",
                                    "GroupId": "sg-0598c7d356eba48d7"
                                }
                            ],
                            "Ipv6Addresses": [],
                            "MacAddress": "0a:ab:58:e0:67:e2",
                            "NetworkInterfaceId": "eni-0c0a29997760baee7",
                            "OwnerId": "123456789012",
                            "PrivateDnsName": "ip-10-0-0-157.us-east-2.compute.internal",
                            "PrivateIpAddress": "10.0.0.157"
                            "PrivateIpAddresses": [
                                {
                                    "Primary": true,
                                    "PrivateDnsName": "ip-10-0-0-157.us-east-2.compute.internal",
                                    "PrivateIpAddress": "10.0.0.157"
                                }
                            ],
                            "SourceDestCheck": true,
                            "Status": "in-use",
                            "SubnetId": "subnet-04a636d18e83cfacb",
                            "VpcId": "vpc-1234567890abcdef0",
                            "InterfaceType": "interface"
                        }
                    ],
                    "RootDeviceName": "/dev/xvda",
                    "RootDeviceType": "ebs",
                    "SecurityGroups": [
                        {
                            "GroupName": "MySecurityGroup",
                            "GroupId": "sg-0598c7d356eba48d7"
                        }
                    ],
                    "SourceDestCheck": true,
                    "StateReason": {
                        "Code": "pending",
                        "Message": "pending"
                    },
                    "Tags": [
                        {
                            "Value": "Test1", 
                            "Key": "Name"
                        }
                    ],
                    "VirtualizationType": "hvm",
                    "CpuOptions": {
                        "CoreCount": 1,
                        "ThreadsPerCore": 1
                    },
                    "CapacityReservationSpecification": {
                        "CapacityReservationPreference": "open"
                    },
                    "MetadataOptions": {
                        "State": "pending",
                        "HttpTokens": "optional",
                        "HttpPutResponseHopLimit": 1,
                        "HttpEndpoint": "enabled"
                    }
                }
            ],
            "OwnerId": "123456789012"
            "ReservationId": "r-02a3f596d91211712",
        },
        {
            # 以下instance分繰り返し
        }
    ]
}

ここから、欲しい情報を--queryで抽出します。 今回は、InstanceとしてInstanceIdを、Nameとしてインスタンス名を抽出しています。

'Reservations[*].Instances[*].{Instance:InstanceId,Name:Tags[?Key==`Name`]|[0].Value}'

EC2インスタンスのインスタンス名は、NameタグのValueとして格納されているので、Tags[?Key==Name]|[0].Valueとして値を抽出しています。

この状態での出力は、以下のようになります。

[
    [
        {
            "Instance": "i-06f7c25f664d1e9ee", 
            "Name": "Test1"
        }
    ], 
    [
        {
            "Instance": "i-06aacb6d35a8c4753", 
            "Name": "Test2"
        }
    ]
]


--output

最後は--outputオプションです。 このオプションはただ出力形式を指定するものなので、任意で指定してください。

--outputには、以下の3つが指定できます

  • json
  • text
  • table

それぞれ、出力は以下のようになります。

  • json
[
    [
        {
            "Instance": "i-06f7c25f664d1e9ee", 
            "Name": "Test1"
        }
    ], 
    [
        {
            "Instance": "i-06aacb6d35a8c4753", 
            "Name": "Test2"
        }
    ]
]


- text

i-06f7c25f664d1e9ee     Test1
i-06aacb6d35a8c4753     Test2


- table

----------------------------------
|        DescribeInstances       |
+----------------------+---------+
|       Instance       |  Name   |
+----------------------+---------+
|  i-06f7c25f664d1e9ee |  Test1  |
|  i-06aacb6d35a8c4753 |  Test2  |
+----------------------+---------+


任意で好きな出力形式を指定してください。


以上、コマンドの説明でした。

aws ec2 describe-instances \
    --filters Name=iam-instance-profile.arn,Values=<対象IAM Roleのインスタンスプロファイル> \
    --query 'Reservations[*].Instances[*].{Instance:InstanceId,Name:Tags[?Key==`Name`]|[0].Value}' \
    --output table


おわりに

今回は、特定のIAM RoleがアタッチされたEC2インスタンスをAWS CLIを用いて列挙する方法を記しました。

こうして調べるたびに、AWS CLIはとても強力だと感じます。

今後も使いこなしていきたいところです。


関連記事

AWS CLIのs3 cps3 syncの違いをまとめました。 www.bioerrorlog.work


S3バケットポリシーとIAMポリシーの関係を、同一アカウント・クロスアカウントそれぞれにおいて整理しました。 www.bioerrorlog.work


AWS Lambdaの中でAWS CLIを実行する方法を書きました。 www.bioerrorlog.work


参考

describe-instances — AWS CLI 1.18.211 Command Reference

Using instance profiles - AWS Identity and Access Management

Grobal parameters - AWS CLI