DockerからSDK経由でAWSのS3にアクセスする時に出会ったエラーの正体は、、、

# はじめに
自分がだいぶ遠回りしたので同じような人がなんだそういうことかよとなるようにここにメモしておきます！(*´ω｀*)
ちなみに後々出てくる`credentials`は期限設定によりますがセッション切れたらちゃんと新しいのにしないと使えません。

# どんなコードを書いていた？

```PHP
//AWS
use Aws\S3\S3Client;  
use Aws\Exception\AwsException;

$s3Client = new S3Client([
    'profile' => '277650267482_PowerUserAccess', //どのプロファイル使うか(後で詳細記載します。)
    'region' => 'ap-northeast-1', //SSO Regionの箇所のとこなのかなと？(後で詳細記載します。)
    'version' => '2006-03-01', //ここ決まりっぽいです。またはlatestかと
]);

try {
    $result = $s3Client->createBucket([
        'Bucket' => 'abcde-img',
    ]);
} catch (AwsException $e) {
    echo $e->getAwsErrorMessage();
}

```

# でたエラーの数々

:sun_with_face:?読めないだけじゃあファイルあるとこ見えてる？
```
Error: [Aws\Exception\CredentialsException] Cannot read credentials from /.aws/credentials in /var/www/html/vendor/aws/aws-sdk-php/src/Credentials/CredentialProvider.php on line 826
Stack
```

:sun_with_face:?ファイルに記載しているのだけど、、なんで見つからないの、、？
```
Error: [Aws\Exception\CredentialsException] '277650267482_PowerUserAccess' not found in credentials file in /var/www/html/vendor/aws/aws-sdk-php/src/Credentials/CredentialProvider.php on line 830
Stack Trace:
```

# 根本原因はなんだったのか、、、、
ファイルマウントする箇所をそもそも間違えていました、、
なので権限疑う前にファイル配置箇所間違えていないか確認するといいかもです。
あと上のエラーではファイルあるのかとかまではエラーだけでは読み取れなかったかもと、、(ライブラリにログ等入れて確認してやっと分かったため)

※ちなみに以下のconfigファイルは空でありむしろファイルなくてもいけるかと思ってはいます、、

:no_good_tone1:before:no_good_tone1:

![スクリーンショット 2023-07-17 18.06.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133940/01ba18ea-9ac3-5610-1777-602c8700154b.png)

※不要な箇所省略しています。
```.yml
volumes:
  - ./apach/credentials:/.aws/credentials
```

:ok_woman_tone1:after:ok_woman_tone1:

![スクリーンショット 2023-07-17 18.06.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133940/01ba18ea-9ac3-5610-1777-602c8700154b.png)

※不要な箇所省略しています。
```.yml
volumes:
  - ./apach/credentials:/.aws
```

# 原因発覚経路、、、(興味ある方のみ)

やったことは簡単でエラーログ出している箇所の以下ファイルのコード確認したりログ入れて確認したりしてました。
最初からそうすればもっと早かっただろうにと、、、

```
※「path/to/path/」の箇所は個人個人で違うかと。
path/to/path/vendor/aws/aws-sdk-php/src/Credentials/CredentialProvider.php
```

:sun_with_face:以下見てファイルに権限ないときこうなるのか〜と思っていたのもそもそもの勘違い、ファイルすらないときもfalseで返すという、、このエラーじゃファイルないのかファイル読み取り権限ないのかまで辿り着けませんね、なのでもう一つチェック追加処理でそもそもファイルすら見つけられていないことを確認、、
https://www.php.net/manual/ja/function.is-readable.php
https://man.plustar.jp/php/function.file-exists.html
```PHP
if (!@is_readable($filename)) {
    return self::reject("Cannot read credentials from $filename");
}
```

:sun_with_face:ここまで来ているならファイルの指定は間違っていないと思っていたら、、フォルダ見つけてあるみたいにしていて結果下の方まで探してという感じでした、、なんだそうだったのかって
```PHP
if (!isset($data[$profile])) {
    return self::reject("'$profile' not found in credentials file");
}
```

:sun_with_face:以下みてあれ？？「credentials」フォルダ内の「credentials」ファイル見ると思っていたら、「credentials」ファイル見るになってて「credentials」フォルダとかじゃないじゃんという勘違い発覚、、
権限以前にコードに従ったファイルの配置に出来ていなかったのでした、、
```PHP
private static function loadProfiles($filename)
{
    $profileData = \Aws\parse_ini_file($filename, true, INI_SCANNER_RAW);
    
    // If loading .aws/credentials, also load .aws/config when AWS_SDK_LOAD_NONDEFAULT_CONFIG is set
    if ($filename === self::getHomeDir() . '/.aws/credentials'
        && getenv('AWS_SDK_LOAD_NONDEFAULT_CONFIG')
    ) {
        $configFilename = self::getHomeDir() . '/.aws/config';
        $configProfileData = \Aws\parse_ini_file($configFilename, true, INI_SCANNER_RAW);
        foreach ($configProfileData as $name => $profile) {
            // standardize config profile names
            $name = str_replace('profile ', '', $name);
            if (!isset($profileData[$name])) {
                $profileData[$name] = $profile;
            }
        }
    }

    return $profileData;
}
```

