NEWSニュース&ブログ

「AWS Lambda for Python」でSnapshotを取得する

この記事は最終更新から9年以上経過しています。内容が古くなっている可能性があります。

投稿日:2015/12/2

今回のブログを更新します、クラウド事業部の東京エリア担当の関口です。

EC2にアタッチされているEBSのSnapshotを定期的に取得する時、今までバックアップスクリプト実行用サーバ(EC2)を用意し、そのサーバからスクリプトを実行したりしていました。
しかしながら、バックスクリプトを実行するサーバ分のコストが掛るため、何とかしたいな~と考えておりました。(他のサーバに機能を相乗りさせた場合も可用性の面や本来機能に影響を与えないようにするなど、考慮する事がいろいろあります。)

2015年10月にAWS Lambdaにcronの様なスケジュール機能などが追加されております。
そこで、AWS LambdaからSnapshot取得をやってみましたのでご紹介したいと思います。

やりたいこと

① AWS Lambdaから指定時間にバックアップスクリプトを実行
② バックアップ対象のEBS Snapshotを取得(管理する世代数を超えるものは削除)
③ バックアップスクリプト完了、失敗時にAWS SNSでメール通知

事前準備

AWS Lambdaの設定を行う前にIAM Role作成やスクリプト作成などいくつか準備を行いました。

1.IAM Role作成

AWS Lambda用のIAM Roleを作成します。(Lambdaを設定する時でも作成可能です。)
Policyには以下のアクセス許可を付与しました。
・EC2の参照権限
・Tagを操作する権限(作成したSnapshotにTagを付けたりするため)
・Snapshot作成・削除権限
・AWS SNSのPublish権限

2.AWS SNS Topic・Subscriptions作成

バックアップスクリプト完了、失敗メールの送信先を設定します。

3.バックアップスクリプト作成

今回はAWS Lambdaの「Python版」でスクリプトを動かします。(Python対応となったので)
その為、Pythonでスクリプトを作成します。

# coding: utf-8

import boto.ec2
import boto.sns
import re

def lambda_handler(event, context):       ← 引数を“event”と“context”にする。
        # 東京リージョン
        region = 'ap-northeast-1'

        ec2 = boto.ec2.connect_to_region(region)
           :
          <省略>
           :
# バックアップ成功メッセージを通知
        topic = 'arn:aws:sns:ap-northeast-1:<AWSアカウントID>:<Topic>
        subject = '[INFO] Daily Backup'
        body = 'Daily Backup Compleated!!' 
        conn = boto.sns.connect_to_region(region)
        conn.publish(topic, body, subject)

少し長くなるのでスクリプトの内容は省略します。
今回は”boto3”ではなく、“boto”を使用しました。(こっちの方が慣れていたので。。。)

スクリプトの内容としては…
①EC2のTagを確認して、バックアップ対象かどうかを確認
②対象である場合はSnapshot取得を開始
③保存世代数を超えるSnapshotを削除(保存世代数はTagに設定)
④ 完了・失敗のメール送信
といった様なものとなっています。

4.作成したスクリプトとPythonライブラリをzipでまとめる

Lambdaにアップロードするzipファイルを作成します。
今回は、古い方の“boto“と”re“ライブラリといった標準ライブラリではないものを使いたかったので、スクリプトと一緒にzipファイルにまとめました。
zipでまとめる時の注意点は以下となります。
※1.zipファイル名が「スクリプト名+.zip」となるようにする。
※2.zipファイルを解凍した時にzipファイルと同名のディレクトリが作成されない様にする。

例) zipファイルの構成

lambda_snapshot.zip
  |- lambda_snapshot.py
  |- boto ※ディレクトリ
  |- boto-2.38.0.dist-info ※ディレクトリ
       :
       :

AWS Lambdaの設定

事前準備が長くなりましたが、ここからAWS Lambdaの設定になります。

以下の設定を実施します。
1.AWS Lambdaの設定画面
2.Blueprintsを選択
3.Event sources設定
4.Configure function設定
5.Event source設定

1.AWS Lambdaの設定画面

AWSマネジメントコンソールにログインし、AWS Lambdaの設定画面の「Get Start Now」を押下します。(既に別のLambda functionがある場合は「Create a Lambda function」を押下します。)


2.“Blueprints”を選択

今回はスケジュール実行する為「lambda-canary」を選択しました。



3.event sources設定

“event sources”を設定して、「Next」を押下します。


・Event source type:Schedule Event ※スケジュール実行
・Name:※適当な名前を設定します。
・Description:※適当な説明を設定します。
・Schedule expression:※実行間隔を設定します。例:cron(0 19 * * ? *)

4.Configure function設定

“Configure function”“で実行するスクリプト等の設定をして、「Next」を押下します。

■Configure function

・Name:※適当な名前を設定
・Description:※説明文を入力。
・Runtime:※“Python2.7”を選択する。

■Lambda function code

・Code entry type:※”Upload a ZIP file”で作成したzipファイルをUploadする。

■Lambda function handler and role

・Handler:※“<スクリプトファイル名(“.py”無し)>.lambda_handler”と設定する。
・Role:※作成したRoleを選択する。

■Advanced settings

・Memory (MB):128MB ※といあえずデフォルトの最小値を設定。
・Timeout:30sec ※デフォルトの”10sec”では短かったので少し延ばしました。

5.Event source設定

Event sourceを”Enable now”にして「Create function」を押下します。


テスト実行

AWS Lambdaの設定が完了したので、動作確認を行ってみます。

1.移動

“Lambda” -> “Functions” -> <設定した“Lambda Function”名>へ移動します。

2.テストコード作成

”Action” -> “Configure test event”へ移動し、Eventを発生させるテストコードを作成します。

以下の様なコードを設定しました。

{
  "account": "<AWSアカウントID>",
  "region": "ap-northeast-1",
  "detail": {},
  "detail-type": "Scheduled Event",
  "source": "aws.events",
  "time": "1970-01-01T00:00:00Z",
  "id": "*********-****-****-****-************",
  "resources": [
    "arn:aws:events:ap-northeast-1:<AWSアカウントID>:rule/<“Lamda Function”名>
  ]
}

3.テスト実行

「Test」を押下し、テスト実行します。
blog48_008

4.テスト結果確認

「Execution result succeeded」と表示されれば成功です。

また、問題なければバックアップ完了のメールもAWS SNSで設定したメール送信先に届いていると思います。

最後に

バックアップスクリプト実行用サーバを“AWS Lambda”を使ってサーバレス化してみました。
これによりAWS利用料金コストを抑えることと、スケーラビリティと可用性を高めることができたのではないかと思います。

また、バックアップスクリプトについてですが、今回”boto”で作成しているので“boto3”に作り変えていこうと思います。
良いものができたら公開していきたいと思います。