i-Vinci TechBlog
株式会社i-Vinciの技術ブログ

AWSにプログラムからアクセスする際の認証情報の設定方法について

どうもみなさん、こんばんちは!
最近PS4のGhost Recon Breakpointにはまっている藤田です。
皆さんご存じですか?逃げ恥で星野源さんが演じる平匡さんは、新垣結衣さんが演じるみくりさんといい感じの関係ですが、IPAのデータベーススペシャリストに合格したことがあるPHPエンジニアという設定だそうです。そう、デスぺを持っていてPHPが書ければ「ガッキーと結婚できる」ということです。
では、本日も張り切っていきましょう!

AWSへのアクセスの仕方

皆さん、AWS使ってますか?
使ってる人は普段どのようにして使っているのか思い出してください。(使ったことない人は昨日食べた夕飯を思い出してください)皆さんどのようなアクセスの仕方をされているでしょうか?
AWSへのアクセスの仕方は大きく分けて次の3つになるかと思います。

  1. マネジメントコンソールからのアクセス
    ルートユーザー、IAMユーザー、もしくは多要素認証によりマネジメントコンソールから各種AWSのサービスを利用する
  2. プログラムからのアクセス
    アクセスキーIDとシークレットアクセスキーをプログラムで利用して、エンドポイントを叩くなどしてAWSのサービスを利用する
  3. 一時アクセスキーを利用したアクセス
    アクセスキーIDとシークレットアクセスキーに加えて有効期限が決められたセキュリティトークンを利用して、エンドポイントを叩くなどしてAWSのサービスを利用する

参考になるページはこちら

本記事では、2つ目に挙げたプログラムからのアクセス(Programmatic Access)をローカル環境で行う場合に、クレデンシャル情報を設定する最短の方法を簡単に説明したいと思います。
しかし、1と3についても簡単に説明させていただきます。

マネジメントコンソールからのアクセス(Console Access)

まず、一つ目のConsole Accessについてですが、これが一番イメージしやすいと思います。
こんな感じの画面から各種サービスを開いて利用する方法ですね。AWSを使ったことのある方ならほとんどの方が触ったことのある画面ではないでしょうか?

AWSを使って物を作ろうとしたときに必ず見ることになる画面だと思います。
ルートユーザーもしくはIAMユーザーのアカウント情報を使用して、サインインすることになります。
詳しくはこちらをご覧ください。

一時アクセスキーを利用したアクセス

これはAWS STS(Security Token Service)で発行された一時的に発行されたアクセスキーを利用したアクセスを指します。
一時アクセスキーを利用したアクセスは非常に多岐な形態をとりますが、以下のようなものをイメージしてもらえると大体あっていると思います。

  • 会社で管理している社員アカウントに対して、AWSで設定したIAMロールに対応するアクセス許可を一時的に発行する
  • Google, Facebook, GitHubなどAWS以外のサービスで作成されたアカウントに対して、一時的なアクセス許可を与える
  • あるIAMアカウントに対して別のIAMアカウントからアクセス可能なAWSリソースに対するアクセス許可を一時的に与える
  • モバイル端末のアプリケーションに対してAWSへのアクセスを許可する

詳しくはこちらをご確認ください。

プログラムからのアクセス(Programmatic Access)

さて、ではプログラムからのアクセスの場合に、必要なクレデンシャル情報を設定する方法を説明したいと思います。今回は特にローカルでプログラムを実行する場合を見ていきます。
前提として、有効なアクセスキーIDとシークレットアクセスキーが作成されている必要があります。
アクセスキーIDとシークレットアクセスキーを作成する方法はこちらです。
アクセスキーIDとシークレットアクセスキーのペアのことをAWSではアクセスキーといいます。

Credential Provider

AWSではプログラムから各種サービスにアクセスする方法として、下記のような各種言語に対応したSDKやツールを提供しています。

  • AWS CLI(Command Line Interface)
  • AWS Tools for Powershell
  • AWS SDK for C++
  • AWS SDK for Go
  • AWS SDK for Java
  • AWS SDK for JavaScript
  • AWS SDK for .NET
  • AWS SDK for PHP
  • AWS SDK for Python(Boto3)
  • AWS SDK for Ruby などなど...

これらのSDKやツールは、必要な認証情報を取得する方法としてCredential Providerという仕組みを提供しています。それぞれのCredential Providerは、いくつか共通点はあるもののSDKやツールによって独自の仕組みを持っており、詳細は使用する言語やツールに対応したドキュメントを確認する必要があります。
例としてGolangとJava、Node.jsの場合を見てみましょう。

まず、Golangでは以下の順序で認証情報を検索します。参考

  1. 環境変数
  2. 共有認証情報ファイル(ホームディレクトリの.awsフォルダ配下のcredentialsファイルのこと。詳細は後ほど説明します。)
  3. プログラムがECSのタスク定義もしくはRunTask APIの定義を使用する場合は、タスクに与えられたIAMロール
  4. プログラムがEC2のインスタンス上で動作する場合は、EC2に与えられたIAMロール

