🦔
Terraform最初の一歩:tfStateをS3バケットで管理する
はじめに
チーム開発するためにはtfStateをリモートで管理する必要があります。
ここではtfStateをリモート管理するためのS3バケットと、tfStateの同時編集をロックするDynamoDBを作成します。
ディレクトリ構造
backend
ディレクトリの中でtfStateをリモート管理するためのS3バケットおよびDynamoDBテーブルを用意します。このS3バケットおよびDynamoDBのtfStateはローカルPCで管理されることになります。
ここで作成したS3バケットでtfStateを管理したいリソースはenvs
ディレクトリの中に記述します。
backend
とenvs
ディレクトリの中に、それぞれstg
やprod
など別々の環境を用意します。
root
│
├── backend
│ ├── stg
│ │ ├── main.tf
│ │ ├── terraform.tfvars
│ │ └── variable.tf
│ └── prod
│ ├── ...
│
├── envs
│ └── stg
│ ├── main.tf
│ ├── ...
│
└── modules
├── backend_s3_dynamoDB
│ ├── main.tf
│ └── variable.tf
├── ...
tfStateを管理するS3バケットとDynamoDBの作成
前述したように、S3バケットとDynamoDBをのtfStateはローカルPCの中で管理されることになります。
事前にAWSのprofileを設定しておきます。
コード
backend/stg/main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "ap-northeast-1"
shared_credentials_files = ["$HOME/.aws/credentials"]
profile = "default"
}
module "backend_s3_and_dynamoDB" {
source = "../../modules/backend_s3_dynamoDB"
bucket_name = var.bucket_name
dynamoDB_name = var.dynamoDB_name
}
backend/stg/variable.tf
variable "bucket_name" {
type = string
default = "tfstate-bucket-xxxx" //全世界でユニークなバケット名である必要があります。
}
variable "dynamoDB_name" {
type = string
default = "terraform_state_lock"
}
modules/backend_s3_dynamoDB/main.tf
resource "aws_s3_bucket" "terraform_state" {
bucket = var.bucket_name
lifecycle {
prevent_destroy = true
}
}
resource "aws_s3_bucket_acl" "terraform_state" {
bucket = aws_s3_bucket.terraform_state.id
acl = "private"
}
resource "aws_s3_bucket_server_side_encryption_configuration" "terraform_state" {
bucket = aws_s3_bucket.terraform_state.bucket
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
resource "aws_s3_bucket_versioning" "terraform_state" {
bucket = aws_s3_bucket.terraform_state.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_dynamodb_table" "terraform_state_lock" {
name = var.dynamoDB_name
hash_key = "LockID"
read_capacity = 20
write_capacity = 20
attribute {
name = "LockID"
type = "S"
}
}
実行
$ cd ./backend/stg
$ terraform init
$ terraform plan
$ terraform apply
作成したS3バケットでtfStateを管理する
実際に作成するリソースはenvs/stg
フォルダの中に作成します。
先ほど作成したS3バケットとDynamoDBを使ってtfStateを管理します。
envs/stg/main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
backend "s3" {
bucket = "tfstate-bucket-xxxx"
key = "stg/terraform.tfstate"
region = "ap-northeast-1"
dynamodb_table = "terraform_state_lock"
shared_credentials_file = "$HOME/.aws/credentials"
profile = "default"
}
}
provider "aws" {
region = "ap-northeast-1"
shared_credentials_files = ["$HOME/.aws/credentials"]
profile = "default"
}
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}
実行
$ cd ./envs/stg
$ terraform init
$ terraform plan
$ terraform apply
参考
Discussion