:sun_with_face:エラーからじゃ今回の勘違いの発見には辿り着けなかったかもと反省、、(◍•ᴗ•。◍)
なんかファイルは読み込めないとか、権限与えられていないとか色々言われていたけど、、、
私の場合それそれ以前の問題でした、、、、、ふふふふ。:sweat_smile:

# そのほかの情報
上記以外にここの値どうなっているみたいな気になる箇所あるかと思うのでここにつらつら書いていきます！

:hatched_chick:以下はホームのパスどうなっているの確認で、、あんま意味なかったのですが、
 
```
$ printenv

以下output必要な箇所のみ出力
HOME=/root
```

ちなみにコンテナ中で以下のように確認もできます。
```
$ cd ~/

$ pwd
output => /root
```

:hatched_chick:exportするとenvで登録されたりするのですがそもそもここなくても問題なかったという。、、ここにprofileとか出ないといけない？とかなったのですがなんかコマンド打ってもあれ、、みたいな感じだったのでそもそもこのコマンド打てなくても問題なかったんだろうなと思う今日この頃、、

参考: https://repost.aws/knowledge-center/s3-locate-credentials-error

```
$ aws configure list

output =>
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key                <not set>             None    None
secret_key                <not set>             None    None
    region                <not set>             None    None
```

:hatched_chick: 権限の確認。以下リンク参考に設定したのですがこれも必要だったのかまだ定かではありません。でも必要ではある気がしているので、、詳しくはリンク先飛んでいただければと
https://vwrs.github.io/aws/2018/09/06/aws-sdk-credentials/

```
$ cd /.aws

$ ls -l

total 4
-rwx------ 1 www-data www-data    0 Jul 16 17:43 config
-rwx------ 1 www-data www-data 1075 Jul 17 08:32 credentials
```

:hatched_chick: そもそも以下のコマンドとか打たなくてよかったのではと思っています。むしろ無意味だったのではとライブラリが指定したところのファイル見てアクセス問題なしか確認する感じかと。これがちゃんとできないといけないのかと思ってずっとハマっていたのは秘密です、、

```
$ aws configure sso
```

# 『後で詳細記載します』の箇所の説明

:hatched_chick: `'profile' => '277650267482_PowerUserAccess'`の箇所説明

お察しのことかと思いますが、以下ファイルに以下ののような記載あるものです。`[]`の中のもの指定しています。

`IAM ID センターのcredentials取得`作成の説明は長くなるので以下リンクで説明させていただきました！

https://qiita.com/sachiko-kame/items/8e98040573d1cbed597c

```.apach/credentials/credentials

[277650267482_PowerUserAccess]
aws_access_key_id=XXXXXXXXXXXXXXXXXXXXXXXXx
aws_secret_access_key=XXXXXXXXXXXXXXXXXXXXXXXXxXXXXXXXXXXXXXXXXXXXXXXXXx
aws_session_token=XXXXXXXXXXXXXXXXXXXXXXXXxXXXXXXXXXXXXXXXXXXXXXXXXxXXXXXXXXXXXXXXXXXXXXXXXXxXXXXXXXXXXXXXXXXXXXXXXXXxXXXXXXXXXXXXXXXXXXXXXXXXxXXXXXXXXXXXXXXXXXXXXXXXXxXXXXXXXXXXXXXXXXXXXXXXXXxXXXXXXXXXXXXXXXXXXXXXXXXxXXXXXXXXXXXXXXXXXXXXXXXXxXXXXXXXXXXXXXXXXXXXXXXXXx
```


:hatched_chick: `'region' => 'ap-northeast-1',`の箇所説明

上記のもの取得できるところの`SSO Region`の値と同じで問題なしでした。自分が思うにS3のリージョンと個々のリージョンはどっちも同じなのではないかと、、なのでS3で一回バケット作成してそこでどこのリージョン使っっているかの確認でもいいのではと思っています。

# おまけ

最初Dockerのコンテナ内で以下打てばいけると勘違いし、
次にコンテナ内で以下打てばいけると勘違いしてみたいな感じでした、、

```
$ aws configure sso
```

# 最後に

ここまで読んで頂きありがとうございました！:hatching_chick:

ローカルから接続できたらあとはコード等以下参考にしながら色々捗りそうだと思っている今日この頃です。
https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/php/example_code/s3/CreateBucket.php