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、接続に必要なものをインストールします。
"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にproviders
とaliases
を設定します。
参考サイト=>GitHub aws/aws-sdk-php-laravel
'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にて設定した環境変数を読み込むように上書きします。
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から勉強してみた
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
にデータ返ってきていると思います。