如何在不依赖模块的情况下共享Terraform脚本 [英] How to share a terraform script without module dependencies

查看:293
本文介绍了如何在不依赖模块的情况下共享Terraform脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想共享一个将在不同项目中使用的terraform脚本.我知道如何创建和共享模块,但是这种设置非常麻烦:当我在脚本中引用模块并执行 terraform apply 时,如果模块资源不存在,则会创建该模块,而且如果我执行 terraform destroy ,此资源也会被销毁.

I want to share a terraform script that will be used across different projects. I know how to create and share modules, but this setup has a big annoyance: when I reference a module in a script and perform a terraform apply, if the module resource does not exist it will be created, but also if I perform a terraform destroy this resource will be destroyed.

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

If I have two projects dependent on the same module, and in one of them I call a terraform destroy it may lead to a inconsistent state, since the module is being used by another project. The script can either fail because it cannot destroy the resource or it will destroy the resource and affect the other project.

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

In my scenario, I want to share network scripts between two projects and I want the network resources to never be destroyed. I cannot create a project only for this resource because I need to reference it somehow in my projects, and the only way to do it is via its ID, which I have no idea what is going to be.

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

prevent_destroy is also not an option, since I do need to destroy other resources but the shared script resource. This configuration makes terraform destroy fail.

是否有任何方法可以引用资源,例如通过名称进行引用,还是有其他更好的方法来完成我想要的工作?

Is there any way to reference the resource, like by its name, or is there any other better approach to accomplish what I want?

推荐答案

如果我对您的理解正确,那么您有一些资源" R "是单个".也就是说,您的AWS账户中只能存在一个 R 实例.例如,您只能将一个 aws_route53_zone 与名称为"foo.com".如果将 R 作为模块包含在两个不同的位置,则在运行 terraform apply 时可以创建一个,而在运行 terraform时可以删除一个销毁.您想避免这种情况,但是仍然需要某种方法来从 R 获取输出属性(例如, aws_route53_zone 资源的 zone_id 是由AWS生成的,因此您无法猜到.)

If I understand you correctly, you have some resource R that is a "singleton". That is, only one instance of R can ever exist in your AWS account. For example, you can only ever have one aws_route53_zone with the name "foo.com". If you include R as a module in two different places, then either one may create it when you run terraform apply and either one may delete it when you run terraform destroy. You'd like to avoid that, but you still need some way to get an output attribute from R (e.g. the zone_id for an aws_route53_zone resource is generated by AWS, so you can't guess it).

如果是这种情况,则应该使用

R 作为模块,而不是:

If that's the case, then instead of using a R as a module, you should:

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

  1. Create R by itself in its own set of Terraform templates. Let's say those are under /terraform/R.
  2. Configure /terraform/R to use Remote State. For example, here is how you can configure those templates to store their remote state in an S3 bucket (you'll need to fill in the bucket name/region as indicated):

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"

  • R 定义所需的任何输出属性作为输出变量.例如:

  • Define any output attributes you need from R as output variables. For example:

    output "zone_id" {
      value = "${aws_route_53.example.zone_id}"
    }
    

  • /terraform/R 中运行 terraform apply 时,它将把其Terraform状态(包括该输出)存储在S3存储桶中.
  • 现在,在所有其他需要 R 中的输出属性的Terraform模板中,您都可以使用

  • When you run terraform apply in /terraform/R, it will store its Terraform state, including that output, in an S3 bucket.
  • Now, in all other Terraform templates that need that output attribute from R, you can pull it in from the S3 bucket using the terraform_remote_state data source. For example, let's say you had some template /terraform/foo that needed that zone_id parameter to create an aws_route53_record (you'll need to fill in the bucket name/region as indicated):

    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}"]
    }
    

  • 请注意, terraform_remote_state 是只读数据源.这意味着,当在使用该资源的任何模板上运行 terraform apply terraform destroy 时,它们在 R 中不会产生任何作用.
  • Note that terraform_remote_state is a read-only data source. That means when you run terraform apply or terraform destroy on any templates that use that resource, they will not have any effect in R.
  • 有关更多信息,请查看如何管理地形状态 平台:向上&正在运行 .

    For more info, check out How to manage terraform state and Terraform: Up & Running.

    这篇关于如何在不依赖模块的情况下共享Terraform脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