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

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


概要

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をローカルで使えるようになりました。


その他の情報

コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2020-12-01 09:41:49 RSSフィード2020-12-01 09:00 分まとめ(69件)