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

TerraformでtfstateファイルをS3で管理する

More than 1 year has passed since last update.

TL;DR

Terraformでのtfstateファイルを管理するためにbackendとしてS3を使用する。

前提条件

  • AWSアカウント
    • CLIから操作できる権限を持つユーザ & AWS-Cliに対するアクセスキーなどの設定
  • Terraform
    • v0.11.0 以上を使用します。

手順

tfstateファイルを格納するS3バケットを作成する

main.tf
terraform {
  required_version = ">= 0.11.0"
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_s3_bucket" "terraform_state" {
  bucket = "example-terraform-state"
  versioning {
    enabled = true
  }
}

実行
$ terraform plan
からの
$ terraform apply

作成したS3バケットでtfstateファイルを管理するよう設定する

main.tf
terraform {
  required_version = ">= 0.11.0"
  backend "s3" {
    bucket = "example-terraform-state" # 作成したS3バケット
    region = "us-east-1"
    key = "terraform.tfstate"
    encrypt = true
  }
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_s3_bucket" "terraform_state" {
  bucket = "example-terraform-state"
  versioning {
    enabled = true
  }
}

terraform ブロック内に backend ブロックを追記する。

backend 設定をいじった後なので、
$ terraform init して、
ローカルの tfstate をS3にコピーするか聞かれるので yes と答えて完了。

(オプショナル)state lockを有効化する

S3によって複数人でtfstateファイルを扱うことが可能になったが、逆にそれによってデータがコンフリクトしてしまう恐れがある。
そこで、TerraformではDynamoDB(S3の場合)を用いてtfstateファイルの一貫性を保つことができる機能を提供している。

DynamoDBを作成する

main.tf
terraform {
  required_version = ">= 0.11.0"
  backend "s3" {
    bucket = "example-terraform-state"
    region = "us-east-1"
    key = "terraform.tfstate"
    encrypt = true
  }
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_s3_bucket" "terraform_state" {
  bucket = "example-terraform-state"
  versioning {
    enabled = true
  }
}

resource "aws_dynamodb_table" "terraform_state_lock" {
  name = "terraform_state_lock"
  read_capacity = 1
  write_capacity = 1
  hash_key = "LockID"

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

これで $ terraform apply する。

DynamoDBをbackendに設定する

main.tf
terraform {
  required_version = ">= 0.11.0"
  backend "s3" {
    bucket = "example-terraform-state"
    region = "us-east-1"
    key = "terraform.tfstate"
    encrypt = true
    dynamodb_table = "terraform_state_lock"
  }
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_s3_bucket" "terraform_state" {
  bucket = "example-terraform-state"
  versioning {
    enabled = true
  }
}

resource "aws_dynamodb_table" "terraform_state_lock" {
  name = "terraform_state_lock"
  read_capacity = 1
  write_capacity = 1
  hash_key = "LockID"

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

backendの設定を変更したので
$ terraform init してあげれば完了。

困ったこと

  • Terraform: Up and Running: Writing Infrastructure as Codeを読みながら学習しているものの、バージョンが古くて参考にならない。
  • S3を作らずにbackend設定しようとすると怒られる。
    • Error loading state: NoSuchBucket: The specified bucket does not existが発生する。
    • 関連するIssueのcomment

参考資料

https://qiita.com/marshmallow911/items/e8c05f580d07451fcf5e
https://qiita.com/sinshutu/items/7d3cc7438871c50ea63c

tsukakei
学生時代はスマホゲームやWebアプリの開発をしていました。今は株式会社イエソドでエンジニアをしています。Qiitaは多分あまりもう更新しません。
https://tsukakei1012.hatenadiary.jp/
udzuki
テスト自動化・自動プログラム修正に関する最先端技術を開発し,ソフトウェア開発者が創造的な仕事に集中できる社会の実現を目指す.
https://udzuki.jp
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