Azure devops 在Azure管道构建中使用Azure Repos git模块源进行身份验证

Azure devops 在Azure管道构建中使用Azure Repos git模块源进行身份验证,azure-devops,terraform,azure-pipelines,azure-repos,Azure Devops,Terraform,Azure Pipelines,Azure Repos,我目前正在为Azure DevOps创建一个管道,以验证Terraform配置并将其应用于不同的订阅 我的terraform配置使用模块,这些模块“托管”在与terraform配置相同的Azure DevOps项目中的其他存储库中 不幸的是,当我试图执行terraforminit获取这些模块时,管道任务“挂起”在那里等待凭证输入 按照中的建议,我尝试使用persistCredentials:true属性添加checkout步骤 从我在任务日志(见下文)中看到的情况来看,凭证信息专门添加到当前回购

我目前正在为Azure DevOps创建一个管道,以验证Terraform配置并将其应用于不同的订阅

我的terraform配置使用模块,这些模块“托管”在与terraform配置相同的Azure DevOps项目中的其他存储库中

不幸的是,当我试图执行
terraforminit
获取这些模块时,管道任务“挂起”在那里等待凭证输入

按照中的建议,我尝试使用
persistCredentials:true
属性添加
checkout
步骤

从我在任务日志(见下文)中看到的情况来看,凭证信息专门添加到当前回购协议中,不可用于其他回购协议

添加持久凭据时执行的命令:true

2018-10-22T14:06:54.4347764Z ##[command]git config http.https://my-org@dev.azure.com/my-org/my-project/_git/my-repo.extraheader "AUTHORIZATION: bearer ***"
terraform初始化任务的输出

2018-10-22T14:09:24.1711473Z terraform init -input=false
2018-10-22T14:09:24.2761016Z Initializing modules...
2018-10-22T14:09:24.2783199Z - module.my-module
2018-10-22T14:09:24.2786455Z   Getting source "git::https://my-org@dev.azure.com/my-org/my-project/_git/my-module-repo?ref=1.0.2"

如何设置git凭据以用于其他存储库?

我认为您不能。通常,您创建另一个构建并链接到该构建中的工件,以便在当前定义中使用它。这样,您就不需要连接到不同的Git存储库

我也遇到了同样的问题,我最终做的是在terraform配置中标记化
SYSTEM\u ACCESSTOKEN
。我在Azure DevOps中使用了Tokenzization任务,其中使用前缀和后缀来识别并用实际变量替换标记(它是可自定义的,但我发现双下划线最适合于不干扰我拥有的任何代码)

类似于
find$(Build.SourcesDirectory)/-typef-name'main.tf'-exec sed-i's~\uuuuu系统\uu访问令牌\uuuuu~$(SYSTEM.ACCESSTOKEN)~g'{}\也可以工作

我的terraform main.tf如下所示:

module "app" {
  source = "git::https://token:__SYSTEM_ACCESSTOKEN__@dev.azure.com/actualOrgName/actualProjectName/_git/TerraformModules//azure/app-service?ref=__app-service-module-ver__"
  ....
}
它并不漂亮,但它完成了任务。模块源(在编写本文时)不支持terraform的变量输入。所以我们能做的就是使用Terrafile它是一个开源项目,通过在代码旁边保留一个简单的YAML文件,帮助您跟上模块和同一模块的不同版本。它似乎不再被积极维护,但它只是工作: 我的Terrafile示例:

app:
    source:  "https://token:__SYSTEM_ACCESSTOKEN__@dev.azure.com/actualOrgName/actualProjectName/_git/TerraformModules"
    version: "feature/handle-twitter"
app-stable:
    source:  "https://token:__SYSTEM_ACCESSTOKEN__@dev.azure.com/actualOrgName/actualProjectName/_git/TerraformModules"
    version: "1.0.5"
默认情况下,Terrafile将您的模块下载到./vendor目录,这样您就可以将模块源指向以下位置:

