Terraform хочет заменить существующие ресурсы

#amazon-s3 #terraform

#amazon-s3 #terraform

Вопрос:

Версия TF: 0.12.28 и 0.13.3

Моя цель:

  • Создайте корзину AWS S3 для PROD env для хранения состояния tf
  • Создайте корзину AWS S3 для НЕПРОИЗВОДСТВЕННОЙ среды для хранения состояния tf

Следуя этому руководству, я успешно выполнил следующее:

  • корзина AWS S3 и dynamodb из папки с именем TEST:
 provider "aws" {
  region = var.aws_region_id
}

resource "aws_s3_bucket" "terraform_state" {
    bucket = var.aws_bucket_name
    versioning {
      enabled = true
    }
    server_side_encryption_configuration {
      rule {
        apply_server_side_encryption_by_default {
          sse_algorithm = "AES256"
        }
      }
    }
}

resource "aws_dynamodb_table" "terraform_locks" {
  name         = var.aws_bucket_name
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"
  attribute {
    name = "LockID"
    type = "S"
  }
}

terraform {
  backend "s3" {
    bucket         = "test-myproject-poc"
    key            = "global/s3/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "test-myproject-poc"
    encrypt        = true
  }
}
  

До этого момента все было успешно развернуто

Однако, когда я захотел иметь еще одно ведро S3 / Dynamodb для PROD env, произошло следующее:

  • Я перешел в другую папку под названием PRODUCTION, я выполнил инициализацию terraform (инициализация прошла нормально)
  • скопировал тот же модуль, который у меня есть на PROD, в эту папку. И я переименовал PROD с помощью TEST в соответствии с env

В плане Terrarom теперь говорится, что он хочет заменить мое фактическое развертывание для создания нового:

 ➜  S3 tf plan
Acquiring state lock. This may take a few moments...
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.

aws_dynamodb_table.terraform_locks: Refreshing state... [id=test-myproject-poc]
aws_s3_bucket.terraform_state: Refreshing state... [id=test-myproject-poc]

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

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

Terraform will perform the following actions:

  # aws_dynamodb_table.terraform_locks must be replaced
-/  resource "aws_dynamodb_table" "terraform_locks" {
      ~ arn              = "arn:aws:dynamodb:us-east-1:1234567890:table/test-myproject-poc" -> (known after apply)
        billing_mode     = "PAY_PER_REQUEST"
        hash_key         = "LockID"
      ~ id               = "test-myproject-poc" -> (known after apply)
      ~ name             = "test-myproject-poc" -> "prod-myproject-poc" # forces replacement
  
  • Состояние фактически включено global/s3/terraform.tfstate
  • Я не использую рабочие пространства

Как правильно создать S3_PROD без удаления первого?

Ответ №1:

Я решил проблему! Только что узнал, что мне нужно удалить этот блок:

 terraform {
  backend "s3" {
    bucket         = "test-myproject-poc"
    key            = "global/s3/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "test-myproject-poc"
    encrypt        = true
  }
}
  

удалена папка .terraform и снова запустите init.

После выполнения этих шагов plan запустился, как и ожидалось (он не пытался удалить мое развертывание).

Что я думаю, но не уверен, что это сложно, так это то, что он пытался использовать тот же файл состояния, который был ранее развернут. Поэтому я просто оставил tf для создания корзины и динамической таблицы, чтобы, наконец, запустить процесс сохранения нового состояния новой папки (PROD) в S3.

HTH