如何在没有模块依赖性的情况下共享 Terraform 脚本
How to share a terraform script without module dependencies
我想分享一个将在不同项目中使用的 Terraform 脚本。我知道如何创建和共享模块,但这个设置有一个很大的烦恼:当我在脚本中引用模块并执行 terraform apply
时,如果模块资源不存在,它将被创建,但如果我执行 terraform destroy
此资源将被销毁。
如果我有两个项目依赖于同一个模块,并且我在其中一个项目中调用 terraform destroy
它可能会导致不一致的状态,因为该模块正在被另一个项目使用。脚本可能因为无法破坏资源而失败,或者会破坏资源并影响其他项目。
在我的场景中,我想在两个项目之间共享网络脚本,并且我希望网络资源永远不会被破坏。我不能只为这个资源创建一个项目,因为我需要在我的项目中以某种方式引用它,唯一的方法是通过它的 ID,我不知道会是什么。
prevent_destroy
也不是一个选项,因为我确实需要销毁除共享脚本资源之外的其他资源。此配置使 terraform destroy
失败。
有没有什么方法可以引用资源,比如通过名称,或者有没有其他更好的方法来完成我想要的?
如果我没理解错的话,你有一些资源 R
是 "singleton"。也就是说,您的 AWS 账户中只能存在一个 R
实例。例如,您只能拥有一个名为 "foo.com" 的 aws_route53_zone。如果您将 R
作为一个模块包含在两个不同的地方,那么当您 运行 terraform apply
时,任何一个都可以创建它,而当您 运行 [=17] 时,任何一个都可以删除它=].你想避免这种情况,但你仍然需要一些方法从 R
获取输出属性(例如 aws_route53_zone
资源的 zone_id
是由 AWS 生成的,所以你可以'别猜了)。
如果是这样,那么不要使用 R
作为模块,您应该:
- 在自己的 Terraform 模板集中自行创建
R
。假设那些在 /terraform/R
. 之下
配置 /terraform/R
以使用 Remote State。例如,以下是如何配置这些模板以将其远程状态存储在 S3 存储桶中(您需要按照指示填写存储桶 name/region):
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
中需要的任何输出属性定义为输出变量。例如:
output "zone_id" {
value = "${aws_route_53.example.zone_id}"
}
- 当您在
/terraform/R
中 运行 terraform apply
时,它会将其 Terraform 状态(包括该输出)存储在 S3 存储桶中。
现在,在所有其他需要来自 R
的输出属性的 Terraform 模板中,您可以使用 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(您需要按照指示填写存储桶 name/region):
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
. 产生任何影响
有关详细信息,请查看 How to manage terraform state and Terraform: Up & Running。
我想分享一个将在不同项目中使用的 Terraform 脚本。我知道如何创建和共享模块,但这个设置有一个很大的烦恼:当我在脚本中引用模块并执行 terraform apply
时,如果模块资源不存在,它将被创建,但如果我执行 terraform destroy
此资源将被销毁。
如果我有两个项目依赖于同一个模块,并且我在其中一个项目中调用 terraform destroy
它可能会导致不一致的状态,因为该模块正在被另一个项目使用。脚本可能因为无法破坏资源而失败,或者会破坏资源并影响其他项目。
在我的场景中,我想在两个项目之间共享网络脚本,并且我希望网络资源永远不会被破坏。我不能只为这个资源创建一个项目,因为我需要在我的项目中以某种方式引用它,唯一的方法是通过它的 ID,我不知道会是什么。
prevent_destroy
也不是一个选项,因为我确实需要销毁除共享脚本资源之外的其他资源。此配置使 terraform destroy
失败。
有没有什么方法可以引用资源,比如通过名称,或者有没有其他更好的方法来完成我想要的?
如果我没理解错的话,你有一些资源 R
是 "singleton"。也就是说,您的 AWS 账户中只能存在一个 R
实例。例如,您只能拥有一个名为 "foo.com" 的 aws_route53_zone。如果您将 R
作为一个模块包含在两个不同的地方,那么当您 运行 terraform apply
时,任何一个都可以创建它,而当您 运行 [=17] 时,任何一个都可以删除它=].你想避免这种情况,但你仍然需要一些方法从 R
获取输出属性(例如 aws_route53_zone
资源的 zone_id
是由 AWS 生成的,所以你可以'别猜了)。
如果是这样,那么不要使用 R
作为模块,您应该:
- 在自己的 Terraform 模板集中自行创建
R
。假设那些在/terraform/R
. 之下
配置
/terraform/R
以使用 Remote State。例如,以下是如何配置这些模板以将其远程状态存储在 S3 存储桶中(您需要按照指示填写存储桶 name/region):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
中需要的任何输出属性定义为输出变量。例如:output "zone_id" { value = "${aws_route_53.example.zone_id}" }
- 当您在
/terraform/R
中 运行terraform apply
时,它会将其 Terraform 状态(包括该输出)存储在 S3 存储桶中。 现在,在所有其他需要来自
R
的输出属性的 Terraform 模板中,您可以使用 terraform_remote_state data source. For example, let's say you had some template/terraform/foo
that needed thatzone_id
parameter to create an aws_route53_record(您需要按照指示填写存储桶 name/region):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
. 产生任何影响
有关详细信息,请查看 How to manage terraform state and Terraform: Up & Running。