[Terraform] 参考不同tfstates描述的资源信息

我叫寺冈,是一名基础设施工程师。


编写 Terraform HCL 时,terraform_remote_state 是
一个很有用的这次我想介绍一下它。

terraform_remote_state 是什么?

你想参考不同 tfstates 中描述的资源信息
时,这是一个方便的数据源

Terraform
使用 terraform apply 进行部署时
创建的资源信息

使用 Terraform 构建基础设施时,
如果您有多个环境(启动/生产/开发等),

则通常的做法是为每个环境单独设置 tfstate,这样 terraform apply 就不会影响其他环境

如果将 tfstate 分离出来,

您可能需要参考
堡垒机环境中创建的资源信息在这种情况下,“terraform_remote_state” 就很有用了。

■何时使用

以下是使用 AWS 的示例。

如果要通过堡垒服务器使用 SSH 连接到另一台服务器,
如何使用 Terraform 创建安全组和规则?
首先,需要为堡垒服务器创建一个 VPC 以及安全组和规则。

堡垒.tf

Terraform { 后端 "s3" { 存储桶 = "terraform-tfstate" 键 = "terraform-b​​log/bastion.tfstate" 区域 = "ap-northeast-1" } } 资源 "aws_vpc" "堡垒机" { cidr_block = "10.0.0.0/16" enable_dns_hostnames = true tags { 名称 = "vpc-bastion" } } 资源 "aws_security_group" "堡垒机" { 名称 = "bastion-sg" description = "堡垒机" vpc_id = "${aws_vpc.bastion.id}" tags { 名称 = "bastion-sg" } } 资源 "aws_security_group_rule" "prod_sg_rule" { security_group_id = "${aws_security_group.bastion.id}" type = "ingress" from_port = "22" to_port = "22" protocol = "tcp" cidr_blocks = "XXX.XXX.XXX.XXX" }

在后端设置中,tfstate 以 bastion.tfstate 的名称存储在 S3 中,
但这没问题,因为它只添加了一个 VPC 和安全组,以及一条允许来自特定 IP 地址的规则。
那么,堡垒机“连接侧”的设置又该如何呢?

production.tf

Terraform { 后端 "s3" { 存储桶 = "terraform-tfstate" 键 = "terraform-b​​log/prod.tfstate" 区域 = "ap-northeast-1" } } 资源 "aws_vpc" "prod" { cidr_block = "10.0.0.0/16" enable_dns_hostnames = true tags { 名称 = "vpc-prod" } } 资源 "aws_security_group" "prod" { 名称 = "prod-sg" 描述 = "用于生产服务器" vpc_id = "${aws_vpc.prod.id}" tags { 名称 = "prod-sg" } } 资源 "aws_security_group_rule" "prod_sg_rule" { security_group_id = "${aws_security_group.prod.id}" type = "ingress" from_port = "22" to_port = "22" protocol = " "tcp" source_security_group_id = "${我应该指定什么???}" }

如果要允许堡垒机服务器进行 SSH 连接,
则需要允许堡垒机的安全组进行访问,因此
需要在 source_security_group_id 中指定堡垒机的安全组的 ID。

但是,由于后端描述将堡垒服务器和 tfstate 分开,因此
您将无法在此状态下引用安全组 ID。

■使用方法

既然我知道这不可能,我想能够引用它。
首先,您需要在 bastion.tf 文件中添加一个输出设置。

堡垒.tf

Terraform { 后端 "s3" { 存储桶 = "terraform-tfstate" 键 = "terraform-b​​log/bastion.tfstate" 区域 = "ap-northeast-1" } } 资源 "aws_vpc" "堡垒机" { cidr_block = "10.0.0.0/16" enable_dns_hostnames = true tags { 名称 = "vpc-bastion" } } 资源 "aws_security_group" "堡垒机" { 名称 = "bastion-sg" description = "堡垒机" vpc_id = "${aws_vpc.bastion.id}" tags { 名称 = "bastion-sg" } } 资源 "aws_security_group_rule" "prod_sg_rule" { security_group_id = "${aws_security_group.bastion.id}" type = "ingress" from_port = "22" to_port = "22" protocol = "tcp" cidr_blocks = "XXX.XXX.XXX.XXX" } ## 添加输出 "security_group_id" { value = "${aws_security_group.bastion.id}" }

如果要引用不同 tfstate 中的值,
必须先输出要引用的值。
在本例中,我们要引用堡垒机安全组的 ID,因此
我们将输出 aws_security_group.bastion.id。

在这种状态下,您可以从 production.tf 中引用 terraform_remote_state 中的值。

production.tf

Terraform { 后端 "s3" { 存储桶 = "terraform-tfstate" 键 = "terraform-b​​log/prod.tfstate" 区域 = "ap-northeast-1" } } 资源 "aws_vpc" "prod" { cidr_block = "10.0.0.0/16" enable_dns_hostnames = true tags { 名称 = "vpc-prod" } } 资源 "aws_security_group" "prod" { 名称 = "prod-sg" 描述 = "用于生产服务器" vpc_id = "${aws_vpc.prod.id}" tags { 名称 = "prod-sg" } } 资源 "aws_security_group_rule" "prod_sg_rule" { security_group_id = "${aws_security_group.prod.id}" type = "ingress" from_port = "22" to_port = "22" protocol = " "tcp" source_security_group_id = "${data.terraform_remote_state.bastion.security_group_id}" } ## 添加数据 "terraform_remote_state" "bastion" { backend = "s3" config { bucket = "terraform-tfstate" key = "terraform-b​​log/bastion.tfstate" region = "ap-northeast-1" } }

使用 terraform_remote_state 数据源
读取存储在 S3 中的堡垒机的 tfstate。
可以通过输出中指定的名称引用该值,因此
为 source_security_group_id 指定的值为
data.terraform_remote_state.bastion.security_group_id。

■概要

由于 terraform_remote_state 使用频率很高,所以值得记住。
现在分离 tfstate 已经没有问题了!

如果您觉得这篇文章有帮助,请点赞!
1
加载中...
1 票,平均:1.00 / 11
11,307
X Facebook 哈特纳书签 口袋

写这篇文章的人

关于作者

寺冈由纪

于 2016 年加入 Beyond,目前是他担任基础设施工程师
MSP 的第六个年头,他负责排除故障,同时
使用 AWS 等公共云设计和构建基础设施。
最近,我
一直在使用 Terraform 和 Packer 等 Hashicorp 工具作为构建 Docker 和 Kubernetes 等容器基础设施以及自动化操作的一部分,并且我
还扮演了在外部学习小组和研讨会上发言的传播者的角色。

・GitHub
https://github.com/nezumisannn

・演示历史
https://github.com/nezumisannn/my-profile

・演示材料(SpeakerDeck)
https://speakerdeck.com/nezumisannn

・认证:
AWS认证解决方案架构师-
谷歌云专业云架构师