[Terraform] 参考不同tfstates描述的资源信息
我叫寺冈,是一名基础设施工程师。
有一个名为 terraform_remote_state 的数据源,
在编写 Terraform HCL 时非常有用这次我想介绍一下这个。
■什么是terraform_remote_state?
我想参考不同tfstates中描述的资源信息。
在这种情况下,这是一个方便使用的数据源。
首先,Terraform
有一个名为 tfstate 的文件,用于记录使用 Terraform Apply 部署时
在使用 Terraform 构建基础设施时,
如果存在多个环境(垫脚石、生产、开发等),
那么为每个环境分离 tfstate 是一条黄金法则,这样 terraform apply 就不会影响其他环境
当tfstate分离时,
,可能需要参考
在垫脚石环境中创建的资源信息在这种情况下,“terraform_remote_state”很有用。
■什么时候应该使用它?
对于 AWS,下面给出了一个示例。
如果我们假设通过 SSH 连接到服务器时,我们将通过垫脚石服务器,那么
如果我们尝试在 Terraform 中创建安全组和规则会发生什么?
首先,我想我们会为垫脚石服务器创建一个VPC和安全组+规则。
堡垒.tf
terraform {后端“s3”{bucket =“terraform-tfstate”key =“terraform-blog/bastion.tfstate”区域=“ap-northeast-1”}}资源“aws_vpc”“堡垒”{cidr_block =“10.0.0.0” /16" enable_dns_hostnames = true 标签 { Name = "vpc-bastion" } } 资源 "aws_security_group" "bastion" { name = "bastion-sg" 描述 = "对于堡垒服务器" vpc_id = "${aws_vpc.bastion.id} " 标签 { Name = "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" 协议 = " tcp" cidr_blocks = "XXX.XXX.XXX.XXX" }
在后端设置中,tfstate 被放置在 S3 中,名称为 bastion.tfstate,但这
没关系,因为我们只是从特定 IP 添加 VPC 和安全组 + 权限规则。
那么,垫脚石的“连接侧”应该如何设置呢?
生产.tf
terraform {后端“s3”{bucket =“terraform-tfstate”key =“terraform-blog/prod.tfstate”区域=“ap-northeast-1”}}资源“aws_vpc”“prod”{cidr_block =“10.0.0.0” /16" enable_dns_hostnames = true 标签 { Name = "vpc-prod" } } 资源 "aws_security_group" "prod" { name = "prod-sg" 描述 = "用于生产服务器" vpc_id = "${aws_vpc.prod.id} " 标签 { Name = "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" 协议 = " tcp" source_security_group_id = "${我应该指定什么?}"
如果要允许来自springboard服务器的SSH连接,则
需要允许来自springboard安全组的访问,因此
需要在source_security_group_id中指定springboard安全组ID。
但由于后台描述中的steppingstone server和tfstate是分开的
,所以无法原样引用安全组ID。
■使用方法
当我发现不可能时,我希望能够参考它。
首先,您需要在 bastion.tf 端添加输出设置。
堡垒.tf
terraform {后端“s3”{bucket =“terraform-tfstate”key =“terraform-blog/bastion.tfstate”区域=“ap-northeast-1”}}资源“aws_vpc”“堡垒”{cidr_block =“10.0.0.0” /16" enable_dns_hostnames = true 标签 { Name = "vpc-bastion" } } 资源 "aws_security_group" "bastion" { name = "bastion-sg" 描述 = "用于堡垒服务器" vpc_id = "${aws_vpc.bastion.id} " 标签 { Name = "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" 协议 = " 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 的值。
生产.tf
terraform {后端“s3”{bucket =“terraform-tfstate”key =“terraform-blog/prod.tfstate”区域=“ap-northeast-1”}}资源“aws_vpc”“prod”{cidr_block =“10.0.0.0” /16" enable_dns_hostnames = true 标签 { Name = "vpc-prod" } } 资源 "aws_security_group" "prod" { name = "prod-sg" 描述 = "用于生产服务器" vpc_id = "${aws_vpc.prod.id} " 标签 { Name = "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" 协议 = " 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" 区域 = "ap-northeast-1" } }
使用数据源 terraform_remote_state
加载保存在 S3 中的垫脚石 tfstate
该值可以通过输出中指定的名称引用,因此
为 source_security_group_id 指定的值
将为 data.terraform_remote_state.bastion.security_group_id。
■概要
terraform_remote_state 使用得相当频繁,因此值得记住。
就算你把tfstate跟这个分开也没有问题!