【问题标题】:Can I merge existing state of an Azure resource with an Azure Bicep or Pulumi file?我可以将 Azure 资源的现有状态与 Azure Bicep 或 Pulumi 文件合并吗?
【发布时间】:2022-10-13 15:07:27
【问题描述】:

我目前正在使用使用 ARM/Bicep 部署的 Azure 应用程序网关的解决方案。随着时间的推移,会部署使用此 AppGw 的其他应用程序,因此会在以下位置为这些应用程序创建规则/后端池/侦听器他们的通过 Az CLI(中央基础设施 IaC 管道/流程之外)的部署时间。在重新部署/更新中央 AppGw 时,我遇到了 ARM/Bicep 模板覆盖所有这些额外添加的经典问题,因为 AppGw 是单个资源,并且更改不在 ARM/Bicep 文件中,它们是删除。

我过去通过检查 AppGw 的存在、输出现有的规则/池/等来解决这个问题。然后在重新部署之前将它们合并到 ARM/Bicep JSON 中。这工作得很好,但 AppGw 现在变得如此庞大/复杂,以至于我在通过 Azure Devops 构建管道部署更新时遇到了 Bash 字符限制。因此,我正在寻找一种更好的方法来处理这个问题。我还尝试将现有配置输出到文件并通过 Azure Bicep 中的文件加载进行摄取,但我需要在全球范围内部署多个具有不同配置的 AppGws,因此由于 Bicep 中的编译时文件引用限制,这对我不起作用.

我需要确保我的 AppGw 基线模板文件(它设置了 TLS 级别或诊断设置等核心内容)以某种方式得到尊重,同时不会覆盖单独部署过程中发生的修改。

我的问题是我是否可以将这个现有 AppGw 的状态与我的基线模板合并/合并,或者使用 Azure Bicep,或者如果这暴露了功能,则重新工具化为 Pulumi/Terraform 之类的东西。我想到的那种方法是:

  • 管道 CLI 任务检查 AppGw 是否已存在
  • 如果否,则使用具有基本要求的基线模板进行部署
  • 如果是,则获取现有的后端池/侦听器/等。 (或获取整体状态)
  • 与模板 IaC 文件比较
  • 合并状态,确保应用来自 IaC 文件的核心设置(即诊断设置、TLS 级别等),同时现有后端池/侦听器/等。被保留

我知道但没有体验过 Pulumi 的 ignoreChanges 和转换概念。我不确定这是否涵盖了这里的用例。我在这里试图实现的目标可能与这些声明性语言的目的相冲突,但我只是想问问其他人是否有任何想法。

首先十分感谢!

【问题讨论】:

    标签: azure pulumi azure-bicep


    【解决方案1】:

    使用二头肌,如果应用程序网关已经存在,您始终可以检索现有配置。 这是使用httpListeners 的示例。

    您可以像这样定义app-gateway.bicep 模块:

    param appGatewayName string
    param location string = resourceGroup().location
    ...
    param httpListeners array
    
    resource appGateway 'Microsoft.Network/applicationGateways@2020-11-01' = {
      name: appGatewayName
      location: location
      ...
      properties: {
        ...    
        httpListeners: httpListeners
      }
    }
    

    然后从您的 main.bicep 文件中,使用默认或现有配置:

    param appGateWayExists bool
    param appGatewayName string
    ...
    
    // Get existing app gateway if existing
    resource existing 'Microsoft.Network/applicationGateways@2020-11-01' existing = if (appGateWayExists) {
      name: appGatewayName
    }
    
    // Deploy app gateway
    var appGatewayId = resourceId('Microsoft.Network/applicationGateways', appGatewayName)
    module appgateway './app-gateway.bicep' = {
      name: 'app-gateway'
      params: {
        appGatewayName: appGatewayName
        ...
        // Use existing configuration if exists
        httpListeners: appGateWayExists ? existing.properties.httpListeners : [
          {
            // default listener configuration
          }
        ]
      }
    }
    

    然后你可以像这样调用它:

    $appGatewayName = "<app-gateway-name>"
    $appGatewayExists = (az resource list --name "$appGatewayName" --query '[].[id]' | ConvertFrom-Json).Length -gt 0
    az deployment group create `
      --resource-group "<resource-group-name>" `
      ...
      --parameters `
      appGateWayExists=$appGatewayExists `
      appGatewayName="$appGatewayName" `
      ...
    

    【讨论】:

    • 感谢托马斯的回复。这是一个可行的解决方案,用于识别现有资源元素的存在并在丢失时将它们放入,或者使用现有的(我以前使用过这个......为什么没有想到它!)。它没有做的是让我能够将两者合并。例如,如果我需要一个必须始终存在的默认后端 HTTP 设置,但在具有其他后端 HTTP 设置的现有 appgw 中缺少该设置。当前的代码会看到它已经存在并假设它是正确的。我试过联合/连接,但我得到重复的错误。有什么想法吗?
    • 是的 union 只合并简单的数组。我过去也尝试过,但没有奏效。 Tbh 我会用所需的配置修复现有的应用程序网关,然后对于未来的部署,你会很好 => 假设对应用程序网关的所有新更改都将使用管道完成。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-08
    • 2021-05-25
    • 2021-05-23
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 2020-01-08
    相关资源
    最近更新 更多