はじめに
Terraform の便利なブロックである3つのブロックを自身の備忘も兼ねて、簡単なサンプルと共にまとめました。
それぞれ以下のバージョンで追加されたブロックとなります。
サンプルユースケース
今回のサンプルは以下のユースケースのシナリオとなります。
- [import] : これまでコード化されていなかったバケットを import して Terraform 管理下にする
- [moved] : ステートを module の配下に移動する
- [removed] : やっぱり Terraform 管理から外す
対象のサンプル S3 バケット名: test-bucket-js3t5x9
# 全フロー共通 terraform ブロック
terraform {
required_version = "1.9.8"
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.75.0"
}
}
}
import
[import] : これまでコード化されていなかったバケットを import して Terraform 管理下にする
まず、対象の tf ファイルにimport ブロックを記載します。
import ブロックに使用する id はリソースの種類ごとに異なるので、公式ドキュメントの import 欄にて確認します。 S3 バケットの例
# main.tf (←任意のファイル名)
import {
to = aws_s3_bucket.sample
id = "test-bucket-js3t5x9" # id はリソースの種類ごとに異なる S3バケットの場合はバケット名
}
続いてステートを出力するので -generate-config-out
オプションを付加して plan を打ちます。
$ terraform plan -generate-config-out=generated.tf # generated.tf は任意のファイル名
generated.tf
が生成されるので、適宜に移動します。(もちろん移動せずそのまま使うでもOK)
main.tf
に移動した例
# main.tf
resource "aws_s3_bucket" "sample" {
bucket = "test-bucket-js3t5x9"
bucket_prefix = null
force_destroy = null
object_lock_enabled = false
tags = {}
tags_all = {}
}
import {
to = aws_s3_bucket.sample
id = "test-bucket-js3t5x9"
}
続いて apply
$ terraform apply
結果
$ terraform apply
aws_s3_bucket.sample: Preparing import... [id=test-bucket-js3t5x9]
aws_s3_bucket.sample: Refreshing state... [id=test-bucket-js3t5x9]
Terraform will perform the following actions:
# aws_s3_bucket.sample will be imported
resource "aws_s3_bucket" "sample" {
acceleration_status = null
arn = "arn:aws:s3:::test-bucket-js3t5x9"
bucket = "test-bucket-js3t5x9"
bucket_domain_name = "test-bucket-js3t5x9.s3.amazonaws.com"
bucket_prefix = null
bucket_regional_domain_name = "test-bucket-js3t5x9.s3.ap-northeast-1.amazonaws.com"
hosted_zone_id = "XXXXXXXXXXXXXX"
id = "test-bucket-js3t5x9"
object_lock_enabled = false
policy = null
region = "ap-northeast-1"
request_payer = "BucketOwner"
tags = {}
tags_all = {}
grant {
id = "999999-dummy"
permissions = [
"FULL_CONTROL",
]
type = "CanonicalUser"
uri = null
}
server_side_encryption_configuration {
rule {
bucket_key_enabled = true
apply_server_side_encryption_by_default {
kms_master_key_id = null
sse_algorithm = "AES256"
}
}
}
versioning {
enabled = false
mfa_delete = false
}
}
Plan: 1 to import, 0 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_s3_bucket.sample: Importing... [id=test-bucket-js3t5x9]
aws_s3_bucket.sample: Import complete [id=test-bucket-js3t5x9]
Apply complete! Resources: 1 imported, 0 added, 0 changed, 0 destroyed.
これで import が完了です!
これ以降 import
ブロックは任意のタイミングで削除してOKです。削除しても plan で差分となりません。
moved
[moved] : ステートを module の配下に移動する
移動元、移動先のコードをそれぞれ実装
# main.tf (移動元)
module "s3" {
source = "./modules/s3"
bucket_name = "test-bucket-js3t5x9"
}
# 移動するので削除でOK
# resource "aws_s3_bucket" "sample" {
# bucket = "test-bucket-js3t5x9"
# bucket_prefix = null
# force_destroy = null
# object_lock_enabled = false
# tags = {}
# tags_all = {}
# }
# moved ブロックで移動元, 移動先を設定
moved {
from = aws_s3_bucket.sample
to = module.s3.aws_s3_bucket.this
}
# ./modules/s3/main.tf (移動先)
resource "aws_s3_bucket" "this" {
bucket = var.bucket_name
bucket_prefix = null
force_destroy = null
object_lock_enabled = false
tags = {}
tags_all = {}
}
variable "bucket_name" {
description = "バケット名"
type = string
}
plan で差分が出ていないことを確認
$ terraform plan
module.s3.aws_s3_bucket.this: Refreshing state... [id=test-bucket-js3t5x9]
Terraform will perform the following actions:
# aws_s3_bucket.sample has moved to module.s3.aws_s3_bucket.this
resource "aws_s3_bucket" "this" {
id = "test-bucket-js3t5x9"
tags = {}
# (12 unchanged attributes hidden)
# (3 unchanged blocks hidden)
}
Plan: 0 to add, 0 to change, 0 to destroy.
続いて apply
$ terraform apply
(省略)
.....
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
これで移動が完了です!
これ以降 moved
ブロックは任意のタイミングで削除してOKです。削除しても plan で差分となりません。
removed
[removed] : やっぱり Terraform 管理から外す
削除するリソースの実装(コメントアウトや行削除など) と removed ブロックを記載します。
注意点として lifecycle
オプションで destroy = false
の指定が必要です。指定しなかった場合、管理外にするのではなく、リソースが削除されてしまいます。
# main.tf
# module の呼び出しをやめた
# module "s3" {
# source = "./modules/s3" # Terraform Registry上のモジュール
# bucket_name = "test-bucket-js3t5x9"
# }
removed {
from = module.s3.aws_s3_bucket.this
lifecycle {
destroy = false
}
}
plan で差分が出ていない & リソース自体は削除されないことを確認
$ terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
Terraform will perform the following actions:
# module.s3.aws_s3_bucket.this will no longer be managed by Terraform, but will not be destroyed
# (destroy = false is set in the configuration)
. resource "aws_s3_bucket" "this" {
id = "test-bucket-js3t5x9"
tags = {}
# (12 unchanged attributes hidden)
# (3 unchanged blocks hidden)
}
Plan: 0 to add, 0 to change, 0 to destroy.
続いて apply
$ terraform apply
(省略)
.....
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Terraform 管理からの除外が完了です!
これ以降 removed
ブロックは任意のタイミングで削除してOKです。削除しても plan で差分となりません。