terraform の state 保存先として S3 backend は大変便利ですが、初期設定のやり方のまとまった情報を意外と見つけられなかったので備忘までにメモ。
この手順の特徴
- tfstate を格納する S3 バケットや DynamoDB 自体を terraform で管理できる
- 例えばバケットへのアクセスをポリシーで制限したり開放したりする際、ポリシーで指定するユーザー名や IP アドレスといった値は terraform で管理したい
- terraform 以外のツールでの手作業なども最小限
Step 1 : Bucket を作成する
state を入れるバケット自体は手動で作る必要があります。
ただし、バージョニングなどの設定はこの段階では必須ではないです。この後のステップを経ることで terraform 管理できるので、terraform で記述する方が良いでしょう。
Step 2 : .tf を書く
S3 backend や、S3 バケットと Lock 用の resource 定義を書きます。
例:
terraform {
backend "s3" {
region = "ap-northeast-1"
bucket = "ほげほげ"
key = "tfstate-dev"
dynamodb_table = "ほげほげ"
}
}
resource "aws_s3_bucket" "tfstate" {
bucket = "ほげほげ"
acl = "private"
# tfstate はバージョニングすることが公式に推奨されている
versioning {
enabled = true
}
# 特に公式に推奨されてはいないが、古いバージョンは消したほうが良いはず
lifecycle_rule {
enabled = true
abort_incomplete_multipart_upload_days = 7
noncurrent_version_expiration {
days = 32
}
}
# SSE で暗号化しておく
server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
tags = { # terraform 0.11 までは = 不要です
Name = "ほげほげ-dev"
}
lifecycle {
# bucket は空でないと消せないが、一応制限しておく
prevent_destroy = true
}
}
resource "aws_dynamodb_table" "tfstate_lock" {
name = "ほげほげ"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S" # S = String
}
}
Update: 手動で bucket を作成する際に有効になっていることが多いはずですが、一応 aws_s3_bucket_public_access_block
も設定しておくとなお安心です:
resource "aws_s3_bucket_public_access_block" "tfstate" {
bucket = aws_s3_bucket.tfstate.bucket # terraform 0.11 以下では "${...}" で囲む必要あり
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
Step 3 : init, import, 初回 apply
以下の順に実行します:
terraform init
-
terraform import -lock=false aws_s3_bucket.tfstate バケット名
- すでに作成済みのバケットを tfstate に追加して認識させます
-
terraform apply -lock=false
- これを実行することで S3 bucket の設定のアップデートや Lock 用の DynamoDB の作成が走ります
- ここまでは
-lock=false
指定が必要
Done
ここまで終われば、あとは普通に terraform plan
や terraform apply
が可能です。
また、S3 や DynamoDB の設定自体が terraform 管理されているので、例えば aws_s3_bucket_policy
を追加で設定してセキュリティを強化したり他のアカウントへ tfstate のアクセス権を与えたり、 aws_dynamodb_table
の capacity を設定変更したり、といった設定を terraform の管理下で行うことができます。