Terraform
使用控制台开发配置
Terraform 控制台是一个解释器,你可以用它来评估 Terraform 表达式并探索你的 Terraform 项目的状态。该控制台有助于你开发和调试配置,尤其是在处理复杂的状态数据和 Terraform 表达式时。
Terraform 控制台命令不会修改你的状态、配置文件或资源。它提供了一种安全的方式来交互式检查你现有项目状态并评估 Terraform 表达式,然后再将它们纳入你的配置中。
在本教程中,你将把一个 S3 存储桶部署到 AWS。然后,你将使用控制台来检查你的存储桶的状态。最后,你将使用控制台来帮助开发配置,将 IAM 策略添加到你的存储桶。
先决条件
您可以使用 Terraform Community Edition 或 HCP Terraform 以相同的流程完成本教程。HCP Terraform 是一个平台,可用于管理和执行您的 Terraform 项目。它包含远程状态和执行、结构化计划输出、工作区资源摘要等功能。
选择 HCP Terraform 标签页以使用 HCP Terraform 完成本教程。
本教程假设您熟悉 Terraform 工作流程。如果您是 Terraform 新手,请先完成 入门教程。
为了完成本教程,您需要以下条件
- Terraform v1.1+ 本地安装。
- 一个配置了本地凭证的AWS 账户,这些凭证已配置为与 Terraform 一起使用。
- 安装了 AWS CLI (2.0+),并 配置了您的 AWS 账户。
克隆 本教程的示例仓库,其中包含您学习如何使用 Terraform 控制台的配置。
$ git clone https://github.com/hashicorp-education/learn-terraform-console
切换到仓库目录。
$ cd learn-terraform-console
审查配置
审查 main.tf 中的配置。 配置 AWS 提供程序后,它定义了您将在本教程中使用的 S3 存储桶。
main.tf
resource "aws_s3_bucket" "data" {
bucket_prefix = var.bucket_prefix
force_destroy = true
}
resource "aws_s3_bucket_public_access_block" "data" {
bucket = aws_s3_bucket.data.id
block_public_acls = false
block_public_policy = false
ignore_public_acls = false
restrict_public_buckets = false
}
resource "aws_s3_bucket_acl" "data" {
depends_on = [aws_s3_bucket_ownership_controls.data, aws_s3_bucket_public_access_block.data]
bucket = aws_s3_bucket.data.id
acl = "public-read"
}
该配置使用 bucket_prefix 变量定义存储桶前缀。 当您配置此配置时,Terraform 将创建一个以该前缀开头的唯一存储桶名称。 force_destroy 参数指示 Terraform 在销毁存储桶时删除存储桶内容。 aws_s3_bucket_public_access_block.data 资源允许您配置存储桶以公开访问。 最后,配置设置了一个 public-read ACL,使用 depends_on 元参数确保在访问阻止之后配置 ACL。
创建 S3 存储桶
初始化此配置。
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Using previously-installed hashicorp/aws v5.14.0
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.
应用配置以创建您的 S3 存储桶。对确认提示回复 yes。
$ terraform apply
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
<= read (data resources)
Terraform will perform the following actions:
# data.aws_s3_objects.data will be read during apply
# (config refers to values not yet known)
<= data "aws_s3_objects" "data" {
## ...
Plan: 4 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ s3_bucket_name = (known after apply)
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
aws_s3_bucket.data: Creating...
aws_s3_bucket.data: Creation complete after 2s [id=hashilearn-20230831161653870900000001]
data.aws_s3_objects.data: Reading...
aws_s3_bucket_ownership_controls.data: Creating...
aws_s3_bucket_public_access_block.data: Creating...
data.aws_s3_objects.data: Read complete after 0s [id=hashilearn-20230831161653870900000001]
aws_s3_bucket_ownership_controls.data: Creation complete after 1s [id=hashilearn-20230831161653870900000001]
aws_s3_bucket_public_access_block.data: Creation complete after 1s [id=hashilearn-20230831161653870900000001]
aws_s3_bucket_acl.data: Creating...
aws_s3_bucket_acl.data: Creation complete after 1s [id=hashilearn-20230831161653870900000001,public-read]
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.
Outputs:
s3_bucket_name = "hashilearn-20230831161653870900000001"
探索 Terraform 状态
Terraform 的控制台加载您的项目的状态,并允许您在配置中使用它们之前交互式地评估 Terraform 表达式。现在启动控制台。
$ terraform console
>
通过粘贴其资源 ID 到控制台提示符中,获取 aws_s3_bucket.data 资源的当前状态。
aws_s3_bucket.data
控制台将打印出 aws_s3_bucket.data 资源的当前状态。
{
"acceleration_status" = ""
"acl" = tostring(null)
"arn" = "arn:aws:s3:::hashilearn-20230831161653870900000001"
"bucket" = "hashilearn-20230831161653870900000001"
"bucket_domain_name" = "hashilearn-20230831161653870900000001.s3.amazonaws.com"
"bucket_prefix" = "hashilearn-"
"bucket_regional_domain_name" = "hashilearn-20230831161653870900000001.s3.us-west-2.amazonaws.com"
"cors_rule" = tolist([])
"force_destroy" = true
"grant" = toset([
{
"id" = "a85d7dd1a99eeb62382bd66710588b2d6cc3e57cfe0c6d5fb7b1261b29fe0e48"
"permissions" = toset([
"FULL_CONTROL",
])
"type" = "CanonicalUser"
"uri" = ""
},
])
"hosted_zone_id" = "Z3BJ6K6RIION7M"
"id" = "hashilearn-20230831161653870900000001"
"lifecycle_rule" = tolist([])
"logging" = tolist([])
"object_lock_configuration" = tolist([])
"object_lock_enabled" = false
"policy" = ""
"region" = "us-west-2"
"replication_configuration" = tolist([])
"request_payer" = "BucketOwner"
"server_side_encryption_configuration" = tolist([
{
"rule" = tolist([
{
"apply_server_side_encryption_by_default" = tolist([
{
"kms_master_key_id" = ""
"sse_algorithm" = "AES256"
},
])
"bucket_key_enabled" = false
},
])
},
])
"tags" = tomap(null) /* of string */
"tags_all" = tomap({
"hashicorp-learn" = "console"
})
"timeouts" = null /* object */
"versioning" = tolist([
{
"enabled" = false
"mfa_delete" = false
},
])
"website" = tolist([])
"website_domain" = tostring(null)
"website_endpoint" = tostring(null)
}
添加结构化输出
在本节中,您将创建一个输出值来描述您的存储桶,并将其转换为 JSON。输出值使您能够将有关 Terraform 项目的数据提供给基础设施自动化工具链的其他部分。为了便于操作,Terraform 可以将输出值打印为 JSON,JSON 具有机器可读性。
您集成的系统可能需要特定的 JSON 数据结构。使用控制台验证创建的 JSON 与所需的格式匹配,然后再将其添加到配置中。
首先,使用控制台创建一个包含您的 S3 存储桶的 ARN、ID 和区域的映射,然后使用 jsonencode() 函数将其编码为 JSON。
jsonencode({ arn = aws_s3_bucket.data.arn, id = aws_s3_bucket.data.id, region = aws_s3_bucket.data.region })
Terraform 控制台将打印出您创建的映射的值作为 JSON 字符串。由于控制台将 JSON 作为字符串值返回,因此它使用 \ 前缀转义了 " 字符。
"{\"arn\":\"arn:aws:s3:::hashilearn-20230831161653870900000001\",\"id\":\"hashilearn-20230831161653870900000001\",\"region\":\"us-west-2\"}"
此 JSON 与预期结构匹配,因此将以下内容添加到 outputs.tf 以定义使用此映射的输出值。
outputs.tf
output "bucket_details" {
description = "S3 bucket details."
value = {
arn = aws_s3_bucket.data.arn,
region = aws_s3_bucket.data.region,
id = aws_s3_bucket.data.id
}
}
Terraform 控制台会锁定您的项目状态文件,因此在控制台运行时您无法计划或应用更改。使用 <Ctrl-D> 或 exit 退出控制台。
exit
应用更改并使用 yes 回应确认提示。Terraform 现在将显示您的新输出值。
$ terraform apply
## ...
Changes to Outputs:
+ bucket_details = {
+ arn = "arn:aws:s3:::hashilearn-20230831161653870900000001"
+ id = "hashilearn-20230831161653870900000001"
+ region = "us-west-2"
}
You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.
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:
bucket_details = {
"arn" = "arn:aws:s3:::hashilearn-20230831161653870900000001"
"id" = "hashilearn-20230831161653870900000001"
"region" = "us-west-2"
}
s3_bucket_name = "hashilearn-20230831161653870900000001"
以 JSON 格式输出存储桶的详细信息。
$ terraform output -json bucket_details
{"arn":"arn:aws:s3:::hashilearn-20230831161653870900000001","id":"hashilearn-20230831161653870900000001","region":"us-west-2"}
当您在 Terraform 输出命令中包含 -json 标志时,Terraform 会将映射和列表转换为等效的 JSON 数据结构。
设置存储桶策略
存储桶策略允许您控制对 S3 存储桶及其内容的访问权限。
在本节中,您将应用一个策略到您的存储桶,该策略允许对存储桶中的对象进行公共读取访问。
添加存储桶策略
将策略添加到您的存储桶。示例仓库中的 bucket_policy.json 文件包含一个基于 AWS 示例 的策略。
bucket_policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"<BUCKET_ARN>/*"
]
}
]
}
AWS 策略定义为 JSON 文档。因此,aws_bucket_policy 资源需要 JSON 字符串格式的策略。使用 HCL 动态生成策略 JSON 字符串可以利用 HCL 的优势,例如语法检查和字符串插值。
使用 Terraform 控制台将策略文档转换为 HCL,然后再将其合并到您的配置中。使用 echo 将命令传递给控制台。
$ echo 'jsondecode(file("bucket_policy.json"))' | terraform console
{
"Statement" = [
{
"Action" = [
"s3:GetObject",
"s3:GetObjectVersion",
]
"Effect" = "Allow"
"Principal" = "*"
"Resource" = [
"<BUCKET_ARN>/*",
]
"Sid" = "PublicRead"
},
]
"Version" = "2012-10-17"
}
file() 函数 将文件内容加载到字符串中,而 jsondecode() 将字符串从 JSON 转换为 HCL 映射。
将以下策略资源(基于前一个输出)添加到 main.tf。
main.tf
resource "aws_s3_bucket_policy" "public_read" {
bucket = aws_s3_bucket.data.id
policy = jsonencode({
"Statement" = [
{
"Action" = [
"s3:GetObject",
"s3:GetObjectVersion",
]
"Effect" = "Allow"
"Principal" = "*"
"Resource" = [
"${aws_s3_bucket.data.arn}/*",
]
"Sid" = "PublicRead"
},
]
"Version" = "2012-10-17"
})
}
aws_s3_bucket_policy.public_read 资源根据在 bucket_policy.json 中定义的策略配置存储桶的策略。它将 <BUCKET_ARN> 占位符替换为对存储桶 ARN 的引用。最后,它使用 jsondecode() 函数将策略转换回 JSON 以供 AWS 使用。
现在,应用此配置。使用 yes 回应确认提示以更新您的存储桶策略。
$ terraform apply
aws_s3_bucket.data: Refreshing state... [id=hashilearn-20230831161653870900000001]
aws_s3_bucket_ownership_controls.data: Refreshing state... [id=hashilearn-20230831161653870900000001]
aws_s3_bucket_public_access_block.data: Refreshing state... [id=hashilearn-20230831161653870900000001]
data.aws_s3_objects.data: Reading...
aws_s3_bucket_acl.data: Refreshing state... [id=hashilearn-20230831161653870900000001,public-read]
data.aws_s3_objects.data: Read complete after 0s [id=hashilearn-20230831161653870900000001]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_s3_bucket_policy.public_read will be created
+ resource "aws_s3_bucket_policy" "public_read" {
+ bucket = "hashilearn-20230831161653870900000001"
+ id = (known after apply)
+ policy = jsonencode(
{
+ Statement = [
+ {
+ Action = [
+ "s3:GetObject",
+ "s3:GetObjectVersion",
]
+ Effect = "Allow"
+ Principal = "*"
+ Resource = [
+ "arn:aws:s3:::hashilearn-20230831161653870900000001/*",
]
+ Sid = "PublicRead"
},
]
+ Version = "2012-10-17"
}
)
}
Plan: 1 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
aws_s3_bucket_policy.public_read: Creating...
aws_s3_bucket_policy.public_read: Creation complete after 1s [id=hashilearn-20230831161653870900000001]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
bucket_details = {
"arn" = "arn:aws:s3:::hashilearn-20230831161653870900000001"
"id" = "hashilearn-20230831161653870900000001"
"region" = "us-west-2"
}
s3_bucket_name = "hashilearn-20230831161653870900000001"
清理你的基础设施
删除您在此教程中创建的基础设施。 使用 yes 回复确认提示。
$ terraform destroy
## ...
Terraform will perform the following actions:
# aws_s3_bucket.data will be destroyed
- resource "aws_s3_bucket" "data" {
- arn = "arn:aws:s3:::hashilearn-20230831161653870900000001" -> null
- bucket = "hashilearn-20230831161653870900000001" -> null
## ...
Plan: 0 to add, 0 to change, 5 to destroy.
Changes to Outputs:
- bucket_details = {
- arn = "arn:aws:s3:::hashilearn-20230831161653870900000001"
- id = "hashilearn-20230831161653870900000001"
- region = "us-west-2"
} -> null
- s3_bucket_name = "hashilearn-20230831161653870900000001" -> null
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
aws_s3_bucket_policy.public_read: Destroying... [id=hashilearn-20230831161653870900000001]
aws_s3_bucket_acl.data: Destroying... [id=hashilearn-20230831161653870900000001,public-read]
aws_s3_bucket_acl.data: Destruction complete after 0s
aws_s3_bucket_ownership_controls.data: Destroying... [id=hashilearn-20230831161653870900000001]
aws_s3_bucket_public_access_block.data: Destroying... [id=hashilearn-20230831161653870900000001]
aws_s3_bucket_policy.public_read: Destruction complete after 0s
aws_s3_bucket_public_access_block.data: Destruction complete after 0s
aws_s3_bucket_ownership_controls.data: Destruction complete after 1s
aws_s3_bucket.data: Destroying... [id=hashilearn-20230831161653870900000001]
aws_s3_bucket.data: Destruction complete after 0s
Destroy complete! Resources: 5 destroyed.
如果你在本教程中使用 HCP Terraform,在销毁你的资源后,请从你的 HCP Terraform 组织中删除 learn-terraform-console 工作区。
下一步
在本教程中,你使用了 Terraform 控制台来探索你的状态并在配置中使用它们之前评估 Terraform 表达式。Terraform 控制台可以帮助你开发和调试你的 Terraform 配置。
尝试以下资源以了解有关创建 Terraform 配置的更多信息。
请参阅 Terraform 状态教程,以了解有关管理 Terraform 状态的更多信息。
了解如何 使用和创建 Terraform 模块。
了解如何 针对特定资源进行更改。