通过 terraform 创建资源但如果手动删除则不重新创建?
Create resource via terraform but do not recreate if manually deleted?
我最初想使用 Terraform 创建资源,但如果资源后来在 TF 之外被删除 - 例如由用户手动 - 我不希望 terraform 重新创建它。这可能吗?
在我的例子中,资源是 Azure Blob 存储上的一个 blob。我尝试使用 ignore_changes = all
但这没有帮助。每次我 运行 terraform apply
,它都会重新创建 blob。
resource "azurerm_storage_blob" "test" {
name = "myfile.txt"
storage_account_name = azurerm_storage_account.deployment.name
storage_container_name = azurerm_storage_container.deployment.name
type = "Block"
source_content = "test"
lifecycle {
ignore_changes = all
}
}
如果您在 terraform 配置中定义了资源,那么 terraform 将始终尝试创建它。我无法想象你的设置是什么,但也许你想将 blob 创建带到 CLI 脚本和 运行 terraform 以及所需顺序的脚本中。
Terraform 不直接支持您提出的要求。要实现它,您需要完全在 Terraform 之外实现某些东西,或者使用 Terraform 作为您编写的一些自定义脚本的一部分来执行几个单独的 Terraform 步骤。
如果您想通过包装 Terraform 来实现它,那么我将描述一种可能的方法,尽管还有其他各种变体可以达到类似的效果。
我实现它的想法是实现一种“bootstrapping 模式”,您的自定义脚本只能在初始创建时启用该模式,但对于后续工作您不会使用 bootstrap平模式。引导模式将是激活它的输入变量和使用它后的额外步骤的组合。
variable "bootstrap" {
type = bool
default = false
description = "Do not use this directly. Only for use by the bootstrap script."
}
resource "azurerm_storage_blob" "test" {
count = var.bootstrap ? 1 : 0
name = "myfile.txt"
storage_account_name = azurerm_storage_account.deployment.name
storage_container_name = azurerm_storage_container.deployment.name
type = "Block"
source_content = "test"
}
仅此是不够的,因为通常情况下,如果您使用 -var="bootstrap=true"
运行 Terraform 一次,然后在没有它的情况下再次使用 Terraform,在注意到它不再存在于配置。
因此,为了完成这项工作,我们需要一个特殊的 bootstrap 脚本,它像这样包装 Terraform:
terraform apply -var="bootstrap=true"
terraform state rm azurerm_storage_blob.test
上面的第二个 terraform state rm
命令告诉 Terraform 忘记它当前绑定到 azurerm_storage_blob.test
的对象。这意味着该对象将继续存在,但 Terraform 将没有它的记录,因此将表现得好像它不存在一样。
如果你 运行 然后 bootstrap 脚本,你将拥有 blob 但 Terraform 不知道它。因此,您可以像往常一样 运行 terraform apply
( 没有 设置 bootstrap
变量)并且 Terraform 将忽略先前创建的对象 and 不打算创建一个新的,因为它现在将有 count = 0
.
这不是 Terraform 的典型用例,因此我建议考虑其他可能的解决方案来满足您的用例,但我希望以上内容对设计工作有用。
我最初想使用 Terraform 创建资源,但如果资源后来在 TF 之外被删除 - 例如由用户手动 - 我不希望 terraform 重新创建它。这可能吗?
在我的例子中,资源是 Azure Blob 存储上的一个 blob。我尝试使用 ignore_changes = all
但这没有帮助。每次我 运行 terraform apply
,它都会重新创建 blob。
resource "azurerm_storage_blob" "test" {
name = "myfile.txt"
storage_account_name = azurerm_storage_account.deployment.name
storage_container_name = azurerm_storage_container.deployment.name
type = "Block"
source_content = "test"
lifecycle {
ignore_changes = all
}
}
如果您在 terraform 配置中定义了资源,那么 terraform 将始终尝试创建它。我无法想象你的设置是什么,但也许你想将 blob 创建带到 CLI 脚本和 运行 terraform 以及所需顺序的脚本中。
Terraform 不直接支持您提出的要求。要实现它,您需要完全在 Terraform 之外实现某些东西,或者使用 Terraform 作为您编写的一些自定义脚本的一部分来执行几个单独的 Terraform 步骤。
如果您想通过包装 Terraform 来实现它,那么我将描述一种可能的方法,尽管还有其他各种变体可以达到类似的效果。
我实现它的想法是实现一种“bootstrapping 模式”,您的自定义脚本只能在初始创建时启用该模式,但对于后续工作您不会使用 bootstrap平模式。引导模式将是激活它的输入变量和使用它后的额外步骤的组合。
variable "bootstrap" {
type = bool
default = false
description = "Do not use this directly. Only for use by the bootstrap script."
}
resource "azurerm_storage_blob" "test" {
count = var.bootstrap ? 1 : 0
name = "myfile.txt"
storage_account_name = azurerm_storage_account.deployment.name
storage_container_name = azurerm_storage_container.deployment.name
type = "Block"
source_content = "test"
}
仅此是不够的,因为通常情况下,如果您使用 -var="bootstrap=true"
运行 Terraform 一次,然后在没有它的情况下再次使用 Terraform,在注意到它不再存在于配置。
因此,为了完成这项工作,我们需要一个特殊的 bootstrap 脚本,它像这样包装 Terraform:
terraform apply -var="bootstrap=true"
terraform state rm azurerm_storage_blob.test
上面的第二个 terraform state rm
命令告诉 Terraform 忘记它当前绑定到 azurerm_storage_blob.test
的对象。这意味着该对象将继续存在,但 Terraform 将没有它的记录,因此将表现得好像它不存在一样。
如果你 运行 然后 bootstrap 脚本,你将拥有 blob 但 Terraform 不知道它。因此,您可以像往常一样 运行 terraform apply
( 没有 设置 bootstrap
变量)并且 Terraform 将忽略先前创建的对象 and 不打算创建一个新的,因为它现在将有 count = 0
.
这不是 Terraform 的典型用例,因此我建议考虑其他可能的解决方案来满足您的用例,但我希望以上内容对设计工作有用。