尝试使用Terraform Cloud的远程状态共享功能
远程状态共享
如果需要引用分割的tfstate文件,可以使用terraform_remote_state。通过使用它,可以引用已在另一个tfstate的输出中定义的信息。
如果要限制对tfstate文件的访问权限,可以通过设置执行用户的访问权限来控制。但是,在Terraform Cloud中,除此之外还有一个名为remote state sharing的功能,它作为Terraform Cloud Workspace的一部分,提供了tfstate文件的访问控制功能。
工作区设置→常规设置可进行更改,选择与该组织中的所有工作区共享,则可以从另一个工作区引用tfstate。选择与特定工作区共享,并指定目标工作区,则可以从指定的工作区引用tfstate,而无法从未指定的工作区引用tfstate。
行动验证
实际尝试远程状态共享
验证环境
准备两个工作空间,一个称为network-workspace,另一个称为app-workspace。在network-workspace中定义与网络相关的资源,在app-workspace中定义应用程序特定的资源。同时,app-workspace会引用network-workspace的输出。
只要在网络工作区使用远程状态共享,允许从应用工作区访问,就能成功构建应用工作区的资源;如果不允许从应用工作区访问,那么期望应用工作区的资源构建会失败。
执行本地计划
使用 network-workspace 的 remote state sharing, 允许访问,并在 app-workspace 中执行 plan。
此时,能够通过terraform_remote_state成功引用 network-workspace 的输出。
(由于已经先前apply,因此在此plan中不会有差异)
$ terraform plan
data.terraform_remote_state.network: Reading...
data.terraform_remote_state.network: Read complete after 2s
data.aws_subnet.sample: Reading...
data.aws_subnet.sample: Read complete after 0s [id=subnet-xxxx]
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
接下来,在网络工作区中使用远程状态共享,在不允许访问的情况下,在应用工作区中执行计划。然后奇怪的是,计划再次成功执行了。实际上应该期望在引用 data.terraform_remote_state.network 时出现错误。
$ terraform plan
data.terraform_remote_state.network: Reading...
data.terraform_remote_state.network: Read complete after 2s
data.aws_subnet.sample: Reading...
data.aws_subnet.sample: Read complete after 0s [id=subnet-xxxx]
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
为什么可以执行?
因为将 app-workspace 的 Execution Mode 设置为 Local 并执行了 plan。
Terraform Cloud 有两种执行模式:Remote Execution Mode 和 Local Execution Mode。在 Remote Execution Mode 下,即使在本地执行了 terraform plan,也只会在 Terraform Cloud 上显示执行计划结果。
当处于本地执行模式时,Terraform Cloud只充当一个tfstate存储的角色。在此情况下,即使在本地执行terraform plan,也直接引用网络工作区的资源,因此无法进行远程状态共享。
远程计划执行
$ terraform plan
...
Terraform v1.3.6
on linux_amd64
Initializing plugins and modules...
data.terraform_remote_state.network: Reading...
╷
│ Error: Error retrieving state: forbidden
│
│ This Terraform run is not authorized to read the state of the workspace 'sample-network-workspace'.
│ Most commonly, this is required when using the terraform_remote_state data source.
│ To allow this access, 'sample-network-workspace' must configure this workspace ('sample-app-workspace')
│ as an authorized remote state consumer. For more information, see:
│ https://www.terraform.io/docs/cloud/workspaces/state.html#accessing-state-from-other-workspaces.
│
│
│
╵
Operation failed: failed running terraform plan (exit 1)
在旁边,顺利实现了通过远程状态共享进行访问控制。
另外,在 network-workspace 的 remote state sharing 中允许对 app-workspace 进行访问,并再次执行 plan。
然后,这次计划执行成功了。当然,无论是否允许访问所有工作区,结果都是一样的。
$ terraform plan
...
Terraform v1.3.6
on linux_amd64
Initializing plugins and modules...
data.terraform_remote_state.network: Reading...
data.terraform_remote_state.network: Read complete after 0s
data.aws_subnet.sample: Reading...
data.aws_subnet.sample: Read complete after 1s [id=subnet-xxxx]
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration
and found no differences, so no changes are needed.
使用tfe_outputs
如果使用Terraform Cloud,可以不使用terraform_remote_state来引用output,而是使用tfe_outputs的方法。该文档推荐使用tfe_outputs而不是terraform_remote_state的outputs。
如果使用tfe_outputs,也是一样的。
通过network-workspace的remote state sharing,允许在app-workspace中访问并执行计划将导致成功,如果不允许访问则计划会失败。
然而,失败时的错误消息不是”forbidden”而是”Unsupported attribute”。
$ terraform plan
...
Terraform v1.3.6
on linux_amd64
Initializing plugins and modules...
data.tfe_outputs.network: Reading...
data.tfe_outputs.network: Read complete after 0s [id=xxxx]
╷
│ Error: Unsupported attribute
│
│ on network.tf line 3, in data "aws_subnet" "sample":
│ 3: id = data.tfe_outputs.network.values.subnet_id
│
│ This object does not have an attribute named "subnet_id".
╵
Operation failed: failed running terraform plan (exit 1)
在访问错误时返回404而不是401是否在安全方面是正确的行为?
总结
-
- Terraform Cloudにおけるwrokspace間のリソース参照の制御にremote state sharing機能がある
-
- remote state sharingはTerraform Cloud上でterraform planを実行するRemote Execution Modeのときのみ有効
-
- ローカルでterraform planを実行するLocal Execution Modeのときはremote state sharingではアクセス制御できない
- terraform_remote_stateでもtfe_outputsでもアスセス制御は可能だがエラー時のレスポンスが異なる