実践Terraform ch24 リファクタリング

Terraform勉強メモ

出典: 


tfstateファイルのバックアップ

  • tfファイルだけでなくtfstateファイルも書き換えるので難易度高め
  • S3などに置く場合はバージョニングを有効にしよう

ステートの参照

  • 準備
resource "null_resource" "foo" {}
resource "null_resource" "bar" {}
null_resource.foo: Creating...
null_resource.bar: Creating...
null_resource.foo: Creation complete after 0s [id=5393035198503103467]
null_resource.bar: Creation complete after 0s [id=894881163496786251]

terraform.tfstateファイル

{
  "version": 4,
  "terraform_version": "0.12.21",
  "serial": 3,
  "lineage": "0f248c28-9316-2c3a-1a3a-0a37ac8a3117",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "null_resource",
      "name": "bar",
      "provider": "provider.null",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "id": "894881163496786251",
            "triggers": null
          },
          "private": "bnVsbA=="
        }
      ]
    },
    {
      "mode": "managed",
      "type": "null_resource",
      "name": "foo",
      "provider": "provider.null",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "id": "5393035198503103467",
            "triggers": null
          },
          "private": "bnVsbA=="
        }
      ]
    }
  ]
}
  • このファイルを直接いじることはしない

terraform state list

terraform state list
null_resource.bar
null_resource.foo

terraform state show

terraform state show null_resource.bar
# null_resource.bar:
resource "null_resource" "bar" {
    id = "894881163496786251"
}

terraform state pull

terraform state pull
{
  "version": 4,
  "terraform_version": "0.12.21",
  "serial": 3,
  "lineage": "0f248c28-9316-2c3a-1a3a-0a37ac8a3117",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "null_resource",
      "name": "bar",
      "provider": "provider.null",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "id": "894881163496786251",
            "triggers": null
          },
          "private": "bnVsbA=="
        }
      ]
    },
    {
      "mode": "managed",
      "type": "null_resource",
      "name": "foo",
      "provider": "provider.null",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "id": "5393035198503103467",
            "triggers": null
          },
          "private": "bnVsbA=="
        }
      ]
    }
  ]
}
  • tfstateファイルをcatするのとおなじ
  • tfstateファイルがリモート管理でも同様に動作する

ステートの上書き

tfstateファイルの書き換え, terraform state push

  • pullの逆
  • 強力にして危険

ステートからリソースを削除

準備

resource "aws_s3_bucket" "example" {
  bucket = "wand-terraform-practice-20200331"
  acl    = "private"
}
terraform apply
terraform state list
aws_s3_bucket.example
aws s3 ls
...
2020-03-31 14:37:45 wand-terraform-practice-20200331

terraform state rm

  • リソース自体はそのままに、Terraform管理外にする
terraform state rm aws_s3_bucket.example
Removed aws_s3_bucket.example
Successfully removed 1 resource instance(s).
  • tfstateからは消える
terraform state list
(空)
  • リソース自体はそのまま
aws s3 ls
2020-03-31 14:37:45 wand-terraform-practice-20200331

後始末

  • Terraform管理外になったのでaws cliもしくはコンソールでリソースを削除する
aws s3 rb s3://wand-terraform-practice-20200331
remove_bucket: wand-terraform-practice-20200331

リネーム

  • terraform上のリソース名を変えたい
resource "null_resource" "before" {}
- resource "null_resource" "before" {}
+ resource "null_resource" "after" {}
  • にすると
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

null_resource.before: Refreshing state... [id=7552165004938551866]

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
  - destroy

Terraform will perform the following actions:

  # null_resource.after will be created
  + resource "null_resource" "after" {
      + id = (known after apply)
    }

  # null_resource.before will be destroyed
  - resource "null_resource" "before" {
      - id = "7552165004938551866" -> null
    }

Plan: 1 to add, 0 to change, 1 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
Plan: 1 to add, 0 to change, 1 to destroy.
  • 意図通りじゃない

    • リソースを削除・再生成したいわけではない

terraform state mv によるリソースのリネーム

  • 作業前確認
terraform state list
null_resource.before
  • terraform state mv <src> <dest>
terraform state mv null_resource.before null_resource.after
Move "null_resource.before" to "null_resource.after"
Successfully moved 1 object(s).
  • tfstateが更新される

    • リソースはそのまま
terraform state list
null_resource.after
  • ここであらためてtfファイルを修正する
- resource "null_resource" "before" {}
+ resource "null_resource" "after" {}
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

null_resource.after: Refreshing state... [id=7552165004938551866]

------------------------------------------------------------------------

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.
  • terraform planして差分なし。OK

tfstateファイル間の移動

./destination:
total 8
-rw-rw-r-- 1 wand wand  42 Mar 31 23:55 main.tf
-rw-r--r-- 1 root root 513 Mar 31 23:58 terraform.tfstate

./source:
total 8
-rw-rw-r-- 1 wand wand  37 Mar 31 23:55 main.tf
-rw-r--r-- 1 root root 508 Mar 31 23:57 terraform.tfstate

./source/main.tf

resource "null_resource" "A" {}

./destination/main.tf

resource "null_resource" "B" {}
  • 別々のディレクトリ、別々のmain.tf、別々のtfstate
  • sourceのAリソースをdestinationに移動したい

tfstateファイル間のリソース移動

terraform state mv -state=./source/terraform.tfstate -state-out=./destination/terraform.tfstate null_resource.A null_resource.A
Move "null_resource.A" to "null_resource.A"
Successfully moved 1 object(s).
terraform state list -state=./source/terraform.tfstate
(空)
terraform state list -state=./destination/terraform.tfstate
null_resource.A
null_resource.B
  • リモート(s3など)にtfstateファイルがある場合は適宜terraform state push等行う

コードの修正

./source/main.tf

- resource "null_resource" "A" {}

./destination/main.tf

+ resource "null_resource" "A" {}
  resource "null_resource" "B" {}
  • terraform planして差分のなきことを確認する

source

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


------------------------------------------------------------------------

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.

destination

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

null_resource.B: Refreshing state... [id=5255672303662796638]
null_resource.A: Refreshing state... [id=1577236031843010058]

------------------------------------------------------------------------

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.