[Terraform] 请参阅不同 tfstate 中描述的资源信息

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


编写 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。

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

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,350
X Facebook Hatena书签 口袋

这篇文章的作者

关于作者

寺冈由纪

他于 2016 年加入 Beyond 公司,目前已是第六年
担任 MSP(托管服务提供商)的基础设施工程师,负责故障排除以及
使用 AWS 等公有云设计和构建基础设施。近期,他开始

使用 HashiCorp 的 Terraform 和 Packer 等工具,用于构建和运维
Docker 和 Kubernetes 等容器基础设施的自动化流程。此外,他还扮演着技术推广者的角色,经常在外部学习小组和研讨会上发表演讲。

・GitHub
https://github.com/nezumisannn

・讲述历史
https://github.com/nezumisannn/my-profile

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

・认证:
AWS认证解决方案架构师 - 助理级、
Google Cloud专业云架构师