LoginSignup
28
29

More than 3 years have passed since last update.

AWSのLambdaとDynamoDBのローカル開発(SAM)

Last updated at Posted at 2019-02-11

概要

AWSのコンソールで割と簡単にLambdaの処理とDynamoDBのテーブルを作成したり、編集したりすることができます。

ただ、チームでやるプロジェクトだと、バージョン管理とローカルのテストが重要になってきます。

SAMのCLIを使うと本物のコンソールを使わなくても、ローカルで動作確認もできますし、簡単にAWSにデプロイもできます。

環境の情報

  • Windows 10
  • Docker for Windows
  • Visual Studio Code
  • Python 3.7 (他のでも大丈夫だと思います)

プロジェクト作成

プロジェクトフォルダーを作成し、VSCodeで開きます。

Pythonの確認

VSCodeのターミナルは【Ctrl+@】で開けます。

sam-lambda-dynamodb> python -V
Python 3.7.2

pipの更新

sam-lambda-dynamodb> python -m pip install --upgrade pip

仮想環境の作成

仮想環境を作ることで、別の環境で構築する時に、Pythonのインストールされているライブラリーのバージョンを簡単に合わせることができるので、ライブラリーのバージョンの違いで問題になることはなくなります。

sam-lambda-dynamodb> python -m venv venv
sam-lambda-dynamodb> .\venv\Scripts\activate
(venv) sam-lambda-dynamodb>

仮想環境に入っていると、左側に(venv)が表示されます。

activateスクリプトを実行できない場合、管理者として以下のコマンドを実行します。

set-executionpolicy remotesigned

仮想環境の中のpipの更新

(venv) sam-lambda-dynamodb> python -m pip install --upgrade pip

VSCodeのWorkspaceの設定

仮想環境のための設定を入れます。
- VSCODEに「Python」というExtensionをインストールします。
- 「F1」を押し、>Preferences: Open Workspace Settings を書きます。
- 「Python: Python Path」の設定を探し、仮想環境のpython.exeのパスを入力します。
- 例:C:\\Users\\path\\to\\sam-lambda-dynamodb\\venv\\Scripts\\python.exe
- 「Python: Venv Path」の設定を探し、仮想環境のベースパスを入力します。
- 例:C:\\Users\\path\\to\\sam-lambda-dynamodb\\venv
- 設定終わると、ワークスペースフォルダーに.vscode/settings.jsonが自動的に作成されます。
- settings.jsonの中身は以下のようになります。

settings.json
{
    "python.pythonPath": "C:\\Users\\path\\to\\sam-lambda-dynamodb\\venv\\Scripts\\python.exe",
    "python.venvPath": "C:\\Users\\path\\to\\sam-lambda-dynamodb\\venv"
}

仮想環境に必要なライブラリーをインストール

(venv) sam-lambda-dynamodb> pip install aws-sam-cli
(venv) sam-lambda-dynamodb> sam --version
SAM CLI, version 0.11.0
(venv) sam-lambda-dynamodb> pip install awscli
(venv) sam-lambda-dynamodb> aws --version
aws-cli/1.16.101 Python/3.7.2 Windows/10 botocore/1.12.91

他の環境でも同じライブラリーのバージョンになるため、requirements.txtを作成します。

(venv) sam-lambda-dynamodb> pip freeze | Out-File -Encoding UTF8 .\requirements.txt

requirements.txtからインストールしたい時、このコマンドでできます。
pip install -r requirements.txt

SAMのinit処理を実行

(venv) sam-lambda-dynamodb> sam init --runtime python3.7

こちらのコマンドを実行すると、sam-appのフォルダーが作成されます。
hello_worldのデフォルトプロジェクトは設定されているので、試してみましょう。

awsの設定

ローカル用のテスト環境なので、内容はあまり重要ではないです。

(venv) sam-lambda-dynamodb> aws configure
AWS Access Key ID [None]: testid
AWS Secret Access Key [None]: testsecret
Default region name [None]: ap-northeast-1
Default output format [None]: json

hello_worldのテンプレートのテスト

  • sam-appに入り、ビルドを実行
(venv) sam-lambda-dynamodb> cd .\sam-app\
(venv) sam-lambda-dynamodb\sam-app> sam build
  • dockerは実行中か確認し、APIを実行
(venv) sam-lambda-dynamodb\sam-app> sam local start-api
  • hello_worldのapiを実行

ブラウザーで「localhost:3000/hello」にアクセスします。

画面に{"message": "hello world"}が表示されたら成功です。

ローカルのDynamoDBの設定

Ctrl+C」でhello_worldのlambdaを止めます。

DynamoDBをプルします。

(venv) sam-lambda-dynamodb\sam-app> docker pull amazon/dynamodb-local

