gpt4 book ai didi

azure - Ansible如何从字典列表中查找字典

转载 作者:行者123 更新时间:2023-12-03 03:49:37 25 4
gpt4 key购买 nike

$ more defaults/mail.yaml

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

我想写一个ansible play来在azure中的注册表之间复制图像https://learn.microsoft.com/en-us/azure/container-registry/container-registry-import-images#import-from-a-registry-in-a-different-subscription

该播放应接受 2 个参数。 source_image 和 target_image,因此播放会将图像从源导入到目标

例如:

ansible-playbook sync-docker-image.yml -e source_image=dit.azurecr.io/repo1:v1.0.0.0 -e target_image=stagreg.azurecr.io/stage-repo:latest

2 个问题:

  1. 这里如何找出source_image或target_image在ansible playbook中属于哪个env(dev,uat或prod),基于env,我想选择subscription-id。因此,从上面的示例中,我想创建 2 个名为 source_subscription 和 target_subscription 的变量,并将它们分别分配给 dev、uat 订阅。

  2. 在 YAML 中,是否可以根据键访问字典列表中的变量,例如 envs[dev] 之类的变量?

谢谢

最佳答案

首先 - 如果可能 - 当您只有三个阶段时,不要在 envs 中使用字典项列表。我认为它们已经被命名,所以使用:

envs:
dev:
acr-names:
- ...
subscription-id: xxx
uat:
acr-names:
- ...
subscription-id: yyy
prod:
acr-names:
- ...
subscription-id: zzz

这将使通过 envs.devenvs.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 }}"

如果无法更改字典(因为您有“很多”),则需要迭代 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) 来获取特殊的字典您可以访问 item.keyand item.value.acr_namesand item.value.subscription_id` 来访问字典中的值。我不建议这样做。

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

所有这些都必须对源和目标执行两次。

关于azure - Ansible如何从字典列表中查找字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67277045/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com