3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AWS SDK for PHP: 認証情報をプロセス間で再利用する

Last updated at Posted at 2022-04-10

背景

AWS EC2 上で AWS SDK を使ってリソースにアクセスする場合、Instance Profile に指定したロールの権限が自動的に使われます。これは実際には IMDS (Instance MetaData Service) へ HTTP でアクセスして一時的な認証情報を取得することで実現しており、Web サービスではリクエスト(プロセス)毎に発生します。しかしこのリクエスト数には一定の上限があり、スロットリングによるリトライやエラー(タイムアウトになる場合もあるようです)が発生する場合があります。これにより、AWS リソースへのアクセスを頻繁におこなう Web サービスでは問題になることがあります。

参考) Retrieve instance metadata - Amazon Elastic Compute Cloud

PHP のプロセス間で共有する領域に認証情報を有効期限までキャッシュすることで、この問題を回避します。IMDS のリクエストが減ることで、パフォーマンスの向上も見込めるかもしれません。

Doctrine Cache を使う場合

公式ドキュメントには Doctrine Cache を使って APCu にキャッシュする方法が記載されています。が、このライブラリは開発が終了している模様。ApcuCache クラスも最新バージョンでは削除されているため、v1 を使う必要があります。

参考) Configuration for the AWS SDK for PHP Version 3 - AWS SDK for PHP

APCu をインストール (例)

sudo yum install -y php-pecl-apcu

Doctrine Cache (v1) をインストール

composer require doctrine/cache:^1.0

キャッシュ例 (公式ドキュメントより)

$s3 = new Aws\S3\S3Client([
    'version' => 'latest',
    'region' => 'ap-northeast-1',
    'credentials' => Aws\Credentials\CredentialProvider::cache(
        Aws\Credentials\CredentialProvider::defaultProvider(),
        new Aws\DoctrineCacheAdapter(new Doctrine\Common\Cache\ApcuCache())
    ),
]);

Cache Provider を自作

Deprecated なライブラリを使うのも気持ちが悪いので、自作してみました。

Aws\CacheInterface を実装した Cache Provider を作り、CredentialProvider::cache() に指定すれば良いだけです。同様にして、保存先を APCu 以外にすることも容易です(ファイルとか Shared Memory とか)。ちなみに Aws\DoctrineCacheAdapter は Doctrine Cache をラップした Cache Provider の実装になります。

例) 保存先となる APCu のキーはプロセス間で共有されるため、他の用途と重複しないよう namespace を指定できるようにします。

class MyApcuCache implements \Aws\CacheInterface
{
    private string $namespace;

    public function __construct(string $namespace)
    {
        $this->namespace = $namespace;
    }

    private function get_apcu_key(string $key): string
    {
        return sprintf('%s[%s]', $this->namespace, $key);
    }

    public function get($key)
    {
        return apcu_fetch($this->get_apcu_key($key));
    }

    public function set($key, $value, $ttl = 0)
    {
        apcu_store($this->get_apcu_key($key), $value, $ttl);
    }

    public function remove($key)
    {
        apcu_delete($this->get_apcu_key($key));
    }
}

$s3 = new Aws\S3\S3Client([
    'version' => 'latest',
    'region' => 'ap-northeast-1',
    'credentials' => Aws\Credentials\CredentialProvider::cache(
        Aws\Credentials\CredentialProvider::defaultProvider(),
        new MyApcuCache('AwsCredentials')
    )
]);
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?