如何使用 Terraform 重新部署 docker-compose 堆栈?
How can I redeploy a docker-compose stack with terraform?
我使用 terraform 配置一个 GCE 实例,它 运行 是一个 docker-compose 堆栈。 docker-compose 堆栈引用带有标签的图像,我希望能够在标签更改时重新运行 docker-compose up
,以便新版本的服务可以 运行。
目前,我在我的地形文件中执行以下操作:
provisioner "file" {
source = "training-server/docker-compose.yml"
destination = "/home/curry/docker-compose.yml"
connection {
type = "ssh"
user = "curry"
host = google_compute_address.training-address.address
private_key = file(var.private_key_file)
}
}
provisioner "remote-exec" {
inline = [
"IMAGE_ID=${var.image_id} docker-compose -f /home/curry/docker-compose.yml up -d"
]
connection {
type = "ssh"
user = "root"
host = google_compute_address.training-address.address
private_key = file(var.private_key_file)
}
}
但由于各种原因这是错误的:
- 根据地形 documentation
,供给者有些不受欢迎
- 如果
image_id
更改这不会被 terraform 视为配置更改,因此它不会 运行 供应商
我想要的是将我的应用程序堆栈视为一种资源,以便当它的一个属性发生变化时,例如。 image_id
,资源已重新创建,但 VM 实例本身未创建。
我如何使用 Terraform 做到这一点?或者还有其他更好的方法吗?
Terraform 有一个 Docker provider,如果您想使用 Terraform 来管理您的容器堆栈,那可能是正确的工具。但是,使用它基本上需要将您的 Compose 文件转换为 Terraform 语法。
我更习惯于使用 Terraform 来管理基础设施的拆分——例如,设置 EC2 实例及其网络设置——但实际上使用 Ansible、Chef 或 Salt Stack 等其他工具 运行软件就在他们身上。然后要更新软件(Docker 容器),您需要更新配置管理工具的设置,说明您想要哪个版本(Docker 图像标签),然后重新运行。
一个可能有用的技巧是使用 null resource ,它会让您 "reprovision the resource" 每当图像 ID 更改时:
resource "null_resource" "docker_compose" {
triggers = {
image_id = "${var.image_id}"
}
provisioner "remote_exec" {
...
}
}
如果您想走全 Terraform 路线,理论上您可以编写一个 Terraform 配置,例如
provider "docker" {
host = "ssh://root@${google_compute_address.training-address.address}"
# (where do its credentials come from?)
}
resource "docker_image" "myapp" {
name = "myapp:${var.image_id}"
}
resource "docker_container" "myapp" {
name = "myapp"
image = "${docker_image.myapp.latest}"
}
但您必须将整个 Docker Compose 配置转换为此语法,并进行设置,以便开发人员可以选择在本地 运行 并复制 Compose 功能,例如default
网络,等等。我不觉得这在实践中通常是这样做的。
我使用 terraform 配置一个 GCE 实例,它 运行 是一个 docker-compose 堆栈。 docker-compose 堆栈引用带有标签的图像,我希望能够在标签更改时重新运行 docker-compose up
,以便新版本的服务可以 运行。
目前,我在我的地形文件中执行以下操作:
provisioner "file" {
source = "training-server/docker-compose.yml"
destination = "/home/curry/docker-compose.yml"
connection {
type = "ssh"
user = "curry"
host = google_compute_address.training-address.address
private_key = file(var.private_key_file)
}
}
provisioner "remote-exec" {
inline = [
"IMAGE_ID=${var.image_id} docker-compose -f /home/curry/docker-compose.yml up -d"
]
connection {
type = "ssh"
user = "root"
host = google_compute_address.training-address.address
private_key = file(var.private_key_file)
}
}
但由于各种原因这是错误的:
- 根据地形 documentation ,供给者有些不受欢迎
- 如果
image_id
更改这不会被 terraform 视为配置更改,因此它不会 运行 供应商
我想要的是将我的应用程序堆栈视为一种资源,以便当它的一个属性发生变化时,例如。 image_id
,资源已重新创建,但 VM 实例本身未创建。
我如何使用 Terraform 做到这一点?或者还有其他更好的方法吗?
Terraform 有一个 Docker provider,如果您想使用 Terraform 来管理您的容器堆栈,那可能是正确的工具。但是,使用它基本上需要将您的 Compose 文件转换为 Terraform 语法。
我更习惯于使用 Terraform 来管理基础设施的拆分——例如,设置 EC2 实例及其网络设置——但实际上使用 Ansible、Chef 或 Salt Stack 等其他工具 运行软件就在他们身上。然后要更新软件(Docker 容器),您需要更新配置管理工具的设置,说明您想要哪个版本(Docker 图像标签),然后重新运行。
一个可能有用的技巧是使用 null resource ,它会让您 "reprovision the resource" 每当图像 ID 更改时:
resource "null_resource" "docker_compose" {
triggers = {
image_id = "${var.image_id}"
}
provisioner "remote_exec" {
...
}
}
如果您想走全 Terraform 路线,理论上您可以编写一个 Terraform 配置,例如
provider "docker" {
host = "ssh://root@${google_compute_address.training-address.address}"
# (where do its credentials come from?)
}
resource "docker_image" "myapp" {
name = "myapp:${var.image_id}"
}
resource "docker_container" "myapp" {
name = "myapp"
image = "${docker_image.myapp.latest}"
}
但您必须将整个 Docker Compose 配置转换为此语法,并进行设置,以便开发人员可以选择在本地 运行 并复制 Compose 功能,例如default
网络,等等。我不觉得这在实践中通常是这样做的。