Help us understand the problem. What is going on with this article?

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 = "ほげほげ"
    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           = "ほげほげ"
  read_capacity  = 10
  write_capacity = 10
  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 planterraform apply が可能です。

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

saiya_moebius
https://www.wantedly.com/users/39397583
https://saiya-moebius.hatenablog.com/
m3dev
インターネット、最新IT技術を活用し日本・世界の医療を改善することを目指します
https://m3.recruitment.jp/engineer/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした