Upgrade to Pro — share decks privately, control downloads, hide ads and more …

セキュアなTerraformの使い方 ~ 機密情報をコードに含めず環境構築するにはどうしたらいいの?

セキュアなTerraformの使い方 ~ 機密情報をコードに含めず環境構築するにはどうしたらいいの?

22/8/5 CloudNative Security Conference 2022にて発表

Haruka Sakihara

August 05, 2022
Tweet

More Decks by Haruka Sakihara

Other Decks in Technology

Transcript

  1. セキュアなTerraformの使い方 Friday, August 5, 2022 Haruka Sakihara ~ 機密情報をコードに含めず環境構築するにはどうしたらいいの?

  2. 自己紹介 Haruka Sakihara Twitter:@saki_engineer • アクセンチュア株式会社 テクノロジーコンサルティング本部所属 • 普段はクラウドインフラ構築の支援をしております •

    アプリケーション……プライベートだとGo, 仕事だ と少しPython • インフラ……ほとんどAWS GitHub: @saki-engineering
  3. Introduction Terraformとは Terraformは、HashiCorp社がOSSとして開発しているIaCツールで、HCLという独自の言語によっ てインフラ構成を宣言的に定義・記述して管理することができます。 AWS Cloud クラウド上の実環境 Terraformコード AWS上にインスタンスが2つ resource

    “aws_instance“ “hello” { count = 2 type = t2.micro } provider "aws" { profile = “default” region = "ap-northeast-1" }
  4. Introduction Terraformとは Terraformで書いたコードに対してplan/applyコマンドを実行することで、実際にどのようなリソー スが作成される予定か確認・デプロイ作業を行うことができます。 resource "aws_instance“ “hello” { count =

    2 type = t2.micro } provider "aws" { profile = “default” region = "ap-northeast-1" } コードの作成 planの実行 applyの実行 $ terraform plan Terraform will perform the following actions: # aws_instance.hello will be created (中略) Plan: 1 to add, 0 to change, 0 to destroy $ terraform apply (中略) Enter a value: yes aws_instance.hello: Creating... (中略) Apply complete! Resource: 1 added, 0 changed, 0 destroyed
  5. Introduction 「構成をコードで管理する」IaCのメリット Terraformのように「インフラ構成をコードの形で管理する」というIaC(Infrastructure as a Code) には数多くの利点があり、昨今はとても一般的になってきました。 環境の再構築が容易 構築の自動化が容易 変更履歴の管理がしやすい

    IaCの主なメリット Deploy! Deploy! ver 1.0 ver 1.1 Auto Deploy! AWS Cloud
  6. Introduction 「構成をコードで管理する」から気をつけるべき点 IaCは便利ですが、コードという形で構成が文字・履歴に残るからこそ、そこに「機密情報が含まれ ないか」という点に気をつかう必要があります。 1. 開発者が機密情報を含む Terraformコードを書く 2. tfファイルをgit push

    3. Commit履歴に 機密情報が入る git push !!!!!! top_secret コードレポジトリ コードレポジトリ
  7. セキュアなTerraformの使い方 Agenda 機密情報をあつかうTerraformコード tfstateファイルに含まれる情報 Terraformと機密情報の共存案候補 tfstateに機密を含ませないための実装 まとめ 1 2 3

    4 5
  8. 1. 機密情報をあつかうTerraformコード Terraformで扱うことができる機密情報例 Terraformを通して扱う機密情報として考えられるものは、APIのアクセスキーの情報や、データ ベースのユーザー名・パスワードなどが挙げられます。 AWS Cloud AWS Systems Manager

    Parameter Store AWS Secrets Manager API Key Password
  9. 1. 機密情報をあつかうTerraformコード Terraformで扱うことができる機密情報例 Terraformを通して扱う機密情報として考えられるものは、APIのアクセスキーの情報や、データ ベースのユーザー名・パスワードなどが挙げられます。 AWS Cloud Amazon Relational Database

    Service (Amazon RDS) Amazon RDS instance Password
  10. 1. 機密情報をあつかうTerraformコード tfファイルには機密情報を記述しない例① 一見考えられる解決方法としては、「TerraformのDataSourceを参照する形で、ユーザー名やパス ワードといった情報を指定する」というやり方がありますが、実はこれはよくない例です。 AWS Cloud AWS Secrets Manager

    DataSourceを使ったリソース属性の参照イメージ my_secret_parameter というkeyに 秘密情報を格納 data.aws_secretsmanager_secret_version.password_secret.[attr] で情報を参照できる
  11. 1. 機密情報をあつかうTerraformコード tfファイルには機密情報を記述しない例① 一見考えられる解決方法としては、「TerraformのDataSourceを参照する形で、ユーザー名やパス ワードといった情報を指定する」というやり方がありますが、実はこれはよくない例です。 AWS Cloud Amazon Relational Database

    Service (Amazon RDS) Amazon RDS instance DataSourceを参照してDBをデプロイするイメージ Passwordに Secrets Managerの値を設定
  12. 1. 機密情報をあつかうTerraformコード tfファイルには機密情報を記述しない例② git管理対象外にしたファイルにパスワードを書き、その値を変数として読み込むという方法もあり ますが、実はこれもあまりいい解決方法ではありません。 変数の値を使用してDBをデプロイするイメージ AWS Cloud Amazon Relational

    Database Service (Amazon RDS) Amazon RDS instance terraform.tfvars (git管理対象外) main.tf (git管理) Passwordの値を 受け付ける変数の定義 変数db_passwordの値を パスワードに指定
  13. 1. 機密情報をあつかうTerraformコード tfファイルとtfstateファイル 実はTerraformのリソースには、開発者が記述するtfファイル以外にもtfstateファイルというものが あり、先ほどの例はそこに機密情報が含まれてしまうのです。 .tfファイル tfstateファイル ???

  14. セキュアなTerraformの使い方 Agenda 機密情報をあつかうTerraformコード tfstateファイルに含まれる情報 Terraformと機密情報の共存案候補 tfstateに機密を含ませないための実装 まとめ 1 2 3

    4 5
  15. 2. tfstateファイルに含まれる情報 tfstateファイルとは tfstateファイルは、「最後にterraform applyを行った際の実環境の状態を記載したもの」です。 AWS Cloud Availability Zone a

    Availability Zone b tfstateファイル • AZ-aにEC2インスタンスが3個 • AZ-bにEC2インスタンスが2個 同内容
  16. 2. tfstateファイルに含まれる情報 tfstateファイルとは terraform applyによって構成を変更する際に、Terraformは.tfファイルの記述内容とtfstateファイ ルの記述内容から差分を検知することで、新たに作成するリソースを把握します。 AWS Cloud Availability Zone

    a Availability Zone b 1. terraform applyの実行 3. リソース作成 2. 差分の検知 .tfファイル • AZ-aにEC2インスタンスが3個 • AZ-bにEC2インスタンスが2個 tfstateファイル • AZ-aにEC2インスタンスが2個 • AZ-bにEC2インスタンスが2個
  17. 2. tfstateファイルに含まれる情報 tfstateファイルとは 実際にリソース作成が行われて実環境の構成が変化した際には、Terraformはその変更内容をtfstate ファイル中に書き込み反映させる作業を行います。 AWS Cloud Availability Zone a

    Availability Zone b tfstateファイル • AZ-aにEC2インスタンスが2→3個 • AZ-bにEC2インスタンスが2個 .tfファイル • AZ-aにEC2インスタンスが3個 • AZ-bにEC2インスタンスが2個 1. terraform applyの実行 3. リソース作成 2. 差分の検知 4. リソース作成 結果の反映
  18. 2. tfstateファイルに含まれる情報 tfstateファイルとは 結果、tfstateファイルの中には実環境上にデプロイされたリソースの情報がまるまる含まれるよう になります。 AWS Cloud Availability Zone a

    Availability Zone b tfstateファイル • AZ-aにEC2インスタンスが3個 • AZ-bにEC2インスタンスが2個 .tfファイル • AZ-aにEC2インスタンスが3個 • AZ-bにEC2インスタンスが2個 1. terraform applyの実行 3. リソース作成 2. 差分の検知 同内容 4. リソース作成 結果の反映
  19. 2. tfstateファイルに含まれる情報 (補足) tfstateの管理パターン① - ローカルに保存 tfstate管理方法のデフォルトはローカル保存です。しかし開発者が複数人いる場合には、各々の ローカルのtfstateが同じ状態であることを担保できないことが問題となります。 AWS Cloud

    Availability Zone b Availability Zone a 1. terraform applyの実行 tfstateファイル .tfファイル tfstateファイル .tfファイル tfstateファイル .tfファイル 2. 変更内容を反映 tfstateが最新のリモート環境 を反映していない
  20. 2. tfstateファイルに含まれる情報 (補足) tfstateの管理パターン② - S3に保存 tfstateをS3に置くことで、複数人の開発者がTerraformコマンド実行時に同じtfstateファイルを同 時に参照できるようになります。 AWS Cloud

    Availability Zone b Availability Zone a tfstateファイル 1. terraform applyの実行 2. 変更内容を反映 他人が変更した 実環境の状態を参照できる .tfファイル .tfファイル .tfファイル
  21. 2. tfstateファイルに含まれる情報 (補足) tfstateの管理パターン② - S3に保存 しかし、リソース変更内容を同時にtfstateファイルに反映することはできません。なぜならば、S3 単体ではファイル書き込みの際の排他制御を行うことができないからです。 AWS Cloud

    Availability Zone b Availability Zone a tfstateファイル .tfファイル .tfファイル .tfファイル 1. 同時にterraform applyの実行 2. 同時に 変更内容 を反映し ようとす る 3. 排他制御できず コンフリクト
  22. 2. tfstateファイルに含まれる情報 (補足) tfstateの管理パターン③ - S3+DynamoDB DynamoDBを使ってtfstateの参照ロックを掛けることによって、デプロイ競合を防ぐことができま す。 AWS Cloud

    Availability Zone b Availability Zone a .tfファイル .tfファイル Aさん Bさん tfstateファイル Amazon DynamoDB 2.tfstateにロックが掛かり 1. Aさんのterraform applyの実行時に 3.Bさんはterraform applyを実行できない
  23. 2. tfstateファイルに含まれる情報 tfstateファイルの中身を見てみよう 例えばRDSのデプロイを行うと、それに伴って生成されるtfstateファイルの中には、マスターユー ザー名とパスワードが記載されます。 .tfファイル tfstateファイル

  24. 2. tfstateファイルに含まれる情報 tfstateファイルの中身を見てみよう 例えばRDSのデプロイを行うと、それに伴って生成されるtfstateファイルの中には、マスターユー ザー名とパスワードが記載されます。 .tfファイル tfstateファイル passwordの値が平文で記載

  25. 2. tfstateファイルに含まれる情報 tfstateファイルの中身を見てみよう Systems ManagerのパラメータストアやSecrets Managerの場合も 同様に、Terraformで値のセッ トを行った場合はtfstateに内容が記載されます。 .tfファイル tfstateファイル

    SecureStringの値が 平文で記載
  26. 2. tfstateファイルに含まれる情報 tfstateファイルの中身を見てみよう DataSourceでパラメータ値を参照した場合にも同様に、tfstateに読みだした値が記録されます。そ れを参照してRDSをデプロイした場合には言わずもがなです。 .tfファイル tfstateファイル secret_stringの値が 平文で記載 tfファイルには機密情報が含まれていないが……

  27. セキュアなTerraformの使い方 Agenda 機密情報をあつかうTerraformコード tfstateファイルに含まれる情報 Terraformと機密情報の共存案候補 tfstateに機密を含ませないための実装 まとめ 1 2 3

    4 5
  28. 3. Terraformと機密情報の共存案候補 Terraformで機密を扱う際に考えられる案 機密が入ったtfstateファイルを扱う際に、以下のような案で乗り切ろうというアイデアが出るかも しれませんが、これらは正しいアプローチではありません。 sensitive属性を付けて定義 tfstateファイルをKMS鍵で暗号化 tfstateファイルを触らせない 案 AWS

    Cloud tfstateファイル sensitive属性が ついた変数 Don’t touch it. tfstateファイル AWS KMS key encrypt
  29. 3. Terraformと機密情報の共存案候補 Terraformで機密を扱う際に考えられる案 機密が入ったtfstateファイルを扱う際に、以下のような案で乗り切ろうというアイデアが出るかも しれませんが、これらは正しいアプローチではありません。 sensitive属性を付けて定義 tfstateファイルをKMS鍵で暗号化 tfstateファイルを触らせない 案 AWS

    Cloud tfstateファイル sensitive属性が ついた変数 Don’t touch it. tfstateファイル AWS KMS key encrypt
  30. 3. Terraformと機密情報の共存案候補 sensitive属性 Terraformにはsensitive属性というフィールドがあり、これを利用するとplanやapplyの際に表示さ れる差分確認に設定値がターミナルに表示されることを防ぐことができます。 画像出典: HashiCorp Blog - Terraform

    0.14 Adds the Ability to Redact Sensitive Values in Console Output sensitive属性がついた 変数を使って リソースを定義 terraform plan plan結果に sensitive属性の値が 非表示になる
  31. 3. Terraformと機密情報の共存案候補 sensitive属性 しかし、sensitive属性を使ったとしてもtfstateファイルには機密を含んだ設定値は残ったままです。 そのため、tfstate経由での漏洩可能性は依然として残ったままです。 出典: HashiCorp Blog - Terraform

    0.14 Adds the Ability to Redact Sensitive Values in Console Output 和訳: sensitive属性の値はtfstateファイルには記録されます。 そのため、stateファイルの閲覧ができる人にはその値を参照することができます。
  32. 3. Terraformと機密情報の共存案候補 Terraformで機密を扱う際に考えられる案 機密が入ったtfstateファイルを扱う際に、以下のような案で乗り切ろうというアイデアが出るかも しれませんが、これらは正しいアプローチではありません。 sensitive属性を付けて定義 tfstateファイルをKMS鍵で暗号化 tfstateファイルを触らせない 案 AWS

    Cloud tfstateファイル sensitive属性が ついた変数 Don’t touch it. tfstateファイル AWS KMS key encrypt
  33. 3. Terraformと機密情報の共存案候補 KMS鍵で暗号化? Terraformでリソースの作成を行うためには、tfstateの読み・書き両方できるようにする必要があり ます。 AWS Cloud tfstateファイル • RDSを1個

    (パスワード: MySecretPass) .tfファイル • RDSを1個 (パスワード: MySecretPass) 1. terraform applyの実行 3. リソース作成 2. 差分の検知 4. リソース作成 結果の反映 Amazon Relational Database Service (Amazon RDS) Amazon RDS instance tfstateの 読みこみ tfstateへの 書きこみ
  34. 3. Terraformと機密情報の共存案候補 KMS鍵で暗号化? 結果、インフラを触りたい開発者に全員暗号化・復号の権限をもたせることになるので、「暗号化し てtfstateを触れる人を制限しよう」というようにはうまくできません。 AWS Cloud tfstateファイル AWS KMS

    key 開発者全員が暗号化・復号の 権限をもつことになる
  35. 3. Terraformと機密情報の共存案候補 おまけ 「機密情報を含んだフィールドのみ、ユーザーが指定した鍵で暗号化して保存する」という機能を導 入するという話もHashiCorp内部ではあったようですが、「鍵を持たないユーザーからの plan/applyリクエストをどう扱うべきか」に難があり頓挫したようです。 .tfファイル terraform apply with

    暗号化鍵A tfstateファイル Key: API_Key_A Value: MyAPIKey 出典: Terraform Plugin SDKv2 Doc - Handling Sensitive Values in State Key: API_Key_A Value: WiKZSUoi terraform plan with 暗号化鍵B ???
  36. 3. Terraformと機密情報の共存案候補 Terraformで機密を扱う際に考えられる案 機密が入ったtfstateファイルを扱う際に、以下のような案で乗り切ろうというアイデアが出るかも しれませんが、これらは正しいアプローチではありません。 sensitive属性を付けて定義 tfstateファイルをKMS鍵で暗号化 tfstateファイルを触らせない 案 AWS

    Cloud tfstateファイル sensitive属性が ついた変数 Don’t touch it. tfstateファイル AWS KMS key encrypt
  37. 3. Terraformと機密情報の共存案候補 tfstateを触らせずに開発? デプロイ時にtfstateの読み書きを行うとはいえ、terraform plan/applyコマンドを通常通りに実行 しているだけならば、tfstateの中身をみることはありません。 そのため、「S3の中にあるtfstateを見ないようなワークフローにすればいいのでは」と思うかもし れません。 AWS Cloud

    tfstateファイル 生のtfstateを見なくても plan/apply自体はできる terraform plan/apply
  38. 3. Terraformと機密情報の共存案候補 tfstateを触らせずに開発? →そんなの無理 しかし、Terraformをある程度の期間運用していると、「tfstateの中身を書き換える」という場面が 発生することは珍しくありません。 AWS Cloud tfstateファイル terraform

    plan/apply 直接書き換える
  39. 3. Terraformと機密情報の共存案候補 tfstateを書き換えるユースケース 例えば、リソース名を変更する・複数個のリソースをモジュールとしてまとめるといった形で.tf ファイルをリファクタすることを考えます。 リソース名をリネーム モジュール化 defaultからmy_test_dbに リネーム セキュリティ

    グループの定義を 直接記述から モジュールを 利用したものに 変更
  40. 3. Terraformと機密情報の共存案候補 tfstateを書き換えるユースケース リソース名をリネームした状態で、terraform planコマンドを実行してみます。 AWS Cloud tfstateファイル terraform plan

    Amazon Relational Database Service (Amazon RDS) Amazon RDS instance 変更なし defaultからmy_test_dbに リネーム
  41. 3. Terraformと機密情報の共存案候補 tfstateを書き換えるユースケース RDSを表すリソース名が変わったことにより、実環境には何も変更がないのにも関わらず、 Terraform上では差分ありとなってしまいます。 AWS Cloud tfstateファイル terraform plan

    Amazon Relational Database Service (Amazon RDS) Amazon RDS instance Plan: 1 to add, 0 to change, 1 to destroy 変更なし defaultからmy_test_dbに リネーム
  42. 3. Terraformと機密情報の共存案候補 tfstateを書き換えるユースケース RDSを表すリソース名が変わったことにより、実環境には何も変更がないのにも関わらず、 Terraform上では差分ありとなってしまいます。 AWS Cloud tfstateファイル terraform plan

    Amazon Relational Database Service (Amazon RDS) Amazon RDS instance Plan: 1 to add, 0 to change, 1 to destroy tfstateファイル内は リソース名: defaultのまま defaultからmy_test_dbに リネーム 差分ありの扱い
  43. 3. Terraformと機密情報の共存案候補 tfstateを書き換えるユースケース そのため、terraform state mvコマンドを用いてtfstateファイルをリファクタ後のコードに沿う形 に書き換えて、余計なdestroy->recreateが起こらないようにするという作業が行われます。 AWS Cloud tfstateファイル

    $ terraform state mv aws_db_instance.default aws_db_instance.my_test_db Amazon Relational Database Service (Amazon RDS) Amazon RDS instance tfstateファイル内は リソース名: defaultのまま defaultからmy_test_dbに リネーム
  44. 3. Terraformと機密情報の共存案候補 tfstateを書き換えるユースケース そのため、terraform state mvコマンドを用いてtfstateファイルをリファクタ後のコードに沿う形 に書き換えて、余計なdestroy->recreateが起こらないようにするという作業が行われます。 AWS Cloud tfstateファイル

    $ terraform state mv (引数略) Move "aws_db_instance.default" to "aws_db_instance.my_test_db" Successfully moved 1 object(s). Amazon Relational Database Service (Amazon RDS) Amazon RDS instance 書き換え
  45. 3. Terraformと機密情報の共存案候補 tfstateを書き換えるユースケース そのため、terraform state mvコマンドを用いてtfstateファイルをリファクタ後のコードに沿う形 に書き換えて、余計なdestroy->recreateが起こらないようにするという作業が行われます。 AWS Cloud tfstateファイル

    terraform plan Amazon Relational Database Service (Amazon RDS) Amazon RDS instance No changes. Your infrastructure matches the configuration. defaultからmy_test_db にリネーム tfstateファイル内も リソース名:my_test_dbに 書き換え済み 差分なし
  46. 3. Terraformと機密情報の共存案候補 tfstateを書き換えるユースケース tfstateファイルは、plan/applyを行う際に差分計算に使うとても重要なファイルです。そのため、 バックアップとして「ローカルにダウンロードしてから」state mvコマンドを打つのが一般的です。 AWS Cloud tfstateファイル terraform

    state mv 直接書き換え 一度ローカルにpullする AWS Cloud tfstateファイル コマンドミスがあると ここが壊れる恐れ tfstateファイル(新) tfstateファイル ローカルで terraform state mv terraform state pull terraform state push tfstateファイル(新)
  47. 3. Terraformと機密情報の共存案候補 tfstateを書き換えるユースケース もしtfstateファイルにDBパスワードのような機密情報が含まれていると、state pullしたときにみえ てしまいますし、その情報が開発者のローカルで不適切な形で保持され続けることも考えられます。 AWS Cloud tfstateファイル tfstateファイル(新)

    tfstateファイル ローカルで terraform state mv terraform state pull terraform state push tfstateファイル(新) ここに機密情報が含まれていると…? • state pullしたときに開発者が容易に値を 確認することができる • state pushした後に、きちんとローカルに 残った古いstateファイルを削除してもら う必要がある (そしてこれを強制するのは困難) • 最悪のケースとして、ローカルに残った stateファイルから情報が流出するという ことも考えられる
  48. 3. Terraformと機密情報の共存案候補 まとめ 結局のところ、tfstateに機密を保持したままセキュアな運用をするのは難しいと言わざるを得ませ ん。そのため、必然的に「そもそもtfstateに機密を含ませない」というやり方が求められます。 sensitive属性を付けて定義 tfstateファイルをKMS鍵で暗号化 tfstateファイルを触らせない 案(???) AWS

    Cloud tfstateファイル sensitive属性が ついた変数 Don’t touch it. tfstateファイル AWS KMS key encrypt
  49. 3. Terraformと機密情報の共存案候補 まとめ 結局のところ、tfstateに機密を保持したままセキュアな運用をするのは難しいと言わざるを得ませ ん。そのため、必然的に「そもそもtfstateに機密を含ませない」というやり方が求められます。 sensitive属性を付けて定義 tfstateファイルをKMS鍵で暗号化 tfstateファイルを触らせない 案(???) AWS

    Cloud tfstateファイル sensitive属性が ついた変数 Don’t touch it. tfstateファイル AWS KMS key encrypt 結論 そもそもtfstateに機密を含ませるのをやめましょう!!!
  50. セキュアなTerraformの使い方 Agenda 機密情報をあつかうTerraformコード tfstateファイルに含まれる情報 Terraformと機密情報の共存案候補 tfstateに機密を含ませないための実装 まとめ 1 2 3

    4 5
  51. 4. tfstateに機密を含ませないために 「tfファイルに機密を直接記入」を防止 「tfstateの中に機密を含ませない」というポイント以前に、まずはtfファイルに機密情報をべた書き するのを防ぐという意味で、静的解析ツールの導入が有効です。 Terraformではaquasecurity/tfsecが有名です。 出典: github.com/aquasecurity/tfsec

  52. 4. tfstateに機密を含ませないために Terraformで扱いたくなる機密情報 Terraformで扱いたくなる機密情報は、大きく分けて以下2種類に分けられます。それぞれについて どのように対処するのか、これから掘り下げていきましょう。 機密情報を使用するリソース Terraformで扱える機密情報 機密情報そのもの AWS Systems

    Manager Parameter Store AWS Secrets Manager Amazon Relational Database Service (Amazon RDS) Amazon DocumentDB (with MongoDB compatibility) Amazon Redshift
  53. 4. tfstateに機密を含ませないために Terraformで扱いたくなる機密情報 Terraformで扱いたくなる機密情報は、大きく分けて以下2種類に分けられます。それぞれについて どのように対処するのか、これから掘り下げていきましょう。 機密情報を使用するリソース Terraformで扱える機密情報 機密情報そのもの AWS Systems

    Manager Parameter Store AWS Secrets Manager Amazon Relational Database Service (Amazon RDS) Amazon DocumentDB (with MongoDB compatibility) Amazon Redshift
  54. 4. tfstateに機密を含ませないために データベースのパスワードをTerraformで扱う DBを構築する際には、ダミーパスワードを使用して構築を行い、その後パスワード変更を行うとい う手段が有効です。 1. パスワード欄には ダミーを指定して構築 2. デプロイ後に

    パスワードを変更 AWS Cloud Amazon RDS instance terraform apply Password: dummy AWS Cloud Amazon RDS instance Change Password!!
  55. 4. tfstateに機密を含ませないために Secrets Managerを用いたパスワード変更 パスワード変更には、Secrets Managerを使う方法が便利です。 AWS Cloud VPC Amazon

    Relational Database Service (Amazon RDS) Amazon RDS instance AWS Lambda Lambda function AWS Secrets Manager Endpoints
  56. 4. tfstateに機密を含ませないために Secrets Managerを用いたパスワード変更 まず、初期パスワードと同じ値を含むsecret revisionを作成します。 AWS Cloud VPC Amazon

    Relational Database Service (Amazon RDS) Amazon RDS instance AWS Lambda Lambda function AWS Secrets Manager Endpoints Password: dummy revision 1 Password: dummy
  57. 4. tfstateに機密を含ませないために Secrets Managerを用いたパスワード変更 Secrets Manager上でパスワードローテーションを指示すると、裏のLambda関数が新しいsecret revisionを作成します。 AWS Cloud VPC

    Amazon Relational Database Service (Amazon RDS) Amazon RDS instance AWS Lambda Lambda function AWS Secrets Manager Endpoints Password: dummy revision 1 Password: dummy ↓ revision 2 Password: diahgd;wvpdxcba 新secretの生成
  58. 4. tfstateに機密を含ませないために Secrets Managerを用いたパスワード変更 その後、Lambda関数はデータベースのパスワードを新secretの値に更新します。 AWS Cloud VPC Amazon Relational

    Database Service (Amazon RDS) Amazon RDS instance AWS Lambda Lambda function AWS Secrets Manager Endpoints Password: dummy Password: diahgd;wvpdxcba revision 1 Password: dummy ↓ revision 2 Password: diahgd;wvpdxcba DBパスワードの 変更
  59. 4. tfstateに機密を含ませないために Secrets Managerを用いたパスワード変更 無事にパスワード更新ができたらLambda関数は新revisionのステータスをCURRENTに変更し、今 どのバージョンの値が実際にパスワードとして使われているのかを記録します。 AWS Cloud VPC Amazon

    Relational Database Service (Amazon RDS) Amazon RDS instance AWS Lambda Lambda function AWS Secrets Manager Endpoints Password: dummy Password: diahgd;wvpdxcba revision 1 Password: dummy ↓ revision 2 Password: diahgd;wvpdxcba 新secretのステータスを CURRENTに変更
  60. 4. tfstateに機密を含ませないために パスワードローテーションのセットアップ Secrets Managerと連携してパスワードローテーションを行うLambda関数は、AWS SAMのテンプ レートとして公開されているので、こちらを使うのが手軽です。 リンク:https://serverlessrepo.aws.amazon.com/applications

  61. 4. tfstateに機密を含ませないために パスワードローテーションのセットアップ AWS SAMテンプレートをTerraform経由でデプロイするためのリソースブロックがあるので、それ を使います。 注: わかりやすさのために、ソースコードに改行を入れています。 SAMテンプレートを デプロイ

  62. 4. tfstateに機密を含ませないために パスワードローテーションのセットアップ Secrets Managerの設定の中に、パスワードローテーション用のLamdba関数を指定する箇所があり ます。そこには先ほどのSAMで作られたLambda関数のARNを指定します。 パスワードローテーション用の設定 SAMでデプロイしたLambda関数の ARNを参照

  63. 4. tfstateに機密を含ませないために パスワードローテーションのセットアップ パスワードローテーションの準備ができたところで、データベースの初期パスワードにはダミー値 「password」を指定してデプロイを行います。 dummy!

  64. 4. tfstateに機密を含ませないために パスワードローテーションのセットアップ Terraformのtfファイル内にダミーパスワードの値を記載したので、当然その値はtfstateファイル内 にも記載されることになります。 RDSの部分 Secrets Managersの部分 ダミーパスワード ダミーパスワードを含んだ

    secret値
  65. 4. tfstateに機密を含ませないために パスワードローテーションのセットアップ パスワードを一度ローテーションしてしまえば、ダミーパスワードの値は古いものとなります。 そのため、tfstateにダミー「password」と書かれていることは問題にならなくなります。 「すぐにシークレットをローテーションさせる」で 即座にパスワード変更を行える

  66. 4. tfstateに機密を含ませないために パスワードローテーションによる差分をうまく扱う しかし今の設定のままでは、手動でのパスワードローテーションがTerraform側で「リソースの差分 発生」と捉えられてしまいます。 パスワードローテーション後にterraform planを実行した結果 差分が検知される

  67. 4. tfstateに機密を含ませないために パスワードローテーションによる差分をうまく扱う そのため、パスワードローテーションに伴って値が変わるプロパティをignore_changesに指定する ことで、無駄な差分検知を回避することができます。 secret_stringとversion_stageの値は 変更があっても無視する

  68. 4. tfstateに機密を含ませないために Terraformで扱いたくなる機密情報 Terraformで扱いたくなる機密情報は、大きく分けて以下2種類に分けられます。それぞれについて どのように対処するのか、これから掘り下げていきましょう。 機密情報を使用するリソース Terraformで扱える機密情報 機密情報そのもの AWS Systems

    Manager Parameter Store AWS Secrets Manager Amazon Relational Database Service (Amazon RDS) Amazon DocumentDB (with MongoDB compatibility) Amazon Redshift
  69. 4. tfstateに機密を含ませないために 機密情報値そのものをTerraformで扱うか? データベースのパスワードのように、定期的に変更することを前提とした値をSecrets Managerに 格納することは、「デプロイ後すぐにローテーションを行うこと」「Secret値をDataSourceで参照 しないようにすること」を徹底することで、tfstateまで含めて安全な状態にすることができます。 1. 初期セットアップのみ terraform

    apply AWS Cloud AWS Secrets Manager 2. デプロイ後に即座に ローテーションを実施 デプロイ後にローテーション secret値を直接参照する DataSourceの使用禁止 secret値が tfstateに書きこまれる
  70. 4. tfstateに機密を含ませないために 機密情報値そのものをTerraformで扱うか? それに対して、ローテーションを前提としないAPI Keyを扱う場合や、そもそもローテーション機能 が備わっていないSSM Paramater StoreのSecureStringは、tfstateへのsecret混入回避が困難&リ ソースの性質上IaC化するメリットも薄いため、Terraformで扱うべきではないでしょう。 環境の再構築が容易

    構築の自動化が容易 変更履歴の管理がしやすい IaCの主なメリット(再掲) Deploy! Deploy! ver 1.0 ver 1.1 Auto Deploy! AWS Cloud
  71. 4. tfstateに機密を含ませないために 機密情報値そのものをTerraformで扱うか? それに対して、ローテーションを前提としないAPI Keyを扱う場合や、そもそもローテーション機能 が備わっていないSSM Paramater StoreのSecureStringは、tfstateへのsecret混入回避が困難&リ ソースの性質上IaC化するメリットも薄いため、Terraformで扱うべきではないでしょう。 環境の再構築が容易

    構築の自動化が容易 変更履歴の管理がしやすい IaCの主なメリット(再掲) Deploy! Deploy! ver 1.0 ver 1.1 Auto Deploy! AWS Cloud secret値の設定だけなら そこまで複雑ではなく 労力も小さい リソースの性質上、変更が生じないため 構築自動化・変更管理の需要がない
  72. セキュアなTerraformの使い方 Agenda 機密情報をあつかうTerraformコード tfstateファイルに含まれる情報 Terraformと機密情報の共存案候補 tfstateに機密を含ませないための実装 まとめ 1 2 3

    4 5
  73. 本日のまとめ • Terraformにて機密情報を記載・参照すると、その値がtfファイルだけでなくtfstateファイル内に も平文で書きこまれます。 • 「tfstateファイルに機密が書きこまれることを許容したうえで、そのtfstateファイルをセキュア に扱う」という手法は現実問題難しいかと思います。 • データベースパスワードのように一定期間でのローテーションを想定した機密情報は、ダミー値 を用いた初期構築のみをTerraformで行うのが安全でしょう。

    • ローテーションを想定していない機密情報をSecrets ManagersやSSMにセットする作業は、そ もそもIaC化するメリットも薄いため手動やCLIを用いたスクリプトでやるのが望ましいです。
  74. Thank You ご意見、ご質問ありましたらお気軽にご連絡下さい haruka.sakihara@accenture.com Haruka Sakihara(崎原 晴香)