AWSのParameter StoreとSecrets Manager、結局どちらを使えばいいのか？比較

# AWSのアクセスキー/シークレットアクセスキーのコード書き込みは危険
GitHubにAccess Key/Secret Access Keyを含むコードをPushしてしまい、
公開されたキーで犯罪者にAWS環境へのアクセスを許してしまい、
ハイスペックインスタンスタイプ(料金が高い)のインスタンスを
仮想通貨マイニング等に利用されてしまい、
請求書を見て青ざめる、
というインシデントが定期的に発生しています。

今年の2月にその危険性を検証された方がおられ、
**「git pushから13分でご利用開始」**とのこと。

[GitHub に AWS キーペアを上げると抜かれるってほんと？？？試してみよー！ - Qiita](https://qiita.com/saitotak/items/813ac6c2057ac64d5fef)

GitHubからアクセスキーを抽出するスクレイピング、
完全に自動化されてますね。

AWSもユーザへの啓蒙として、
AWSアクセスキーを管理するためのベストプラクティスを公開しており、
その中でもコードへのキーの埋め込みはバッドプラクティスとされています。

[AWS アクセスキーを管理するためのベストプラクティス - アマゾン ウェブ サービス](https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws-access-keys-best-practices.html)

>アクセスキーを直接コードに埋め込まないでください。AWS SDK と AWS コマンドラインツールでは、既知のロケーションにアクセスキーを置くことができるため、コードで保持する必要はありません。

対策としては**「認証情報をAWS 認証情報ファイルに保存する」**、**「認証情報を環境変数に設定する」**が挙げられています。

それでは、アプリケーションのコードと、アクセスキーやID/パスワード情報を安全に分離するにはどうすればよいのでしょうか？

# Parameter StoreとSecrets Manager

AWS Systems Managerの一機能として、**パラメータストア機能**が提供されており、
パスワードのような秘密データや、
その他の設定データを一元管理する機能が提供されています。

2018年初頭までは、
AWSの機能を活用したアプリコードとID/パスワード情報の分離の有力な方法は、
パラメータストア機能の利用でした。

しかし、2018年4月のAWS Summits 2018 | San Franciscoにおいて、
ID/パスワードや認証情報の管理サービスとして、
**AWS Secrets Manager**が発表されました。
東京リージョンでも利用可能です。

こうなると、素朴な疑問として、
**「どっちを使えばいいの？」**
となります。

ググると、海外ユーザも混乱しているらしく、
reddit上で活発な議論が交わされていました。

[Parameter Store vs Secrets Manager? : aws](https://www.reddit.com/r/aws/comments/8e70z8/parameter_store_vs_secrets_manager/)

## 機能、料金比較

redditの議論、AWSのドキュメント、Black Beltの情報等を参考に、
両者の特徴を比較してみました。

|比較項目 |Parameter Store |Secrets Manager |
|:--:|:--|:--|
|情報の保管単位  |"/dev/os-users"のような階層型のパラメータに保管可能。パラメータには1つまたは複数の値を保管可能。パラメータと値は1:1または1:n   |dev/db-string"のような階層型のシークレットに保管可能。**シークレットには、1つまたは複数の「キーと値のペア」を保管可能。**シークレットと、「キーと値のペア」は1:1または1:n   |
|保管された情報の暗号化 |暗号化され、KMSに保存   |暗号化され、KMSに保存   |
|保管された情報へのAPIアクセス  |可能   |可能   |
|APIアクセス時のRate limit  |**非公開**   |700 Req/sec ※DescribeSecret、GetSecretValueの場合([参照](https://docs.aws.amazon.com/secretsmanager/latest/userguide/reference_limits.html))   |
|保管された情報へのアクセス制御  |IAMポリシーで制御可能   |IAMポリシーで制御可能   |
|連携可能なAWSサービス   |多数([参照](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html))   |RDS for MySQL、PostgreSQL、Auroraの認証情報保存を標準サポート(Secrets Managerの設定画面上で、対象のRDSを選択可能)。AWS CLIやSDKを通じてEC2やECS、Labmda等と連携可能  |
|保管された情報のバージョニング   |複数バージョンを保持可能。1パラメータにつき100([参照](https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#limits_ssm))|複数バージョンを保持可能。Secrets Managerの内部的には1シークレットにつき約100保持可能だが、バージョンに付与できるラベルの最大数は20([参照](https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#limits_secrets-manager))。バージョンとラベルの関係性については、クラメソさんの[ブログ](https://dev.classmethod.jp/cloud/aws/aws-secrets-manager-with-cli/)が詳しい   |
|保管された情報の使用状況の監査・監視   |CloudTrail、CloudWatch、SNSを活用して監査・監視可能   |CloudTrail、CloudWatch、SNSを活用して監査・監視可能   |
|シークレット情報の自動更新   |Parameter Storeの機能としては不可。AWS CLIやLambda等を活用して作り込みすることで対応可能   |RDS for MySQL、PostgreSQL、Auroraの認証情報自動更新を標準サポート。その他DBの接続情報やAPIキー等は、Parameter Storeにて提供されるLambdaスクリプトをカスタマイズすることで対応可能   |
|利用料金   |**無料**。但し、暗号化に利用されるKMSにてCMK(カスタマーマスターキー。ユーザ側で生成したキー)を利用する場合、KMSのAPI呼び出し料金が必要   |**有料**。シークレット 1 件あたり 0.40 USD/月。10,000 回の API コールあたり 0.05 USD。料金例は[こちら](https://aws.amazon.com/jp/secrets-manager/pricing/)。更に、Parameter Storeと同様、KMSの暗号化にCMKを利用する場合、KMSのAPI呼び出し料金が必要   |

## 比較してみた印象

RDS for MySQL、PostgreSQL、AuroraのDB接続情報(パスワード)の自動更新要件があるのであれば、
Secrets Managerの方が便利かもしれません。
が、有料というところが気になりますね。

また、DBのパスワードを変更するのであれば、
変更したタイミングでアプリの動作に影響ないかどうかリグレッションテストが必要かと思いますので、
自動でパスワードを変更されてしまうのはちょっと怖い印象があります。

などと考えながらふとSystems Managerの[「よくある質問」](https://aws.amazon.com/jp/systems-manager/faq/)を読むと、
答えが書いてありました。

>Q: パラメータストアとシークレットマネージャーのどちらを使えば良いですか?

>設定とシークレットにひとつのストアが欲しい場合、パラメータストアをお使いください。ライフサイクル管理を備えたシークレット専用のストアが欲しい場合、シークレットマネージャーをお使いください。パラメータストアは追加料金なしで、パラメータ数 10,000 個の制限でお使いいただけます。料金の詳細についてはシークレットマネージャー料金ページをご覧ください。

## しかし・・

あら、じゃあRDSのパスワード自動更新要件がない(または自前でやる前提)のであれば、
Parameter Storeでいいのでは？と納得しかけていたところ、
Twitterで以下のようなつぶやきを見かけました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ECS でtask起動時に AWS ssm にアクセスしてパラメータを env に設定してプロセス起動、ってことをしてるんだけど、デプロイで一気にtaskを大量起動すると ssm の rate limit を食らって死ぬので困る。自前で cache とかしたくないしもうちょっと強くなってほしい</p>&mdash; fujiwara (@fujiwara) <a href="https://twitter.com/fujiwara/status/1030293676121972736?ref_src=twsrc%5Etfw">2018年8月17日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

おや？**Parameter Storeは大量アクセスに弱い？**

ググると、AWSのDiscussion Forumに、Parameter Storeに大量アクセス(以下のケースではLambda)すると、
ThrottlingExceptionが発生するというケースが上がっていました。

[AWS Developer Forums: Throttling limits on SSM Parameter Store GetParameters request?](https://forums.aws.amazon.com/thread.jspa?messageID=834134&tstart=0)
※AWSへのログインが必要です。

>Hello,

>We use SSM Parameter Store for storing secrets used by Lambdas.

>Under high load, the Python boto3 client fails with
ClientError: An error occurred (ThrottlingException) when calling the GetParameters operation (reached max retries: 4): Rate exceeded


>I can't find any such limit mentioned under https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html

>How high is the limit we're hitting, and how can we get it increased?

>Thanks in advance!

AWS側の回答は、

>Hello everyone

>Thank you for your feedback on Parameter Store, and for using the service.

>We currently have limits on Parameter Store APIs (just like any other AWS service). However, we do realize that there are use cases as mentioned in this post where customers may want higher Parameter Store API limits. The team is working on prioritizing this and taking the next steps to ensure we provide the requested and best experience for customers. 

>Thanks
>Ananth

API Limitsの上限を上げる検討をしている、とのこと。
スレッドの最後の投稿は2018年8月13日でケースはオープンのままなので、
**Parameter StoreのAPI Limitsの問題はまだ解消していない**のでしょう。

# 結論(2018年8月時点)
- シンプルな3-Tierの小規模WebシステムやDWH等、DBへの接続情報がプーリングされ、パラメータへのアクセスが少ない環境であれば、アプリの利用する情報の外部化にはParameter Storeの利用がコスト的にもリーズナブルである。

- パラメータやシークレット情報に対するスパイクアクセスが予想されるEC2やECSのAuto Scaling環境、Labmda等では、Parameter Storeではパラメータ情報取得のAPIリクエストを捌ききれない可能性がある。

- シークレット情報の取得リクエストが700 Req/secに収まるのであれば、Secrets Managerを試してみる価値あり。ただし有料なのでコスト試算を。

# 2019年5月8日更新
Parameter Storeで、1 秒間に最大 1,000 件のリクエストがサポートされるようになりました！
これで、相当大規模な環境でない限り、Throttlingに悩ませられることはなさそうですね。

・AWS Systems Manager がより高い API スループットでのパラメーターストアの使用のサポートを開始 
https://aws.amazon.com/jp/about-aws/whats-new/2019/04/aws_systems_manager_now_supports_use_of_parameter_store_at_higher_api_throughput/


# 参考
[AWS Systems Manager のよくある質問 – アマゾン ウェブ サービス (AWS)](https://aws.amazon.com/jp/systems-manager/faq/)

[よくある質問 | AWS Secrets Manager | アマゾン ウェブ サービス (AWS)](https://aws.amazon.com/jp/secrets-manager/faqs/)

[20180725 AWS Black Belt Online Seminar AWS Systems Manager](https://www.slideshare.net/AmazonWebServicesJapan/20180723-aws-black-belt-online-seminar-aws-systems-manager)