设置
我正在使用存储在外部云存储中的远程状态文件,并且我的 Terraform 资源被拆分成不同的模块。我只想在图像模块中下载一次基本图像,并希望在我想要创建的每个域的定义中引用它们。域和图像文件均由 libvirt 的第三方 Terraform 提供程序定义。状态文件按组件分开,因为 Terraform 希望在terraform apply
一次为各个组件设置所需状态时销毁资源。
https://github.com/dmacvicar/terraform-provider-libvirt
Terraform 代码
图片/main.tf
resource "libvirt_volume" "centos-7" {
name = "centos-7.qcow2"
pool = "default"
source = "http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2"
format = "qcow2"
}
堡垒主机/main.tf
# Create a volume to attach to the "mgmt_bastion" domain as main disk
resource "libvirt_volume" "mgmt_bastion_volume" {
name = "mgmt_bastion.qcow2"
base_volume_id = "${libvirt_volume.centos-7.id}"
}
地形状态
libvirt_volume.centos-7:
id = /var/lib/libvirt/images/centos-7.qcow2
format = qcow2
name = centos-7.qcow2
pool = default
size = 8589934592
source = http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2
问题
当我在相同的 terraform 配置中定义资源时,资源工作正常。但是每个域都希望下载相同的基础映像。状态文件是分开的,因此构建一个域不会删除未在特定 main.tf 文件中定义的其他域/资源。当我在不同的模块中定义图像时,当然我无法引用它:
Error: resource 'libvirt_volume.mgmt_bastion_volume' config: unknown resource 'libvirt_volume.centos-7' referenced in variable libvirt_volume.centos-7.id
可能的解决方案/我尝试过的方法
当使用像 AWS 这样的云提供商时,通常这不是问题,可以通过配置数据源和过滤来解决。 https://www.terraform.io/docs/configuration/data-sources.html
然而使用 libvirt 提供程序需要一些额外的考虑。
我知道如何terraform show
检查另一个组件的当前地形状态文件。在那里我可以从 shell 中读取 ID。
也许我只需要运行一个外部脚本,以便用 id 填充变量,然后可以在 terraform dsl 中重复使用该变量。
也许我必须对 ID 进行硬编码。似乎我可以使用路径来实现这一点:/var/lib/libvirt/images/centos-7.qcow2
但是我不喜欢硬编码,而且我的测试表明,一些图像还包含 uuid 来引用它们:
/var/lib/libvirt/images/commoninit.iso;5a79dcf5-4420-5169-b9f4-5340e9904944
因此,当下次资源不那么容易识别时,我希望学习一种更好的方法来解决这个问题。
编辑:
硬编码路径不起作用:
libvirt_volume.mgmt_bastion_volume: Creating...
base_volume_id: "" => "centos-7.qcow2"
name: "" => "mgmt_bastion.qcow2"
pool: "" => "default"
size: "" => "<computed>"
Failed to save state: Resource not found
适用于图像文件的完整路径和部分路径。
问题
- 如何获取已下载文件的 ID,以便将其指定为 CoW 后备卷?(无需手动查看状态文件并对 ID 进行硬编码)
- 有没有更好的方法可以在不同的 Terraform 定义中引用相同的云映像而无需再次下载?毕竟,我想引用相同的基础映像以节省空间的方式生成大量 libvirt 域。
答案1
经过进一步调查,我找到了我自己的问题的答案:
必须base_volume_id
与目标卷的完整路径一起使用(默认池的路径为:/var/lib/libvirt/images)。
状态文件包含用“/”分隔的组件名称。这导致在云存储上写入状态文件时出现问题。我发现