module "app" {
  source = "./vendor/modules/app-stable/azure/app_service"
  ....
}
现在,您只需了解如何在terrafile所在的目录中执行
terrafile
命令。 My azure.pipelines.yml示例:

- script: curl -L https://github.com/coretech/terrafile/releases/download/v0.6/terrafile_0.6_Linux_x86_64.tar.gz | tar xz -C $(Agent.ToolsDirectory)
  displayName: Install Terrafile

- script: |
    cd $(Build.Repository.LocalPath)
    $(Agent.ToolsDirectory)/terrafile
  displayName: Download required modules
是我干的

_ado_token.ps1

# used in Azure DevOps to allow terrform to auth with Azure DevOps GIT repos
$tfmodules = Get-ChildItem $PSScriptRoot -Recurse -Filter "*.tf"
foreach ($tfmodule in $tfmodules) {
    $content = [System.IO.File]::ReadAllText($tfmodule.FullName).Replace("git::https://myorg@","git::https://" + $env:SYSTEM_ACCESSTOKEN +"@")
    [System.IO.File]::WriteAllText($tfmodule.FullName, $content)
}
azure-pipelines.yml

- task: PowerShell@2
  env: 
    SYSTEM_ACCESSTOKEN: $(System.AccessToken)
  inputs:
    filePath: '_ado_token.ps1'
    pwsh: true
  displayName: '_ado_token.ps1'

基本上有两种方法

先决条件 确保阅读并根据需要应用“在脚本中运行Git命令”文档中的部分

解决方案1:在管道运行时动态插入
System.AccessToken
(或PAT,但我不推荐) 您可以通过以下方式来解决此问题:

  • 在代码中插入替换令牌,如
    \uu系统\u访问令牌
    (如建议),并使用一些令牌替换代码或
    qetza.replaceTokes.replaceTokes任务。replaceTokes
    任务插入值。此解决方案的缺点是,在本地运行
    terraform
    时,还必须替换令牌
  • 使用一些代码替换所有
    git::https://dev.azure.com
    带有
    git:的文本:https://YOUR_ACCESS_TOKEN@dev.azure.com
我使用了第二种方法,使用了下面的bash任务脚本(它搜索
terragrunt
文件,但您可以适应
terraform
文件,而无需做太多更改):

提供一个PowerShell脚本来执行类似的操作

但是,如果您的
terraform
modules
git
repo中的模块在另一个
git
repo中调用自己的模块,则这种类型的解决方案不起作用,这就是我们的情况

解决方案2:在您的
terraform
modules
git
repos的url的
extraheader
中全局添加访问令牌 这样,所有模块的repo(由您的代码直接调用或由被调用模块的代码间接调用)都将能够使用您的访问令牌。为此,我在您的
terraform
/
terragrunt
调用之前添加了以下步骤:

- bash: |
    git config --global http.https://dev.azure.com/<your-org>/<your-first-repo-project>/_git/<your-first-repo>.extraheader "AUTHORIZATION: bearer $(System.AccessToken)"
    git config --global http.https://dev.azure.com/<your-org>/<your-second-repo-project>/_git/<your-second-repo>.extraheader "AUTHORIZATION: bearer $(System.AccessToken)"
- bash: |
    find $(Build.SourcesDirectory)/ -type f -name 'terragrunt.hcl' -exec sed -i 's~git::https://dev.azure.com~git::https://$(System.AccessToken)@dev.azure.com~g' {} \;
- bash: |
    git config --global http.https://dev.azure.com/<your-org>/<your-first-repo-project>/_git/<your-first-repo>.extraheader "AUTHORIZATION: bearer $(System.AccessToken)"
    git config --global http.https://dev.azure.com/<your-org>/<your-second-repo-project>/_git/<your-second-repo>.extraheader "AUTHORIZATION: bearer $(System.AccessToken)"
- bash: |
    git config --global --unset-all http.https://dev.azure.com/<your-org>/<your-first-repo-project>/_git/<your-first-repo>.extraheader
    git config --global --unset-all http.https://dev.azure.com/<your-org>/<your-second-repo-project>/_git/<your-second-repo>.extraheader