【问题标题】:Terraform azurerm schedule start_time always resets on new deploysTerraform azurerm schedule start_time 总是在新部署时重置
【发布时间】:2020-08-28 22:31:53
【问题描述】:

我正在尝试让资源azurerm_automation_schedule 在每月发生的特定时间(ex: 18:00) 进行部署。

我正在使用以下代码:

locals {
  update_time = "18:00"
  update_date = formatdate("YYYY-MM-DD", timeadd(timestamp(), "24h"))
  update_timezone = "UTC"
}

resource "azurerm_automation_schedule" "main" {
  name                    = "test"
  resource_group_name     = "myresourcegroupname"
  automation_account_name = "myautomationaccountname"
  frequency               = "Month"
  timezone                = local.update_timezone
  start_time              = "${local.update_date}T${local.update_time}:00+02:00"
  description             = "This is an example schedule"
  monthly_occurrence {
    day = "Tuesday"
    occurrence = "1"
  }
}

"${local.update_date}T${local.update_time}:00+02:00" 将当前时间增加 2 小时并将日期提前 1。这是确保计划在未来开始所必需的。

这很好用,除了下次我回来运行部署时,它会检测到由于日期更改而发生的新更改,即使没有发生真正的更改。 start_time 将始终向前移动。

我似乎找不到任何可以提供帮助的 terraform 逻辑。 有没有办法在变量中设置静态开始时间,并且只有在它改变时才更新? (不是日期)。

伪代码是:

if [update_time] has not changed, do not update [azurerm_automation_schedule]
else update [azurerm_automation_schedule] with the new time, incrementing the day forward

更新

我的最终工作代码(奖励:使用 Windows 更新调度程序,开始工作很痛苦!)

//== Provider used to store timestamp for updates ==//
provider "time" {
  version = "~> 0.4"
}

//== Store 1 day in the future, only update if [local.update_time] is altered ==//
resource "time_offset" "next_day" {
  offset_days = 1
  triggers = {
    update_time = local.update_time
  }
}

locals {
  update_time = "19:40"
  update_date = substr(time_offset.next_day.rfc3339, 0, 10)
  update_timezone = "UTC"
  update_max_hours = "4"
  update_classifications = "Critical, Security, UpdateRollup, ServicePack, Definition, Updates"
  update_reboot_settings = "IfRequired"
  update_day = "Tuesday"
  update_occurrence = "2"
}

#This type should eventually replace the manual deploy via azurerm: azurerm_automation_softwareUpdateConfigurations
#https://github.com/terraform-providers/terraform-provider-azurerm/issues/2812
resource "azurerm_template_deployment" "windows" {
  name                = "windows-update"
  resource_group_name = module.stack.azurerm_resource_group.name

  template_body = <<DEPLOY
  {
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "resources": [
      {
          "apiVersion": "2017-05-15-preview",
          "type": "Microsoft.Automation/automationAccounts/softwareUpdateConfigurations",
          "name": "${module.stack.azurerm_automation_account.name}/windows-updates",
          "properties": {
              "updateConfiguration": {
                  "operatingSystem": "Windows",
                  "duration": "PT${local.update_max_hours}H",
                  "windows": {
                      "excludedKbNumbers": [
                      ],
                      "includedUpdateClassifications": "${local.update_classifications}",
                      "rebootSetting": "${local.update_reboot_settings}"
                  },
                  "azureVirtualMachines": [
                      "${module.server_1.azurerm_virtual_machine.id}",
                      "${module.server_2.azurerm_virtual_machine.id}"
                  ],
                  "nonAzureComputerNames": [
                  ]
              },
              "scheduleInfo": {
                  "frequency": "Month",
                  "startTime": "${local.update_date}T${local.update_time}:00",
                  "timeZone":  "${local.update_timezone}",
                  "interval": 1,
                  "advancedSchedule": {
                      "monthlyOccurrences": [
                          {
                            "occurrence": "${local.update_occurrence}",
                            "day": "${local.update_day}"
                          }
                      ]
                  }
              }
          }
      }
    ]
  }
  DEPLOY

  deployment_mode = "Incremental"
}

