【boto3】EC2インスタンスの情報を取得する

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

SRE1課の古川(と)です。
「EC2インスタンス(以下、EC2)の情報をスマートに得たい。」という思いから自動化を目指して試行錯誤しています。

はじめに

今回はboto3(AWS SDK for Python)を使用して、私のアカウント内にある2台のEC2の情報を取得したいと思います。 f:id:swx-tomoe-furukawa:20210428180059p:plain

今回欲しい情報は以下です。

  • インスタンスID
  • インスタンスタイプ
  • インスタンスの状態
  • インスタンス名(「Name」タグ)
  • タグの値

boto3を初めて使用する方は以下のブログを読んだうえで、今回のブログを見てくださるとより理解が深まると思います。
↓boto3初心者の方には必読のブログです!!

blog.serverworks.co.jp

実行環境

項目 内容
実行場所 EC2
OS Amazon Linux2
Pythonバージョニング Python 3.7.9
AWS CLI 1.18.147

インスタンスのID・タイプ・状態を取得する

まず、boto3でインスタンスID、インスタンスタイプ、インスタンスの状態を取得しましょう。 以下のようなpython3ファイルを作成します。
(今回の例ではカンマ区切りで結果を出力していますが、適宜変更してください。)

import boto3

ec2 = boto3.client('ec2')
ec2_data = ec2.describe_instances()

for ec2_reservation in ec2_data['Reservations']:
    for ec2_instance in ec2_reservation['Instances']:
        ec2_instance_id = ec2_instance['InstanceId']
        ec2_instance_type = ec2_instance['InstanceType']
        ec2_instance_state = ec2_instance['State']['Name']
        
        print(ec2_instance_id + ',' + ec2_instance_type + ',' + ec2_instance_state)

出力結果↓

i-xxxxxxxx,t2.micro,running
i-xxxxxxxx,t3a.nano,running

for文を使うことで、指定したリージョンの全インスタンス情報を取得することが可能です。

今回はAWS CLIがインストール済みの環境なので、aws configureコマンドで指定したデフォルトリージョンのインスタンス情報を取ってきています。

region_nameを使用してスクリプト内でリージョンを指定することも可能です。詳細については以下boto3公式ドキュメントを確認してください。

boto3.amazonaws.com

boto3.amazonaws.com

EC2のすべてのタグ情報を取得する

インスタンスごとにすべてのタグ情報を取ってきましょう。

import boto3

ec2 = boto3.client('ec2')
ec2_data = ec2.describe_instances()

for ec2_reservation in ec2_data['Reservations']:
    for ec2_instance in ec2_reservation['Instances']:
        ec2_tags = ec2_instance['Tags']

        print(ec2_tags)

出力結果↓

[{'Key': 'Name', 'Value': 'kensho'}, {'Key': 'hoge', 'Value': 'hogehoge'}, {'Key': 'OS', 'Value': 'Linux'}]
[{'Key': 'Name', 'Value': 'test'}, {'Key': 'hoge', 'Value': 'hogehoge'}]

出力結果に「Key」と「Value」という文字が入り、少し見にくい気がします。
値のみ出力するには、以下のように書きます。

import boto3

ec2 = boto3.client('ec2')
ec2_data = ec2.describe_instances()

for ec2_reservation in ec2_data['Reservations']:
    for ec2_instance in ec2_reservation['Instances']:
        ec2_tags = dict([(tag['Key'], tag['Value']) for tag in ec2_instance['Tags']])

        print(ec2_tags)

出力結果↓

{'Name': 'kensho', 'hoge': 'hogehoge', 'OS': 'Linux'}
{'Name': 'test', 'hoge': 'hogehoge' }

特定のタグの値を取得する

すべてのタグ情報を取得するのではなく、特定のタグの値のみ取得したい!といったときはこんな感じです。

今回は「Name」タグと「hoge」タグの値を取得し、「Nameの値,hogeの値」という形で出力させます。

import boto3

ec2 = boto3.client('ec2')
ec2_data = ec2.describe_instances()

for ec2_reservation in ec2_data['Reservations']:
    for ec2_instance in ec2_reservation['Instances']:
        ec2_tags = dict([(tag['Key'], tag['Value']) for tag in ec2_instance['Tags']])
       
        print(ec2_tags['Name'] + ',' + ec2_tags['hoge'])

出力結果↓

kensho,hogehoge
test,hogehoge

特定のタグがない場合に任意の文字を返す

次に「Name」タグと「OS」タグの値を取得したいとします。
上記の方法と同じようにやってしまうとこのようにエラーが出てしまいます。

kensho,Linux #←1台目のEC2の「Name」タグと「OS」タグの値
Traceback (most recent call last):
  File "blog.py", line 14, in <module>
    print(ec2_tags['Name'] + ',' + ec2_tags['OS'])
KeyError: 'OS'

1台目のEC2は「Name」タグと「OS」タグの値が出力されていますが、2台目のEC2でエラーが起きています。
これは、2台目のEC2に「OS」タグが存在していないのが原因です。

そんな時にはpythonのgetメソッドを使います。getメソッドを使用することでキーが存在しない場合、任意の文字列を返すことが可能となります!

キーが存在しない時は「タグなし」と返すようにしてみます。

import boto3

ec2 = boto3.client('ec2')
ec2_data = ec2.describe_instances()

for ec2_reservation in ec2_data['Reservations']:
    for ec2_instance in ec2_reservation['Instances']:
        ec2_tags = dict([(tag['Key'], tag['Value']) for tag in ec2_instance['Tags']])
        ec2_name = ec2_tags.get('Name', 'タグなし')
        ec2_os = ec2_tags.get('OS', 'タグなし')

        print(ec2_name + ',' + ec2_os)

出力結果↓

kensho,Linux
test,タグなし

意図した通りに出力されました!

おわりに

boto3使いこなすことができれば、結構便利かもな~と思いました。

コードの内容や書き方で「もっとこうしたほうが分かりやすくていいよ!」ということがあれば、アドバイスいただけると嬉しいです!

参考

古川智絵 (執筆記事の一覧)

2020年新卒入社 技術課(SRE1課)に所属 好きな食べ物はみそ汁