S3にTerraforのtfstateファイルを置いて複数のAWS環境から使用する

  • 2021.01.31
  • AWS
S3にTerraforのtfstateファイルを置いて複数のAWS環境から使用する

概要

Terraform の tfstate ファイルを S3 に置いて使用する方法はよく見かけるのですが、複数のAWS環境(異なるクレデンシャル情報)から使用する方法が見つからなかったのでメモしておきます。

想定シーン

開発チームのメンバーは主にAWS環境はアカウントNo.1234-1234-1234を使用している。運用チームのメンバーは主にAWS環境はアカウントNo.5678-5678-5678を使用しているが、他にも複数のAWS環境を運用している。今回、開発チームが開発したアカウントNo.1234-1234-1234も運用することとなった。

その際、アカウントNo.1234-1234-1234の監視用のDatadog Organizationも運用することとなった。Datadog は Terraform で設定されており、その Terraform も一緒に運用チームに回ってきた。ただし、開発チームもDatadogの設定を変更する必要がある。

ここで tfstate ファイルを S3 で管理することとなった場合、どのAWS環境の S3 に置くか。運用チームとしては他の複数のAWS環境の Datadog 用の Terraform もまとめて No.5678-5678-5678 の S3 で管理したい。

このような場合に問題となるのが、開発チームがS3にアクセスする場合に、クレデンシャル情報を切り替えなくてはいけないため、面倒臭くなってしまう。

そこで今回、社内のグローバルIPのみ許可した S3 のバケットポリシーを設定し、開発チームも運用チームも AWSクレデンシャル情報を切り替えることなく S3 の tfstate ファイルにアクセスできるようにした。

S3の設定

オブジェクト所有者の設定

まずはS3のオブジェクト所有者の設定をしておきます。

S3のアクセス許可から [編集する] を開きます。

[希望するバケット所有者] を選択し、 [変更の保存] をクリックします。

バケットポリシーの設定

バケットポリシーは次のように設定します。

{
    "Version": "2012-10-17",
    "Id": "Policy111122223333",
    "Statement": [
        {
            "Sid": "Stmt111122223333",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::test-test-terraform-tsstate",
                "arn:aws:s3:::test-test-terraform-tsstate/*"
            ],
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "123.456.789.123"
                }
            }
        }
    ]
}

グローバルIP 123.456..789.123 からのみアクセスを許可します。

Datadog の backend.tf の設定

次に Datadog側の Terraform で使用する backend.tf の設定をします。この tf ファイルを置いておけば、S3 にある tfstate ファイルを参照してくれるようになります。

terraform {
  backend "s3" {
    bucket = "test-test-terraform-tfstate"
    key    = "accountname/terraform.tfstate"
    acl    = "bucket-owner-full-control"
    region = "ap-northeast-1"
  }
}

解説

まだこの機能自体2020年の10月に追加されたばかりの機能ですが、オブジェクト所有者をアップロードしたユーザーではなく、バケット所有者をオブジェクト所有者にするところがポイントです。

その際、Datadog で使用する Terraform にも acl = “bucket-owner-full-control” を付与してあげることで、思ったような動作をするようになります。

これで、指定したグローバル IP からは、AWSアカウントが異なる複数のユーザーから同一の tfstate ファイルを参照・更新することができるようになります。