Пропуск указанного этапа в конвейере

Я создал новый файл Pipeline.yml, который при запуске создает несколько ресурсов с помощью Terraform. Когда они уже созданы, конкретный этап следует пропустить и проверять только текущее состояние.

    parameters:
      - name: myConn
        type: string
        default: 'dev'
    
    variables:
    - group: dev-group
    - name: workingDirectory
      value: '$(Build.SourcesDirectory)/configs'
    
    stages:
      - stage: Just_printing
        displayName: 'Printing some variables'
        jobs:
          - job: PrintJobs
            displayName: 'Print Job'
            steps:   
              - script: |
                  echo "printing directory: $(Build.SourcesDirectory)"
                  cd $(Build.SourcesDirectory)
                  ls -lha $(Build.SourcesDirectory)
    
              - script: |
                  echo "printing directory: $(workingDirectory)"
                  cd $(workingDirectory)
                  ls -lha $(workingDirectory)
     
    
      - stage: Deployment
        displayName: 'Terraform deploy'
        dependsOn: 
          - Just_printing
        jobs:
          - deployment: terraform
            environment:
              name: dev
            pool: "server"
            strategy:
              runOnce:
                deploy:
                  steps:
                  - task: ManualValidation@0
                    timeoutInMinutes: 1440
                    inputs:
                      notifyUsers: |
                          [email protected]
                      instructions: "approving..."
                      onTimeout: "reject"
    
          - job: "TerraformApprove"
            displayName: "Deployment ..."
            dependsOn: terraform
            steps:            
              - task: TerraformCLI@0
                displayName: 'Terraform Init'
                inputs:
                  command: init
                  backendType: gcs
                  backendGcsCredentials: ${{ parameters.myConn}}
                  backendGcsBucket: 'dev-state'
                  workingDirectory: $(workingDirectory)
    
    
              - task: TerraformCLI@0
                displayName: 'Terraform Plan'
                name: plan
                inputs:
                  command: plan
                  publishPlanResults: 'TerraformPlan'
                  workingDirectory: $(workingDirectory)
                  commandOptions: '-out=$(Build.SourcesDirectory)/configs/tf.tfplan'
                  providerGoogleCredentials: ${{ parameters.myConn}}
    
              - task: PublishBuildArtifacts@1  
                displayName: 'Publish Terraform Plan'
                inputs:
                  pathtoPublish: '$(Build.SourcesDirectory)/configs/tf.tfplan'
                  artifactName: 'Plan'
    
              - task: TerraformCLI@0
                displayName: 'Terraform Apply'
                inputs:
                  command: apply
                  workingDirectory: $(workingDirectory)
                  commandOptions: '$(Build.SourcesDirectory)/configs/tf.tfplan'
                  providerGoogleCredentials: ${{ parameters.myConn}}
    
      - stage: Just_state
        displayName: 'Just_state'
        dependsOn: Deployment
        jobs:
          - job: Just_state
            displayName: 'Just state Job'
            steps:
              - task: TerraformCLI@0
                displayName: 'Terraform Init'
                inputs:
                  command: init
                  backendType: gcs
                  backendGcsCredentials: ${{ parameters.myConn}}
                  backendGcsBucket: 'dev-state'
                  workingDirectory: $(workingDirectory)
                  commandOptions: '-reconfigure'
    
              - task: TerraformCLI@0
                displayName: 'terraform state list'
                inputs:
                  command: state
                  workingDirectory: $(workingDirectory)
                  stateSubCommand: list
                  commandOptions: '-state=$(Build.SourcesDirectory)/configs/tf.tfstate'

Я хотел бы пропустить весь этап развертывания, когда terraform проверяет, не было ли изменений в ресурсе до последнего запуска конвейера. Я не уверен, как этого добиться.

Попробовал использовать скрипт bash на этапе Just_printing, который только проверяет, были ли внесены изменения, и, если нет, пропускает весь этап развертывания, однако на моей стороне возникло множество ошибок, и я застрял. Наконец, на этапе Just_state он проверяет только текущие развернутые ресурсы.

РЕДАКТИРОВАТЬ 1.

Добавлено в соответствии с ответом ниже, однако каждое мое изменение вызывает разные ошибки. Обычно это приводит к проблеме с учетными данными, но я не знаю, как передать их в предоставленном сценарии.

Текущая ошибка при запуске этого конвейера::

Инициализация серверной части... │ Ошибка: Google: не удалось найти значение по умолчанию. реквизиты для входа. Видеть https://cloud.google.com/docs/authentication/external/set-up-adc для Дополнительная информация

Фрагмент кода для Pipeline.yaml