【问题讨论】:

    标签: azure terraform terraform-provider-azure azure-rm


    【解决方案1】:

    它保持计划更改的原因是因为您编写的代码指的是当前时间,而不是获取“明天”并以某种方式跟踪它。

    为此,您需要一种方法来获得“明天”一次,并将其保持在状态中。存在于状态中的事物是资源,因此您需要一个表示具有偏移量的时间的资源。这就是time provider 的用武之地。

    这是基本部分:

    resource "time_offset" "tomorrow" {
      offset_days = 1
    }
    

    这将为您获得“明天”,并且在应用后它将保存在 Terraform 状态。

    time_offset.tomorrow.rfc3339
    

    将评估为:

    2020-05-13T04:28:07Z
    

    但是,我们只想要 YYYY-MM-DD,所以我们使用 substr 来获取前 10 个字符:

    substr(time_offset.tomorrow.rfc3339, 0, 10)
    

    把它们放在一起,我们得到了这个(添加了 4 行,包括空格,1 行改变了):

    locals {
      update_time = "18:00"
      update_date = substr(time_offset.tomorrow.rfc3339, 0, 10)
      update_timezone = "UTC"
    }
    
    resource "time_offset" "tomorrow" {
      offset_days = 1
    }
    
    resource "azurerm_automation_schedule" "main" {
      name                    = "test"
      resource_group_name     = "myresourcegroupname"
      automation_account_name = "myautomationaccountname"
      frequency               = "Month"
      timezone                = local.update_timezone
      start_time              = "${local.update_date}T${local.update_time}:00+02:00"
      description             = "This is an example schedule"
      monthly_occurrence {
        day = "Tuesday"
        occurrence = "1"
      }
    }
    

    您可能需要引入 time 提供程序才能使用它(如果没有它就无法工作,请将其放在您的 AzureRM 提供程序旁边):

    provider "time" {}
    

    如果需要,您可以使用terraform taint 'time_offset.tomorrow' 强制重新计算时间。

    【讨论】:

    • 完美!不知道资源类型 [time_offset] 存在,这是关键!我将发布最终剪辑(不再需要 2 小时的内容)欠你一杯虚拟啤酒 :)。
    • 还必须添加触发逻辑以确保它在时间正确更改时更新。
    • 好收获。我忘了那个细节!
    【解决方案2】:

    回馈。我从这个线程中的信息创建了一个 terraform 模块,以简化调度更新。适用于 linux 和 windows 虚拟机:

    https://github.com/canada-ca-terraform-modules/terraform-azurerm_update_management

    这是一个示例,说明如何使用该模块来完成您正在寻找的内容:

    locals {
      update_time = "18:00"
      update_date = substr(time_offset.tomorrow.rfc3339, 0, 10)
      update_timezone = "UTC"
    }
    
    resource "time_offset" "tomorrow" {
      offset_days = 1
    }
    
    module "linux-weekly-updates" {
      source                     = "github.com/canada-ca-terraform-modules/terraform-azurerm_update_management?ref=20200527.1"
      name                       = "test"
      resource_group_name        = "my_resource_group_name"
      azurerm_automation_account = azurerm_automation_account.my_azurerm_automation_account
      operatingSystem            = "Linux"
      scope                      = [azurerm_resource_group.somerg1.id, azurerm_resource_group.somerg1.id]
      timeZone                   = "EST"
      startTime                  = "${local.update_date}T${local.update_time}:00+02:00"
      weekDays                   = ["Sunday"]
    }
    

    【讨论】:

    • 您的模块需要明确设置开始时间,并不能解决问题中提出的问题。您也没有解释您的解决方案,只是将其链接起来,这里不适合作为答案。
    • 该模块将采用您需要的格式的时间字符串。它使 Azurerm 部分的代码易于使用。随着我添加所需的文档,该模块将随着时间的推移而改进。它消除了 Azure Arm json 语法的复杂处理,并允许扩展以支持更多模板功能。喜欢就用,不喜欢就放弃。与其对共享内容持否定态度,不如让我知道如何改进或更好地创建拉取请求。我们一起变得更强大。
    • 我不想消极。我要指出的是,StackOverflow 不是一个发布酷炫相关内容的论坛,它是一个直接回答直接问题的问答平台。展示如何使用您的解决方案来回答问题,我很乐意对此表示赞同。
    • 更清晰并立即适用于问题。不错的编辑。
    猜你喜欢
    • 2021-12-27
    • 2019-12-01
    • 1970-01-01
    • 2021-12-08
    • 2019-12-13
    • 2016-09-14
    • 1970-01-01
    • 2023-03-17
    • 2021-10-05
    相关资源
    最近更新 更多