AWS
Terraform

Backend の S3 や DynamoDB 自体を terraform で管理するセットアップ方法

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 = "ほげほげ-terraform-dev"
    key    = "tfstate-dev"

    dynamodb_table = "ほげほげ-terraform-lock-dev"
  }
}
resource "aws_s3_bucket" "tfstate" {
  bucket = "ほげほげ-dev"

  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 {
    Name = "ほげほげ-dev"
  }

  lifecycle {
    # bucket は空でないと消せないが、一応制限しておく
    prevent_destroy = true
  }
}
resource "aws_dynamodb_table" "tfstate_lock" {
  name           = "ほげほげ-terraform-lock-dev"
  read_capacity  = 10
  write_capacity = 10
  hash_key       = "LockID"

  attribute {
    name = "LockID"
    type = "S"      # S = String
  }
}

Step 3 : init, import, 初回 apply

以下の順に実行します:

  • terraform init
  • terraform import aws_s3_bucket.tfstate バケット名
    • すでに作成済みのバケットを tfstate に追加して認識させます
  • terraform apply -lock=false
    • これを実行することで S3 bucket の設定のアップデートや Lock 用の DynamoDB の作成が走ります
    • この初回の apply のみ -lock=false 指定が必要

Done

ここまで終われば、あとは普通に terraform planterraform apply が可能です。

また、S3 や DynamoDB の設定自体が terraform 管理されているので、例えば aws_s3_bucket_policy を追加で設定してセキュリティを強化したり他のアカウントへ tfstate のアクセス権を与えたり、 aws_dynamodb_table の capacity を設定変更したり、といった設定を terraform の管理下で行うことができます。