tl;dr
EC2 Classic で稼働しているインスタンスについて、ClassicLinkを設定しないインスタンスを一覧する
背景
インクリメンツでは一部EC2 Classic環境のインスタンスが稼働しています。これらのClassicLinkの状況をチェックしたいのですが、以下の状況から1つのAPIで実現できず、AWS CLIでは厳しい。
-
DescribeInstances
では、EC2 Classicで稼働しているインスタンスのみを取得するのができなさそう- filterでは実現できなさそうだし、queryでは結構つらい
- ClassicLinkの状態は取得できない
-
DescribeClassicLinkInstances
というAPIはありますが、これはClassicLink設定済みのインスタンスしか返却されない
ということでコードを書いた。
AWS Config の Custom Rule を作れば、新しくインスタンスが起動してきてもチェックすることができて安心。
EC2 Classicのインスタンスを列挙する
いくつか方法はありますが、VpcId
の要素が無いのは Classic インスタンスです。
import boto3
ec2 = boto3.client('ec2')
paginator = ec2.get_paginator('describe_instances')
response_iterator = paginator.paginate()
for response in response_iterator:
for reservations in response['Reservations']:
for instance in reservations['Instances']:
if instance.get('VpcId') is not None:
continue
instanceId = instance['InstanceId']
imageId = instance['ImageId']
state = instance['State']['Name']
name = dict([[x['Key'], x['Value']] for x in instance.get('Tags')]).get('Name')
print("\t".join([imageId, instanceId, state, name]))
タグの要素は [{Key: 'key', Value: 'value'}, ..]
とリストの中に辞書が入っているのでリスト内包表記で [['key', 'value'], ...]
の形式にしてdict()
で辞書にした。
ClassicLink未設定のインスタンスを列挙
ClassicLinkが未設定のインスタンスは、EC2 Classicインスタンス一覧から、ClassicLinkインスタンス一覧を引いたもの。
import sys
import boto3
ec2 = boto3.client('ec2')
paginator = ec2.get_paginator('describe_instances')
response_iterator = paginator.paginate()
classicInstances = dict()
# fetch classic instances
for response in response_iterator:
for reservations in response['Reservations']:
for instance in reservations['Instances']:
if instance.get('VpcId') is not None:
continue
instanceId = instance['InstanceId']
imageId = instance['ImageId']
state = instance['State']['Name']
name = dict([[x['Key'], x['Value']] for x in instance.get('Tags')]).get('Name')
classicInstances[instanceId] = {'imageId': imageId, 'state': state, 'name': name}
# fetch ClassicLink-ed instances
response = ec2.describe_classic_link_instances()
classicLinkInstances = dict()
for instance in response['Instances']:
classicLinkInstances[instance['InstanceId']] = instance
# check ClassicLink not enabled instances
notActivatedInstanceIds = set(classicInstances.keys()) - set(classicLinkInstances.keys())
print("# ClassicLink is not enabled")
for instanceId in notActivatedInstanceIds:
print(classicInstances[instanceId])
describe_classic_link_instances
には paginator が無いので、上のコードだとインスタンスが多い場合は駄目ですね。残念。
ClassicLinkが設定されているインスタンスの情報取得
これは、describe-classic-link-instances
でいけるので、AWS CLIで。
aws ec2 describe-classic-link-instances \
--query 'Instances[].{InstanceId:InstanceId,VpcId:VpcId,Group:Groups[0].GroupId,Name:Tags[?Key==`Name`].Value|[0]}' \
--output table
aws ec2 describe-classic-link-instances --query 'Instances[].{InstanceId:InstanceId,VpcId:VpcId,Group:Groups[0].GroupId,Name:Tags[?Key==`Name`].Value|[0]}' --output table
---------------------------------------------------------------------------------------------------
| DescribeClassicLinkInstances |
+-------------+----------------------+-------------------------------------------+----------------+
| Group | InstanceId | Name | VpcId |
+-------------+----------------------+-------------------------------------------+----------------+
| sg-c4effff| i-04c1410db8deffff | classic-foo-bar-baz | vpc-16a2ffff |
Nameタグを取ってくるのが面倒。