AWS活用における便利な小技を簡潔に紹介する連載「AWSチートシート」。今回は、「AWS Lambda」とPython Boto3を使ってEC2インスタンスを操作する方法を紹介する。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
「Amazon Web Services」(AWS)活用における便利な小技を簡潔に紹介する連載「AWSチートシート」。今回は、サーバレスでコードを実行できる「AWS Lambda」を使い、Pythonのコードを実行して「Amazon EC2」インスタンスを操作する方法を紹介します。
PythonのコードからAWSの各種サービスを操作するには「AWS SDK for Python(Boto3)」というライブラリを利用する必要があります。これはAWSが提供する公式ライブラリです。APIとして提供されている機能のほとんどを、Boto3を通じて利用できます。
SDKを利用することでAWSの「マネジメントコンソール」上で操作せずとも各種サービスを操作できる他、「Amazon CloudWatch Events」(EventBridge)などと組み合わせることで、「定期的にインスタンスを停止する」といった処理が可能になります。SDKを使いこなすことでAWSを利用する幅がぐっと広がります。今後の業務や個人での学習にぜひ取り入れてみてください。
以降、図1にあるようにLambda上でBoto3を使ったPythonのコードを実行して、EC2インスタンスに対する基本的な操作を幾つか示します。
今回は下記の手順でEC2インスタンスの起動、情報取得、停止、削除を順番に実施します。
まずは、Lambda関数からEC2インスタンスを操作する際に利用するIAMロールを作成します。
「IAMコンソール」から「ロール」→「ロールの作成」と遷移し、ユースケースとして「Lambda」を選択して「次へ」をクリックします。
ロールにアタッチするポリシーは、検索窓から「AmazonEC2FullAccess」を検索してチェックを付け「次へ」をクリックします。
確認画面では、「lambda-ec2fullaccess-role」などとロール名を指定して「ロールを作成」をクリックします。
続いて、Lambda関数を作成するためにLambdaコンソールにアクセスして「関数の作成」をクリックします。
関数の作成画面に遷移したら、作成オプションとして「一から作成」を選択し、基本的な情報欄にある各設定項目を以下のように設定します。
設定項目 | 設定値 |
---|---|
関数名 | manageEC2Function |
ランタイム | Python 3.9 |
アーキテクチャ | x86_64 |
アクセス権限 | 「デフォルト実行ロールの変更」→「既存のロールを使用する」と選択し、【手順1】で作成した「lambda-ec2fullaccess-role」を選択 |
上記の設定が完了したら「関数の作成」をクリックします。
作成したLambda関数の詳細ページに遷移したら、次の手順からBoto3を利用してソースコードを編集します。
公式レファレンスを参照しながら、初めにEC2インスタンスを起動するコードを書きます。
EC2インスタンスを操作する方法には、ClientクラスとService Resourceクラスを利用する方法がありますが、今回はインスタンスをオブジェクトとして扱えるService Resourceクラスを利用する方法を紹介します。
このServiceResourceクラスの説明を見ると、「create_instances()」というメソッドがあるので、これを利用します。
create_instances()の引数には上記のレファレンスとAPIドキュメントを併せて参照しながら、まずは最低限の情報だけを指定してEC2インスタンスを起動するコードを実行します。
下記は、「Amazon Machine Image」(AMI)に「Amazon Linux2(ami-02c3627b04781eada)」、インスタンスタイプに「t2.micro」、最大/最小台数を1台としてEC2インスタンスを作成するコードです。
import boto3 def lambda_handler(event, context): # EC2の利用準備 EC2 = boto3.resource("ec2", region_name='ap-northeast-1') # EC2インスタンスの作成 instance = ec2.create_instances( ImageId = 'ami-02c3627b04781eada', InstanceType='t2.micro', MaxCount=1, MinCount=1 ) # 作成したインスタンスを出力 print(instance)
上記のコードをLambda関数のエディタ部分に転記したら「Deploy」→「Test」の順にクリックします。
テストイベントの作成ウィンドウが表示されたら、イベント名に「test」などと入力し、他の設定はデフォルトのまま「保存」をクリックします。
また、コードの実行前に「設定」タブから一般設定の「編集」ボタンを押して、タイムアウト時間を「3分」に変更しておきます。
タイムアウト時間の変更が完了したら「コード」タブを押して元の画面に戻り、再度「Test」ボタンをクリックしてコードを実行します。
コードの実行結果を見ると、ログ部分に作成したインスタンスがInstanceクラスのオブジェクトとしてインスタンスIDと一緒に出力されていることを確認できます。
EC2コンソールを開いてインスタンスの一覧を見ると、新たに1台インスタンスが作成されていることを確認できます。
なお今回は、AMI、インスタンスタイプ、最大/最小台数のみしか指定していません。他の設定項目についてはデフォルトの値が登録されていますが、サブネットやセキュリティグループ、キーペアなどを指定してインスタンスを作成することもできますので詳しくは公式レファレンスをご覧ください。
インスタンス情報を取得するには、まず先ほどと同様に「boto3.resource('ec2')」と指定してEC2を利用する準備が整った後、情報を取得したい対象のインスタンスIDを引数に指定してInstanceオブジェクトを生成します。
このInstanceオブジェクトは、レファレンスに記載があるようにインスタンスの各種情報を「アトリビュート(属性)」として保持しているので、任意の属性を指定することでその値を取得できます。
import boto3 def lambda_handler(event, context): # EC2の利用準備 EC2 = boto3.resource("ec2", region_name='ap-northeast-1') # インスタンスIDを指定してインスタンス情報を取得 instance = ec2.Instance('i-0bb5293f3a46f5e55') # 各インスタンス情報を取得 image_id = instance.image_id instance_type = instance.instance_type security_groups = instance.security_groups state = instance.state launch_time = instance.launch_time # 各インスタンス情報を出力 print(image_id) print(instance_type) print(security_groups) print(state) print(launch_time)
こちらのコードの実行結果は図9のようになります。
また、特定のインスタンスではなく、存在するインスタンスの一覧を取得したい場合は、ServiceResourceクラスのinstancesコレクションのall()メソッドを利用します。
Lambda関数のコードは次のように記載します。
import boto3 def lambda_handler(event, context): # EC2の利用準備 EC2 = boto3.resource("ec2", region_name='ap-northeast-1') # EC2インスタンスの一覧を取得 instances = ec2.instances.all() # 取得した全EC2インスタンスの情報を出力 for instance in instances: instance_id = instance.instance_id instance_type = instance.instance_type print(instance_id, instance_type)
このコードを実行すると、今回は図11の通り、3つのEC2インスタンスのIDとインスタンスタイプを出力できます。
EC2インスタンスを停止するには、EC2インスタンスの情報を取得するときのように、インスタンスIDによって停止したいインスタンスを指定して、Instanceクラスのstop()メソッドを利用します。
import boto3 def lambda_handler(event, context): #EC2の利用準備 EC2 = boto3.resource("ec2", region_name='ap-northeast-1') # 停止するインスタンスのIDを指定 instance = ec2.Instance('i-0bb5293f3a46f5e55') # EC2インスタンスを停止 response = instance.stop() # EC2インスタンスのIDとステータスを出力 print(response['StoppingInstances'][0]['InstanceId'], response['StoppingInstances'][0]['CurrentState']['Name'])
こちらのLambda関数を実行した結果が図12です。
EC2インスタンスの一覧を見ると、Lambda関数の実施後に対象のインスタンスが停止していることを確認できます。
マルチクラウドへの閉域接続サービスのサービスマネジメント業務に従事した後、AWS案件での基盤構築支援などを担当。社内では、検証・学習用にAWSを完全定額で利用できるサービス「安心サンドボックス」の立ち上げや東京ITスクールのAWS研修におけるコンテンツ開発、Java・AWS研修の講師などを歴任。
Copyright © ITmedia, Inc. All Rights Reserved.