Terraform-如何避免使用单一状态文件进行破坏和创建

Posted

技术标签:

【中文标题】Terraform-如何避免使用单一状态文件进行破坏和创建【英文标题】:Terraform- How to avoid destroy and create with single state file 【发布时间】:2020-05-11 08:20:21 【问题描述】:

我有一个创建流分析作业的 terraform 代码,该作业的输入和输出也是如此。 以下是我的 terraform 代码:​​

provider "azurerm" 
  version = "=1.44"

resource "azurerm_stream_analytics_job" "test_saj" 
  name                                     = "test-stj"
  resource_group_name                      = "myrgname"
  location                                 = "Southeast Asia"
  compatibility_level                      = "1.1"
  data_locale                              = "en-US"
  events_late_arrival_max_delay_in_seconds = 60
  events_out_of_order_max_delay_in_seconds = 50
  events_out_of_order_policy               = "Adjust"
  output_error_policy                      = "Drop"
  streaming_units                          = 3

  tags = 
    environment = "test"
  
  transformation_query = var.query


resource "azurerm_stream_analytics_output_blob" "mpl_saj_op_jk_blob" 
  name                      = var.saj_jk_blob_output_name
  stream_analytics_job_name = "test-stj"
  resource_group_name       = "myrgname"
  storage_account_name      = "mystaname"
  storage_account_key       = "mystakey"
  storage_container_name    = "testupload"
  path_pattern              = myfolder/day"
  date_format               = "yyyy-MM-dd"
  time_format               = "HH"

  depends_on = [azurerm_stream_analytics_job.test_saj]

  serialization 
    type            = "Json"
    encoding        = "UTF8"
    format  = "LineSeparated"
  

resource "azurerm_stream_analytics_stream_input_eventhub" "mpl_saj_ip_eh" 
  name                         = var.saj_joker_event_hub_name
  stream_analytics_job_name    = "test-stj"
  resource_group_name          = "myrgname"
  eventhub_name                = "myehname"
  eventhub_consumer_group_name = "myehcgname"
  servicebus_namespace         = "myehnamespacename"
  shared_access_policy_name    = "RootManageSharedAccessKey"
  shared_access_policy_key     = "ehnamespacekey"

      serialization 
        type     = "Json"
        encoding = "UTF8"
      
      depends_on = [azurerm_stream_analytics_job.test_saj]
    

以下是我的 tfvars 输入文件:

query=<<EOT
myqueryhere
EOT
saj_jk_blob_output_name="outputtoblob01"
saj_joker_event_hub_name="inputventhub01"

我对创作没有任何问题。现在我的问题是,当我想为同一个流分析作业创建一个新的输入和输出时,我在 tfvars 文件中单独更改了名称值并给出了 terraform apply (在给出第一次应用的同一目录中。相同的状态文件) .

Terraform 正在用新的 i/p 和 o/p 替换现有的 i/p 和 o/p,这不是我的要求。我想要旧的和新的。当使用 terraform import 在完全不同的文件夹中导入现有流分析并且我使用相同的代码时,此用例得到了满足。但是有没有办法在没有 terraform 导入的情况下做到这一点。这可以用单个状态文件本身来完成吗?

【问题讨论】:

为什么要在同一个状态文件中?状态文件的重点是告诉 Terraform 它正在管理什么资源。 @ydaetskcoR 因为这将成为我未来的全局状态维护,如果流分析存在这样的限制,我会考虑其他一些解决方案。出于测试目的,我目前正在使用本地状态文件。如果我不够清楚,请告诉我。 【参考方案1】:

State 允许 Terraform 知道要添加、更新或删除哪些 Azure 资源。除非您直接在配置文件中部署具有不同名称的资源,否则您想要做的事情不能用单个状态文件本身来完成。

例如,如果您想创建两个虚拟网络。您可以像这样直接创建资源,也可以在循环的资源级别上使用count 参数。

resource "azurerm_virtual_network" "example" 
  name                = "examplevnet1"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  address_space       = ["10.1.0.0/16"]


resource "azurerm_virtual_network" "example" 
  name                = "examplevnet2"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  address_space       = ["10.2.0.0/16"]

在团队中使用 Terraform 时,您可以使用 remote state 将状态数据写入远程数据存储,然后可以在团队的所有成员之间共享。推荐store Terraform state in Azure Storage。

有关更多信息,您可以在this blog 中查看 Terraform 工作流程。

【讨论】:

以上是关于Terraform-如何避免使用单一状态文件进行破坏和创建的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Terraform 中管理本地生成的有状态文件

AWS on Terraform - 如何避免“强制使用新资源”

避免更新 Terraform 中的资源

带有 S3 后端的 Terraform 如何发现所有工作区?

如何使用 terraform 在多个区域进行设置?

如何在使用脚本创建新的 ec2 时避免 terraform 以前的 ec2 被破坏