Terraformでtfstateファイル場所と設定内容一緒に変更時エラーを回避する方法

この記事は[Wanoグループ Advent Calendar 2020の15日目](https://qiita.com/advent-calendar/2020/wano-group)の記事になります。

## はじめに

サービスを長く運用していると、リポジトリでさまざまなリファクタリングをすることがよくあります。
その中で、運用に影響与えないよう更新することがとても大切ですよね。
そのために、今回はterraformの設定内容変更について、簡単なのネタを紹介したいと思います。

## とりあえずやってみます

tfstate場所とresource内容を両方に変更

```terraform:
terraform {
  required_version = "0.12.28"
  backend "s3" {
    region = "ap-northeast-1"
    bucket = "test-origin-bucket"             //"test-target-bucket" に変更したい  　　　　　　 
    key    = "origin_path/terraform.tfstate"  //"new_path/terraform.tfstate" に変更したい
  }
}

resource "aws_sqs_queue" "test-queue1" {
  name                       = "test-queue1.fifo"
  visibility_timeout_seconds = 30             // 3600に変更したい
  message_retention_seconds  = 345600
  max_message_size           = 262144
  delay_seconds              = 0
  receive_wait_time_seconds  = 0
  fifo_queue                 = true
}

```

terraform applyの結果大丈夫らしいけが・・・

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

Terraform will perform the following actions:

  # aws_sqs_queue.test-queue1 will be created
  + resource "aws_sqs_queue" "test-queue1" {
      + arn                               = (known after apply)
      + content_based_deduplication       = false
      + delay_seconds                     = 30
      + fifo_queue                        = true
      + id                                = (known after apply)
      + kms_data_key_reuse_period_seconds = (known after apply)
      + max_message_size                  = 262144
      + message_retention_seconds         = 345600
      + name                              = "test-queue1"
      + policy                            = (known after apply)
      + receive_wait_time_seconds         = 0
      + redrive_policy                    = jsonencode(
            {
              + deadLetterTargetArn = "arn:aws:sqs:ap-northeast-1:XXXXXX:test-queue1"
              + maxReceiveCount     = 1
            }
        )
      + visibility_timeout_seconds        = 3600
    }

Plan: 1 to add, 0 to change, 0 to destroy.
```
実行した結果失敗：

```
aws_sqs_queue.test-queue1: Creating...

Error: Error creating SQS queue: QueueAlreadyExists: A queue already exists with the same name and a different value for attribute VisibilityTimeout
	status code: 400, request id: XXXXXXXXXXXXXXXXXXXX

```

どうやら既存のqueueとコンフリクトした模様。
一旦既存のqueueを削除する方法もありますが、ちょっと面倒なので、
できればそのまま更新したいですね。


## 解決方法

いろいろ試した結果、二段階で実行したらうまくいきました！

1回目：

```terraform:
terraform {
  required_version = "0.12.28"
  backend "s3" {
    region = "ap-northeast-1"
    bucket = "test-target-bucket"          //ここは先に変更　　　　　　 
    key    = "new_path/terraform.tfstate"  //ここは先に変更
  }
}

resource "aws_sqs_queue" "test-queue1" {
  name                       = "test-queue1.fifo"
  visibility_timeout_seconds = 30             // 一旦そのまま
  message_retention_seconds  = 345600
  max_message_size           = 262144
  delay_seconds              = 0
  receive_wait_time_seconds  = 0
  fifo_queue                 = true
}

```

```terraform:
aws_sqs_queue.test-queue1: Creating...
aws_sqs_queue.test-queue1: Creation complete after 5s [id=XXXXXX]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
```

2回目：

```terraform:
terraform {
  required_version = "0.12.28"
  backend "s3" {
    region = "ap-northeast-1"
    bucket = "test-target-bucket"          
    key    = "new_path/terraform.tfstate"  
  }
}

resource "aws_sqs_queue" "test-queue1" {
  name                       = "test-queue1.fifo"
  visibility_timeout_seconds = 3600             //tfstate場所既に変わるので、普通で更新できます
  message_retention_seconds  = 345600
  max_message_size           = 262144
  delay_seconds              = 0
  receive_wait_time_seconds  = 0
  fifo_queue                 = true
}

```

```terraform:
aws_sqs_queue.test-queue1: Modifying... 
aws_sqs_queue.test-queue1: Modifications complete after 6s [id=XXXXXX]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
```

無事更新！

初歩的なことですが、意外にハマってる人がいるかもしれませんので、共有しておきます。


----
Wanoは積極的にエンジニア採用を行なっています！
まずはオンラインでVPoEとのカジュアル面談から。お好きな入り口からお気軽にお声がけください！
Wano Recruitページ　https://group.wano.co.jp/recruit/
QiitaJobs　https://jobs.qiita.com/employers/wano-inc/postings/1297
Wantedly　https://www.wantedly.com/companies/wano/projects
Findy　https://findy-code.io/companies/522