Аутентификация с использованием источников модуля git Azure Repos в сборке Azure Pipelines

В настоящее время я создаю конвейер для Azure DevOps для проверки и применения конфигурации Terraform к другой подписке.

В моей конфигурации terraform используются модули, которые «размещены» в других репозиториях в том же проекте Azure DevOps Project, что и конфигурация terraform.

К сожалению, когда я пытаюсь выполнить terraform init для получения этих модулей, задача конвейера «зависает» в ожидании ввода учетных данных.

Как рекомендовано в документации по конвейеру при выполнении команд Git в скрипте Я попытался добавить checkout шаг с атрибутом persistCredentials:true.

Из того, что я вижу в журнале задачи (см. Ниже), информация об учетных данных добавляется специально в текущее репо и не может использоваться для других репозиториев.

Команда, выполняемая при добавлении persistCredentials:true

2018-10-22T14:06:54.4347764Z ##[command]git config http.https://[email protected]/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://[email protected]/my-org/my-project/_git/my-module-repo?ref=1.0.2"

Как я могу настроить учетные данные git для работы с другими репозиториями?


person Groumy    schedule 22.10.2018    source источник


Ответы (4)


У меня была та же проблема, что я закончил, это токенизация SYSTEM_ACCESSTOKEN в конфигурации terraform. Я использовал задачу Tokenzization в Azure DevOps, где префикс и суффикс __ используются для идентификации и замены токенов фактическими переменными (это настраивается, но я считаю, что двойное подчеркивание лучше всего, чтобы не мешать любому имеющемуся у меня коду)

- task: qetza.replacetokens.replacetokens-task.replacetokens@3
    displayName: 'Replace tokens'
    inputs:
      targetFiles: |
       **/*.tfvars
       **/*.tf
      tokenPrefix: '__'
      tokenSuffix: '__'

Что-то вроде find $(Build.SourcesDirectory)/ -type f -name 'main.tf' -exec sed -i 's~__SYSTEM_ACCESSTOKEN__~$(System.AccessToken)~g' {} \; также будет работать, если у вас нет возможности устанавливать собственные расширения в свою организацию DevOps.

Мой terraform main.tf выглядит так:

module "app" {
  source = "git::https://token:[email protected]/actualOrgName/actualProjectName/_git/TerraformModules//azure/app-service?ref=__app-service-module-ver__"
  ....
}

Это некрасиво, но выполняет свою работу. Источник модуля (на момент написания) не поддерживает ввод переменных из terraform. Итак, что мы можем сделать, так это использовать Terrafile, это проект с открытым исходным кодом, помогающий не отставать от модулей и различных версий одного и того же модуля, который вы можете использовать, сохраняя простой файл YAML рядом с вашим кодом. Кажется, что он больше не поддерживается, но он просто работает: https://github.com/coretech/terrafile мой пример Terrafile:

app:
    source:  "https://token:[email protected]/actualOrgName/actualProjectName/_git/TerraformModules"
    version: "feature/handle-twitter"
app-stable:
    source:  "https://token:[email protected]/actualOrgName/actualProjectName/_git/TerraformModules"
    version: "1.0.5"

Terrafile по умолчанию загружает ваши модули в каталог ./vendor, чтобы вы могли указать источник вашего модуля на что-то вроде:

module "app" {
  source = "./vendor/modules/app-stable/azure/app_service"
  ....
}

Теперь вам просто нужно выяснить, как выполнить команду terrafile в каталоге, где находится Terrafile. Мой пример 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
person Nilsas    schedule 09.05.2020

я сделал это

_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'
person Abu Belal    schedule 08.06.2020

По сути, у вас есть два способа сделать это.

Обязательное условие

Убедитесь, что вы прочитали и, в зависимости от ваших потребностей, применили Включить скрипты для выполнения команд Git в разделе" Выполнить команды Git "в документе сценария.

Решение №1: динамически вставьте System.AccessToken (или PAT, но я бы не рекомендовал это) во время выполнения конвейера

Вы можете сделать это одним из следующих способов:

  • вставив в код заменяющий токен, например __SYSTEM_ACCESSTOKEN__ (как предлагает Nilsas), и используйте код замены токена или задачу qetza.replacetokens.replacetokens-task.replacetokens для вставьте значение. Недостатком этого решения является то, что вам также придется заменять токен при terraform локальном запуске.
  • используя некоторый код для замены всего текста git::https://dev.azure.com на git::https://[email protected].

Я использовал второй подход, используя следующий сценарий задачи bash (он ищет terragrunt файлы, но вы можете адаптироваться к terraform файлам без особых изменений):

- 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' {} \;

Abu Belai предлагает сценарий PowerShell для выполнения чего-то подобного.

Однако этот тип решения не работает, если модули в вашем репозитории terraform модулей git называют себя модулями в другом git репозитории, как это было в нашем случае.

Решение №2: глобальное добавление токена доступа в extraheader URL-адреса ваших terraform модулей git репозиториев

Таким образом, все репозитории модулей, вызываемые непосредственно вашим кодом или вызываемые косвенно кодом вызываемых модулей, смогут использовать ваш токен доступа. Я сделал это, добавив следующий шаг перед вашими _16 _ / _ 17_ звонками:

- 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)"

Вам нужно будет установить extraheader для каждого из вызываемых git репозиториев.

Помните, что вам может потребоваться отключить extraheader после ваших terraform вызовов, если ваш конвейер устанавливает extraheader несколько раз на одном и том же воркере. Это потому, что git можно спутать с несколькими extraheader объявлениями. Вы делаете это, добавляя к следующему шагу:

- 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 
person Emmanuel Sciara    schedule 18.01.2021
comment
Пожалуйста, не следуйте решению №2. Вы обнаружите, что у вас есть машины-агенты, у которых так или иначе не был очищен внешний заголовок, и что ваш конвейер начинает давать сбой с ошибкой git 128. Это ужасная вещь, которую пытаться отследить. - person GaTechThomas; 18.06.2021
comment
С другой стороны, решение №1 работает хорошо. - person GaTechThomas; 19.06.2021

Я не думаю, что ты сможешь. Обычно вы создаете другую сборку и связываете ее с артефактами, чтобы использовать ее в текущем определении. Таким образом, вам не нужно подключаться к другому репозиторию Git

person Rob Bos    schedule 22.10.2018