Terraform で Amazon S3 バックエンドを使う場合に「Amazon S3 バケット自体をどうやってデプロイする?」というブートストラップ問題がある.よく聞く選択肢としてはマネジメントコンソール・AWS CLI・AWS CloudFormation などがある.他にも Terraform で解決する選択肢もあって簡単にまとめておく❗️
簡単に言うと,最初は「ローカルバックエンド」で Amazon S3 バケットをデプロイして,その後に Amazon S3 バックエンドの設定を追加して terraform.tfstate
ファイルを Amazon S3 バケットに引っ越すイメージ👌
Step.1
まずは terraform.tf
と providers.tf
を準備しておく.
👾 terraform.tf
terraform { required_version = "~> 1.13.0" required_providers { aws = { source = "hashicorp/aws" version = "~> 6.13.0" } } }
👾 providers.tf
provider "aws" { region = "ap-northeast-1" }
Step.2
次に backend.tf
に Amazon S3 バケットを実装する.
resource "aws_s3_bucket" "tfstate" { bucket = "kakakakakku-tfstate-bootstrap" }
ここで一度 terraform apply
を実行しておく.すると「ローカルバックエンド」で Amazon S3 バケットをデプロイできる👌
$ terraform apply Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_s3_bucket.tfstate will be created + resource "aws_s3_bucket" "tfstate" { + acceleration_status = (known after apply) + acl = (known after apply) + arn = (known after apply) + bucket = "kakakakakku-tfstate-bootstrap" + bucket_domain_name = (known after apply) + bucket_prefix = (known after apply) + bucket_region = (known after apply) + bucket_regional_domain_name = (known after apply) + force_destroy = false + hosted_zone_id = (known after apply) + id = (known after apply) + object_lock_enabled = (known after apply) + policy = (known after apply) + region = "ap-northeast-1" + request_payer = (known after apply) + tags_all = (known after apply) + website_domain = (known after apply) + website_endpoint = (known after apply) + cors_rule (known after apply) + grant (known after apply) + lifecycle_rule (known after apply) + logging (known after apply) + object_lock_configuration (known after apply) + replication_configuration (known after apply) + server_side_encryption_configuration (known after apply) + versioning (known after apply) + website (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. (中略) Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Step.3
今度は backend.tf
に Amazon S3 バックエンドの設定を追加する.
👾 backend.tf
terraform { backend "s3" { region = "ap-northeast-1" bucket = "kakakakakku-tfstate-bootstrap" key = "terraform.tfstate" use_lockfile = true } } resource "aws_s3_bucket" "tfstate" { bucket = "kakakakakku-tfstate-bootstrap" }
そして terraform init
を実行すると,自動的に terraform.tfstate
ファイルが Amazon S3 バケットにコピーされる👌
$ terraform init Initializing the backend... Do you want to copy existing state to the new backend? Pre-existing state was found while migrating the previous "local" backend to the newly configured "s3" backend. No existing state was found in the newly configured "s3" backend. Do you want to copy this state to the new "s3" backend? Enter "yes" to copy and "no" to start with an empty state. Enter a value: yes Successfully configured the backend "s3"! Terraform will automatically use this backend unless the backend configuration changes. Initializing provider plugins... - Reusing previous version of hashicorp/aws from the dependency lock file - Using previously-installed hashicorp/aws v6.13.0 Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary.
terraform.tfstate
ファイルも確認できた.
$ aws s3 ls kakakakakku-tfstate-bootstrap 2025-09-19 00:31:25 2950 terraform.tfstate
次にローカルバックエンドの terraform.tfstate
ファイルを削除してから terraform plan
を実行してみると No changes. になって期待通り👌イイ感じに Amazon S3 バックエンドをブートストラップできた.
$ rm terraform.tfstate terraform.tfstate.backup
$ terraform plan
No changes. Your infrastructure matches the configuration.
Step.4
ドキュメントには「バージョニングを有効化せよ!」と書いてある.
Warning! It is highly recommended that you enable Bucket Versioning on the S3 bucket to allow for state recovery in the case of accidental deletions and human error.
よって backend.tf
を更新して,Amazon S3 バケットの設定を変更する.もちろん最初から設定しておくのもヨシ❗️
👾 backend.tf
terraform { backend "s3" { region = "ap-northeast-1" bucket = "kakakakakku-tfstate-bootstrap" key = "terraform.tfstate" use_lockfile = true } } resource "aws_s3_bucket" "tfstate" { bucket = "kakakakakku-tfstate-bootstrap" } resource "aws_s3_bucket_versioning" "tfstate" { bucket = aws_s3_bucket.tfstate.id versioning_configuration { status = "Enabled" } }
terraform apply
を実行すると「Amazon S3 バックエンド」前提でバージョニングを有効化できた👌
$ terraform apply Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_s3_bucket_versioning.tfstate will be created + resource "aws_s3_bucket_versioning" "tfstate" { + bucket = "kakakakakku-tfstate-bootstrap" + id = (known after apply) + region = "ap-northeast-1" + versioning_configuration { + mfa_delete = (known after apply) + status = "Enabled" } } Plan: 1 to add, 0 to change, 0 to destroy. (中略) Apply complete! Resources: 1 added, 0 changed, 0 destroyed.