環境と前提条件
- Laravel8
- AWS SDK for PHP 3.x(https://github.com/aws/aws-sdk-php) をcomposerでインストールして利用
- .envファイルにAWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY を設定している
症状
AWS SDKのAPIを実行すると以下のエラーが発生してしまう。
Aws\Exception\CredentialsException
Error retrieving credentials from the instance profile metadata service. (cURL error 7: Failed to connect to 169.254.169.254 port 80: Connection refused (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for http://169.254.169.254/latest/meta-data/iam/security-credentials/)
権限のエラーっぽい。
悩んだ末に解決できたので原因と解決策をまとめておきます。
原因
.envを書き換えた時に、癖で php artisan config:cache
を実行していたのが原因でした。
これが原因で、AWS SDKから各種キーの内容が参照できなくなっていた。
もう少し詳しく解説
AWS SDK for PHPではAWSのキーの参照をgetenv()で行なっています
laravel-app/vendor/aws/aws-sdk-php/src/Credentials/CredentialProvider.phpの300行目あたり
public static function env()
{
return function () {
// Use credentials from environment variables, if available
$key = getenv(self::ENV_KEY);
$secret = getenv(self::ENV_SECRET);
....
そして、Laravelではphp artisan config:cache
を行うと設定ファイルをキャッシュしてしまい、env(), getenv()の実行結果はNULLになってしまいます。
参照: 【Laravel】.envの項目をenvやgetenv関数で取得できない場合の対策 (https://e-seventh.com/laravel-unable-to-read-env/)
これにより、AWS SDKでAPIを実行した時にAWSの認証キーを取得できずにエラーが起きるという流れでした。
解決策
その1, 2のどちらかで解決できます。
その1
configのキャッシュをクリアすれば、getenv()で認証キーが取得できるようになりエラーが解決されます。
php artisan cache:clear
そもそもconfigキャッシュを使わないという道もありそうだが、それはちょっとという方は「その2」を試してみてください。
その2
Laravel用のSDK( https://github.com/aws/aws-sdk-php-laravel ) を使えば解決できそうです。
こちらはこれから試しますが、ざっと見た所.envの内容の読み込みをconfigで行なっているので、問題は起きなそうです。
Laravel用のSDKがあればそちらを使おう!!