1
0

More than 1 year has passed since last update.

tfstateをS3で管理

Last updated at Posted at 2023-09-10

はじめに

こんにちは、こうへいです。
今回は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

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ブロックでは変数を使用できませんのでご注意ください。

envs/dev/backend.tf
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
envs/dev/main.tf
module "dev_tfstate" {
  source = "../../modules/tfstate"
}

module "network" {
  source = "../../modules/network"
}
envs/dev/provider.tf

デフォルトタグを使用して、作成するAWSリソースにdevというタグを付与します。

envs/dev/provider.tf
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が作成されません。

スクリーンショット 2023-09-10 17.20.21.png

終わりに

今回は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
DynamoDBを使用
terraform {
  backend "s3" {
    bucket         = "S3バケット名"
    key            = "dev/terraform.tfstate"
    region         = "ap-northeast-1"
    dynamodb_table = "DynamoDB名"
    encrypt        = true
  }
}

※この記事では個人でリソースを作成するので、dynamoDBは使用しません。

参考文献

今後作成予定の記事

  • Terraform Plan・ApplyのCIを作成
  • セキュリティグループの作成
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0