17
10

More than 5 years have passed since last update.

AWS Secrets ManagerからParameter StoreをTerraformで作成する

Last updated at Posted at 2019-03-18

概要

タイトルの通りですが、AWS Secrets ManagerからParameter StoreをTerraformで作成する方法を紹介します。

想定読者

AWSのParameter StoreとSecrets Manager、結局どちらを使えばいいのか?比較 で両サービスが比較されているので分かりやすいです。

どういう場面で役に立つか

一見すると何の為にこんな事をするのか?普通にSecrets Managerから環境変数を取得すれば良いのでは?と思うかもしれませんが、以下の状況が揃った時に使えると思っています。

  • 複数のアプリケーションをAWSアカウントで管理している
    • ここでは news-appweather-app という2つのアプリケーションを例に説明します
  • 複数のアプリケーションから同様の機密情報を参照する必要がある
    • この記事では以下の2つが登録されていると仮定します。

SeecretManager.png

dev/keitakn/slack
{
  "TOKEN": "DummySlackToken0001"
}
dev/keitakn/sendgrid
{
  "API_KEY": "DummySendGridAPIKEY0001"
}

それぞれ Slack のトークンと SendGrid のAPIキーです。

このように複数のアプリケーションで使いまわす機密情報が存在すると言う前提です。

この方法であれば AWS Secrets Manager だけに機密情報を入れておけば各アプリケーション毎のParameter Storeを動的に作成する事が可能なので、手動で管理する部分を最小限に抑える事が出来るというメリットがあります。

Terraformで aws_ssm_parameter resourcesを使いParameter Storeを作成

以下のようにHCLを書きます。

main.tf
// 既に存在するSeecretManagerリソースを参照する
// この場合AWSに {環境変数}/keitakn/slack という名前で登録されている前提
data "aws_secretsmanager_secret" "slack_secret" {
  name = "${terraform.workspace}/keitakn/slack"
}

data "aws_secretsmanager_secret_version" "slack_secret" {
  secret_id = "${data.aws_secretsmanager_secret.slack_secret.id}"
}

// 既に存在するSeecretManagerリソースを参照する
// この場合AWSに {環境変数}/keitakn/sendgrid という名前で登録されている前提
data "aws_secretsmanager_secret" "sendgrid_secret" {
  name = "${terraform.workspace}/keitakn/sendgrid"
}

data "aws_secretsmanager_secret_version" "sendgrid_secret" {
  secret_id = "${data.aws_secretsmanager_secret.sendgrid_secret.id}"
}

// terraformのExternal Data Sourceを使ってSeecretManagerのJSONをデコードする
// https://www.terraform.io/docs/providers/external/data_source.html
data "external" "slack_secret_json" {
  program = ["echo", "${data.aws_secretsmanager_secret_version.slack_secret.secret_string}"]
}

data "external" "sendgrid_secret_json" {
  program = ["echo", "${data.aws_secretsmanager_secret_version.sendgrid_secret.secret_string}"]
}

// デコードしたJSONを元にパラメータストアを作成する
resource "aws_ssm_parameter" "news_app_slack_token" {
  name  = "/${terraform.workspace}/test-app/news/slack-token"
  type  = "SecureString"
  value = "${data.external.slack_secret_json.result["TOKEN"]}"
}

resource "aws_ssm_parameter" "news_app_sendgrid_api_key" {
  name  = "/${terraform.workspace}/test-app/news/sendgrid-api-key"
  type  = "SecureString"
  value = "${data.external.sendgrid_secret_json.result["API_KEY"]}"
}

resource "aws_ssm_parameter" "weather_app_slack_token" {
  name  = "/${terraform.workspace}/test-app/weather/slack-token"
  type  = "SecureString"
  value = "${data.external.slack_secret_json.result["TOKEN"]}"
}

resource "aws_ssm_parameter" "weather_app_sendgrid_api_key" {
  name  = "/${terraform.workspace}/test-app/weather/sendgrid-api-key"
  type  = "SecureString"
  value = "${data.external.sendgrid_secret_json.result["API_KEY"]}"
}

${terraform.workspace} はTerraformのworkspace名が入ります。
workspaceを以下のように定義しておけば各環境変数毎にParameter Storeを生成する事が可能です。(上記のサンプルコードの場合、Secrets Managerも環境毎に作成する必要あり)

※ workspaceの設定例

  • dev
  • stg
  • prod

terraform apply を実行すると以下のようにParameter Storeが生成されます。

ParameterStore.png

補足

/dev/test-app/news/sendgrid-api-key のような名前でParameter Storeを生成しているのは階層化を行う為です。

例えば以下のようにAWS-CLIを使うと news-app 用の環境変数がまとめて取得出来ます。

AWS-CLIで以下を実行する
aws ssm get-parameters-by-path --path /dev/test-app/news --with-decryption

--with-decryption はセキュアな文字列を復号化する為のオプションです。
他にも必要に応じて --region--profile 等を指定して下さい。

regionとprofileを指定する場合の例
aws ssm get-parameters-by-path --path /dev/test-app/news --with-decryption --profile nekochans-dev --region ap-northeast-1

結果は以下の通りです。

AWS-CLIの結果
{
    "Parameters": [
        {
            "Name": "/dev/test-app/news/sendgrid-api-key",
            "Type": "SecureString",
            "Value": "DummySendGridAPIKEY0001",
            "Version": 1,
            "LastModifiedDate": 1552918997.781,
            "ARN": "arn:aws:ssm:ap-northeast-1:000000000000:parameter/dev/test-app/news/sendgrid-api-key"
        },
        {
            "Name": "/dev/test-app/news/slack-token",
            "Type": "SecureString",
            "Value": "DummySlackToken0001",
            "Version": 1,
            "LastModifiedDate": 1552918997.788,
            "ARN": "arn:aws:ssm:ap-northeast-1:000000000000:parameter/dev/test-app/news/slack-token"
        }
    ]
}

作成したParameter Storeの使い道

AWSのサービスなので当然ですがAWSのサービスと親和性が高いです。

主にコンテナやServerlessアーキテクチャの利用時に力を発揮します。

利用用途として参考になりそうな記事をいくつか載せておきます。

  1. 【祝!】FargateでもECSにごっつ簡単に環境変数に機密情報を渡せるようになりました!
  2. パラメータストアを使って安全なLambda関数を作成する
  3. CodeBuild(buildspec.yml)での環境変数指定方法あれこれまとめ

終わりに

最近EC2のアプリケーションをAWS Fargateに置き換える案件を行っており、機密情報をどう管理するか?という情報が以外と少なかったので記事にしてみました。

今回作成したサンプルコードはGitHubで公開しています。

最後まで読んで頂きありがとうございました。

17
10
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
17
10