プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

AWS CLI 複数の認証情報の設定について

以前、EC2のインスタンスを t1.micro から t2.nano へ移行する作業について書きました。

blog.mori-soft.com

この中で、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 で現在の認証情報の設定状況を確認できることがわかりました。

dev.classmethod.jp

早速、試してみると

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 を指定する

というものでした。

で、まず大きく間違っていたのが、下記の説明にある、

docs.aws.amazon.com

この部分、

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$ 

この認証情報を使うようにバックアップスクリプトを修正したら、問題なく動作しました。 めでたし、めでたし。