
AWS入門 初心者が覚えておくべきAWSの基本
AWS Lambdaの一般的な利用方法の中から1つを取り上げ、環境構築からLambda関数の作成および動作確認までの一連の作業手順を詳細に解説しています。
今回はDynamoDBを操作するLambdaの作成手順を解説します。
また今回はLambdaの起動するサービスとしてAmazon API Gatewayを使用します。Amzon API Gatewayを使用することで、LambdaをREST APIとして外部ネットワークから利用することができます。
Amazon API GatewayでのREST API作成から外部ネットワークからのアクセス確認手順についても併せて解説します。
LambdaとAmazon API Gatewayの組み合わせは、外部ネットワークで動作しているアプリケーションからDynamoDBやS3などのAWSサービスにアクセスする際によく使用される形態のひとつです。
ユースケースとしては以下のようなものがあります。
動作の全体像を以下に示します。
Amazon API GatewayがユーザからHTTPリクエストを受信すると、登録しているLambdaを起動します。
起動されたLambda関数は、引数からDynamoDBの操作要求を抽出して要求に応じた操作(全レコードスキャン/指定レコード検索/レコードの追加・更新/レコードの削除)を実行し、結果を応答します。
Amazon API GatewayはLambdaから受け取った応答メッセージをユーザへ返信します。
サンプル用のDBを作成します。今回はデバイスに搭載された温度、湿度センサーの計測値を管理するDBを以下の内容で作成します。
キー設定 | カラム名 | 意味 | 記事 |
---|---|---|---|
パーティションキー | DeviceID | 装置識別子 | DevXXXX ※XXXX:0001からの整数 |
ソートキー | SensorID | センサー識別子 |
温度:TempXXX 湿度:HumXXX ※XXX:001からの整数 |
- | value | 値(温度/湿度) | 整数 |
- | unit | 単位 | 温度:℃/湿度:% |
DynamoDBコンソール画面から「テーブル作成」ボタンを押下します。
テーブル作成画面で以下を設定し、画面右下の「作成」ボタンを押下します。
動作確認用に幾つかのレコードを作成します。
DynamoDBのコンソール画面から「テーブル」のメニュー画面を開きます。
「テーブル」一覧から「SensorTables」を選択します。
「SensorTables」の設定画面から「項目」タブを選択します。
「項目」タブの画面から「項目の追加」ボタンを押下します。
「項目の作成」画面が開くので、以下を設定します。
最後に画面右下の「保存」ボタンを押下します。
湿度のレコードを作成します。
「SensorTables」の設定画面から「アクション」ボタンを押下します。
ドロップダウンリストから「コピー」を選択します。
「項目の作成」画面が開くので、以下を設定します。
最後に画面右下の「保存」ボタンを押下します。
同様の手順でDeviceIDがDev0003までの温度&湿度センサーレコードを作成します。
LambdaがDynamoDBにアクセスするためのIAMロールを作成します。
IAMコンソール画面の左ペインから「ロール」を選択します。
「ロール」の設定画面から「ロールの作成」ボタンを押下します。
「ロールの作成」画面からデフォルトで選択されている「AWSサービス」を選択し、「ユースケースの選択」一覧から「Lambda」を選択します。
「ユースケースの選択」画面が表示されるので「次のステップ:アクセス権限」ボタンを押下します。
「Attachアクセス権限ポリシー」作成画面が表示されるので「ポリシーのフィルタ」のキーワード入力欄に「dynamo」と入力します。
表示された候補から以下を選択し、「次のステップ:タグ」ボタンを押下します。
「AmazonDynamoDBFullAccess」
「AWSLambdaDynamoDBExecutionRole」
「タグの追加(オプション)」設定画面では何もせず、「次のステップ:確認」ボタンを押下します。
「確認」画面が表示されるので「ロール名」に「LambdaAccess2DynamoDB」と入力し、「ロールの作成」ボタンを押下します。
ロールの作成が完了するとロールの一覧に作成した「LambdaAccess2DynamoDB」が登録されます。
DynamoDBの操作を行うLambda関数を作成します。
Lambdaの作成方法には以下の2通りがあります。
①AWS Lambdaコンソールで直接コードを作成。
②外部ライブラリとLambda関数をパッケージ化してアップロード。
今回はDynamoDBの操作のみで外部ライブラリを必要としないため、①での作成になります。
Lambdaコンソールから「関数の作成」ボタンを押下します。「関数の作成」画面のオプションの中から「一から作成」を選択します。
「基本的な情報」画面が表示されるので以下を設定します
「実行ロール」の候補の中から「既存のロールを使用する」を選択
キーワード入力欄に「LambdaAccess」と入力。
表示された候補から「LambdaAccess2DynamoDB」を選択
「関数の作成」ボタンを押下
デフォルトで提供されているLambda関数を編集してDynamoDBを操作するコードを作成します。
コード内容を以下に示します。
import json
import boto3
from boto3.dynamodb.conditions import Key //Keyオブジェクトを利用できるようにする
dynamodb = boto3.resource('dynamodb') //Dynamodbアクセスのためのオブジェクト取得
table = dynamodb.Table("SensorTables") //指定テーブルのアクセスオブジェクト取得
# テーブルスキャン
def operation_scan()::
scanData = table.scan() //scan()メソッドでテーブル内をscan。一覧を取得
items=scanData['Items'] //応答からレコード一覧を抽出
print(items) //レコード一覧を表示
return scanData
# レコード検索
def operation_query(partitionKey, sortKey):
queryData = table.query( //query()メソッドでテーブル内を検索
KeyConditionExpression = Key("DeviceID").eq(partitionKey) & Key("SensorID").eq(sortKey) //検索キー(DeviceIDとSensorID)を設定
)
items=queryData['Items'] //応答から取得レコードを抽出
print(items) //取得レコードを表示
return queryData
# レコード追加・更新
def operation_put(partitionKey, sortKey, value, unit):
putResponse = table.put_item( //put_item()メソッドで追加・更新レコードを設定
Item={ //追加・更新対象レコードのカラムリストを設定
'DeviceID': partitionKey,
'SensorID': sortKey,
'value': value,
'unit': unit
}
)
if putResponse['ResponseMetadata']['HTTPStatusCode'] != 200: //HTTPステータスコードが200 OKでないか判定
print(putResponse) //エラーレスポンスを表示
else:
print('PUT Successed.')
return putResponse
# レコード削除
def operation_delete(partitionKey, sortKey):
delResponse = table.delete_item( //delete()メソッドで指定テーブルを削除
key={ //Keyオブジェクトで削除対象レコードのキー設定
'DeviceID': partitionKey,
'SensorID': sortKey
}
)
if delResponse['ResponseMetadata']['HTTPStatusCode'] != 200: //HTTPステータスコードが200 OKでないか判定
print(delResponse) //エラーレスポンスを表示
else:
print('DEL Successed.')
return delResponse
def lambda_handler(event, context): //Lambdaから最初に呼びされるハンドラ関数
print("Received event: " + json.dumps(event)) //引数:eventの内容を表示
OperationType = event['OperationType'] //引数から操作タイプを取得
try:
if OperationType == 'SCAN': //OperationTypeが'SCAN'か判定
return operation_scan()
PartitionKey = event['Keys']['DeviceID'] //引数からDeviceIDの値を取得
SortKey = event['Keys']['SensorID'] //引数からSensorIDの値を取得
if OperationType == 'QUERY': //OperationTypeが'QUERY'か判定
return operation_query(PartitionKey, SortKey)
elif OperationType == 'PUT': //OperationTypeが'PUT'か判定
Value = event['Keys']['value'] //引数からvalueの値を取得
Unit = event['Keys']['unit'] //引数からunitの値を取得
return operation_put(PartitionKey, SortKey, Value, Unit)
elif OperationType == 'DELETE': //OperationTypeが'DELETE'か判定
return operation_delete(PartitionKey, SortKey)
except Exception as e:
print("Error Exception.")
print(e)
(※)LambdaからDynamoDBへのアクセスにはAWS SDK for Python(boto3)を使用します。
boto3全体のドキュメントは「Boto 3 Documentation」を参照してください
boto3でのDynamoDBについての記載は「DynamoDB」を参照してください
(※) boto3ではDynamoDBのテーブル操作手段として2種類のクラスが提供されています。
DynamoDB.Client()はDynamoDBの全般の操作が可能なクラスで、DynamoDB.Table()はテーブル操作に特化したクラスです。テーブル操作に特化している分、操作性が良いので今回はDynamoDB.Table()クラスを使用します。
以下にDynamoDB.Table()クラスの使用方法とそれぞれのメソッド仕様を解説します。
import boto3 //boto3をインポート
from boto3.dynamodb.conditions import Key //boto3.dynamodb.conditionsのKeyクラスをインポート
dynamodb = boto3.resource('dynamodb') //DynamoDBアクセスのためのオブジェクトを取得
table = dynamodb.Table("テーブル名") //引数のテーブルへのアクセスのためのオブジェクトを取得
テーブル内の全レコードをスキャンし、取得したレコード一覧を返します。
書式:
response = table.scan()
戻り値:
レコード一覧(dict形式)
主キーに基づいてアイテムを検索します。パーティションキーとソートキーの複合キーでの検索も可能です。
書式:
response = table.query(
KeyConditionExpression=Key('key1').eq('keyValue1')
)
引数:
KeyConditionExpression=Key('mykey').eq('myvalue')
KeyConditionExpression:キー、インデックスによる検索の定義
'mykey':キー名
'myvalue':キー値
複合キーの場合はKey('key1').eq('keyValue1')& Key('key2').eq('keyValue2')としてください。
戻り値:
検索条件に一致したレコード(dict形式)
テーブル内に引数のレコードを設定します。テーブル内に引数のレコードが存在しない場合は新たに追加し、存在する場合は引数の内容で上書き更新します。
(※)引数で設定した内容をそのまま設定するため、更新時でも全ての要素を設定する必要があります。引数にない要素は空欄として設定されます。
書式:
response = table.put_item(
Item={'key1': 'keyValue1', 'key2': 'keyValue2', 'column1': ' columnValue1',・・・}
)
引数:
Item={'key1': 'keyValue1', 'key2': 'keyValue2', 'column1': ' columnValue1',・・・}
テーブルに設定するアイテム。
(※)dict形式でプライマリーキー、ソートキーの他、レコード内の要素を全て設定してください
戻り値:
実行結果(dict形式)
指定したキーに一致するレコードを削除します。
書式:
response = table.delete_item(
Key={'key1': keyValue1', 'key2': 'keyValue2'}
)
引数:
Key={'key1': keyValue1', 'key2': 'keyValue2'}
dict形式でプライマリーキー、ソートキーを設定
戻り値:
実行結果(dict形式)
Lambda関数「HeatHumiditySensorSet」のメニュー画面を「関数コード」の設定欄まで画面をスクロールします。
関数コードを上記の内容に書き替えます。
画面右上の「保存」ボタンを押下して関数コードの内容を保存します。
Amazon API Gatewayのコンソール画面から「APIを作成」ボタンを押下します。
「APIタイプの選択」画面で「REST API」を選択し「構築」ボタンを押下します。
以下を設定し、画面右下の「APIの作成」ボタンを押下します。
APIが作成されると「API:LambdaRest」のトップページが開きます。
「アクション」ボタンを押下し、ドロップダウンリストから「リソースの作成」を選択します。
「リソース名」に「dynamodbctrl」と設定し、面右下の「リソースの作成」ボタンを押下します。
「アクション」ボタンを押下し、ドロップダウンリストから「メソッドの作成」を選択します。
「/dynamodbctrl」の下にメソッド設定用の空欄が作成されますのでクリックします。
ドロップダウンリストから「POST」を選択します。
「POST」の右横にある「✓」を押下します。
「POSTのセットアップ」画面が開くので以下を設定し画面右下の「保存」ボタンを押下します。
「保存」ボタンを押下すると「Lambda関数に権限を追加する」というポップアップメッセージが表示されるので「OK」ボタンを押下してください。
これによりPOSTメソッドリクエストがLambda関数「HeatHumiditySensorSet」に渡されるルートが確立されます。
この設定によりLambda関数「HeatHumiditySensorSet」に自動的にAPI Gatewayのトリガーが設定されます。
API Gateway内部でのテストを実施し、API GatewayのAPI設定とLambda関数の動作確認を実施します。
「POST – メソッドの実行」画面で「テスト」ボタンを押下します。
「POST –メソッドテスト」の入力画面が開きます。
「リクエスト本文」にLambda関数に渡すメッセージをJSON形式で入力し、「テスト」ボタンを押下します。
図はテーブルスキャン要求の入力例になります。
Lambda関数「HeatHumiditySensorSet」に渡すメッセージは以下のように作成します。
操作 | 意味 | リクエスト本文 | 記事 |
---|---|---|---|
SCAN | スキャン |
{ "OperationType": "SCAN" } |
操作タイプにSCANを設定 |
QUERY | 検索 |
{ "OperationType": "QUERY", "Keys": { "DeviceID":"DevXXXX", "SensorID":"XXX00X" } |
操作タイプにQUERYを設定 Keys:検索用のキーを定義 "DevXXXX":(※)XXXX:0001からの整数 "XXX00X":(※)TempXXX or HumXXX ※XXX=001からの整数 |
PUT | 追加/変更 |
{ "OperationType": "PUT", "Keys": { "DeviceID":"DevXXXX", "SensorID":" XXX00X", "value":XX, "unit":"X" } |
操作タイプにPUTを設定 Keys:追加/変更対象のレコード内容を定義 "DevXXXX":(※)XXXX:0001からの整数 "XXX00X":(※)TempXXX or HumXXX ※XXX=001からの整数 |
DELETE | 削除 |
{ "OperationType": "DELETE", "Keys": { "DeviceID":"DevXXXX", "SensorID":"XXX00X" } |
操作タイプにDELETEを設定 Keys:削除対象レコードのキーを定義 "DevXXXX":(※)XXXX:0001からの整数 "XXX00X":(※)TempXXX or HumXXX ※XXX=001からの整数 |
テストを実行すると、メソッドテスト画面右側に応答情報が表示されます。
図はテーブルスキャンを実施した際の応答になります。
Lambdaのログからも動作内容を確認することが出来ます。
Lambda関数「HeatHumiditySensorSet」のメニュー画面から「モニタリング」タブを選択します。
「モニタリングタブ」画面から「CloudWatchのログを表示」を選択します。
Lambda関数「HeatHumiditySensorSet」のロググループにジャンプします。
ログストリームのリストに表示されているファイルをクリックすると、Lambda関数のログ詳細を見ることが出来ます。
図はテーブルスキャンを実施した際のログになります。
作成したAPIを外部に公開して外部ネットワークからアクセスできるようにします。
APIをデプロイすることによりAPIが外部に公開されます。
「POST – メソッドの実行」画面で「アクション」ボタンを押下します。
ドロップダウンリストから「APIのデプロイ」を選択します。
「APIのデプロイ」画面が開くので以下を設定し「デプロイ」ボタンを押下します。
※ステージ名は以下のようにAPIのURLの一部に使用されます。
https://{restapi_id}.execute-api.{region}.amazonaws.com/{stage_name}/
※{restapi_id} : API ID(一意性を持ったAPIの識別子)
{region} :リージョン
{stage_name} :ステージ名
APIのデプロイに成功すると、「ステージエディター」が表示され、APIにアクセスするためのURLが表示されます。
公開されたAPIに対し、外部からアクセス可能か確認します。
アクセス確認にはcurlコマンドやAPI開発ツール「Postman」を使う方法などがあります。今回はcurlコマンドでの接続テスト方法について解説します。
Amazon API Gatewayへは、以下の書式でcurlコマンドを実行してください。
curl –X POST https://URL -d PARAM | jq
以下にDynamoDBに対し、scan, query, put, deleteそれぞれの入力例と実行例を示します
入力例
$ curl -X POST 'https://XXXXXX.execute-api.ap-northeast-1.amazonaws.com/APItest/dynamodbctrl' -d '{"OperationType":"SCAN"}' | jq
実行例
レコードリストが返信されます。jqコマンドにより応答メッセージが整形されます。
入力例
$ curl -X POST 'https://XXXXXX.execute-api.ap-northeast-1.amazonaws.com/APItest/dynamodbctrl' -d '{"OperationType":"QUERY","Keys":{"DeviceID": "Dev0003", "SensorID": "Temp003"}}' | jq
実行例
Dev0003, Temp003のレコードが返信されます。jqコマンドにより応答メッセージが整形されます。
入力例
$ curl -X POST 'https://XXXXXX.execute-api.ap-northeast-1.amazonaws.com/APItest/dynamodbctrl' -d '{"OperationType":"PUT","Keys":{"unit": "\u2103", "value": 23, "DeviceID": "Dev0005", "SensorID": "Temp005"}}' | jq
実行例
実行結果が返信されます。jqコマンドにより応答メッセージが整形されます。
DyanamoDBのコンソールで「SensorTables」の設定画面からDeviceID:Dev0005, SensorID:Temp005のレコードが追加されたことが確認できます。
入力例
$ curl -X POST 'https://XXXXXX.execute-api.ap-northeast-1.amazonaws.com/APItest/dynamodbctrl' -d ' {"OperationType":"DELETE","Keys":{"DeviceID": "Dev0005", "SensorID": "Temp005"}}' | jq
実行例
実行結果が返信されます。jqコマンドにより応答メッセージが整形されます
DyanamoDBのコンソールで「SensorTables」の設定画面からDeviceID:Dev0005, SensorID:Temp005のレコードが削除されたことが確認できます。
DynamoDBの操作を行うLambdaと、LambdaをREST APIとして外部ネットワークに公開するAmazon API Gatewayの作成手順と環境構築から外部ネットワークからのアクセス確認手順まで解説しました。
LambdaでのDynamoDBの操作方法、Amazon API GatewayでのREST API作成と外部への公開方法などが理解できたと思います。
Amazon API GatewayとLambdaの組み合わせは外部ネットワークからREST APIとしてAWSサービスを利用できるため、手軽にAWSサービスを利用したWebアプリケーションを開発することができます。
やはり難しい??事例からAWS Lambda活用のヒントを得ましょう!
一歩進んだAWS Lambda活用!ローカル環境での活用方法を学びましょう。
自社のクラウド導入に必要な知識、ポイントを
この1冊に総まとめ!
初めての自社クラウド導入、
わからないことが多く困ってしまいますよね。
クラウド化のポイントを知らずに導入を進めると、以下のような事になってしまうことも・・・
など、この1冊だけで自社のクラウド化のポイントが簡単に理解できます。
またNTT東日本でクラウド化を実現し
問題を解決した事例や、
導入サポートサービスも掲載しているので、
ぜひダウンロードして読んでみてください。
NTT東日本なら貴社のクラウド導入設計から
ネットワーク環境構築・セキュリティ・運用まで
”ワンストップ支援”が可能です!
特に以下に当てはまる方はお気軽に
ご相談ください。
クラウドを熟知するプロが、クラウド導入におけるお客さまのLAN 環境や接続ネットワーク、
クラウドサービスまでトータルにお客さまのお悩みや課題の解決をサポートします。
相談無料!プロが中立的にアドバイスいたします
クラウド・AWS・Azureでお困りの方はお気軽にご相談ください。