Help us understand the problem. What is going on with this article?

IAM Roleを使ってAWS ElasticSearch ServiceのデータをLaravelで取得する

More than 1 year has passed since last update.

ESデータをIAM Roleで取得する方法です。
ESのポリシーがガチガチじゃないかたはこちら=>AWS ElasticSearch ServiceのデータをPHPで取得する

はじめに

PHPが稼働しているサーバーに以下環境変数を設定して下さい。
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_DEFAULT_REGION

AWS側の設定

Amazon Elasticsearch Serviceポリシー例
上記で設定したユーザーでみGETで取得が出来るように設定します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::000000000000:user/xxx"
      },
      "Action": "es:ESHttpGet",
      "Resource": "arn:aws:es:ap-northeast-1:000000000000:domain/xxx/*"
    }
  ]
}

Composerでインストール

AWS-SDK、ClientBuilder、接続に必要なものをインストールします。

composer.json
"require": {
  "aws/aws-sdk-php-laravel": "~3.0",
  "elasticsearch/elasticsearch": "~6.0",
  "guzzlehttp/guzzle": "^6.0",
  "psr/http-message": "^1.0"
}

$ composer update

参考サイト=>Amazon Elasticsearch Service 検索リクエストへの署名

aws-sdk-php-laravelの設定

READMEを参考に先ほど設定した環境変数を読み込むためにconfig/app.phpにprovidersaliasesを設定します。

参考サイト=>GitHub aws/aws-sdk-php-laravel

config/app.php
'providers' => array(
    // ~
    Aws\Laravel\AwsServiceProvider::class,
)
// ~
'aliases' => array(
    // ~
    'AWS' => Aws\Laravel\AwsFacade::class,
)

以下を実行するとconfig/aws.phpが生成されます。

$ php artisan vendor:publish --provider="Aws\Laravel\AwsServiceProvider"

うまくできない人は以下のコマンドを先に入力すると解決するかもしれません。

$ php artisan config:clear

生成されたconfig/aws.phpにて設定した環境変数を読み込むように上書きします。

config/aws.php
return [
    'credentials' => [
        'key'    => env('AWS_ACCESS_KEY_ID'),
        'secret' => env('AWS_SECRET_ACCESS_KEY'),
    ],
    'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
];

PHP側から読み込み

リクエスト署名を挿入してClientBuilderに接続します。
途中でPromise rejectエラーなど出た場合はコメントアウト部分を表示してみるとエラー詳細が出ると思います。

Promiseって何という方はこちらを参考にすると良いかもしれません。
参考サイト=>Promiseについて0から勉強してみた

xxx.php
use AWS;
use Aws\Credentials\CredentialProvider;
use Aws\Signature\SignatureV4;
use Elasticsearch\ClientBuilder;
use GuzzleHttp\Ring\Future\CompletedFutureArray;
use GuzzleHttp\Psr7\Request as psr7Request;
use GuzzleHttp\Psr7\Uri;
//use Psr\Http\Message\ResponseInterface;

$psr7Handler = Aws\default_http_handler();

$signer = new SignatureV4('es', env('AWS_DEFAULT_REGION'));

$credentialProvider = CredentialProvider::defaultProvider();

$handler = function (array $request) use ($psr7Handler, $signer, $credentialProvider)
{
    $request['headers']['Host'][0] = parse_url($request['headers']['Host'][0], PHP_URL_HOST);

    $psr7Request = new psr7Request(
        $request['http_method'],
        (new Uri($request['uri']))
            ->withScheme($request['scheme'])
            ->withHost($request['headers']['Host'][0]),
        $request['headers'],
        $request['body']
    );

    $signedRequest = $signer->signRequest(
        $psr7Request,
        call_user_func($credentialProvider)->wait()
    );

    $response = $psr7Handler($signedRequest)->wait();
    /*$response = $psr7Handler($signedRequest)->then(
        function(Psr\Http\Message\ResponseInterface $r) {
            return $r;
        }, function($error) {
            return $error['response'];
        }
    )->wait();*/

    return new CompletedFutureArray([
        'status' => $response->getStatusCode(),
        'headers' => $response->getHeaders(),
        'body' => $response->getBody()->detach(),
        'transfer_stats' => ['total_time' => 0],
        'effective_url' => (string) $psr7Request->getUri(),
    ]);
};

$hosts = [
    'https://xxx.ap-northeast-1.es.amazonaws.com:443'
];

$client = ClientBuilder::create()->setHandler($handler)->setHosts($hosts)->build();

$params = [
    'index' => '*'
];

$response = $client->search($params);

$responseにデータ返ってきていると思います。

参考サイト=>AWS ElasticSearch Service の認証にIAM Roleを使う [PHP編]

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした