Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Terraform在销毁传出数据之前创建_Terraform_Devops_Digital Ocean - Fatal编程技术网

Terraform在销毁传出数据之前创建

Terraform在销毁传出数据之前创建,terraform,devops,digital-ocean,Terraform,Devops,Digital Ocean,在同一应用程序中,是否有方法从即将离开的资源中引用即将到来的资源的信息?例如,如果我想知道我在一个资源中替换了什么资源 resource "digitalocean_droplet" "droplet" { name = "example" region = "nyc3" image = "docker-18-04" size = "s-1vcpu-2gb" ssh_keys = [...] provisioner "remote-e

在同一应用程序中,是否有方法从即将离开的资源中引用即将到来的资源的信息?例如,如果我想知道我在一个资源中替换了什么资源

resource "digitalocean_droplet" "droplet" {
  name      = "example"
  region    = "nyc3"
  image     = "docker-18-04"
  size      = "s-1vcpu-2gb"
  ssh_keys  = [...]

  provisioner "remote-exec" {
     inline = [
         "echo replacing ${digitalocean_droplet.droplet[0:old].ipv4_address} with ${self.ipv4_address}"
     ]
  }

  lifecycle {
      create_before_destroy = true
  }
}
我省略了一点水滴代码,但我认为这应该足够了。如果我没有很好地解释这个问题,请告诉我



或者,如果在同一个应用程序中不可能做到这一点,否则我将如何进行呢?

我没有与DigitalOcean合作过,也没有可以使用的游乐场。但是,我使用AWSEC2尝试了以下方法,并获得了预期的结果

也许有更好的方法可以做到这一点(欢迎评论和贡献!),但您可以使用对象来获取现有水滴的IP地址。然后,作为terraform应用程序的一部分,您可以为旧IP地址引用该数据对象

data "aws_instance" "web" {
  filter {
    name   = "tag:Name"
    values = ["HelloWorld"]
  }
}

resource "aws_instance" "web" {
  ami           = "ami-0d8e27447ec2c8410"
  instance_type = "t2.micro"

  subnet_id = "subnet-1bb60f60"
  private_ip = "172.31.15.31"

  tags = {
    Name = "HelloWorld"
  }

  lifecycle {
      create_before_destroy = true
  }

  provisioner "local-exec" {
      command =  "echo old IP is ${data.aws_instance.web.private_ip}, new one is ${self.private_ip}"
  }

}
然后我将IP地址更新为.32,输出如下

aws_instance.web: Still creating... [30s elapsed]
aws_instance.web: Provisioning with 'local-exec'...
aws_instance.web (local-exec): Executing: ["/bin/sh" "-c" "echo old IP is 172.31.15.31, new one is 172.31.15.32"]
aws_instance.web (local-exec): old IP is 172.31.15.31, new one is 172.31.15.32
aws_instance.web: Creation complete after 32s [id=i-0cf1ac2618be9d202]
aws_instance.web: Destroying... [id=i-0bcad4b6988f60976]
aws_instance.web: Still destroying... [id=i-0bcad4b6988f60976, 10s elapsed]
aws_instance.web: Destruction complete after 20s
这应该同样适用于你的液滴。下面是我为您编写代码的尝试,但可能需要在某些地方进行更正

data "digitalocean_droplet" "droplet" {
  name = "example"
}

resource "digitalocean_droplet" "droplet" {
  name      = "example"
  region    = "nyc3"
  image     = "docker-18-04"
  size      = "s-1vcpu-2gb"
  ssh_keys  = [...]

  provisioner "remote-exec" {
     inline = [
         "echo replacing ${data.digitalocean_droplet.droplet.ipv4_address} with ${self.ipv4_address}"
     ]
  }

  lifecycle {
      create_before_destroy = true
  }
}

您可以使用数据属性、ipv4\U地址获取它:


Terraform保证访问旧实例值的唯一地方是销毁时间供应器,但它们没有访问新实例值的权限,因此在一个地方访问这两个实例值需要在其他地方跟踪该信息

话虽如此,你可以通过这种方式得到你想要做的事情:

resource "digitalocean_droplet" "droplet" {
  name      = "example"
  region    = "nyc3"
  image     = "docker-18-04"
  size      = "s-1vcpu-2gb"
  ssh_keys  = [...]

  provisioner "remote-exec" {
     inline = [
         "echo creating droplet with with ${self.ipv4_address}"
     ]
  }

  provisioner "remote-exec" {
     when = destroy
     inline = [
         "echo destroying droplet with with ${self.ipv4_address}"
     ]
  }

  lifecycle {
      create_before_destroy = true
  }
}
原则上,您可以让销毁时间供应器将IP地址写入本地磁盘的某个位置,然后让创建时间供应器读取IP地址,从而让后者同时访问这两个地址。这无论如何都不是一个干净的解决方案,但应该是有效的

由于Terraform的一些实现细节,目前可以通过使用数据源或其他技术间接观察旧值,但这不是Terraform保证的,因此可能会在未来的Terraform版本中发生变化

Terraform假设给定的配置管理或读取对象,因此在同一配置中执行这两项操作可能会导致未定义的行为。如果您这样做,您将需要小心地显式地告诉Terraform对象之间的所有依赖关系,以便在将来可能的Terraform版本中,它们不会被重新排序,而Terraform版本可能会以不同的方式实现图形遍历

resource "digitalocean_droplet" "droplet" {
  name      = "example"
  region    = "nyc3"
  image     = "docker-18-04"
  size      = "s-1vcpu-2gb"
  ssh_keys  = [...]

  provisioner "remote-exec" {
     inline = [
         "echo creating droplet with with ${self.ipv4_address}"
     ]
  }

  provisioner "remote-exec" {
     when = destroy
     inline = [
         "echo destroying droplet with with ${self.ipv4_address}"
     ]
  }

  lifecycle {
      create_before_destroy = true
  }
}