🙌

Laravelでローカル/本番環境のDynamoDBへアクセスするまで

2023/10/28に公開

できるようになること

Laravel、DynamoDB、DynanoDBのGUIをdockerでローカル環境に構築し、データアクセス及びGUIでのデータの確認ができる。また環境変数の設定を変えることでAWS本番環境に対してもでデータアクセスができる。

やること

  • ローカル環境にDynamoDBをエミュレート(by LocalStack)
  • ローカル環境のDynamoDBのGUIを用意(by dynamodb-admin)
  • DynamoDBへデータアクセス(by baopham/laravel-dynamodb)
  • データ取得は環境変数に応じてローカル/本番環境を切り替え

バージョン

  • PHP 7.2.10
  • Laravel 10.29.0
  • LocalStack 0.14.4

前提

  • dockerがインストールされている。

dockerでローカル環境立ち上げ

LocalStackはAWSの各種サービスをエミュレートしてくれるツール
今回はこれを使用してローカル環境のDynamoDBを立ち上げる。
https://docs.localstack.cloud/user-guide/aws/dynamodb/

またDynamoDBのGUI構築にはdynamodb-adminを使用

手順

  1. docker-compose.ymlを作成
docker-compose.yml
version: "3"

services:
  web:
    container_name: web
    image: laravelfans/laravel:10.29.0
    platform: linux/amd64
    ports:
      - 8080:80
    environment:
      - COMPOSER_MEMORY_LIMIT=-1
    depends_on:
      - localstack
    # volumes:
    #   - ./src:/var/www/laravel
  localstack:
    container_name: localstack
    image: localstack/localstack:0.14.4
    ports:
      - 4566:4566
    volumes:
      - 'localstack-data:/tmp/localstack'
    environment:
      - SERVICES=dynamodb
      - AWS_ACCESS_KEY_ID=test
      - AWS_SECRET_ACCESS_KEY=test
      - AWS_DEFAULT_REGION=ap-northeast-1
      - DATA_DIR=/tmp/localstack/data
      - DISABLE_CORS_CHECKS=1
  dynamodb-admin:
    container_name: dynamodb-admin
    image: aaronshaf/dynamodb-admin:latest
    ports:
      - 8081:8001
    environment:
      - DYNAMO_ENDPOINT=localstack:4566
      - AWS_REGION=ap-northeast-1
    depends_on:
      - localstack
volumes:
  localstack-data:
    driver: 'local'
  1. コンテナを立ち上げる。
$ docker-compose -f docker-compose.yml up
  1. プロジェクトのルートディレクトリ(docker-compose.ymlと同じ階層)にLaravelのコード一式を格納してリネーム。
  1. コンテナを一度落として、docker-compose.ymlの以下のコメントアウトを外して立ち上げ直す。
    # volumes:
    #   - ./src:/var/www/laravel
  1. 確認
    http://localhost:8080/にアクセスしてLaravelの初期画面
    http://localhost:8081/にアクセスしてDynamoDBのGUI
    が表示されればOK。

DynamoDBへアクセス

baopham/laravel-dynamodbを使えるようにする。
https://github.com/baopham/laravel-dynamodb

手順

  1. コンテナの中に入る
$ docker exec -it web /bin/bash 
  1. ライブラリをインストール
# composer require baopham/dynamodb
  1. config/app.phpのprovidersに以下を追加
config/app.php
'providers' => [
    ...
    BaoPham\DynamoDb\DynamoDbServiceProvider::class,
    ...
];
  1. 以下を実行してconfig/dynamo.phpを作成
# php artisan vendor:publish --provider 'BaoPham\DynamoDb\DynamoDbServiceProvider'
  1. config/dynamo.phpのlocalのregionを変更
    LocalStackをap-northeast-1で立ち上げているので、ap-northeast-1を指定できるようにする。
config/dynamo.php
'local' => [
    'credentials' => [
	'key' => 'dynamodblocal',
	'secret' => 'secret',
    ],
-     'region' => 'stub',
+     'region' => env('DYNAMODB_REGION'),
     // see http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tools.DynamoDBLocal.html
    'endpoint' => env('DYNAMODB_LOCAL_ENDPOINT'),
    'debug' => true,
],
  1. 環境変数の設定
    .envを作成して以下を設定
    この内容はconfig/dynamo.phpに読み込まれて使用される。
.env
DYNAMODB_CONNECTION=local
DYNAMODB_KEY=test
DYNAMODB_SECRET=test
DYNAMODB_REGION=ap-northeast-1
DYNAMODB_LOCAL_ENDPOINT=http://host.docker.internal:4566/

上記はローカル環境に対する設定で本番環境に接続する際は以下となる。
キーはアクセスしたい本番のDynamoDBに対するアクセス権限があるIAMユーザーのものを入れる。

.env
DYNAMODB_CONNECTION=aws
DYNAMODB_KEY=[AWSのアクセスキー]
DYNAMODB_SECRET=[AWSのシークレットキー]
DYNAMODB_REGION=ap-northeast-1
  1. モデルを作成
    (既にDynamoDBにCommentテーブルが作成されている前提。dynamodb-adminでポチポチして作れる。)
# php artisan make:model Comment
  1. 以下の要領で記述
Comment.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use BaoPham\DynamoDb\DynamoDbModel;

class Comment extends DynamoDbModel
{
    use HasFactory;

    protected $table = 'Comment';
}
  • インストールしたライブラリが使えるようにBaoPham\DynamoDb\DynamoDbModelをuseする。
  • Modelクラスの継承をDynamoDbModelクラスにする。
  • protected $tableでテーブル名を指定する。

これで以下のようなEloquentを使ったデータアクセスができるようになっているはず。

$comments = Comment::all();

あとはControllerやviewを作成して、ルーティングを設定してと、いつも通りのことをやるだけ。

参考

https://zenn.dev/dove/articles/c0bc8aca695f07
https://zenn.dev/goemon/articles/2a78c3e52d40c8
https://tech.willgate.co.jp/entry/2018/02/28/134537

Discussion