5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Terraform】ステートファイルを共有管理する

Last updated at Posted at 2020-10-17

概要

terraform applyを実行した際に作成されるステートファイルをクラウド上で管理する方法を記載します。
AWS上のリソースをterraformで管理しているケースを想定しています。

管理方法

applyを実行した際の現在の結果を記録しているファイルがtfstateファイルとなります。(このファイルを見て差分を割り出してくれていますね)
デフォルトではローカルに生成されますが、チーム開発を行っていくにあたって特定の人物のローカルにしかないと困ってしまいますね。
そこで通常tfstateファイルは、以下のように管理します。

  • Cloud上にステートファイル管理用のバケット(ECSGCS)を作成
  • Terraform Cloudを利用

AWS S3 Bucketの利用

管理対象となるAWS上で手軽に管理します。
なお、ステートファイルを保管するバケット自体はterraformでの管理するインフラストラクチャ外にあることが理想です。(公式ドキュメントより)
このバケットを管理するためのアカウントを別に発行することが望ましいようですが、ややこしくなるので、ここではaws-cliを用いてバケットを作成し、terraformの管理外とすることを実現します。

1. ステート管理バケットの作成

単純に作成するだけでも構いませんが、以下の設定を入れておくと安心でしょう。

  • バージョニング      :不用意な削除等が行われた場合でも復元することができる
  • 暗号化          :バケット自体の暗号化を行う
  • ブロックパブリックアクセス:バケットを公開しないよう設定
Terminal
# バケット作成
aws s3api create-bucket           --bucket ${bucket_name} --create-bucket-configuration LocationConstraint=${region}
# バージョニングの有効化
aws s3api put-bucket-versioning   --bucket ${bucket_name} --versioning-configuration Status=Enabled
# バケットの暗号化
aws s3api put-bucket-encryption   --bucket ${bucket_name} \
          --server-side-encryption-configuration '{"Rules": [{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "AES256"}}]}'
# ブロックパブリックアクセス
aws s3api put-public-access-block --bucket ${bucket_name} \
            --public-access-block-configuration '{
              "BlockPublicAcls"      : true,
              "IgnorePublicAcls"     : true,
              "BlockPublicPolicy"    : true,
              "RestrictPublicBuckets": true
            }'
# タグ付け
aws s3api put-bucket-tagging      --bucket ${bucket_name} \
          --tagging 'TagSet=[{Key=description,Value=manage mintak-terraformer tfstate}]'
スクリーンショット 2020-06-21 15.49.02.png

2. DynamoDBテーブル作成

DynamoDBを組み合わせることによって、ステートロックを実現可能とします。
※真偽は明らかではないですが、パーティションキー名称はLockIDでないとうまく動作しませんでした。

Terminal
aws dynamodb create-table \
      --table-name ${state_lock_table_name} \
      --attribute-definitions '[{"AttributeName":"LockID","AttributeType": "S"}]' \  # S=stringの意味
      --key-schema            '[{"AttributeName":"LockID","KeyType": "HASH"}]' \   # HASH=パーティションキーの意味
      --provisioned-throughput '{"ReadCapacityUnits": 1, "WriteCapacityUnits": 1}' # 念のため最低値を設定しておく
スクリーンショット 2020-06-21 16.54.51.png

3. backend設定

ステートファイルを上記で作成したバケットに保管するように設定するための実装を行います。
tfファイルがある階層にbackend.tfを新たに作成します。

backend.tf
terraform {
  backend s3 {
    bucket         = "1で作成したバケット名"
    key            = "terraform.tfstate"
    dynamodb_table = "2で作成したテーブル名"
    region         = "ap-northeast-1"
    encrypt        = true
  }
}

この状態でapplyやdestroyを行ってみると、ローカルにステートファイルが作成されることがなくなり、
S3バケット上に作成されるようになります。
スクリーンショット 2020-06-21 16.59.47.png

Terraform Cloudの利用

GithubやGitLabと連携してplanapplyを行う機能もあるようですが、
今回はあくまでステートファイルの共有管理の目的に閉じて利用する前提での例となります。
変更内容(履歴)がUI上で確認できる点が優れていると感じました。

1. サインアップ

Terraform Cloudの「Sign up for Cloud」ボタンをクリックしてアカウントを作成します。必要なものはメールアドレスのみです。
作成が必要なものは、アカウント・組織・ワークスペースの3つとなります。

2. ワークスペース設定

あくまでステートファイルの共有管理のみに閉じるため、次の設定を行います。

  • 実行モードをLocalに

ワークスペース->Settings->generalの画面Execution ModeLocalに設定します。
スクリーンショット 2020-06-21 6.05.20.png

  • VCS provider off

ワークスペース設定時にVCS providerを設定している場合は今回の用途では不要なためオフにします。
ワークスペース->Settings->Version Controlよりdeleteを行います。

3. CLIログイン

コンソールからログインを行います。このタイミングでAPI Keyを発行します。(key情報は~/.terraform.d/credentials.tfrc.jsonに保管されます。1
Do you want to proceed? (y/n)は「y」を入力してください。

Terminal
$ terraform login

Do you want to proceed? (y/n) y

# ここでTerraform CloudのUIでAPI Keyを発行する画面へ遷移する。そのまま発行を行いコピーして、コンソールにペーストする

Terraform must now open a web browser to the tokens page for app.terraform.io.

If a browser does not open this automatically, open the following URL to proceed:
    https://app.terraform.io/app/settings/tokens?source=terraform-login


---------------------------------------------------------------------------------
Generate a token using your browser, and copy-paste it into this prompt.

Terraform will store the token in plain text in the following file
for use by subsequent commands:
    /Users/mintak/.terraform.d/credentials.tfrc.json

Token for app.terraform.io:

Retrieved token for user mintak21
---------------------------------------------------------------------------------

Success! Terraform has obtained and saved an API token.

4. backend設定

ステートファイルをTerraform Cloudに保管するように設定するための実装を行います。
tfファイルがある階層にbackend.tfを新たに作成します。

backend.tf
terraform {
  backend remote {
    hostname     = "app.terraform.io"
    organization = "組織名"

    workspaces {
      name = "ワークスペース名"
    }
  }
}

この状態でapplydestroyを行ってみると、ローカルにステートファイルが作成されることがなくなり、
Terraform Cloud上に作成されるようになります。
現在の状態と前回からの差分をUI上で確認することが可能です。

スクリーンショット 2020-06-21 6.19.26.png

References

  1. 環境変数TF_CLI_CONFIG_FILEを設定することで、任意の場所に配置しているcredentialファイルを参照することが可能です。credentialファイルにはこちらのような形式でトークンを保持します。

5
3
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
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?