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
    ~ 機密情報をコードに含めず環境構築するにはどうしたらいいの?

    View Slide

  2. 自己紹介
    Haruka Sakihara
    Twitter:@saki_engineer
    • アクセンチュア株式会社
    テクノロジーコンサルティング本部所属
    • 普段はクラウドインフラ構築の支援をしております
    • アプリケーション……プライベートだとGo, 仕事だ
    と少しPython
    • インフラ……ほとんどAWS
    GitHub: @saki-engineering

    View Slide

  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"
    }

    View Slide

  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

    View Slide

  5. Introduction
    「構成をコードで管理する」IaCのメリット
    Terraformのように「インフラ構成をコードの形で管理する」というIaC(Infrastructure as a Code)
    には数多くの利点があり、昨今はとても一般的になってきました。
    環境の再構築が容易 構築の自動化が容易 変更履歴の管理がしやすい
    IaCの主なメリット
    Deploy!
    Deploy!
    ver 1.0
    ver 1.1
    Auto
    Deploy!
    AWS Cloud

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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の値を
    パスワードに指定

    View Slide

  13. 1. 機密情報をあつかうTerraformコード
    tfファイルとtfstateファイル
    実はTerraformのリソースには、開発者が記述するtfファイル以外にもtfstateファイルというものが
    あり、先ほどの例はそこに機密情報が含まれてしまうのです。
    .tfファイル tfstateファイル
    ???

    View Slide

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

    View Slide

  15. 2. tfstateファイルに含まれる情報
    tfstateファイルとは
    tfstateファイルは、「最後にterraform applyを行った際の実環境の状態を記載したもの」です。
    AWS Cloud
    Availability Zone a
    Availability Zone b
    tfstateファイル
    • AZ-aにEC2インスタンスが3個
    • AZ-bにEC2インスタンスが2個
    同内容

    View Slide

  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個

    View Slide

  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. リソース作成
    結果の反映

    View Slide

  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. リソース作成
    結果の反映

    View Slide

  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が最新のリモート環境
    を反映していない

    View Slide

  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ファイル

    View Slide

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

    3. 排他制御できず
    コンフリクト

    View Slide

  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を実行できない

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    AWS Cloud
    tfstateファイル
    sensitive属性が
    ついた変数
    Don’t touch it.
    tfstateファイル
    AWS KMS key
    encrypt

    View Slide

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

    AWS Cloud
    tfstateファイル
    sensitive属性が
    ついた変数
    Don’t touch it.
    tfstateファイル
    AWS KMS key
    encrypt

    View Slide

  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属性の値が
    非表示になる

    View Slide

  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ファイルの閲覧ができる人にはその値を参照することができます。

    View Slide

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

    AWS Cloud
    tfstateファイル
    sensitive属性が
    ついた変数
    Don’t touch it.
    tfstateファイル
    AWS KMS key
    encrypt

    View Slide

  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への
    書きこみ

    View Slide

  34. 3. Terraformと機密情報の共存案候補
    KMS鍵で暗号化?
    結果、インフラを触りたい開発者に全員暗号化・復号の権限をもたせることになるので、「暗号化し
    てtfstateを触れる人を制限しよう」というようにはうまくできません。
    AWS Cloud
    tfstateファイル
    AWS KMS key
    開発者全員が暗号化・復号の
    権限をもつことになる

    View Slide

  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
    ???

    View Slide

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

    AWS Cloud
    tfstateファイル
    sensitive属性が
    ついた変数
    Don’t touch it.
    tfstateファイル
    AWS KMS key
    encrypt

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  40. 3. Terraformと機密情報の共存案候補
    tfstateを書き換えるユースケース
    リソース名をリネームした状態で、terraform planコマンドを実行してみます。
    AWS Cloud
    tfstateファイル
    terraform plan
    Amazon Relational Database
    Service (Amazon RDS)
    Amazon RDS
    instance
    変更なし
    defaultからmy_test_dbに
    リネーム

    View Slide

  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に
    リネーム

    View Slide

  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に
    リネーム
    差分ありの扱い

    View Slide

  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に
    リネーム

    View Slide

  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
    書き換え

    View Slide

  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に
    書き換え済み
    差分なし

    View Slide

  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ファイル(新)

    View Slide

  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ファイルから情報が流出するという
    ことも考えられる

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  54. 4. tfstateに機密を含ませないために
    データベースのパスワードをTerraformで扱う
    DBを構築する際には、ダミーパスワードを使用して構築を行い、その後パスワード変更を行うとい
    う手段が有効です。
    1. パスワード欄には
    ダミーを指定して構築
    2. デプロイ後に
    パスワードを変更
    AWS Cloud
    Amazon RDS
    instance
    terraform apply
    Password: dummy
    AWS Cloud
    Amazon RDS
    instance
    Change
    Password!!

    View Slide

  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

    View Slide

  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

    View Slide

  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の生成

    View Slide

  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パスワードの
    変更

    View Slide

  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に変更

    View Slide

  60. 4. tfstateに機密を含ませないために
    パスワードローテーションのセットアップ
    Secrets Managerと連携してパスワードローテーションを行うLambda関数は、AWS SAMのテンプ
    レートとして公開されているので、こちらを使うのが手軽です。
    リンク:https://serverlessrepo.aws.amazon.com/applications

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  69. 4. tfstateに機密を含ませないために
    機密情報値そのものをTerraformで扱うか?
    データベースのパスワードのように、定期的に変更することを前提とした値をSecrets Managerに
    格納することは、「デプロイ後すぐにローテーションを行うこと」「Secret値をDataSourceで参照
    しないようにすること」を徹底することで、tfstateまで含めて安全な状態にすることができます。
    1. 初期セットアップのみ
    terraform apply AWS Cloud
    AWS Secrets Manager
    2. デプロイ後に即座に
    ローテーションを実施
    デプロイ後にローテーション secret値を直接参照する
    DataSourceの使用禁止
    secret値が
    tfstateに書きこまれる

    View Slide

  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

    View Slide

  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値の設定だけなら
    そこまで複雑ではなく
    労力も小さい
    リソースの性質上、変更が生じないため
    構築自動化・変更管理の需要がない

    View Slide

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

    View Slide

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

    View Slide

  74. Thank You
    ご意見、ご質問ありましたらお気軽にご連絡下さい
    [email protected]
    Haruka Sakihara(崎原 晴香)

    View Slide