首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Terraform希望在修改开始/停止调度程序时取代Google计算引擎

Terraform希望在修改开始/停止调度程序时取代Google计算引擎
EN

Stack Overflow用户
提问于 2021-08-30 15:08:51
回答 3查看 821关注 0票数 1

首先,我感到惊讶的是,我在Google上发现很少有资源提到Terraform的这个问题。不过,这是优化云实例成本的一个基本特性,所以我可能忽略了一些东西,谢谢您的提示和想法!

我希望创建一个实例,并以编程的方式管理它的开始和停止。资源"google_compute_resource_policy“似乎符合我的用例。但是,当我更改停止或启动时间时,Terraform计划销毁并重新创建实例.我绝对不想要!

资源"google_compute_resource_policy“通过指定的参数政策附加到实例:”修改此列表将导致实例重新创建。“

我不明白为什么Terraform这么糟糕地处理这个简单的更新。确实,不可能更新调度程序,而完全有可能手动将其从实例中分离出来,然后在使用新的停止/启动计划重新创建它并再次附加到实例之前销毁它。

是否有一种解决办法,而不需要使用空资源来运行gcloud脚本来执行这些步骤?

我试图在我的实例的"ignore_changes“参数中添加一个"resource_policies”生命周期,Terraform不再想破坏我的实例,但是它给了我以下错误:

代码语言:javascript
复制
Error when reading or editing ResourcePolicy: googleapi: Error 400: The resource_policy resource 'projects/my-project-id/regions/europe-west1/resourcePolicies/my-instance-schedule' is already being used by 'projects/my-project-id/zones/europe-west1-b/instances/my-instance', resourceInUseByAnotherResource"

这是我的Terraform代码

代码语言:javascript
复制
resource "google_compute_resource_policy" "instance_schedule" {
  name = "my-instance-schedule"
  region = var.region
  description = "Start and stop instance"

  instance_schedule_policy {
    vm_start_schedule {
      schedule = var.vm_start_schedule
    }
    vm_stop_schedule {
      schedule = var.vm_stop_schedule
    }
    time_zone = "Europe/Paris"
  }
}

resource "google_compute_instance" "my-instance" {

  // ******** This is my attempted workaround ********
  lifecycle {
    ignore_changes = [resource_policies]
  }

  name = "my-instance"
  machine_type = var.machine_type
  zone = "${var.region}-b"

  allow_stopping_for_update = true

  resource_policies = [
    google_compute_resource_policy.instance_schedule.id
  ]

  boot_disk {
    device_name = local.ref_name
    initialize_params {
      image = var.boot_disk_image
      type = var.disk_type
      size = var.disk_size
    }
  }

  network_interface {
    network = data.google_compute_network.default.name
    access_config {
      nat_ip = google_compute_address.static.address
    }
  }
}

如果有用的话,下面是terraform apply返回的内容

代码语言:javascript
复制
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  - destroy
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # google_compute_resource_policy.instance_schedule must be replaced
-/+ resource "google_compute_resource_policy" "instance_schedule" {
      ~ id          = "projects/my-project-id/regions/europe-west1/resourcePolicies/my-instance-schedule" -> (known after apply)
        name        = "my-instance-schedule"
      ~ project     = "my-project-id" -> (known after apply)
      ~ region      = "https://www.googleapis.com/compute/v1/projects/my-project-id/regions/europe-west1" -> "europe-west1"
      ~ self_link   = "https://www.googleapis.com/compute/v1/projects/my-project-id/regions/europe-west1/resourcePolicies/my-instance-schedule" -> (known after apply)
        # (1 unchanged attribute hidden)

      ~ instance_schedule_policy {
            # (1 unchanged attribute hidden)

          ~ vm_start_schedule {
              ~ schedule = "0 9 * * *" -> "0 8 * * *" # forces replacement
            }

            # (1 unchanged block hidden)
        }
    }

Plan: 1 to add, 0 to change, 1 to destroy.

Do you want to perform these actions in workspace "prd"?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

google_compute_resource_policy.instance_schedule: Destroying... [id=projects/my-project-id/regions/europe-west1/resourcePolicies/my-instance-schedule]

Error: Error when reading or editing ResourcePolicy: googleapi: Error 400: The resource_policy resource 'projects/my-project-id/regions/europe-west1/resourcePolicies/my-instance-schedule' is already being used by 'projects/my-project-id/zones/europe-west1-b/instances/my-instance', resourceInUseByAnotherResource

NB:我正在使用Terraform0.14.7,我使用的是GoogleProviderVersion3.76.0

EN

回答 3

Stack Overflow用户

发布于 2021-08-30 20:07:33

GCP中的一个实例可以在不使用参数实例破坏它的情况下关闭,请记住,如果您是第一次创建实例,则此参数需要“运行”。此模块可用于以下几个方面。

代码语言:javascript
复制
resource "google_compute_instance" "default" {
  name         = "test"
  machine_type = "f1-micro"
  zone         = "us-west1-a"
  desired_status = "RUNNING"
}

如果需要先停止VM,然后开始使用main.tf创建地形相依性,也可以修改“depends_on”文件。

正如您在下面的注释中所看到的,服务帐户将被创建,但是键将被分配,直到第一句完成。

代码语言:javascript
复制
resource "google_service_account" "service_account" { 
   account_id = "terraform-test" 
   display_name = "Service Account"
}

resource "google_service_account_key" "mykey" {
  service_account_id = google_service_account.service_account.id 
  public_key_type = "TYPE_X509_PEM_FILE" 
  depends_on = [google_service_account.service_account]
}

如果第一个组件已经存在,terraform只部署依赖项。

票数 1
EN

Stack Overflow用户

发布于 2021-12-07 15:25:06

快照策略也面临着同样的问题。

我使用一个标志输入变量并使用count控制资源策略的创建。这是我第一次使用标志作为“true”创建策略资源。当我想更改计划时间时,我将标志更改为“false”并应用该计划。这将分离资源。

然后,我再次将标志设置为“真”,并在新的时间内应用该计划。

这对我的快照策略是有效的。希望它也能解决你的问题。

票数 0
EN

Stack Overflow用户

发布于 2022-04-22 10:31:51

我通过向resourceInUseByAnotherResource资源添加以下生命周期来解决“google_compute_resource_policy”错误:

代码语言:javascript
复制
lifecycle {
  create_before_destroy = true
}

而且,这需要在每次更改时都有一个唯一的名称,否则就无法创建新的资源,因为同名的资源已经存在。因此,我在时间表名称的末尾附加了一个随机ID:

代码语言:javascript
复制
resource "random_pet" "schedule" {
  keepers = {
    start_schedule = "${var.vm_start_schedule}"
    stop_schedule  = "${var.vm_stop_schedule}"
  }
}
...
resource "google_compute_resource_policy" "schedule" {
  name = "schedule-${random_pet.schedule.id}"
  ...
  lifecycle {
     create_before_destroy = true
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68986334

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档