lambdaとdynamodbは同じネットワークにあると楽なので、dockerのネットワークを作成します。

(venv) sam-lambda-dynamodb\sam-app> docker network create lambda-local

containerを作成し、runします。

(venv) sam-lambda-dynamodb\sam-app> docker run --network lambda-local --name dynamodb -p 8000:8000 amazon/dynamodb-local -jar DynamoDBLocal.jar -sharedDb

runの後は「Ctrl+C」を押します。

PS: 上のコマンドを1回目の時にしか使わないです。次の実行の時「docker start dynamodb」のコマンドを使います。

DynamoDBのテーブルを作成

  • プロジェクトフォルダに「DynamoDB」のフォルダを作成し、AccessTable.jsonのファイルを作成します。
AccessTable.json
{
  "TableName": "Access",
  "KeySchema": [
    {
      "AttributeName": "Path",
      "KeyType": "HASH"
    },
    {
      "AttributeName": "Date",
      "KeyType": "RANGE"
    }
  ],
  "AttributeDefinitions": [
    {
      "AttributeName": "Path",
      "AttributeType": "S"
    },
    {
      "AttributeName": "Date",
      "AttributeType": "S"
    }
  ],
  "ProvisionedThroughput": {
    "ReadCapacityUnits": 2,
    "WriteCapacityUnits": 2
  }
}
  • プロジェクトのルートフォルダーに戻り、テーブルの作成コマンドを実行します。
(venv) sam-lambda-dynamodb\sam-app> cd ..
(venv) sam-lambda-dynamodb> aws dynamodb create-table --cli-input-json file://.\DynamoDB\AccessTable.json --endpoint-url http://localhost:8000
(venv) sam-lambda-dynamodb> aws dynamodb list-tables --endpoint-url http://localhost:8000
{
    "TableNames": [
        "Access"
    ]
}

これでテーブルの作成ができました。

「hello_world」のapiを編集

まず、ローカルと本番の接続処理は違うので、ローカルだとわかるようにtemplate.yamlに環境のパラメーターを追加します。

実際にデプロイをする時パラメーターを上書きできます。

template.yaml
... 略

+Parameters:
+    Env:
+        Type: String
+        Default: local

Globals:
    Function:
        Timeout: 3
+       Environment:
+           Variables:
+               ENV: !Ref Env

... 略

「hello_world」のフォルダーの中にあるrequirements.txtboto3のライブラリーを追加します。

requirements.txt
requests
boto3

「hello_world」のフォルダーの中にあるapp.pyを編集します。

returnの前に以下のコードを追加します。

app.py
import json
import boto3
import os
import logging
from datetime import datetime

# ... 略

try:
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)

    session = boto3.session.Session()
    awsRegion = session.region_name
    paramList = event['queryStringParameters']

    client = boto3.client('dynamodb')
    # ローカルの場合
    if os.environ['ENV'] == 'local':
        dynamodb = boto3.resource('dynamodb', region_name = awsRegion, endpoint_url = "http://dynamodb:8000")
    # ローカル以外の環境の場合
    else:
        dynamodb = boto3.resource('dynamodb', region_name = awsRegion)
    # テーブルを取得
    table = dynamodb.Table('Access')
    # 日時の文字列
    date = datetime.utcnow().isoformat()
    # 登録するアイテムのベース
    item = {'Path': event['path'], 'Date': date}

    if paramList != None:
        for key,value in paramList.items():
            item[key] = value

    table.put_item(
        Item=item
    )

except Exception as e:
    # Lambdaログにエクセプションの情報を入れる
    logger.exception(e)
    return {
        'statusCode': 500,
        'body': json.dumps({
            'error_message': str(e)
        }),
    }

# ... 略

APIを試す

もう一度「sam-app」に入り、ビルドを実行します。

(venv) sam-lambda-dynamodb> cd .\sam-app\
(venv) sam-lambda-dynamodb\sam-app> sam build

APIをlambda-localのネットワークで開始します。

(venv) sam-lambda-dynamodb\sam-app> sam local start-api --docker-network lambda-local

ブラウザーでGatewayにアクセスします。(http://localhost:3000/hello?param=test)

成功できたら、以下のコマンドでテーブルのアイテムが見れます。

(venv) sam-lambda-dynamodb> aws dynamodb scan --table-name Access --endpoint-url http://localhost:8000
{
    "Items": [
        {
            "Path": {
                "S": "/hello"
            },
            "param": {
                "S": "test"
            },
            "Date": {
                "S": "2019-02-11T03:48:44.017178"
            }
        }
    ],
    "Count": 1,
    "ScannedCount": 1,
    "ConsumedCapacity": null
}

これでDynamoDBとLambdaをローカルで使えるようになりました。

その他の情報

28
29
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
28
29