はじめに
こんにちは、こうへいです。
今回はtfstateをS3に保存したいと思います。
Terraform Applyでリソースを作成するときにtfstateがS3に保管されていることが必要です。
記事の概要
S3を作成します。今回もregistryのmoduleを使用します。
またディレクトリ構成を記事を参考に変更しています。
想定読者
- AWSのリソースをTerraformで作成しようと考えている方
- tfstateをS3で管理したい方
今回作成するAWSリソース
- S3
以上
ディレクトリ構成
環境ごとにディレクトリを分けています。
main.tfからmoduleを呼び出す形式です。
2つの記事を参考にディレクトリ構成を変更しています。
.
├── envs
│ ├── dev # develop環境
│ │ ├── backend.tf # tfstateを管理
│ │ ├── main.tf # module呼び出し
│ │ ├── provider.tf # providerブロック
│ │ ├── terraform.tfvars # 変数を入力
│ │ └── variables.tf # 変数
│ ├── prd # production環境
│ └── stg # staging環境
└── modules
├── network # ネットワークリソース
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
└── tfstate # tfstate
├── main.tf
├── outputs.tf
└── variables.tf
※ outputs.tfとvariables.tfは空でも作成します。
Terraformのコードと解説
まずはtfstateを格納するためのS3を作成します。
modules/tfstate/main.tf
module "s3_bucket_dev_bucket" {
source = "terraform-aws-modules/s3-bucket/aws"
version = "3.15.1"
bucket = "${var.env}-qiita-bucket-s3"
acl = "private"
control_object_ownership = true
object_ownership = "ObjectWriter"
versioning = {
enabled = true
}
server_side_encryption_configuration = {
rule = {
apply_server_side_encryption_by_default = {
sse_algorithm = "AES256"
}
}
}
tags = {
name = "${var.env}-qiita-bucket-s3"
}
}
コード解説
acl : S3を作成した人のみアクセスできる
control_object_ownership ・ object_ownership : オブジェクトの所有権の制御を有効
versioning : バージョニングを有効化
server_side_encryption_configuration : 暗号化アルゴリズムに使用する手法
envs/dev/backend.tf
S3を作成しましたら、backend
ブロックを使用してtfstateをS3に格納するように設定します。
backendブロックでは変数を使用できませんのでご注意ください。
terraform {
backend "s3" {
bucket = "dev-qiita-bucket-s3"
key = "dev/terraform.tfstate"
region = "ap-northeast-1"
encrypt = true
}
}
またmain.tfではmoduleを呼び出し、provider.tfではterraformの初期設定を定義しています。
envs/dev/main.tf
module "dev_tfstate" {
source = "../../modules/tfstate"
}
module "network" {
source = "../../modules/network"
}
envs/dev/provider.tf
デフォルトタグを使用して、作成するAWSリソースにdevというタグを付与します。
terraform {
required_version = "1.3.9"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~>5.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
default_tags {
tags = {
Environment = "dev"
}
}
}
動作確認
tfstateがs3に格納されているか確認します。
dev/terraform.tfstateに無事作成されました。
これでローカルにはtfstateが作成されません。
終わりに
今回はtfstateをS3で管理するように設定しました。
tfstateファイルの管理は非常に大事なので、大切に管理しましょう。
またディレクトリ構成は2つの記事を参考にしています。
次回はTerraform PlanをするようにCIを作成します。
今回作成したgithubのリポジトリ : https://github.com/hikobend/terraform-qiita
ブランチ : https://github.com/hikobend/terraform-qiita/pull/4
DynamoDBを使用してtfstateを管理
tfstateを管理するときにS3とDynamoDBを使用して管理する方法もあります。
DynamoDBを使用すると、stateLockをかけることができます。
もしStateLockがかかっていない時に、複数人がApplyを実行してAWSリソースを作成しようとすると、Stateファイルにズレが生じてしまうことがあります。
そこでStateLockを追加すると、Applyしている人がいる場合、他の人がApplyできないようになります。
チーム開発ではtfstateをS3 + DynamoDBで管理、個人開発ではS3のみで管理すると良いと思います。
参考記事 : State管理ベストプラクティス
envs/dev/backend.tf
terraform {
backend "s3" {
bucket = "S3バケット名"
key = "dev/terraform.tfstate"
region = "ap-northeast-1"
dynamodb_table = "DynamoDB名"
encrypt = true
}
}
※この記事では個人でリソースを作成するので、dynamoDBは使用しません。
参考文献
- AWS S3 bucket Terraform module
- 20 Terraform Best Practices to Improve your TF
- Standard Module Structure
- State管理ベストプラクティス
今後作成予定の記事
- Terraform Plan・ApplyのCIを作成
- セキュリティグループの作成