LoginSignup
4
1

More than 1 year has passed since last update.

【Python×AWS】botocore.exceptions.NoCredentialsErrorエラー対応。clientとresourceの違いも

Posted at

概要

  • Pythonのライブラリboto3でAWSのSecretManagerを使って実装していたら、下記エラーが表示されたので、その解決方法を記します。
botocore.exceptions.NoCredentialsError: Unable to locate credentials

原因の追求

  • 上記エラーの原因は、boto3の認証権限。AWSに繋ぐための認証情報が設定されていないエラーです。
    • boto3とは:PythonからAWSを操作するためのライブラリ
  • 認証情報を設定するってどういう意味かというと、boto3に「Python3を動かすためのIAMユーザー」を認識させてあげる必要があります。結論、以下の2つの手順が必要です。
    • ①Python3を動かすためのIAMユーザーを作成(設定)
    • ②boto3が認識するcredentialsに認証情報を記載
      • (他にも方法がありますがわかりやすく解説するため上記のように記載。詳細は後述)

①Python3を動かすためのIAMユーザーを作成(設定)

  • boto3にIAMユーザーを認識してもらうには、APIキー(アクセスキーとシークレットキー)が必要です。
  • すでにIAMユーザーが存在する場合、設定する方法は以下の通りです。
    • ①AWSログイン→IAM→ユーザー→該当のユーザーをクリック→「セキュリティ認証情報」タブをクリック→少し下にいくと「アクセスキー」の欄に「アクセスキーを作成」というボタンがあるのでそれをクリック→作成後、CSVをダウンロード可能。アクセスキーとシークレットアクセスキーはこの時しか取得するチャンスがありませんのでご注意。

②boto3が認識するcredentialsに認証情報を記載

  • IAMユーザーの設定を行ったら、次は、boto3が認識してくれる場所にアクセスキーとシークレットキーを記載してあげます。その場所が「\.aws\config\.aws\credentials」です。
    • 正確には他の方法もあるので後述しますが、一旦後回しにします
  • ローカルの\Users\<ユーザー名>/.awscredentialsファイルを作成し、そこに以下の情報を記載します。
[default]
aws_access_key_id = XXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXX
  • \.aws\configにも必要な情報があれば記載します。
    • ここに認証情報を記載することもできますが、一般的な使い方ではないようです。
[default]
region = ap-northeast-1
output = json
botocore.exceptions.ConfigParseError: Unable to parse config file:

CLIから実行可能なコマンド"aws configure"

  • 上記の①②をより簡単に行う方法として、AWS CLIを利用してaws configureコマンドから以下の項目を順番に登録する方法があります。これにより、自動的にcredentialsが作成されます。
    • AWS Access Key ID [None]:<アクセスキー>
    • AWS Secret Access Key [None]:<シークレットキー>
    • Default region name [None]:<リージョン>
    • Default output format [None]:
  • 参考:設定ファイルと認証情報ファイルの設定

解決策

補足①:重要情報のベタうちは避けるように!

  • 以下の書き方はベタうちの事例ですが、githubなどに挙げる場合は、重要な情報であるアクセスキーIDとシークレットアクセスキーが外部に公開されてしまうので、要注意です。
  • ベタうちの場合の記載:
import boto3

s3 = boto3.client('s3',
        aws_access_key_id=XXXXXXXXXXXXX,
        aws_secret_access_key=XXXXXXXXXXXXX,
        region_name='ap-northeast-1'
)
  • ベタうちを避ける場合にも色々方法があります。上記解決策の方法は、credentialsファイルに認証情報を記載する方法でしたが、AWS CLIによって環境変数でセットする方法やSTSのAssumeRoleによって一時的な認証情報を取得する方法がありますので、以下記事をご参照ください。

  • AWS CLIによって環境変数でセットする場合などの記載:

export AWS_ACCESS_KEY_ID=XXXXXXXXXXXXX
export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXX
export AWS_DEFAULT_REGION=XXXXXXXXXXXXX
import boto3

    s3 = boto3.client('sts')

    assumed_role_object = s3.assume_role(
        RoleArn=IAM_ROLE_ARN, # IAMロールのARN
        RoleSessionName=IAM_ROLE_SESSION_NAME # 識別できる名前
    )
    credentials = assumed_role_object['Credentials']
    s3_resource = boto3.client(
        's3',
        aws_access_key_id=credentials['AccessKeyId'],
        aws_secret_access_key=credentials['SecretAccessKey'],
        aws_session_token=credentials['SessionToken'],
    )

補足②:clientとresourceの違い

Client API
REST APIと1対1で対応しているため、理論上は「できないことはない。」
結果が基本的に辞書型で得られるので、必要な情報を取り出すのが若干めんどう。

Resource API
オブジェクト指向で処理を記述できるので、コードの見通しが良くなる。
サービスやリソースの種類によってはResource APIが用意されていないことがある。(その場合はClient APIを使う必要がある)

  • 何か気になるところや指摘ありましたら、ぜひコメントいただければ幸いです。
4
1
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
4
1