В шаблоне конвейера Azure DevOps мне нужно передать переменные в качестве словаря в другой шаблон, который будет использовать задачу ansible для обработки всех ключей в словаре.
type: object
кажется уместным, но я ищу работающий пример.
trigger:
- main
stages:
- stage: Deploy
jobs:
- job: DeployJob
pool:
vmImage: 'ubuntu-latest'
steps:
- template: ansible-template.yml
parameters:
ansibleVars:
var1: value1
var2: value2
parameters:
- name: ansibleVars
type: object
default: {}
jobs:
- job: AnsibleJob
pool:
vmImage: 'ubuntu-latest'
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.x'
addToPath: true
- script: |
python -m pip install ansible-core
displayName: 'Install Ansible'
- script: |
echo "${{ parameters.ansibleVars }}" > vars.yml
displayName: 'Create vars file'
- task: Ansible@0
displayName: 'Run playbook'
inputs:
ansibleInterface: 'agentMachine'
playbookPathOnAgentMachine: './ansible/playbook.yml'
inventoriesAgentMachine: 'file'
inventoryFileOnAgentMachine: './ansible/inventory/hosts'
args: -vv -e @vars.yaml
failOnStdErr: false
Согласно документации, вы можете использовать переменные из файла JSON или YAML:
ansible-playbook release.yml --extra-vars "@some_file.json"
ansible-playbook release.yml --extra-vars "@some_file.yaml"
В своем конвейере вы можете использовать ConvertToJson, чтобы преобразовать параметр в строку JSON, а затем сгенерировать файл JSON и использовать его в своей задаче Ansible@0
.
parameters:
- name: ansibleVars
type: object
default:
version: 1.0.0
other_varialbe: foo
- name: varsFile
type: string
default: $(Agent.TempDirectory)/ansible-vars.json
trigger: none
pool:
vmImage: 'ubuntu-latest'
steps:
- script: |
echo ${ANSIBLE_VARS} > ${ANSIBLE_VARS_FILE}
cat ${ANSIBLE_VARS_FILE}
displayName: Create json variables file
env:
ANSIBLE_VARS_FILE: ${{ parameters.varsFile }}
ANSIBLE_VARS: ${{ convertToJson(parameters.ansibleVars) }}
- task: Ansible@0
displayName: 'Run playbook'
inputs:
ansibleInterface: 'agentMachine'
playbookPathOnAgentMachine: './ansible/playbook.yml'
inventoriesAgentMachine: 'file'
inventoryFileOnAgentMachine: './ansible/inventory/hosts'
args: -vv -e @${{ parameters.varsFile }} # <-------------- use generated json file
failOnStdErr: false
Обратите внимание, что я присваиваю строку json переменной среды задачи вместо того, чтобы использовать ее непосредственно в теле сценария — таким образом мне не нужно экранировать кавычки и другие специальные символы:
- script: |
# ...
env:
ANSIBLE_VARS: ${{ convertToJson(parameters.ansibleVars) }}
Вы можете воспользоваться примером ниже, чтобы передать словарь в шаблон YAML:
# templates/steps.yml
parameters:
- name: vars
type: object
default: []
steps:
- powershell: |
Write-Host "var1 = $env:var1"
Write-Host "var2 = $env:var2"
Write-Host "var3 = $env:var3"
displayName: 'Show all vars'
env:
${{ parameters.vars }}
- ${{ each var in parameters.vars }}:
- powershell: |
Write-Host "Key = ${{ var.Key }}"
Write-Host "Value = ${{ var.Value }}"
displayName: 'Show var - ${{ var.Key }}'
# azure-pipelines.yml
steps:
- template: templates/steps.yml
parameters:
vars:
var1: valu1
var2: valu2
var3: valu3
Если вы хотите передать все пары ключ-значение в поле args
задачи Ansible@0, вы можете установить шаблон, как показано ниже.
# templates/steps.yml
parameters:
- name: vars
type: object
default: []
steps:
- powershell: Write-Host "##vso[task.setvariable variable=argVar;]empty"
displayName: 'Set argVar'
- ${{ each var in parameters.vars }}:
- powershell: |
Write-Host "Key = ${{ var.Key }}"
Write-Host "Value = ${{ var.Value }}"
if ("$(argVar)" -ne "empty" ) {
Write-Host "##vso[task.setvariable variable=argVar;]$(argVar) ${{ var.Key }}=${{ var.Value }}"
}
else {
Write-Host "##vso[task.setvariable variable=argVar;]${{ var.Key }}=${{ var.Value }}"
}
displayName: 'Show var - ${{ var.Key }}'
- powershell: Write-Host "$(argVar)"
displayName: 'Show var argVar'
- task: Ansible@0
displayName: 'Run playbook'
inputs:
playbookPathOnAgentMachine: path/to/playbook.yml
inventoriesAgentMachine: file
inventoryFileOnAgentMachine: path/to/hosts
args: '$(argVar)'
Можете ли вы показать нам код, чтобы лучше проиллюстрировать проблему? Например, как вы делаете вид, что используете задачу Ansible?