SRE1課の古川(と)です。
「EC2インスタンス(以下、EC2)の情報をスマートに得たい。」という思いから自動化を目指して試行錯誤しています。
はじめに
今回はboto3(AWS SDK for Python)を使用して、私のアカウント内にある2台のEC2の情報を取得したいと思います。
今回欲しい情報は以下です。
- インスタンスID
- インスタンスタイプ
- インスタンスの状態
- インスタンス名(「Name」タグ)
- タグの値
boto3を初めて使用する方は以下のブログを読んだうえで、今回のブログを見てくださるとより理解が深まると思います。
↓boto3初心者の方には必読のブログです!!
実行環境
項目 | 内容 |
---|---|
実行場所 | 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公式ドキュメントを確認してください。
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使いこなすことができれば、結構便利かもな~と思いました。
コードの内容や書き方で「もっとこうしたほうが分かりやすくていいよ!」ということがあれば、アドバイスいただけると嬉しいです!
参考
- boto3公式ドキュメント boto3.amazonaws.com
古川智絵 (執筆記事の一覧)
2020年新卒入社 技術課(SRE1課)に所属 好きな食べ物はみそ汁