Terraform
从 Terraform 输出数据
Terraform 输出值允许你导出关于你的资源结构化数据。你可以使用这些数据来使用自动化工具配置你的基础设施的其他部分,或者作为另一个 Terraform 工作区的的数据源。输出也是将子模块的数据暴露给根模块的方式。
在本教程中,你将使用 Terraform 在 AWS 上部署应用程序基础设施,并使用输出获取有关资源的信息。然后,你将使用 sensitive 标志来降低意外泄露数据库管理员用户名和密码的风险。你还将学习如何将输出格式化为机器可读的 JSON。
先决条件
您可以使用 Terraform Community Edition 或 HCP Terraform 以相同的流程完成本教程。HCP Terraform 是一个平台,可用于管理和执行您的 Terraform 项目。它包含远程状态和执行、结构化计划输出、工作区资源摘要等功能。
选择 HCP Terraform 标签页以使用 HCP Terraform 完成本教程。
本教程假定您熟悉 Terraform 工作流程。如果您是 Terraform 新手,请先完成 入门系列。
为了完成本教程,您需要以下条件
- 本地安装的 Terraform v1.2+ 。
- 一个配置了本地凭证的AWS 账户,这些凭证已配置为与 Terraform 一起使用。
创建基础设施
克隆 本教程的示例仓库,其中包含一个 Web 应用程序的 Terraform 配置,包括 VPC、负载均衡器、EC2 实例和数据库。
$ git clone https://github.com/hashicorp-education/learn-terraform-outputs
切换到仓库目录。
$ cd learn-terraform-outputs
初始化此配置。
$ terraform init
Initializing the backend...
##...
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
现在应用配置。回复 yes 以确认操作。
$ terraform apply
##...
Plan: 46 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
##...
Apply complete! Resources: 46 added, 0 changed, 0 destroyed.
输出 VPC 和负载均衡器信息
你可以在 Terraform 配置文件中的任何位置添加输出声明。但是,我们建议将它们定义在一个名为 outputs.tf 的单独文件中,以便用户更容易理解你的配置并查看其预期输出。
将一个块添加到 outputs.tf 以显示 VPC 的 ID。
outputs.tf
output "vpc_id" {
description = "ID of project VPC"
value = module.vpc.vpc_id
}
虽然 description 参数是可选的,但你应该在所有输出声明中包含它,以记录输出的意图和内容。
你可以使用 Terraform 表达式 的结果作为输出的值。将以下定义添加到 outputs.tf。
outputs.tf
output "lb_url" {
description = "URL of load balancer"
value = "http://${module.elb_http.elb_dns_name}/"
}
output "web_server_count" {
description = "Number of web servers provisioned"
value = length(module.ec2_instances.instance_ids)
}
The lb_url 输出使用 字符串插值 来从负载均衡器的域名创建 URL。 web_server_count 输出使用 length() 函数 来计算附加到负载均衡器的实例数量。
Terraform 将输出值存储在配置的状态文件中。为了查看这些输出,你需要通过应用这个新的配置来更新状态,即使基础设施不会改变。对确认提示回复 yes。
$ terraform apply
random_string.lb_id: Refreshing state... [id=5YI]
module.vpc.aws_vpc.this[0]: Refreshing state... [id=vpc-004c2d1ba7394b3d6]
## ...
Plan: 0 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ lb_url = "http://lb-5YI-project-alpha-dev-2144336064.us-east-1.elb.amazonaws.com/"
+ vpc_id = "vpc-004c2d1ba7394b3d6"
+ web_server_count = 4
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
lb_url = "http://lb-5YI-project-alpha-dev-2144336064.us-east-1.elb.amazonaws.com/"
vpc_id = "vpc-004c2d1ba7394b3d6"
web_server_count = 4
查询输出
在创建输出后,使用 terraform output 命令来查询所有输出。
$ terraform output
lb_url = "http://lb-5YI-project-alpha-dev-2144336064.us-east-1.elb.amazonaws.com/"
vpc_id = "vpc-004c2d1ba7394b3d6"
web_server_count = 4
接下来,通过名称查询单个输出。
$ terraform output lb_url
"http://lb-5YI-project-alpha-dev-2144336064.us-east-1.elb.amazonaws.com/"
从版本 0.14 开始,Terraform 默认会将字符串输出包装在引号中。在查询指定的输出时,可以使用 -raw 标志以获得机器可读的格式。
$ terraform output -raw lb_url
http://lb-5YI-project-alpha-dev-2144336064.us-east-1.elb.amazonaws.com/
使用带有 -raw 标志的 lb_url 输出值来 cURL 负载均衡器并验证响应。
$ curl $(terraform output -raw lb_url)
<html><body><div>Hello, world!</div></body></html>
如果你使用的是 HCP Terraform,你还可以在你的工作区的概述页面上找到配置输出的表格。
隐藏敏感输出
你可以将 Terraform 输出指定为敏感。Terraform 将隐藏敏感输出的值,以避免意外地将其打印到控制台。使用敏感输出将敏感数据从你的配置共享给其他 Terraform 模块、自动化工具或 HCP Terraform 工作区。
Terraform 在计划、应用或销毁你的配置时,或者当你查询所有输出时,将隐藏敏感输出。Terraform 不会在其他情况下隐藏敏感输出,例如当你通过名称查询特定输出、以 JSON 格式查询所有输出或在根模块中使用子模块的输出时。
将以下输出块添加到你的 outputs.tf 文件中。请注意,sensitive 属性设置为 true。
outputs.tf
output "db_username" {
description = "Database administrator username"
value = aws_db_instance.database.username
sensitive = true
}
output "db_password" {
description = "Database administrator password"
value = aws_db_instance.database.password
sensitive = true
}
应用此更改将这些输出添加到你的状态文件,并对确认提示回复 yes。
$ terraform apply
random_string.lb_id: Refreshing state... [id=5YI]
module.vpc.aws_vpc.this[0]: Refreshing state... [id=vpc-004c2d1ba7394b3d6]
## ...
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
db_password = <sensitive>
db_username = <sensitive>
lb_url = "http://lb-5YI-project-alpha-dev-2144336064.us-east-1.elb.amazonaws.com/"
vpc_id = "vpc-004c2d1ba7394b3d6"
web_server_count = 4
请注意,Terraform 隐藏了标记为敏感的输出的值。
使用 terraform output 通过名称查询数据库密码,并注意 Terraform 在你指定输出名称时不会隐藏该值。
$ terraform output db_password
"notasecurepassword"
Terraform 将所有输出值(包括标记为敏感的输出)作为纯文本存储在你的状态文件中。
使用 grep 命令查看你的状态文件中敏感输出的值。
$ grep --after-context=10 outputs terraform.tfstate
"outputs": {
"db_password": {
"value": "notasecurepassword",
"type": "string",
"sensitive": true
},
"db_username": {
"value": "admin",
"type": "string",
"sensitive": true
},
输出的 sensitive 参数可以帮助避免意外暴露这些值。但是,你仍然必须保护你的 Terraform 状态以避免暴露这些值。
生成机器可读的输出
Terraform CLI 输出设计为由人类解析。为了获得用于自动化的机器可读格式,请对 JSON 格式的输出 使用 -json 标志。
$ terraform output -json
{
"db_password": {
"sensitive": true,
"type": "string",
"value": "notasecurepassword"
},
"db_username": {
"sensitive": true,
"type": "string",
"value": "admin"
},
"lb_url": {
"sensitive": false,
"type": "string",
"value": "http://lb-5YI-project-alpha-dev-2144336064.us-east-1.elb.amazonaws.com/"
},
"vpc_id": {
"sensitive": false,
"type": "string",
"value": "vpc-004c2d1ba7394b3d6"
},
"web_server_count": {
"sensitive": false,
"type": "number",
"value": 4
}
}
Terraform 不使用 `-json` 选项来隐藏敏感的输出值,因为它假定自动化工具将使用这些输出。
清理你的基础设施
在继续之前,请销毁本教程中创建的基础设施,以避免产生不必要的费用。 确保对确认提示回复 yes。
$ terraform destroy
##...
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
##...
Apply complete! Resources: 0 added, 0 changed, 46 destroyed.
如果在本教程中使用了 HCP Terraform,请在销毁资源后,从你的 HCP Terraform 组织中删除 learn-terraform-outputs 工作区。
下一步
在本教程中,你使用了 Terraform 输出来查询有关你的基础设施的数据。 Terraform 输出允许你在 Terraform 配置之间以及与其他工具和自动化之间共享数据。 输出也是将子模块的数据共享到你的配置的根模块的唯一方法。
现在你已经知道如何使用 Terraform 输出,请查看以下资源以获取更多信息。
- 阅读 Terraform 输出文档。
- 管理 状态中的敏感数据。
- 使用和创建 Terraform 模块.
- 使用运行触发器连接 HCP Terraform 工作区,并使用一个工作区的输出配置另一个工作区。