LoginSignup
0
2

More than 1 year has passed since last update.

【AWS】DynamoDBのデータ更新時にLambdaを使ってバックアップを作成するプログラムをpythonで実装する

Last updated at Posted at 2021-06-14

先日公開した記事『【個人開発】ごみのお知らせをしてくれるLINEBot「ごみのお知らせくん」を作りました。』を多くの方に見ていただいており、思った以上の反響に少し驚いています。Qiitaの通知が2桁だったことがなかったので、「何か悪いことをしてしまったのか...!?」とビビりました。LGTMやストックしていただき、ありがとうございます!

さて、本記事ではDynamoDBのデータ更新をトリガーにしてデータのバックアップを作成するというフローを、DynamoDBストリーム、Lambda、Pythonを使って実装する話について書いています。LINEBot『ごみのお知らせくん』で地区情報を更新した際にデータのバックアップを取っておきたいな、と思ったのがきっかけです。それでは早速いきましょう!

■構成

アプリ開発きっかけ.png
今回のシステム構成です。試行錯誤しながらだったので結構時間がかかったのですが、図にするとかなりシンプルですね。

■作業手順

下記が今回の実行手順です。
やりたい内容に沿ってカスタマイズしてください。

1.DynamoDBの「DynamoDB ストリーム」を有効にする
2.IAMロールとIAMポリシーを作成する
3.Lambda関数を作成する
4.バックアップ作成用のプログラムをアップロードする
5.IAMポリシーを少し修正
6.データを更新してバックアップが作成されることを確認

1.DynamoDBの「DynamoDB ストリーム」を有効にする

アプリ開発きっかけ.png

まず、DynamoDBのデータ変更をトリガーにするためDynamoDBストリームを有効にします。これを有効にすることでデータ変更を取得できるようになります。

「概要」タブにある項目「DynamoDBストリームの詳細」の「DynamoDBストリームを管理」をクリックします。クリックすると”どの情報を保存するか”という設定ポップアップが開くので、用途に合わせて選択し、有効化をクリックします。僕の場合は変更後の状態を保存しておきたかったので「新しいイメージ」を選択しました。

アプリ開発きっかけ.png

有効にすると上画像のようにストリーム有効の値が「はい」の表示になります。この時表示されるARNについては後ほど、IAMポリシーの設定で使用します。この値は覚えておかなくても大丈夫です。

2.IAMロールとIAMポリシーを作成する

アプリ開発きっかけ.png
Lambdaに設定するIAMロールとIAMポリシーを作成します。特に重要なDynamoDBに付与するポリシーについては太字で書いています。

作成するIAMポリシーは下記のようになります。これらのポリシーをIAMロールに付与し、IAMロールをLambdaに付与します。

■DynamoDB
 アクション:書き込み『CreateBackup』
 *リソース:DynamoDBのリソースを選択

 アクション:読み込み
 『GetRecords』『GetShardIterator』『ListStreams』『DescribeStream』
 *リソース:DynamoDBストリームのリソースを選択

■Lambda
 アクション:書き込み『InvokeFunction』
 *リソース:Lambdaの関数を選択

■CloudWatch Logs
 アクション:書き込み『すべて選択』
 リソース:すべてのリソース

ここで、「*」をつけたDynamoDBとLambdaのリソースについては後でまとめて設定するので、一旦は「すべてのリソース」で設定します。

3.Lambda関数を作成する

アプリ開発きっかけ.png

バックアップを作成するLambda関数を作成します。ここでは「createDynamoDBBackup」という名前で作成しています。

アプリ開発きっかけ.png

関数作成の際、先ほど作成したIAMロールを実行ロールに設定します。また、今回はpythonで実装するのでランタイムにはpythonを選択しています。

4.バックアップ作成用のプログラムをアップロードする

アプリ開発きっかけ.png
Lambdaのコードソースからソースをアップします。僕の場合はdockerで構築した開発環境でソースコードを用意しました。

下記が今回使用した、「pyファイル」「docker-compose.yml」「Dockerfile」です。Lambdaにアップロードするときにはoptディレクトリ配下をzipで圧縮します。dockerによる開発環境の構築については『補足』に記載しています。

■ ディレクトリ構成
docker-compose.yml
Dockerfile
opt
 L lambda_function.py
lambda_function.py
import json
import os
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)

import boto3

DATABASE = os.environ['DATABASE']
TABLE_NAME = os.environ['TABLE_NAME']

def lambda_handler(event, context):
    logger.info("backup取得開始")
    dynamodb_client = boto3.client(DATABASE)
    res = dynamodb_client.create_backup(
        TableName = TABLE_NAME,          # テーブル名
        BackupName  = TABLE_NAME + '_bk' # バックアップファイル名
    )
    logger.info(res)

    return {
        'statusCode': 200,
        'body': json.dumps('backup取得完了')
    }
