AWS Lambda でPHP動かして DynamoDBを操作する
AWS Lambda でPHP動かして DynamoDBを操作する:
この記事は、駆け出しエンジニアのための Advent Calendar 2018の15日目の記事です
先日ラスベガスで開催された、AWS re:Invent2018にて、
AWS Lambdaに、
Lambdaのサポート外の言語もLambda上で実行可能となりました。
今回は、PHPをLambda上で動かすために、STACKERYより提供されているこちらのPHPの Custom Runtimeを使用し、
Lambda上のPHPからDynamodbを操作するためにAWSが提供しているAWS SDK for PHPを使います。
PHPのCustom Runtime上で、
以下のように
こちらについては以下のカスタムランタイムのGithubのREADMEにて解説があります。
https://github.com/stackery/php-lambda-layer
データ登録処理
データ取得処理
最終的なディレクト構成 以下ようになります
AWS SAM CLI 用のデプロイファイル
パッケージしてS3バケットへアップロード
デプロイ
API Gatewayも同時に作成されているので、自動的に作成されたURLを確認し動作検証する
↓
レスポンスとして、発行されたIDが返却される
↓
以下のようにDynamoDBから取得したデータが表示される
DynamoDBを確認するとリクエストしたデータが登録されているはずです
https://dev.classmethod.jp/cloud/aws/php-vpc-lambda-alb-rds/
https://dev.classmethod.jp/cloud/aws/lambda-custom-runtime-php-extension
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GettingStarted.PHP.03.html
はじめに
この記事は、駆け出しエンジニアのための Advent Calendar 2018の15日目の記事です
re:Invent2018
先日ラスベガスで開催された、AWS re:Invent2018にて、AWS Lambdaに、
Custom Runtime
という機能が追加され、Lambdaのサポート外の言語もLambda上で実行可能となりました。
今回は、PHPをLambda上で動かすために、STACKERYより提供されているこちらのPHPの Custom Runtimeを使用し、
Lambda上のPHPからDynamodbを操作するためにAWSが提供しているAWS SDK for PHPを使います。
環境
- AWS CLI
デプロイ用 - AWS SAM CLI
デプロイ用 - Composer
AWS SDK for PHP
をインストールするために使用します。
開発準備
- 処理対象となる、DynamoDBを作成する
-
以下IAMポリシーがあるロールを作成する
- AmazonDynamoDBFullAccess
- AWSLambdaDynamoDBExecutionRole
- デプロイ用にファイルを上げるS3バケットを作成する
- 以下の構成でディレクトリを作成
|-- src | `-- php `-- template.yml //AWS SAM CLI のデプロイ時に必要な構成ファイル
- AWS SDK for PHPのインストール
$ php composer require aws/aws-sdk-php
- php.iniの編集
json.so
の機能が使えません。AWS SDK for PHP
では内部でjson.so
を使用しているため有効化する必要があります。PHPのCustom Runtime上で、
json.so
を有効化するために、php.iniファイルを作成し、以下のように
extension
を追加します。php.ini
extension=json.so
https://github.com/stackery/php-lambda-layer
プログラムの作成
データ登録処理post.php
<?php require 'vendor/autoload.php'; use Aws\Sdk; use Aws\DynamoDb\Marshaler; use Aws\DynamoDb\Exception\DynamoDbException; $tableName = 'php_test'; //対象のテーブル名 $name = $_GET["name"]; //GETでリクエストされたデータ(name)を取得 $sdk = new Sdk([ 'region' => 'ap-northeast-1', //使用するregion情報 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $marshaler = new Marshaler(); $uid = uniqid(); //登録用にuuidを作成 $item = $marshaler->marshalJson('{ "id": "' . $uid . '", "name": "'. $name .'" } '); $params = [ 'TableName' => $tableName, 'Item' => $item ]; try { $result = $dynamodb->putItem($params); echo "Added item success id:". $uid; } catch (DynamoDbException $e) { echo "Unable to add item:\n"; echo $e->getMessage() . "\n"; }
getphp
<?php require 'vendor/autoload.php'; use Aws\Sdk; use Aws\DynamoDb\Marshaler; use Aws\DynamoDb\Exception\DynamoDbException; $tableName = 'php_test'; //対象のテーブル名 $id = $_GET["id"]; //GETでリクエストされたデータ(id)を取得 $sdk = new Sdk([ 'region' => 'ap-northeast-1', //使用するregion情報 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $marshaler = new Marshaler(); $key = $marshaler->marshalJson('{ "id": "' . $id . '" } '); $params = [ 'TableName' => $tableName, 'Key' => $key ]; try { $result = $dynamodb->getItem($params); print_r($result["Item"]); } catch (DynamoDbException $e) { echo "Unable to get item:\n"; echo $e->getMessage() . "\n"; }
|-- src | `-- php | |-- vendor //AWS SDK for PHP | |-- composer.json //Composer file | |-- composer.lock //Composer file | |-- get.php //データ取得用処理 | |-- php.ini // php.ini | `-- post.php //データ登録用処理 `-- template.yml
template.yml
AWSTemplateFormatVersion: 2010-09-09 Description: My PHP Application Transform: AWS::Serverless-2016-10-31 Resources: phppost: Type: AWS::Serverless::Function Properties: FunctionName: !Sub test-phppost Description: PHP Post Role: [作成したロール情報] CodeUri: src/php Runtime: provided Handler: post.php MemorySize: 3008 Timeout: 30 Tracing: Active Layers: - !Sub arn:aws:lambda:[region]:887080169480:layer:php71:5 Events: api: Type: Api Properties: Path: /post Method: ANY phpget: Type: AWS::Serverless::Function Properties: FunctionName: !Sub test-phpget Description: PHP Get Role: [作成したロール情報] CodeUri: src/php Runtime: provided Handler: get.php MemorySize: 3008 Timeout: 30 Tracing: Active Layers: - !Sub arn:aws:lambda:[region]:887080169480:layer:php71:5 Events: api: Type: Api Properties: Path: /get Method: ANY
デプロイ
パッケージしてS3バケットへアップロード$ sam package --template-file template.yml --output-template-file serverless-output.yaml --s3-bucket [作成したS3バケット]
sam deploy --template-file serverless-output.yaml --stack-name custom-runtime-php71 --capabilities CAPABILITY_IAM
動作検証
API Gatewayも同時に作成されているので、自動的に作成されたURLを確認し動作検証する- 登録処理
登録する内容をURLパラメータname
をリクエストする
https://xxxxxxx.execute-api.[resion].amazonaws.com/Prod/post?name=tanaka
レスポンスとして、発行されたIDが返却される
Added item success id:5c14940af36b0
- データ取得処理
id
をリクエストするhttps://xxxxxx.execute-api.[resion].amazonaws.com/Prod/get?id=5c14940af36b0
以下のようにDynamoDBから取得したデータが表示される
Array ( [id] => Array ( [S] => 5c1524cec4aa7 ) [name] => Array ( [S] => tanaka ) )
参考
https://dev.classmethod.jp/cloud/aws/php-vpc-lambda-alb-rds/https://dev.classmethod.jp/cloud/aws/lambda-custom-runtime-php-extension
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GettingStarted.PHP.03.html
コメント
コメントを投稿