- job: CheckChanges
  displayName: 'Check Changes'
  steps:
    - task: Bash@3
      displayName: 'Check resource changes'
      name: setvar
      inputs:
        backendType: gcs
        backendGcsCredentials: ${{ parameters.myConn}}
        backendGcsBucket: 'dev-state'
        workingDirectory: $(workingDirectory)
        targetType: 'inline'
        script: |
          cd $(workingDirectory)
          terraform init -reconfigure -backend-config = "bucket=dev-state" -backend-config = "[email protected]"
          terraform plan -input=false -no-color -detailed-exitcode
          retVal=$?
          if [ $retVal -eq 2 ]; then
              echo "##vso[task.setvar variable=deploy;isOutput=true]true"
          else
              echo "##vso[task.setvar variable=deploy;isOutput=true]false"
          fi

  - stage: Deployment
    displayName: 'Terraform deploy'
    dependsOn: Just_printing
    condition: eq(dependencies.Just_printing.outputs['CheckChanges.setvar.deploy'], 'true')
    jobs:
      - deployment: terraform

К вашему сведению:

  1. Для или $(workingDirectory) я установил путь в переменных как $(sourceDirectory)/terraform, где у меня есть весь мой файл .tf (main.tf,variable.tf), а $(sourceDirectory) хранит все yml, например, Pipeline.yaml. Так и должно быть.
  2. Для ${{parameters.myConn}} я храню ключ непосредственно в Azure DevOps. Это также работает таким образом на всех этапах развертывания.
stackoverflow.com/questions/75889916/…
Rui Jarimba 03.06.2024 16:35

Я попробую, дайте мне несколько дней. В любом случае спасибо за очень быстрое обновление.

Kreg 03.06.2024 16:57

Привет @Kreg, ты пробовал yaml ниже? Это сработало для вас?

Ziyang Liu-MSFT 06.06.2024 11:36

Спасибо @ZiyangLiu-MSFT за первый и быстрый ответ. Я ответил в EDIT 1, так как текста для комментариев слишком много.

Kreg 07.06.2024 10:16

В моем реальном тесте я использую сервисный принцип аутентификации в Azure и использую azurerm бэкэнд. Я обновил свой ответ ниже для вашей справки.

Ziyang Liu-MSFT 07.06.2024 11:08
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
100
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как упоминалось в этом вопросе , вы можете использовать опцию -detailed-exitcode в terraform plan, чтобы проверить, есть ли какие-либо изменения. Согласно Команде: план,

-detailed-exitcode — Возвращает подробный код выхода при завершении команды. Если этот аргумент предоставлен, он изменяет коды выхода и их значения, чтобы предоставить более подробную информацию о том, что содержит результирующий план:

  • 0 = успешно с пустым диффом (без изменений)
  • 1 = Ошибка
  • 2 = успешно с непустым diff (присутствуют изменения)

Затем создайте выходную переменную , в моем примере ниже это deploy, чтобы контролировать, запускать ли Deployment этап. Когда значение retVal равно 2, установите значение deploy на true. В противном случае установите значение false.

На этапе Deployment используйте condition, чтобы контролировать, что этап будет запускаться только тогда, когда значение deploy равно true.

stages:
- stage: Just_printing
  displayName: 'Printing some variables'
  jobs:
  - job: CheckChanges
    displayName: 'Check Changes'
    steps:
    - task: Bash@3
      displayName: 'Check resource changes'
      name: setvar
      env: 
        ARM_CLIENT_ID: ${{ parameters.clientId }}
        ARM_CLIENT_SECRET: $(clientSecret)
        ARM_TENANT_ID: ${{ parameters.tenantId }}
        ARM_SUBSCRIPTION_ID: ${{ parameters.deploymentSubscriptionId }}
      inputs:
        targetType: 'inline'
        script: |
          terraform init -backend-config = "resource_group_name = {resource group which holds my storage account}" -backend-config = "storage_account_name = {storage account name}" -backend-config = "container_name = {container name}" -backend-config = "key=terraform.tfstate" -backend-config = "subscription_id = {Sub id}"
          terraform plan -input=false -no-color -detailed-exitcode
          retVal=$?
          if [ $retVal -eq 2 ]; then
              echo "##vso[task.setvariable variable=deploy;isOutput=true]true"
          else
              echo "##vso[task.setvariable variable=deploy;isOutput=true]false"
          fi

- stage: Deployment
  displayName: 'Terraform deploy'
  dependsOn: Just_printing
  condition: eq(dependencies.Just_printing.outputs['CheckChanges.setvar.deploy'], 'true')
  jobs:
  - deployment: terraform
...

В приведенном выше примере я использую принцип службы для аутентификации в Azure и сохраняю учетные данные как переменные среды. (По соображениям безопасности ARM_CLIENT_SECRET предоставляется через секретную переменную clientSecret) Вы также можете предоставить учетные данные в блоке вашего провайдера. Подробности см. в разделе Аутентификация с использованием принципала службы с секретом клиента. Убедитесь, что у вашего принципала службы достаточно разрешений для развертывания целевого ресурса. Вы можете назначить ему роль участника вашего подписчика.

Я использую бэкэнд azurerm и настраиваю его с помощью команды. Вы также можете настроить бэкэнд в блоке backend "azurerm". См. пример здесь Примеры конфигураций серверной части.

Другие вопросы по теме