在 azure 后端存储中使用状态文件将 terraform 的输出传递到 Azure Devops Pipeline

Posted

技术标签:

【中文标题】在 azure 后端存储中使用状态文件将 terraform 的输出传递到 Azure Devops Pipeline【英文标题】:pass output from terraform to Azure Devops Pipeline with state file in azure backend store 【发布时间】:2019-12-19 04:19:21 【问题描述】:

我似乎无法检索 Terraform 的公共 IP 地址输出,以便在 AzureDevops 中构建管道的下一步。

Terraform state pull 工作并输出到 json 文件,不能 grep 输出。

Terraform state show [options] ADDRESS 不支持 azure 后端,因此无法使用、grep 或过滤输出

还尝试存储为文件并读取值。

resource "local_file" "foo" 
    content     = "foo!"
    filename = "$path.module/foo.bar"


data "azurerm_public_ip" "buildserver-pip" 
  name                = "$azurerm_public_ip.buildserver-pip.name"
  resource_group_name = "$azurerm_virtual_machine.buildserver.resource_group_name"


output "public_ip_address" 
  value = "$data.azurerm_public_ip.buildserver-pip.ip_address"

预计公共 ip 地址会被传递出去,以便在下一步中用于 ansible playbook、bash 或 python 脚本

【问题讨论】:

想知道这是否可以帮助terraform.io/docs/providers/terraform/d/remote_state.html 不清楚你想做什么,如果你想从远程状态获取信息?还是只想输出公网IP? 希望从输出或远程状态获取公共 IP 地址。 azure devops 没有为我导出价值 【参考方案1】:

在上面的@JleruOHeP 答案的基础上,以下解决方案将自动为terraform 脚本提供的每个输出创建一个变量

    在您的版本中创建一个 PowerShell 步骤并插入以下内联 PowerShell:
$json = Get-Content $env:jsonPath | Out-String | ConvertFrom-Json

foreach($prop in $json.psobject.properties) 
    Write-Host("##vso[task.setvariable variable=$($prop.Name);]$($prop.Value.value)")

    确保您已提供环境变量jsonPath,如下所示:

【讨论】:

请参考下面@jleruohep 的答案,因为它概述了我们也需要包含参考名称的面孔。【参考方案2】:

如果我正确理解您的问题,您想使用 terraform 提供一些东西(公共 ip),然后通过变量将其用于进一步的步骤。所有这些都在一个 Azure DevOps 管道中。

可以通过简单的输出和 powershell 脚本来完成(可以内联!):

1) 我假设您已经在管道中使用了 terraform 任务 (https://github.com/microsoft/azure-pipelines-extensions/tree/master/Extensions/Terraform/Src/Tasks/TerraformTaskV1)

2)另一个假设你有一个输出变量(从你的例子 - 你做)

3) 您可以指定此任务的输出变量:

4) 最后用最简单的脚本添加一个powershell步骤作为下一步,并将其环境变量设置为$(TerraformOutput.jsonOutputVariablesPath)

$json = Get-Content $env:jsonPath | Out-String | ConvertFrom-Json

Write-Host "##vso[task.setvariable variable=MyNewIp]$($json.public_ip_address.value)"

5) ....

6) 利润!您现在可以将 IP 地址用作管道变量 MyNewIp

【讨论】:

【参考方案3】:

出于您的目的,我建议您将 terraform 存储在 Azure 存储帐户中。然后您可以在另一个 terraform 文件中使用远程状态。这是一个例子:

创建公共 IP 并将状态存储在 Azure 存储帐户 blob 中:

terraform 
    backend "azurerm" 
        storage_account_name = "yourAccountName"
        container_name       = "yourContainerName"
        key                  = "terraform.tfstate"
    


resource "azurerm_public_ip" "main" 
    name            = "terraform_backend_pip"
    location        = "East US"
    resource_group_name = "yourResourceGroup"
    allocation_method = "Static"


# this is important, you can get the remote outputs for this
output "public_address" 
    value = "$azurerm_public_ip.main.ip_address"

在另一个 Terraform 文件中引用远程状态:

data "terraform_remote_state" "azure" 
        backend = "azurerm"
        config = 
                storage_account_name = "charlescloudshell"
                container_name       = "terraform"
                key                  = "terraform.tfstate"
        


# the remote state outputs contain all the output that you set in the above file
output "remote_backend" 
        value = "$data.terraform_remote_state.azure.outputs.public_address"

结果如下:

您可以按照如何在 Azure Storage here 中存储状态的步骤进行操作。

希望对您有所帮助。如果您还有其他问题,请告诉我。如果它适合你,请接受它作为答案。

【讨论】:

Charles 这是我已经拥有的并且是正确的,问题是在 azure devops 代理中从未传递或检索该值,下一步是 terraform 输出并且没有返回任何内容,相信这可能是azure devops 和 terraform 插件的问题 @DeclanG 它表明如果您在创建资源时设置输出,远程状态只会在其输出中给出。即使输出无法在 DevOps 中显示。【参考方案4】:

terraform output variable

1.如上图所示,只有将“Terraform by Microsoft DevLabs”添加为任务时,您才会得到变量列表。其他 terraform 提供程序不支持输出变量。 Terraform by Microsoft DevLabs

2.还有另一种方法可以将terraform输出变量转换为管道变量(在此您需要将Terraform CLI添加为任务Terraform CLI by Charles Zipp)

第一步:Terraform code to output storage account access key

第二步:Add terraform output as task after terraform apply

terraform 输出变量将以 TF_OUT 为前缀,以将其转换为管道变量 通过引用 $(TF_OUT_variable_name) 访问管道变量 terraform 输出的配置目录必须与 terraform apply 相同

第三步:Powershell script to access pipeline variable

参考: Terraform 输出到管道变量 https://marketplace.visualstudio.com/items?itemName=charleszipp.azure-pipelines-tasks-terraform

【讨论】:

以上是关于在 azure 后端存储中使用状态文件将 terraform 的输出传递到 Azure Devops Pipeline的主要内容,如果未能解决你的问题,请参考以下文章

安全访问 Microsoft Azure Blob 存储

使用 AspNet 从 Azure Blob 存储下载和重命名文件

将 Microsoft 无状态服务绑定到 Azure 存储 Blob?

在 Azure 移动应用服务后端将字符串属性反序列化为 Json 对象

使用 python 将 csv 文件上传到 azure blob 存储

JavaScript Azure Blob 存储移动 blob