以前、EC2のインスタンスを t1.micro から t2.nano へ移行する作業について書きました。
この中で、S3 へバックアップを行うという設定を行っていたのですが、月一動作だったので、改めて動作確認をしてみると、どうもうまく動いていません。 こんな感じのエラーです。
2017-06-01 03:05:01 JST: aws s3 cp バックアップファイル名 s3://バケット名/ upload failed: バックアップファイル名 to s3://バケット名/ファイル名 An error occurred (AccessDenied) when calling the CreateMultipartUpload operation: Access Denied
アクセス拒否のようです。
aws cli はいろんな方法で認証情報を指定できるので、これが間違っているのだろうと予想されます。 いろいろと調べてみると、 aws configure list で現在の認証情報の設定状況を確認できることがわかりました。
早速、試してみると
bitnami@ip-172-30-0-73:~/.aws$ aws configure list Name Value Type Location ---- ----- ---- -------- profile <not set> None None access_key ****************AAAA shared-credentials-file secret_key ****************aaaa shared-credentials-file region <not set> None None bitnami@ip-172-30-0-73:~/.aws$
あれ?なんかおかしいぞ。
実は、aws cli を使う際、EC2 用のユーザーと S3 用のユーザーを分けていました。 で、上記のアクセスキーなどは、EC2ユーザーのものです。 おまけに、 region も設定されていない。
ということで、認証情報の設定方法を見直しました。
間違っていた点
恥ずかしならが、調べた結果、いろいろと間違っていました。まず現在設定していた方法は、
- EC2 用のユーザーは aws configure コマンドで設定する
- .aws/config と .aws/credentials に内容が書かれている
- S3 用のユーザーは .aws/config.s3 ファイルにすべての内容を記述する
- S3 用のユーザーを使う場合は、 環境変数で AWS_DEFAULT_CONFIG=.aws/config.s3 を指定する
というものでした。
で、まず大きく間違っていたのが、下記の説明にある、
この部分、
Storing Credentials in Config
The AWS CLI will also read credentials from the config file. If you want to keep all of your profile settings in a single file, you can. If there are ever credentials in both locations for a profile (say you used aws configure to update the profile's keys), the keys in the credentials file will take precedence.
(頑張って意訳)
Config ファイルへの認証情報の保存について
AWS CLI は config ファイルから認証情報を読むこともできます。プロファイル設定のすべてを1ファイルに保存することも可能です。もし、プロファイルの情報が複数個所にある場合は、credentialsファイルのキーが優先されます。
です。
この前半部分を読んで、configファイルに認証情報全部を書けると思い込んでしまいました。でも、上記の意訳からもわかるように、書けることはかけるんですが、(同じプロファイル)に対する認証情報が複数ある場合、credentialsファイルのものが優先的に使われるそうです。 やられました。
更なる間違い
上記の問題が大きいので、些細なことですが、さらに、ついでに間違っていたのが、config.s3 ファイルの書き方です。 config.s3 ファイルを、
bitnami@ip-172-30-0-73:~/.aws$ cat config.s3 [s3] aws_access_key_id = アクセスキー aws_secret_access_key = シークレットアクセスキー region = ap-northeast-1 bitnami@ip-172-30-0-73:~/.aws$
と書いており、いつつけたか覚えのない s3 というプロファイル名がついていました。 これは、プロファイル名になるはずなので、切り替えたければ、 --profile s3 のようにコマンド実行時にプロファイル名も指定する必要がありました。
仮にここを [default] に修正すると、
bitnami@ip-172-30-0-73:~/.aws$ aws configure list Name Value Type Location ---- ----- ---- -------- profile <not set> None None access_key ****************AAAA shared-credentials-file secret_key ****************aaaa shared-credentials-file region ap-northeast-1 config-file /home/bitnami/.aws/config.s3 bitnami@ip-172-30-0-73:~/.aws$
のように、regionは正しく認識されました(もっとも、上記の二重に認証情報がある場合の問題が残っているので、これでも使えませんがね)。
最終的な設定内容
で、結局、認証情報を使い分けるために、プロファイルを追加することとしました。ここで、プロファイル名は s3user としています。 設定後のファイルはこんな感じになります。
~/.aws/credentials
[default] aws_access_key_id = EC2アクセス用のアクセスキー aws_secret_access_key = EC2アクセス用のシークレットアクセスキー [s3user] aws_access_key_id = S3アクセス用のアクセスキー aws_secret_access_key = S3アクセス用のシークレットアクセスキー
~/.aws/config
[default] region = ap-northeast-1 [profile s3user] region = ap-northeast-1
--profile s3user をつけてコマンドを実行すると、S3 用ユーザーの認証情報が使われています。
bitnami@ip-172-30-0-73:~/.aws$ aws configure list --profile s3user Name Value Type Location ---- ----- ---- -------- profile s3user manual --profile access_key ****************BBBB shared-credentials-file secret_key ****************bbbb shared-credentials-file region ap-northeast-1 config-file ~/.aws/config bitnami@ip-172-30-0-73:~/.aws$
念のために、 --profile なしを試すと、ちゃんと EC2 用ユーザーの認証情報が使われます。
bitnami@ip-172-30-0-73:~/.aws$ aws configure list Name Value Type Location ---- ----- ---- -------- profile <not set> None None access_key ****************AAAA shared-credentials-file secret_key ****************aaaa shared-credentials-file region ap-northeast-1 config-file ~/.aws/config bitnami@ip-172-30-0-73:~/.aws$
この認証情報を使うようにバックアップスクリプトを修正したら、問題なく動作しました。 めでたし、めでたし。