メインコンテンツまでスキップ

Kubernetes(EKS)クラスタ上にVaultを構築する際のStorageBackendの選定を検討する中で、「DynamoDB Storage Backend」に関するHashiCorp社の公式Docを読んだので、内容をまとめた上で、設計について軽く考えてみた。

DynamoDB Storage Backend

DynamoDB storage backendは、VaultのデータをDynamoDBテーブルに永続化する為に使用される。

  • High Availabirity
    • DynamoDBはVaultのHAをサポートする
    • DynamoDBはVault Nodeの時間を使って、locksのsession lifetimeを実装するため、Vaultノード間で大幅なクロックスキューが発生すると、ロックで競合の問題を発生させる可能性がある
  • Community Supported
    • DynamoDB storage backendは、コミュニティによってサポートされる
    • HashiCorp社員によってレビューを受けているが、もしかするとそこまで知識がないかもしれない
    • もしこのストレージバックエンドで問題が発生した場合は、元の作者に問い合わせてください
  • なお、現在HashiCorpは、ほとんどのユースケースでIntegrated Storage(Raft)の利用を推奨している
    • DynamoDBのような外部ストレージは、HashiCorpによるサポートが限定的になる(storage)
storage "dynamodb" {
ha_enabled = "true"
region = "us-west-2"
table = "vault-data"
}

Required AWS Permissions

VaultがDybamoDBにアクセスする為のIAMポリシーとして、以下のpermissionを含む必要がある。

"Statement": [
{
"Action": [
"dynamodb:DescribeLimits",
"dynamodb:DescribeTimeToLive",
"dynamodb:ListTagsOfResource",
"dynamodb:DescribeReservedCapacityOfferings",
"dynamodb:DescribeReservedCapacity",
"dynamodb:ListTables",
"dynamodb:BatchGetItem",
"dynamodb:BatchWriteItem",
"dynamodb:CreateTable",
"dynamodb:DeleteItem",
"dynamodb:GetItem",
"dynamodb:GetRecords",
"dynamodb:PutItem",
"dynamodb:Query",
"dynamodb:UpdateItem",
"dynamodb:Scan",
"dynamodb:DescribeTable",
"dynamodb:UpdateTable"
],
"Effect": "Allow",
"Resource": [ "arn:aws:dynamodb:us-east-1:... dynamodb table ARN" ]
},

DynamoDB Parameters

  • もしVaultの初期化及び実行の前にDynamoDBテーブルを作成する予定ならば、以下の属性をもったテーブルを作成する必要がある。
    • Primary partition key:"Path" String
    • Primary sort key:"Key" String
  • もし既に名前が定義されたテーブルが存在する場合、デフォルトではVaultは変更を加えない。
    • dynamodb_allow_updatesを設定していなければ、Vaultの設定におけるread_capacityとwrite_capacityは効果がない。
    • dynamodb_allow_updatesを設定すると、billing_mode・read_capacity・write_capacityの値が既存のテーブルと異なる場合に、Vaultはテーブルの更新を試みる。
  • もしテーブルがまだ存在いない場合は、Vaultは作成を試みる。
    • BillingModeとread/writeキャパシティは、それぞれbilling_mode・read_capacity・write_capacityの値で作成される。
    • Vaultの利用要件によっては、billing_modeはデフォルトのPROVISIONEDではなくPAY_PER_REQUESTの方がコストパフォーマンスが高いかもしれない
  • DynamoDBのテーブルを明示的にTerraformで作成するか、VaultのConfigに書いて自動的に作らせるか?
    • Terraformで書く(タグなど細かい制御が微妙にやりづらいし、バックアップからのリストアなどの柔軟性がなさそうである。

TerraformでDynamoDBを作成

  • テーブルにautoscaling policyがアタッチされているならば、read_capacity``write_capacityについてはlifecycle:ignore_changesを推奨する。

設計考慮ポイント

採用理由​

  • StorageBackendにDynamoDBを採用する理由は以下のとおり
    • AWSマネージドのサービスであり、維持管理コストが低い
    • 高い可用性と堅牢性を持っている(Multi-AZに自動的にレプリケーションされている)
    • HAをサポートしている
  • ただし現在は、HashiCorpが推奨し、外部ストレージの運用が不要なIntegrated Storageと比較した上で選ぶべきである

BillingMode​

  • PROVISIONEDは秒間あたりのキャパシティを事前に設定し、設定したキャパシティに応じて課金される方式
  • PAY_PER_REQUESTは所謂従量課金方式
  • Vaultのユースケースを考慮し、従量課金の方がコスパが良いなら従量課金を選択する

バックアップ&リストア​

  • PITRを使ってバックアップを取得すればよい
    • ただし、リストア時にはテーブル名を変更する必要がある
  • PITRを有効にしたテーブルを削除すると、削除直前の状態のシステムバックアップが自動で作成され、35日間保持される(AWSドキュメント)
  • それより長く保持したい場合は、別途オンデマンドバックアップも取る
    • AWS Backupで実行できる
  • 誤削除を防ぐ為に、テーブルの削除保護(deletion protection)も有効にしておくとよい

VPCエンドポイント​

  • DynamoDBはGatewayタイプに加えて、Interfaceタイプ(AWS PrivateLink)のVPCエンドポイントもサポートする
    • VPC内からのアクセスだけなら、課金されないGatewayタイプで足りる
  • (暗号化されたデータが格納されるとはいえ)ネットワークレイヤでのリスク極小化のため、VPCエンドポイント経由でDynamoDBにアクセスしたほうがよい