はじめに
Terraformのコマンドの1つにterraform state mv
があります。
これはリソース名をリネームしたり、リソースブロックを移動したい場合に使うコマンドなのですが、コマンド実行後にStateがどうなっているのか、具体的な解説が見つからなかったので動かしながら検証してみることにしました。
※検証環境はAzureでローカルから実行しています。
事前準備
リポジトリはこちらです。
まずはAzureにログインして、リソースを作成するサブスクリプションを設定します。
$ az login
$ az account set --subscription "サブスクリプション名"
developディレクトリで下記コマンドを実行、リソースグループとAppServicePlanを作成します。
$ terraform init
$ terraform plan
$ terraform apply
以上でAzure上にリソースが作成されました。
Stateファイルの中身は下記の通りとなります。
{
"version": 4,
"terraform_version": "1.3.2",
"serial": 3,
"lineage": "XXXX",
"outputs": {},
"resources": [
{
"module": "module.common_app_service_plan",
"mode": "managed",
"type": "azurerm_service_plan",
"name": "common_module_app_service_plan",
"provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"app_service_environment_id": "",
"id": "XXXX",
"kind": "linux",
"location": "japaneast",
"maximum_elastic_worker_count": 1,
"name": "plan-common-dev-je-001",
"os_type": "Linux",
"per_site_scaling_enabled": false,
"reserved": true,
"resource_group_name": "rg-common-dev-je-001",
"sku_name": "B1",
"tags": null,
"timeouts": null,
"worker_count": 1
},
"sensitive_attributes": [],
"private": "XXX",
"dependencies": [
"module.common_resource_group.azurerm_resource_group.common_module_resource_group"
]
}
]
},
{
"module": "module.common_resource_group",
"mode": "managed",
"type": "azurerm_resource_group",
"name": "common_module_resource_group",
"provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"id": "XXXX",
"location": "japaneast",
"name": "rg-common-dev-je-001",
"tags": null,
"timeouts": null
},
"sensitive_attributes": [],
"private": "XXXX"
}
]
}
],
"check_results": []
}
これで事前準備は完了ですね。
あとはterraform state mv
コマンドで、Stateがどういった動きになるのか検証していきます。
ユースケース1:Terraform上のリソース名を変更したい
例えば、下記のcommon_module_app_service_plan
の名前を変更したい場合にコマンドが使えます。
resource "azurerm_service_plan" "common_module_app_service_plan" {
name = var.common_app_service_plan_config.name
~~~~~~省略~~~~~~
当然Stateファイルにもcommon_module_app_service_plan
の名称が記載されています。
~~~~~~省略~~~~~~
"module": "module.common_app_service_plan",
"mode": "managed",
"type": "azurerm_service_plan",
"name": "common_module_app_service_plan",
"provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]",
"instances": [
~~~~~~省略~~~~~~
なので、普通にrenameしてしまうとTerraformとしては別物として扱われしまい、既存のものはdestoryとなり、新しくrenameしたリソースが作成されます。
ということで、これを回避するためにterraform state mv
コマンドを実行していきます。
リソース名の変更
まずはじめに、リソース名をhoge_module_app_service_plan
にします
resource "azurerm_service_plan" "hoge_module_app_service_plan" {
name = var.common_app_service_plan_config.name
resource_group_name = var.common_app_service_plan_config.resource_group_name
location = var.common_config.location
~~~~~~省略~~~~~~
コマンドの実行
terraform state mv
を実行します。
ちなみにterraform state list
コマンドでリソース名を取得できます。
$ terraform state mv module.common_app_service_plan.azurerm_service_plan.common_module_app_service_plan module.common_app_service_plan.azurerm_service_plan.hoge_module_app_service_plan
State内のnameが変わっており無事成功しています。
破壊的なコマンドなので自動でバックアップが作成されるようです。
~~~~~~省略~~~~~~
"module": "module.common_app_service_plan",
"mode": "managed",
"type": "azurerm_service_plan",
"name": "hoge_module_app_service_plan",
"provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]",
"instances": [
~~~~~~省略~~~~~~
さいごに
眠いのでここまでにして、明日以降ここに追記していきます。