【问题标题】:How to share a terraform script without module dependencies如何在没有模块依赖的情况下共享 terraform 脚本
【发布时间】:2017-02-15 11:11:10
【问题描述】:

我想分享一个将在不同项目中使用的 terraform 脚本。我知道如何创建和共享模块,但是这个设置有一个很大的烦恼:当我在脚本中引用一个模块并执行 terraform apply 时,如果模块资源不存在,它将被创建,但如果我执行terraform destroy此资源将被销毁。

如果我有两个项目依赖于同一个模块,并且在其中一个项目中我调用terraform destroy,它可能会导致状态不一致,因为该模块正在被另一个项目使用。该脚本可能会因为无法销毁资源而失败,或者会销毁资源并影响其他项目。

在我的场景中,我想在两个项目之间共享网络脚本,并且我希望网络资源永远不会被破坏。我不能只为这个资源创建一个项目,因为我需要在我的项目中以某种方式引用它,唯一的方法是通过它的 ID,我不知道会是什么。

prevent_destroy 也不是一个选项,因为我确实需要销毁共享脚本资源以外的其他资源。此配置使terraform destroy 失败。

有没有办法引用资源,比如通过它的名字,或者有没有其他更好的方法来完成我想要的?

【问题讨论】:

    标签: amazon-web-services terraform


    【解决方案1】:

    如果我对您的理解正确,您有一些资源 R 是“单身人士”。也就是说,您的 AWS 账户中只能存在一个 R 实例。例如,您只能拥有一个名为“foo.com”的aws_route53_zone。如果您将R 作为一个模块包含在两个不同的地方,那么任何一个都可以在您运行terraform apply 时创建它,而任何一个都可以在您运行terraform destroy 时删除它。您想避免这种情况,但您仍然需要某种方式从R 获取输出属性(例如,aws_route53_zone 资源的zone_id 是由 AWS 生成的,因此您无法猜测)。

    如果是这种情况,那么您应该:

    1. 在自己的一组 Terraform 模板中自行创建 R。假设这些在/terraform/R 之下。
    2. /terraform/R 配置为使用Remote State。例如,您可以通过以下方式配置这些模板以将其远程状态存储在 S3 存储桶中(您需要按照指示填写存储桶名称/区域):

      terraform remote config \
        -backend=s3 \
        -backend-config="bucket=(YOUR BUCKET NAME)" \
        -backend-config="key=terraform.tfstate" \
        -backend-config="region=(YOUR BUCKET REGION)" \
        -backend-config="encrypt=true"
      
    3. R 定义您需要的任何输出属性作为输出变量。例如:

      output "zone_id" {
        value = "${aws_route_53.example.zone_id}"
      }
      
    4. 当您在 /terraform/R 中运行 terraform apply 时,它会将其 Terraform 状态(包括该输出)存储在 S3 存储桶中。
    5. 现在,在所有其他需要来自 R 的输出属性的 Terraform 模板中,您可以使用 terraform_remote_state data source 从 S3 存储桶中提取它。例如,假设您有一些模板/terraform/foo 需要zone_id 参数来创建aws_route53_record(您需要按照指示填写存储桶名称/区域):

      data "terraform_remote_state" "r" {
        backend = "s3"
        config {
          bucket = "(YOUR BUCKET NAME)"
          key = "terraform.tfstate"    
          region = "(YOUR BUCKET REGION)"
        }
      }
      
      resource "aws_route53_record" "www" {
        zone_id = "${data.terraform_remote_state.r.zone_id}"
        name = "www.foo.com"
        type = "A"
        ttl = "300"
        records = ["${aws_eip.lb.public_ip}"]
      }
      
    6. 请注意,terraform_remote_state 是只读数据源。这意味着当您在使用该资源的任何模板上运行 terraform applyterraform destroy 时,它们不会对 R 产生任何影响。

    如需了解更多信息,请查看How to manage terraform stateTerraform: Up & Running

    【讨论】:

    • 哇!这真是一个不错的方法!我不知道您可以检索远程状态并将其用作数据源。
    猜你喜欢
    • 2013-11-29
    • 1970-01-01
    • 2020-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-12
    • 2011-12-16
    • 2015-10-28
    相关资源
    最近更新 更多