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

    アプリケーション……プライベートだとGo, 仕事だ と少しPython • インフラ……ほとんどAWS GitHub: @saki-engineering
  2. 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
  3. 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個
  4. 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. リソース作成 結果の反映
  5. 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. リソース作成 結果の反映
  6. 2. tfstateファイルに含まれる情報 (補足) tfstateの管理パターン① - ローカルに保存 tfstate管理方法のデフォルトはローカル保存です。しかし開発者が複数人いる場合には、各々の ローカルのtfstateが同じ状態であることを担保できないことが問題となります。 AWS Cloud

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

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

    Availability Zone b Availability Zone a tfstateファイル .tfファイル .tfファイル .tfファイル 1. 同時にterraform applyの実行 2. 同時に 変更内容 を反映し ようとす る 3. 排他制御できず コンフリクト
  9. 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を実行できない
  10. 3. Terraformと機密情報の共存案候補 sensitive属性 しかし、sensitive属性を使ったとしてもtfstateファイルには機密を含んだ設定値は残ったままです。 そのため、tfstate経由での漏洩可能性は依然として残ったままです。 出典: HashiCorp Blog - Terraform

    0.14 Adds the Ability to Redact Sensitive Values in Console Output 和訳: sensitive属性の値はtfstateファイルには記録されます。 そのため、stateファイルの閲覧ができる人にはその値を参照することができます。
  11. 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への 書きこみ
  12. 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に リネーム 差分ありの扱い
  13. 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に リネーム
  14. 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に 書き換え済み 差分なし
  15. 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ファイル(新)
  16. 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ファイルから情報が流出するという ことも考えられる
  17. 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
  18. 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の生成
  19. 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パスワードの 変更
  20. 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に変更
  21. 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値の設定だけなら そこまで複雑ではなく 労力も小さい リソースの性質上、変更が生じないため 構築自動化・変更管理の需要がない