次に、Javaでは次の順序で認証情報を検索します。参考

  1. Java System Properties(Javaの言語仕様の特徴ですね)
  2. 環境変数
  3. 共有認証情報ファイル(ホームディレクトリの.awsフォルダ配下のcredentialsファイルのこと。詳細は後ほど説明します。)
  4. プログラムがECSのタスク定義もしくはRunTask APIの定義を使用する場合は、タスクに与えられたIAMロール
  5. プログラムがEC2のインスタンス上で動作する場合は、EC2に与えられたIAMロール

最後に、Node.jsでは次の順序で認証情報を検索します。参考

  1. サービスクライアントコンストラクタで明示的に設定されている認証情報
  2. 環境変数
  3. 共有認証情報ファイル(ホームディレクトリの.awsフォルダ配下のcredentialsファイルのこと。詳細は後ほど説明します。)
  4. プログラムがECSのタスク定義もしくはRunTask APIの定義を使用する場合は、タスクに与えられたIAMロール
  5. 共有AWS設定ファイルまたは共有認証情報ファイルで指定された認証情報プロセスを使用して取得された認証情報(外部プロセスを使用して認証情報を取得する場合に使用します)
  6. プログラムがEC2のインスタンス上で動作する場合は、EC2に与えられたIAMロール

以上のようにCredential Providerの挙動には差異があり、開発に使用する言語やプロジェクトによって認証情報を設定する方法は変わってくるものと思います。

とはいえ、環境変数や共有認証情報ファイルから読み込むという点は、共通しています。
これは私が今まで経験させていただいた開発ではというお話なのですが、設定ファイルなどに記載しておいた認証情報をプログラム実行時に環境変数に展開し、AWSへのアクセスに利用する、といったプロジェクトが多い印象です。
こうすることで、AWSのリソースを開発 → 維持管理・検証 → 運用と変える時も、開発したモジュールそのものにはほぼ手を付けずに設定ファイルを編集するのみでアプリ側は対応する、といったことができるようになります。

ローカルでとりあえず動かす場合の最短パターンとは?

AWS CLI(Command Line Interface)を使用して認証情報を設定するのが、もっとも簡単な方法だと私は思います。
AWS CLIを利用して認証情報を設定することで、ローカルPCのホームディレクトリに.aws/credentialsファイルと.aws/configファイルが作成されます。
機密性の高い情報(アクセスキー)はcredentialsに、機密性の低い情報(リージョンなどの情報)はconfigファイルにプロファイル毎に書き込まれます。

credentialsファイル、configファイル及びプロファイルなどについての詳細はこちらを参照してください。

AWS CLIの準備

AWS CLIを使用して認証情報を設定するためには、AWS CLIがインストール済みである必要があります。インストール済みかどうかは、"aws --version"とターミナルで打つと確認できます。
インストール済みであれば次のようなメッセージが表示されると思います。

$ aws --version
aws-cli/2.1.19 Python/3.7.9 Windows/10 exe/AMD64 prompt/off

インストールがまだの方は、ここを参考にインストールを行ってください。

AWS CLIでの認証情報の設定(defaultプロファイル)

ターミナルを起動して"aws configure"とコマンドを打ってみましょう。次のようなメッセージが一行ずつ表示されます。
この手順で入力された内容はdefaultのプロファイルとして保存されます。

$ aws configure
AWS Access Key ID [None]: << accesskey >>
AWS Secret Access Key [None]: << secretkey >>
Default region name [None]: us-west-2
Default output format [None]: json

<< accesskey >>の場所でアクセスキーIDを、<< secretkey >>の場所でシークレットアクセスキーを入力することでプログラムからAWSへアクセスするための認証情報の設定を行うことが出来ます。
入力された内容が、アクセスキーについての情報はcredentialsファイルへ、リージョンなどの情報はconfigファイルに保存されます。
これにより、ローカルで実行されるプログラム内でアクセスキーを明示的に記載しなくても、Credential Providerが認証情報を取得できるようになり、AWSの各種サービスにプログラムからアクセスできるようになります。

AWS CLIでの認証情報の設定(名前付きプロファイル)

aws configure --profile << profile name >>

とすることで、プロファイル名を指定して認証情報を設定することが出来ます。設定されたプロファイル名をプログラム側で指定することで、プログラムで使用する認証情報を変更することが出来ます。

credentialsファイルで設定するメリット

アプリ側の設定ファイルなどにアクセスキーを直接書く必要がなくなることが一番のメリットと言えます。個人開発のアプリの設定ファイルなどのアクセスキーを書いてGitHubに挙げてしまう、などという恐ろしい事故を起こす可能性がぐっと下がります。

また個人的には、認証情報の設定はプロファイル毎に切り分けて設定してあげるのがいいのかなと思います。
個人開発などでは面倒くさがって全てdefaultのプロファイルに設定された認証情報を利用しがちですが、これはすなわち全て同じIAMロールを使用していることと同義になります。
あるアプリでは必要な権限も別のアプリでは不要な場合もあると思います。セキュリティの観点から別々のプロファイルとして切り分けてあげるのが妥当かなと思います。

まとめ

今回は認証情報を設定する方法をご紹介しました。
AWSの認証周りは非常に多様な形態をとることが出来ます。今回の記事で紹介した内容は、一つの例として参考にしていただけると嬉しいです。