Во-первых, если возможно, когда у вас есть только три этапа, не используйте список элементов словаря в envs
. Я предполагаю, что они уже названы, поэтому используйте:
envs:
dev:
acr-names:
- ...
subscription-id: xxx
uat:
acr-names:
- ...
subscription-id: yyy
prod:
acr-names:
- ...
subscription-id: zzz
Это упростит доступ к этапам через envs.dev
или envs.uat
и т. д. Поэтому вам нужно перебирать только envs.dev.acr-names
(можно использовать _ вместо -, иначе позже у вас возникнут проблемы). Внутри итерации вы можете использовать условие when для проверки элемента по вашему источнику:
- name: "Facts"
set_fact:
envs:
dev:
acr_names:
- intake.azurecr.io
- dit.azurecr.io
- dev.azurecr.io
subscription_id: xxx
uat:
acr_names:
- stagreg.azurecr.io
subscription_id: yyy
prod:
acr_names:
- prodreg.azurecr.io
subscription_id: zzz
source_image: "dit.azurecr.io/repo1:v1.0.0.0"
target_image: "stagreg.azurecr.io/stage-repo:latest"
- name: "Identify source subscription"
set_fact:
source_subscription: "{{ envs.dev.subscription_id }}"
when:
- "item in source_image"
- "source_subscription is undefined"
loop: "{{ envs.dev.acr_names }}"
Если невозможно изменить dict (потому что у вас их много), вам нужно перебрать элементы в envs
. Если возможно, не создавайте случайные ключи, а используйте именованный элемент. Так что такая структура была бы лучше
envs:
- name: dev
acr_names:
- ...
subscription_id: xxx
- name: uat
acr_names:
- ...
subscription_id: yyy
...
Итак, вы перебираете элементы в envs
, а затем перебираете item.acr_names
, чтобы найти свою систему. Это сложнее, потому что вы перебираете список, а затем перебираете элементы в этом списке. Я думаю, что это невозможно с одной единственной задачей. Но с данной структурой проблема в том, что строка в source_target
не совсем та, что в acr_names
. Поэтому удалите все после косой черты, и тогда вы сможете использовать другой метод для поиска строки в списке.
- name: "Identify source subscription"
set_fact:
source_subscription: "{{ env.subscription_id }}"
when:
- "source_image.split('/')[0] in env.acr_names"
- "source_subscription is undefined"
loop: "{{ envs }}"
loop_control:
loop_var: env
Вы также можете использовать фильтр split
в первом примере, не зацикливаясь на envs.dev
и т. д.
- name: "Show result"
set_fact:
source_subscription: "{{ envs.dev.subscription_id }}"
when:
- "source_image.split('/')[0] in envs.dev.acr_names"
Если вам действительно нужно использовать данную структуру, вам нужно перебрать файл envs
. Он считает словарь со случайным ключом корневым элементом. Это делает его очень сложным. В этом случае вам нужно перебрать его, включить отдельный файл задач с include_tasks
и внутри этого списка задач вам нужен фильтр lookup('dict',env) to get a special dict and you can access
item.keyand
item.value.acr_namesand
item.value.subscription_id` для доступа к значениям внутри dict. Я бы не рекомендовал это.
- name: "Identify source subscription"
include_tasks: find_env.yml
loop: "{{ envs }}"
loop_control:
loop_var: env
а find_env.yml
содержит:
- name: "Show result"
set_fact:
source_subscription: "{{ env[item.key].subscription_id }}"
when:
- "source_image.split('/')[0] in env[item.key].acr_names"
- "source_subscription is undefined"
loop: "{{ env | dict2items }}"
Все это нужно сделать дважды для источника и цели.
person
TRW
schedule
29.04.2021