サイトアイコン 【TechGrowUp】

TerraformでtfstateをS3で管理する

ローカルPCへのAWS設定

 ローカルPCにAWSの設定を入れます。(AWSマネジメントコンソール上でアクセスキーを取得しているものとします。
 ターミナル上でaws configureと入力し、取得済みのID、Keyを入力します。リージョンは利用したいもので問題ありません(東京ならap-northeast-1)。フォーマットはjsonが良いでしょう。

$ aws configure
(※下記については右のコマンドで確認可「$ cat ~/.aws/credentials」)
AWS Access Key ID [None]: AWSアカウントで発行したアクセスキー IDを入力
AWS Secret Access Key [None]: AWSアカウントで発行したシークレットアクセスキーを入力
(※下記については右のコマンドで確認可「$ cat ~/.aws/credentials」)
Default region name [None]: ap-northeast-1など利用したいリージョン名を入力
Default output format [None]: jsonを入力

tfstateを管理するためのS3を準備

まずtfstateを管理するためのS3バケットを作成します。適当にmain.tfなどの名前をつけたtfファイルを用意して、下記コードをコピペして後、tfstateを管理するバケットの名前を変更してください。

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

provider "aws" {
  profile = "default"
  region  = "ap-northeast-1"
}

resource "aws_s3_bucket" "terraform_state" {
  bucket = "terraform-state" #適当なユニークの名前に変えてください
}

resource "aws_s3_bucket_versioning" "versioning_example" {
  bucket = aws_s3_bucket.terraform_state.id
  versioning_configuration {
    status = "Enabled"
  }
}

次にterraformを初期化します

$ terraform init

次に上記を反映させるためにplanとapplyをします

$ terraform plan

planでは作成(変更/削除も含む)されるリソースが表示されるので、S3のバケットが作成されることを確認してください。問題なければapplyを実行します。

$ terraform apply

ここで「Do you want to perform these actions? Terraform will perform the actions described above. Only ‘yes’ will be accepted to approve.」と聞かれるので「yes」入力してEnterを押しましょう。

すると「Apply complete! Resources: 2 added, 0 changed, 0 destroyed」となると思いますので一旦完了です。

tfstateの管理を作成したS3バケットにする

現状ではtfstateの管理はローカルになっていて、tfstate用にS3バケットが作成されただけなので、今後はS3に管理してもらうようにします。以下のようにbackendの部分を追加し、tfstate用のバケット名に変更しましょう。

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }

  backend "s3" {
    bucket  = "" #作成したtfstate用のS3バケット名を入力
    region  = "ap-northeast-1"
    key     = "terraform.tfstate"
    encrypt = true
  }
}

続いてもう一度初期化を実行します

$ terraform init

ここでtfstateの管理対象がS3に切り替わりました。

複数人でteffaformを変更する際のTips

複数人でterraformを利用するときは、1つのS3バケットを利用していると同時に変更を走らせてしまったときなどにコンフリクトしてしまったり不用意に削除してしまったりすることがあるので、backendにDynamoDBを利用して状態をロックするような仕組みを用います。

まずDynamoDBのテーブルを作成します。main.tfなどのtfファイルに以下を追加しましょう。

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"
  }
}

そして、planとapplyを同様に実行しましょう。

backendにDynamoDBを追加する

最初に追加したコードのbackend部分にDynamoDBを追加します。

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"
    }
  }

  required_version = ">= 0.14.9"

  backend "s3" {
    bucket  = ""
    region  = "ap-northeast-1"
    key     = "terraform.tfstate"
    encrypt = true
    dynamodb_table = "terraform_state_lock" #追加した部分
  }
}

そしてbackendが変更されたので、terraformを初期化するのですが、現在のsteteとバッティングして怒られので今回はmigrateを実行します。

$ terraform init -migrate-state

こうすることで複数人で開発ができるようになりました。以上になります。

モバイルバージョンを終了