$ 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
I want to write a ansible play to copy the image between registries in azure https://learn.microsoft.com/en-us/azure/container-registry/container-registry-import-images#import-from-a-registry-in-a-different-subscription
The play should accept 2 parameters. source_image and target_image, so the play will import the image from source to destination
For Ex:
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 questions:
Here how can I find out the which env(dev,uat or prod) the source_image or target_image belongs to in ansible playbook, based on env, I want to choose the subscription-id. So from the above example, I want to create 2 variables called source_subscription and target_subscription and assign them to dev, uat subscriptions respectively.
In YAML, is it possible to access a variable in list of dictionaries based on key, for example something like envs[dev]?
Thanks
First - if possible - when you only have the three stages, don't use a list of dict items in
envs
. I asume they are already named, so use:This would make it easier to access the stages via
envs.dev
orenvs.uat
etc. So you need to iterate only overenvs.dev.acr-names
(maybe use _ instead of -, otherwise you'll get in trouble later). Inside the iteration you can use the when condition to check the item against your source:If it isn't possible to change the dict (because you have "many"), you need to iterate over the items in
envs
. If possible, do not create "random" keys but use "name"d item. So a structure like this would be betterSo you iterate over the items in
envs
and then iterate overitem.acr_names
to find your system. This is more complicated, because you loop over a list and iterate then over items in that list. I think, this isn't possible with one single task. But with the given structure the problem is - the string insource_target
is not exactly what is inacr_names
. So remove anything after the slash and then you can use a different method to search for a string in a list.You could also use the
split
filter in the first example without looping overenvs.dev
etc.If you really need to use your given structure, then you need to iterate over the
envs
. It countains a dictionary with a random key as root element. That makes it very complicated. In that case you need to loop over it, include a separate tasks file withinclude_tasks
and inside that tasks list, you need the filterlookup('dict',env) to get a special dict and you can access
item.keyand
item.value.acr_namesand
item.value.subscription_id` to access the values inside the dict. I wouldn't recommend that.and
find_env.yml
contains:All of this must be done twice for source and target.