Docker compose 如何使用terraform重新部署docker compose堆栈?

Docker compose 如何使用terraform重新部署docker compose堆栈?,docker-compose,google-compute-engine,terraform,Docker Compose,Google Compute Engine,Terraform,我使用terraform来配置一个运行docker compose堆栈的GCE实例。docker compose堆栈引用带有标记的图像,我希望能够在标记更改时重新运行docker compose up,以便运行新版本的服务。 目前,我在terraform文件中执行以下操作: provisioner "file" { source = "training-server/docker-compose.yml" destination = "/home/curry/doc

我使用terraform来配置一个运行docker compose堆栈的GCE实例。docker compose堆栈引用带有标记的图像,我希望能够在标记更改时重新运行
docker compose up
,以便运行新版本的服务。 目前,我在terraform文件中执行以下操作:

  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)
    }
  }
但这是错误的,原因有很多:

  • 根据地形,供给者有点不受欢迎
  • 如果
    image\u id
    发生更改,terraform不会将此视为配置的更改,因此不会运行provisioners
  • 我想把我的应用程序栈看作一个资源,这样当它的一个属性改变时,例如<代码> IMAGEII/<代码>,资源被重新创建,但是VM实例本身不是。 我怎样才能用terraform做到这一点?或者还有其他更好的方法吗?

    Terraform有一个更好的方法,如果您想使用Terraform来管理容器堆栈,这可能是正确的工具。但是,使用它本质上需要将Compose文件转换为Terraform语法

    我更习惯于使用Terraform来管理基础设施的拆分,例如设置EC2实例及其网络设置,但使用另一种工具,如Ansible、Chef或Salt Stack来实际运行软件。然后,要更新软件(Docker容器),您需要更新配置管理工具的设置,以说明需要哪个版本(Docker图像标记),然后重新运行该设置

    一个可能有用的技巧是使用,它可以让您在图像ID更改时“重新分配资源”:

    resource "null_resource" "docker_compose" {
      triggers = {
        image_id = "${var.image_id}"
      }
      provisioner "remote_exec" {
        ...
      }
    }
    
    如果你想沿着全地形路线走,理论上你可以编写一个地形配置,如

    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功能,例如
    默认值
    网络等等。我觉得在实践中通常不会这样做。

    非常感谢null_资源技巧,这很有趣。我同意将资源调配和配置分开可能会更好,但我感觉这两个领域之间的界限越来越模糊。在这种情况下,配置实际上是一个带有一个参数的单一操作(当然,堆栈很简单),因此沿着ansible/chef/puppet/XXX路径进行配置似乎有些过分。很多“配置”已经在底层映像中完成。也许我应该在某个时候重新考虑我的方法……在terraform的最新版本(v0.12.20)中,人们可以编写image_id=var.image_id,但这确实起到了作用!非常感谢大卫·梅兹。