Я определил основную книгу воспроизведения, которая вызывает другую книгу подготовки через import_playbook.
Книга подготовки возвращает учетные данные для репозитория S3, var в данный момент называется «service_secrets», что является словарем (см. ниже). Этот словарь необходимо добавить в последний элемент product.dependents. Индикатором выбора конкретного элемента списка может быть просто «Source=S3».
---
- name: 'Preparation'
ansible.builtin.import_playbook: 'playbook_preparation.yml'
vars:
product:
name: 'mssql'
dependencies:
- Name: 'SqlServer'
Source: 'psgallery'
Type: 'psmodule'
- Name: 'SqlServerDsc'
Source: 'psgallery'
Type: 'dscmodule'
- Name: 'AWSPowershell.NetCore'
Source: 'psgallery'
Type: 'psmodule'
- Name: 'ComputerManagementDsc'
Source: 'psgallery'
Type: 'dscmodule'
- Name: >-
{{
["mssql", ci.attributes.input_parameters.mssql.version,
ci.attributes.input_parameters.mssql.edition,
ci.attributes.input_parameters.mssql.language]
| join("_")
}}
Source: 'S3'
Type: 'iso'
Bucket: 'repository'
Новый факт «service_secrets» выглядит примерно так:
"service_secrets": {
"Access_key_id": "abc",
"Access_key_secret": "defghi",
"Bucket": "repository",
"Endpoint": "https://s3.abc.com"
}
Я пытался поэкспериментировать с функцией join(), но мне не удалось поместить service_secrets в последний элемент списка.
- name: DEBUG
debug:
msg: '{{ product | combine({"dependencies": [service_secrets]}, list_merge = "append") }}'
loop: '{{ product.dependencies }}'
when: 'item.Source == "S3"'
Это приведет к:
ok: [localhost] => (item = {'Name': 'mssql_2022_standard_en', 'Source': 'S3', 'Type': 'iso', 'Bucket': 'repository'}) => {
"msg": {
"dependencies": [
{
"Name": "SqlServer",
"Source": "psgallery",
"Type": "psmodule"
},
{
"Name": "SqlServerDsc",
"Source": "psgallery",
"Type": "dscmodule"
},
{
"Name": "AWSPowershell.NetCore",
"Source": "psgallery",
"Type": "psmodule"
},
{
"Name": "ComputerManagementDsc",
"Source": "psgallery",
"Type": "dscmodule"
},
{
"Bucket": "repository",
"Name": "mssql_2022_standard_en",
"Source": "S3",
"Type": "iso"
},
{
"Access_key_id": "abc",
"Access_key_secret": "defgh",
"Bucket": "repository",
"Endpoint": "https://s3.abc.com"
}
],
"name": "mssql"
}
}
Чтобы было более понятно: последние два элемента списка product.dependents должны быть одним элементом.
Есть несколько способов добиться этого, я хотел бы показать вам два разных, поскольку оба имеют свои преимущества и недостатки.
Ваши исходные данные
vars:
dependencies:
- Name: 'SqlServer'
Source: 'psgallery'
Type: 'psmodule'
- Name: 'SqlServerDsc'
Source: 'psgallery'
Type: 'dscmodule'
- Name: 'AWSPowershell.NetCore'
Source: 'psgallery'
Type: 'psmodule'
- Name: 'ComputerManagementDsc'
Source: 'psgallery'
Type: 'dscmodule'
- Name: mssql_2022_standard_en
Source: 'S3'
Type: 'iso'
Bucket: 'repository'
- Name: 'AnotherDependency_notFromS3'
Source: 'psgallery'
Type: 'dscmodule'
service_secrets:
Access_key_id: abc
Access_key_secret: defghi
Bucket: repository
Endpoint: https://s3.abc.com
Может быть реализовано в одной задаче без необходимости подготовки данных в отдельной задаче. Сначала ваш dependencies
список разбивается на элементы Source == 'S3'
да или нет.
Разделение работает с помощью функций ignoreattr() или selectattr(). Элементы, атрибут Source == 'S3'
которых либо отклонен, либо отфильтрован (выбран).
Для всех элементов, источником которых является S3, добавляются service_secrets. Service_secrets добавляются с помощью map() , при этом объединение(service_secrets) выполняется для каждого элемента в списке.
Два отдельных списка затем снова добавляются вместе.
Я рассматриваю это как способ реализации этого с помощью Ansible. Недостаток в том, что ваш список dependencies
может иметь другой порядок сортировки, чем в начале. Сравните порядок сортировки обоих результатов. Однако, если порядок не имеет значения, я бы порекомендовал этот метод.
Код задачи
- name: Variant 1 - split by Source, enrich and recombine
debug:
msg: "{{ dependencies_not_s3 + dependencies_s3 }}"
vars:
dependencies_not_s3: "{{ dependencies | rejectattr('Source', 'eq', 'S3') }}"
dependencies_s3: "{{ dependencies | selectattr('Source', 'eq', 'S3') | map('combine', service_secrets) }}"
Результат
TASK [Variant 1 - split by Source, enrich and recombine] ************
ok: [localhost] => {
"msg": [
{
"Name": "SqlServer",
"Source": "psgallery",
"Type": "psmodule"
},
{
"Name": "SqlServerDsc",
"Source": "psgallery",
"Type": "dscmodule"
},
{
"Name": "AWSPowershell.NetCore",
"Source": "psgallery",
"Type": "psmodule"
},
{
"Name": "ComputerManagementDsc",
"Source": "psgallery",
"Type": "dscmodule"
},
{
"Name": "AnotherDependency_notFromS3",
"Source": "psgallery",
"Type": "dscmodule"
},
{
"Access_key_id": "abc",
"Access_key_secret": "defghi",
"Bucket": "repository",
"Endpoint": "https://s3.abc.com",
"Name": "mssql_2022_standard_en",
"Source": "S3",
"Type": "iso"
}
]
}
Во втором варианте вы перебираете список dependencies
как исходный набор и создаете новый список с помощью модуля set_fact. В зависимости от источника новый элемент сначала дополняется атрибутом service_secrets.
Для каждой записи в списке dependencies
требуется шаг итерации задачи, но это гарантирует сохранение исходного порядка сортировки списка dependencies
.
Будьте осторожны, если вы делаете это несколько раз для разных списков зависимостей, которые начинаются с пустой новой переменной.
Код задачи
- name: Variant 2 - iterate over dependencies
set_fact:
extended_dependencies: "{{ (extended_dependencies | default([])) + [new_item] }}"
vars:
new_item: "{{ item | combine(service_secrets) if item.Source == 'S3' else item }}"
with_items: "{{ dependencies }}"
- name: Print result from Variant 2
debug:
var: extended_dependencies
Результат
TASK [Variant 2 - iterate over dependencies] **************************************************************************
ok: [localhost] => (item = {'Name': 'SqlServer', 'Source': 'psgallery', 'Type': 'psmodule'})
ok: [localhost] => (item = {'Name': 'SqlServerDsc', 'Source': 'psgallery', 'Type': 'dscmodule'})
ok: [localhost] => (item = {'Name': 'AWSPowershell.NetCore', 'Source': 'psgallery', 'Type': 'psmodule'})
ok: [localhost] => (item = {'Name': 'ComputerManagementDsc', 'Source': 'psgallery', 'Type': 'dscmodule'})
ok: [localhost] => (item = {'Name': 'mssql_2022_standard_en', 'Source': 'S3', 'Type': 'iso', 'Bucket': 'repository'})
ok: [localhost] => (item = {'Name': 'AnotherDependency_notFromS3', 'Source': 'psgallery', 'Type': 'dscmodule'})
TASK [Print result from Variant 2] ************************************************************************************
ok: [localhost] => {
"extended_dependencies": [
{
"Name": "SqlServer",
"Source": "psgallery",
"Type": "psmodule"
},
{
"Name": "SqlServerDsc",
"Source": "psgallery",
"Type": "dscmodule"
},
{
"Name": "AWSPowershell.NetCore",
"Source": "psgallery",
"Type": "psmodule"
},
{
"Name": "ComputerManagementDsc",
"Source": "psgallery",
"Type": "dscmodule"
},
{
"Access_key_id": "abc",
"Access_key_secret": "defghi",
"Bucket": "repository",
"Endpoint": "https://s3.abc.com",
"Name": "mssql_2022_standard_en",
"Source": "S3",
"Type": "iso"
},
{
"Name": "AnotherDependency_notFromS3",
"Source": "psgallery",
"Type": "dscmodule"
}
]
}