从powershell脚本跨YAML管道将输出变量解析为Terraform变量



我一直在研究一种解决方案,使用逻辑应用程序向Slack发送Azure警报(为了将警报的输出转换为Slack可以显示为消息的JSON模式)。逻辑应用被部署为ARM模板,以便完整地保留逻辑应用的内容,而其余的Azure资源由Terraform部署。Terraform和ARM模板正在通过Azure DevOps YAML管道进行部署,有多个阶段。到目前为止,我已经编写了逻辑应用程序来将警报转换为消息(逻辑应用程序在模式转换后发布消息)

我目前的困境是如何在Terraform配置中以编程方式包括逻辑应用程序的URL(应该发送警报的地方)。在逻辑应用程序工作流或标准逻辑应用程序实例的可用数据块中没有URL的配置属性,这使得这一点变得更加困难。

为了减轻terrraform功能的缺乏,我试图用Az Powershell模块命令检索逻辑应用程序的URL (Azure CLI似乎还没有这个功能)。使用一个简短的脚本,我能够得到url来触发逻辑应用程序:

$logicApp = Get-AzLogicAppTriggerCallbackUrl -ResourceGroupName "logic-app-rg" -Name "mylogicapp" -TriggerName "Manual"
$url = logicApp.Value
通过添加以下行,可以将其添加到YAML管道中:
write-host "##vso[task.setvariable variable=outputURL;isOutput=true]$url"

因为有多个阶段,只需要一个逻辑应用程序,所以它被放在第一阶段,在那里创建核心基础设施(Terraform状态的存储帐户)

当我无法将输出URL的任务的数据发送到包含地形的不同阶段时,困难就出现了。YAML管道的大致结构(简化):

stages:
- stage: infra-1
jobs:
- job: deploy-common-infra
steps:
- script: |
cd core-infra
terraform init
terraform plan
terraform apply
$logicApp = Get-AzLogicAppTriggerCallbackUrl -ResourceGroupName "logic-app-rg" -Name "mylogicapp" -TriggerName "Manual"
$url = logicApp.Value
write-host "##vso[task.setvariable variable=outputURL;isOutput=true]$url"
name: getLogicAppURL
- stage: build
jobs:
- job: build
- task: build-app
- stage: infra-2
dependsOn:
- infrastructure-1
variables:
outputURL: $[stageDependencies.infra-1.deploy-common-infra.outputs['getLogicAppURL.outputURL']]
jobs:
- job: deploy-infra
- script: |
cd infra
terraform init
terraform plan -var="logicAppUrl='$(outputURL)'"
terraform apply

应该注意的是,在实际的管道中,我使用的是专用的Terraform任务,而不是在脚本中编写Terraform命令。

我的麻烦主要来自于我不想跳过"构建"。阶段,否则我不会在最后阶段部署应用程序(从上面的示例管道中排除)。另外,发送给terraform的值为"null";(没有发送URL !)

我已经使用并查看了如何跨工作和阶段共享变量的现有答案,同时在管道中使用依赖关系,但到目前为止,我一直在努力寻找一个解决方案,允许我跨阶段解析URL变量。这是跨阶段解析YAML变量到Terraform的唯一方法吗?

(另一个问题可能是,这是解决手头挑战的最佳方法,还是我应该尝试的不同解决方案?))

我最终通过将脚本添加到特定作业中来解决这个问题,并将其添加到仅针对特定Terraform模块运行的条件中,并更改脚本,以便它直接写入Terraform文件。例如,要在上面的管道上构建我现在手头的解决方案:

stages:
- stage: infra-1
jobs:
- job: deploy-common-infra
steps:
- script: |
cd core-infra
terraform init
terraform plan
terraform apply
- stage: build
jobs:
- job: build
steps:
- task: build-app
- stage: infra-2
dependsOn:
- infrastructure-1
variables:
outputURL: $[stageDependencies.infra-1.deploy-common-infra.outputs['getLogicAppURL.outputURL']]
jobs:
- job: deploy-infra
steps:
- template: logic-app.yaml
- script: |
cd infra
terraform init
terraform plan -var="logicAppUrl='$(outputURL)'"
terraform apply

logic-app.yaml模板具有将url添加到变量文件的脚本,该变量文件存储在DevOps使用的代理上的临时存储位置:

steps:
- script: |
$logicApp = Get-AzLogicAppTriggerCallbackUrl -ResourceGroupName "logic-app-rg" -Name "mylogicapp" -TriggerName "Manual"
$url = $logicApp.Value
Add-Content -Path "$directory/infra/vars.tfvars" -Value "`nslack_url=`"$url`""

应该注意的是,terraform/vars.tfvars是存储库中用于管道的路径。通过将其添加到管道中,它现在可以成功运行了。

最新更新