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