[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-blog/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-blog/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-blog/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-blog/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-blog/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