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の方がコストパフォーマンスが高いかもしれない
- BillingModeとread/writeキャパシティは、それぞれ
- 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にアクセスしたほうがよい