docker-compose.yml
version: "3"
services:
  python3:
    build: .
    container_name: "python3_lambda"
    working_dir: "/root/opt"
    tty: true
    volumes:
      - ./opt:/root/opt
    ports:
      - "8000:80"
FROM python:3
USER root

RUN apt-get update

ADD . /code
WORKDIR /code
RUN apt-get install -y vim less
RUN pip install --upgrade pip
RUN pip install --upgrade setuptools

5.IAMポリシーを少し修正

アプリ開発きっかけ.png
Lambda関数が作成できたらDynamoDBをトリガーに追加します。

部品が揃ったので、IAMポリシーを少し修正していきます。

Lambdaのリソースを修正

アプリ開発きっかけ.png
IAMポリシーのLambdaリソースを先ほど作成したLambda関数に修正します。入力するのはLambdaの「関数のARN」の値です。「Lambda_functionのARNの設定」に入力すれば下の「Region」「Account」「Function name」欄にも自動的に入力されます。

DynamoDBのリソースを修正

アプリ開発きっかけ.png
▲DynamoDBストリームのARN

アプリ開発きっかけ.png
▲DynamoDBのARN

IAMポリシーのDynamoDBリソースに「DynamoDBストリームのARN」と「DynamoDBのARN」を入力します。ARNはそれぞれ上画像の部分です。

6.データを更新してバックアップが作成されることを確認

アプリ開発きっかけ.png
ここまで出来れば後は確認です。
Lambda関数は簡単にテストができるので確認してみます。

アプリ開発きっかけ.png

テストした際に該当テーブルの「バックアップ」タブに「テーブル名_bk」というファイルができていれば成功です。次は、DynamoDBのデータを更新してバックアップが出来ているか確認します。

バックアップができていない場合はどこかでエラーが起きているので、Lambdaの「モニタリング」タブでログを確認します。

アプリ開発きっかけ.png

バックアップファイルが確認できたら「バックアップの復元」をクリックして、更新したデータでテーブルができるかどうか確認します。問題なく出来ていれば完了です。

補足

pythonファイル、docker-compose.yml、Dockerfileついて

githubにアップしました。

コンテナ起動後、python3コンテナに入り、下記コマンドを実行してください。

・docker-compose.ymlがあるディレクトリで
docker-compose up -d

・ステータスがupになったら
docker-compose exec python3 bash

・boto3をインストール
pip install boto3 -t ./

boto3はpythonでAWSを操作するためのライブラリです。
Lambdaにzipでアップする必要があるので、現ディレクトリ(/opt内)にインストールするようにしています。

pythonコード内のos.environ['-']について

アプリ開発きっかけ.png

プログラム内にはDBの情報を直接記載せず、Lambdaの環境変数で設定しています。環境変数は、Lambdaの「設定」タブ→環境変数から設定ができます。

最後に

DynamoDBのバッグアップには「オンデマンドバックアップ」と「ポイントインタイムリカバリ」の2種類あります。オンデマンドバックアップはバックアップを取得した時点のテーブル状態を保存し、ポイントインタイムリカバリは有効にした時点からテーブルに対する更新処理が記録されます。

今回は「データが更新された際にバックアップを作成したいこと」「無料の範囲で実装したいこと」があったので、これらのバックアップ方法は使わず、DynamoDBストリームとLambdaを組み合わせました。

ポイントインタイムリカバリを有効にしようとすると「追加料金がかかります」というように表示がされるため、『この方法は料金がかかってしまう!これでは実現できない!』と考え、本記事の実装をしました。ですが、ポイントタイムリカバリの説明を改めて見てみると、もしかしたらポイントタイムリカバリでもできるんですかね...?この部分についてはまた改めて調べてみたいと思います。ご存知の方がいたら教えて欲しいです。

それでは!

参考サイト

Amazon DynamoDB
https://boto3.amazonaws.com/v1/documentation/api/latest/guide/dynamodb.html

CreateBackup
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/APIReference/API_CreateBackup.html

DynamoDB StreamをトリガーにしてLambdaを実行する
https://qiita.com/Fujimon_fn/items/1f18360ee9ebf6832617

チュートリアル: DynamoDB Streams と Lambda を使用して新しい項目を処理する
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Streams.Lambda.Tutorial.html#Streams.Lambda.Tutorial.CreateTrigger

DynamoDB テーブルのバックアップ
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Backup.Tutorial.html

AWS SDK for Python (Boto3) の “Client API” と “Resource API” の違いについて調べてみた
https://dev.classmethod.jp/articles/boto3-client-api-and-resource-api/

ステップ 3: Python で項目を作成、読み込み、更新、削除する
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GettingStarted.Python.03.html

AWS Lambda 実行ロール
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-intro-execution-role.html

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2