azure
azure copied to clipboard
azure_rm_galleryimageversion: delete doesn't catch permission issues
SUMMARY
Delete image version fails silently.
ISSUE TYPE
- Bug Report
COMPONENT NAME
azure_rm_galleryimageversion
ANSIBLE VERSION
ansible [core 2.11.8]
config file = None
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python3.6/site-packages/ansible
ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/local/bin/ansible
python version = 3.6.8 (default, Nov 16 2020, 16:55:22) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
jinja version = 2.11.3
libyaml = True
COLLECTION VERSION
Collection Version
------------------ -------
azure.azcollection 1.11.0
OS / ENVIRONMENT
CentOS Linux release 7.9.2009
STEPS TO REPRODUCE
- name: delete gallery image version
azure_rm_galleryimageversion:
state: absent
resource_group: "{{ resource_group }}"
gallery_name: "{{ image_gallery }}"
location: "{{ image_location }}"
gallery_image_name: "{{ image_name }}"
name: "{{ image_version }}"
publishing_profile:
exclude_from_latest: no
replica_count: "{{ regional_replica_count }}"
storage_account_type: "{{ storage_account_type }}"
target_regions:
- name: "{{ image_location }}"
regional_replica_count: "{{ regional_replica_count }}"
storage_account_type: "{{ storage_account_type }}"
storage_profile:
source_image: "{{ image_name }}"
EXPECTED RESULTS
Image version is deleted.
ACTUAL RESULTS
Image version is not deleted and result is ok.
TASK [delete gallery image version] *******************************************************************************************************************************************************************************
[WARNING]: Azure API profile latest does not define an entry for GenericRestClient
ok: [localhost]
Note that the image version to delete produces an error at creation, not sure if both issues are linked.
just realized that it comes from a permission issue...
tested in same environment with az cli:
- name: delete gallery image version
ignore_errors: yes
ansible.builtin.shell: |
set -e
az login --service-principal -u $AZURE_CLIENT_ID -p "$AZURE_SECRET" --tenant $AZURE_TENANT >/dev/null
az account set --subscription $AZURE_SUBSCRIPTION_ID >/dev/null
az sig image-version delete \
--resource-group {{ resource_group }} \
--gallery-name "{{ image_gallery }}" \
--gallery-image-definition "{{ image_name }}" \
--gallery-image-version "{{ image_version }}"
result:
stderr_lines": ["ForbiddenError: The client '...' with object id '...' does not have authorization to perform action 'Microsoft.Compute/galleries/images/versions/delete' over scope '/subscriptions/.../resourceGroups/images/providers/Microsoft.Compute/galleries/images/images/.../versions/1.10.1' or the scope is invalid. If access was recently granted, please refresh your credentials."]
Fixed by adding Microsoft.Compute/galleries/images/versions/delete
permission.
@achevalet Thank you for submitting this question? Could you please provide a complete Playbook and the implementation results? This will go a long way towards solving the problem. Thank you very much!
ansible-playbook ***.yml -vvv
@Fred-sun I'm sorry but it would be full of redacted lines.. I think that the required information are listed in this ticket. Basically, if the user does not have the permission Microsoft.Compute/galleries/images/versions/delete
, this module is not able to delete an image version (which is normal) but it does not return any error.
@achevalet If it can't be delete it, I will definitely get an error. I executed YAML as follows and the created resource was deleted. Can you try it on? Thank you very much!
- name: Get a simple gallery Image Version info.
azure_rm_galleryimageversion_info:
resource_group: "{{ resource_group }}"
gallery_name: myGallery{{ rpfx }}
gallery_image_name: myImage
name: 10.1.3
- name: Delete gallery image Version.
azure_rm_galleryimageversion:
resource_group: "{{ resource_group }}"
gallery_name: myGallery{{ rpfx }}
gallery_image_name: myImage
name: 10.1.3
state: absent
Sorry for late answer. Yes, this code is working fine on my end as long as the Azure user has correct permissions.
On Azure side, if you drop only the delete permission on images versions (Microsoft.Compute/galleries/images/versions/delete
), keep read and create permissions, this code produces no error but does not actually delete the image version.
Thank you for your reply, I think there is no problem with my local deletion. Could you do it again? First, use azure_rn_galleryImageversion_info to get related information, then delete, and help provide all -vvvv info and information in the register. Thank you very much!
ansible-playbook ****.yml -vvvv
- name: Get a simple gallery Image Version info.
azure_rm_galleryimageversion_info:
resource_group: "{{ resource_group }}"
gallery_name: myGallery{{ rpfx }}
gallery_image_name: myImage
name: 10.1.3
register: output
- debug:
var: output
Sorry again, I don't have any test environment right now. Basically, to be able to reproduce this bug, az
cli must produce this error when you try to delete the image:
stderr_lines": ["ForbiddenError: The client '...' with object id '...' does not have authorization to perform action 'Microsoft.Compute/galleries/images/versions/delete' over scope '/subscriptions/.../resourceGroups/images/providers/Microsoft.Compute/galleries/images/images/.../versions/1.10.1' or the scope is invalid. If access was recently granted, please refresh your credentials."]
It occurs only if you use a service principal with limited access to connect to Azure API. This "user" is defined in the environment variable $AZURE_CLIENT_ID
used by the ansible module for authentication. You must set read
and write
permission but not delete
to be able to repoduce.
Please let me know if verbose mode still needed, I could send it later if needed.
I am seeing a similar issue with collection version 1.13.0, but I am authenticated with an MSI that has contributor role over the whole subscription and using the CLI to delete the gallery image version works.
- name: List all gallery {{ image_name }} versions
azure.azcollection.azure_rm_galleryimageversion_info:
gallery_name: "{{ azure.sig_name }}"
gallery_image_name: "{{ image_name }}"
resource_group: "{{ azure.sig_resource_group }}"
register: sig_image
- name: sorting all gallery {{ image_name }} versions
set_fact:
sig_image_sorted: "{{ sig_image.versions | sort(attribute='publishing_profile.publishedDate') }}"
when: sig_image |length > 0
- name: Remove old {{ image_name }} versions
azure.azcollection.azure_rm_galleryimageversion:
gallery_name: "{{ azure.sig_name }}"
gallery_image_name: "{{ image_name }}"
location: "{{ azure.location }}"
name: "{{ version_item.name }}*"
resource_group: "{{ azure.sig_resource_group }}"
state: absent
loop: "{{ sig_image_sorted[:-(azure.versions_to_keep|int)] }}"
loop_control:
label: "{{ version_item.name }}"
loop_var: version_item
The task to delete the old versions has this output
TASK [retire-base-images : Remove old com.lgc.windows2012.base versions] *******
Thursday 14 July 2022 10:54:04 +0000 (0:00:00.168) 0:00:09.924 *********
ok: [localhost] => (item=21.02.17)
Here's debug output of that task
83 1657807441.69273: ^ task is: TASK: retire-base-images : Remove old {{ image_name }} versions
83 1657807441.69283: ^ state is: HOST STATE: block=2, task=3, rescue=0, always=0, run_state=ITERATING_TASKS, fail_state=FAILED_NONE, pending_setup=False, tasks child state? (HOST STATE: block=0, task=5, rescue=0, always=0, run_state=ITERATING_TASKS, fail_state=FAILED_NONE, pending_setup=False, tasks child state? (HOST STATE: block=0, task=1, rescue=0, always=0, run_state=ITERATING_TASKS, fail_state=FAILED_NONE, pending_setup=False, tasks child state? (None), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False
83 1657807441.69288: done building task lists
83 1657807441.69293: counting tasks in each state of execution
83 1657807441.69300: done counting tasks in each state of execution:
num_setups: 0
num_tasks: 1
num_rescue: 0
num_always: 0
83 1657807441.69306: advancing hosts in ITERATING_TASKS
83 1657807441.69310: starting to advance hosts
83 1657807441.69314: getting the next task for host localhost
83 1657807441.69327: done getting next task for host localhost
83 1657807441.69334: ^ task is: TASK: retire-base-images : Remove old {{ image_name }} versions
83 1657807441.69341: ^ state is: HOST STATE: block=2, task=3, rescue=0, always=0, run_state=ITERATING_TASKS, fail_state=FAILED_NONE, pending_setup=False, tasks child state? (HOST STATE: block=0, task=5, rescue=0, always=0, run_state=ITERATING_TASKS, fail_state=FAILED_NONE, pending_setup=False, tasks child state? (HOST STATE: block=0, task=1, rescue=0, always=0, run_state=ITERATING_TASKS, fail_state=FAILED_NONE, pending_setup=False, tasks child state? (None), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False
83 1657807441.69346: done advancing hosts to next task
83 1657807441.69351: getting variables
83 1657807441.69355: in VariableManager get_vars()
83 1657807441.69384: Calling all_inventory to load vars for localhost
83 1657807441.69395: Calling groups_inventory to load vars for localhost
83 1657807441.69401: Calling all_plugins_inventory to load vars for localhost
83 1657807441.70307: Loading ModuleDocFragment 'vars_plugin_staging' from /usr/lib/python3.8/site-packages/ansible/plugins/doc_fragments/vars_plugin_staging.py (found_in_cache=True, class_only=False)
83 1657807441.70712: Loaded config def from plugin (vars/host_group_vars)
83 1657807441.70723: Loading VarsModule 'host_group_vars' from /usr/lib/python3.8/site-packages/ansible/plugins/vars/host_group_vars.py (found_in_cache=True, class_only=False)
83 1657807441.70792: Calling all_plugins_play to load vars for localhost
83 1657807441.71621: Loading ModuleDocFragment 'vars_plugin_staging' from /usr/lib/python3.8/site-packages/ansible/plugins/doc_fragments/vars_plugin_staging.py (found_in_cache=True, class_only=False)
83 1657807441.71960: Loaded config def from plugin (vars/host_group_vars)
83 1657807441.71968: Loading VarsModule 'host_group_vars' from /usr/lib/python3.8/site-packages/ansible/plugins/vars/host_group_vars.py (found_in_cache=True, class_only=False)
83 1657807441.72018: Calling groups_plugins_inventory to load vars for localhost
83 1657807441.72809: Loading ModuleDocFragment 'vars_plugin_staging' from /usr/lib/python3.8/site-packages/ansible/plugins/doc_fragments/vars_plugin_staging.py (found_in_cache=True, class_only=False)
83 1657807441.73169: Loaded config def from plugin (vars/host_group_vars)
83 1657807441.73178: Loading VarsModule 'host_group_vars' from /usr/lib/python3.8/site-packages/ansible/plugins/vars/host_group_vars.py (found_in_cache=True, class_only=False)
83 1657807441.73208: Calling groups_plugins_play to load vars for localhost
83 1657807441.74123: Loading ModuleDocFragment 'vars_plugin_staging' from /usr/lib/python3.8/site-packages/ansible/plugins/doc_fragments/vars_plugin_staging.py (found_in_cache=True, class_only=False)
83 1657807441.74461: Loaded config def from plugin (vars/host_group_vars)
83 1657807441.74470: Loading VarsModule 'host_group_vars' from /usr/lib/python3.8/site-packages/ansible/plugins/vars/host_group_vars.py (found_in_cache=True, class_only=False)
83 1657807441.75530: Loading ModuleDocFragment 'vars_plugin_staging' from /usr/lib/python3.8/site-packages/ansible/plugins/doc_fragments/vars_plugin_staging.py (found_in_cache=True, class_only=False)
83 1657807441.75939: Loaded config def from plugin (vars/host_group_vars)
83 1657807441.75948: Loading VarsModule 'host_group_vars' from /usr/lib/python3.8/site-packages/ansible/plugins/vars/host_group_vars.py (found_in_cache=True, class_only=False)
83 1657807441.76882: Loading ModuleDocFragment 'vars_plugin_staging' from /usr/lib/python3.8/site-packages/ansible/plugins/doc_fragments/vars_plugin_staging.py (found_in_cache=True, class_only=False)
83 1657807441.77261: Loaded config def from plugin (vars/host_group_vars)
83 1657807441.77269: Loading VarsModule 'host_group_vars' from /usr/lib/python3.8/site-packages/ansible/plugins/vars/host_group_vars.py (found_in_cache=True, class_only=False)
83 1657807441.77832: done with get_vars()
83 1657807441.77860: done getting variables
83 1657807441.77953: sending task start callback, copying the task so we can template it temporarily
83 1657807441.77966: done copying, going to template now
83 1657807441.78122: variable 'image_name' from source: include params
83 1657807441.78133: variable 'item' from source: include params
83 1657807441.78213: variable 'item' from source: include params
83 1657807441.78229: done templating
83 1657807441.78235: here goes the callback...
TASK [retire-base-images : Remove old com.lgc.windows2012.base versions] *******
Thursday 14 July 2022 14:04:01 +0000 (0:00:00.174) 0:00:10.438 *********
83 1657807441.78272: sending task start callback
83 1657807441.78278: entering _queue_task() for localhost/azure.azcollection.azure_rm_galleryimageversion
83 1657807441.78284: Creating lock for azure.azcollection.azure_rm_galleryimageversion
83 1657807441.78592: worker is 1 (out of 1 available)
83 1657807441.78658: exiting _queue_task() for localhost/azure.azcollection.azure_rm_galleryimageversion
83 1657807441.78772: done queuing things up, now waiting for results queue to drain
83 1657807441.78781: waiting for pending results...
187 1657807441.78847: running TaskExecutor() for localhost/TASK: retire-base-images : Remove old {{ image_name }} versions
187 1657807441.78952: in run() - task 0242ac11-0003-677f-a7a8-000000000051
187 1657807441.78976: variable 'ansible_search_path' from source: unknown
187 1657807441.78983: variable 'ansible_search_path' from source: unknown
187 1657807441.81388: Loading FilterModule 'core' from /usr/lib/python3.8/site-packages/ansible/plugins/filter/core.py
187 1657807441.81449: Loading FilterModule 'encryption' from /usr/lib/python3.8/site-packages/ansible/plugins/filter/encryption.py
187 1657807441.81508: Loading FilterModule 'mathstuff' from /usr/lib/python3.8/site-packages/ansible/plugins/filter/mathstuff.py
187 1657807441.81563: Loading FilterModule 'urls' from /usr/lib/python3.8/site-packages/ansible/plugins/filter/urls.py
187 1657807441.81606: Loading FilterModule 'urlsplit' from /usr/lib/python3.8/site-packages/ansible/plugins/filter/urlsplit.py
187 1657807441.81872: variable 'sig_image_sorted' from source: set_fact
187 1657807441.81959: variable 'azure' from source: role '' defaults
187 1657807441.82296: trying /usr/lib/python3.8/site-packages/ansible/plugins/lookup
187 1657807441.82955: Loaded config def from plugin (lookup/env)
187 1657807441.82965: Loading LookupModule 'env' from /usr/lib/python3.8/site-packages/ansible/plugins/lookup/env.py
187 1657807441.83691: Loaded config def from plugin (lookup/env)
187 1657807441.83706: Loading LookupModule 'env' from /usr/lib/python3.8/site-packages/ansible/plugins/lookup/env.py (found_in_cache=True, class_only=False)
187 1657807441.84462: Loaded config def from plugin (lookup/env)
187 1657807441.84472: Loading LookupModule 'env' from /usr/lib/python3.8/site-packages/ansible/plugins/lookup/env.py (found_in_cache=True, class_only=False)
187 1657807441.84825: variable 'ansible_connection' from source: host vars for 'localhost'
187 1657807441.84850: variable 'omit' from source: magic vars
187 1657807441.85179: variable 'dry_run' from source: role '' defaults
187 1657807441.85331: Loading FilterModule 'core' from /usr/lib/python3.8/site-packages/ansible/plugins/filter/core.py (found_in_cache=True, class_only=False)
187 1657807441.85341: Loading FilterModule 'encryption' from /usr/lib/python3.8/site-packages/ansible/plugins/filter/encryption.py (found_in_cache=True, class_only=False)
187 1657807441.85354: Loading FilterModule 'mathstuff' from /usr/lib/python3.8/site-packages/ansible/plugins/filter/mathstuff.py (found_in_cache=True, class_only=False)
187 1657807441.85364: Loading FilterModule 'urls' from /usr/lib/python3.8/site-packages/ansible/plugins/filter/urls.py (found_in_cache=True, class_only=False)
187 1657807441.85371: Loading FilterModule 'urlsplit' from /usr/lib/python3.8/site-packages/ansible/plugins/filter/urlsplit.py (found_in_cache=True, class_only=False)
187 1657807441.86030: Loaded config def from plugin (lookup/env)
187 1657807441.86043: Loading LookupModule 'env' from /usr/lib/python3.8/site-packages/ansible/plugins/lookup/env.py (found_in_cache=True, class_only=False)
187 1657807441.86083: Evaluated conditional (not dry_run): True
187 1657807441.86093: variable 'omit' from source: magic vars
187 1657807441.86198: variable 'image_name' from source: include params
187 1657807441.86208: variable 'item' from source: include params
187 1657807441.86297: variable 'item' from source: include params
187 1657807441.86351: variable 'omit' from source: magic vars
187 1657807441.86455: variable 'azure' from source: role '' defaults
187 1657807441.87111: Loaded config def from plugin (lookup/env)
187 1657807441.87123: Loading LookupModule 'env' from /usr/lib/python3.8/site-packages/ansible/plugins/lookup/env.py (found_in_cache=True, class_only=False)
187 1657807441.87904: Loaded config def from plugin (lookup/env)
187 1657807441.87924: Loading LookupModule 'env' from /usr/lib/python3.8/site-packages/ansible/plugins/lookup/env.py (found_in_cache=True, class_only=False)
187 1657807441.88587: Loaded config def from plugin (lookup/env)
187 1657807441.88597: Loading LookupModule 'env' from /usr/lib/python3.8/site-packages/ansible/plugins/lookup/env.py (found_in_cache=True, class_only=False)
187 1657807441.88641: variable 'image_name' from source: include params
187 1657807441.88739: variable 'image_name' from source: include params
187 1657807441.88749: variable 'item' from source: include params
187 1657807441.88883: variable 'azure' from source: role '' defaults
187 1657807441.89529: Loaded config def from plugin (lookup/env)
187 1657807441.89540: Loading LookupModule 'env' from /usr/lib/python3.8/site-packages/ansible/plugins/lookup/env.py (found_in_cache=True, class_only=False)
187 1657807441.90180: Loaded config def from plugin (lookup/env)
187 1657807441.90190: Loading LookupModule 'env' from /usr/lib/python3.8/site-packages/ansible/plugins/lookup/env.py (found_in_cache=True, class_only=False)
187 1657807441.90879: Loaded config def from plugin (lookup/env)
187 1657807441.90889: Loading LookupModule 'env' from /usr/lib/python3.8/site-packages/ansible/plugins/lookup/env.py (found_in_cache=True, class_only=False)
187 1657807441.91027: variable 'version_item' from source: unknown
187 1657807441.91148: variable 'azure' from source: role '' defaults
187 1657807441.91822: Loaded config def from plugin (lookup/env)
187 1657807441.91833: Loading LookupModule 'env' from /usr/lib/python3.8/site-packages/ansible/plugins/lookup/env.py (found_in_cache=True, class_only=False)
187 1657807441.92498: Loaded config def from plugin (lookup/env)
187 1657807441.92508: Loading LookupModule 'env' from /usr/lib/python3.8/site-packages/ansible/plugins/lookup/env.py (found_in_cache=True, class_only=False)
187 1657807441.93256: Loaded config def from plugin (lookup/env)
187 1657807441.93267: Loading LookupModule 'env' from /usr/lib/python3.8/site-packages/ansible/plugins/lookup/env.py (found_in_cache=True, class_only=False)
187 1657807441.93329: variable 'omit' from source: magic vars
187 1657807441.93475: variable 'image_name' from source: include params
187 1657807441.93486: variable 'item' from source: include params
187 1657807441.93549: variable 'ansible_connection' from source: host vars for 'localhost'
187 1657807441.93556: variable 'ansible_connection' from source: host vars for 'localhost'
187 1657807441.93580: trying /usr/lib/python3.8/site-packages/ansible/plugins/connection
187 1657807441.93927: Loading ModuleDocFragment 'connection_pipelining' from /usr/lib/python3.8/site-packages/ansible/plugins/doc_fragments/connection_pipelining.py (found_in_cache=True, class_only=False)
187 1657807441.94438: Loaded config def from plugin (connection/local)
187 1657807441.94450: Loading Connection 'local' from /usr/lib/python3.8/site-packages/ansible/plugins/connection/local.py (found_in_cache=True, class_only=False)
187 1657807441.94476: trying /usr/lib/python3.8/site-packages/ansible/plugins/shell
187 1657807441.94679: Loading ModuleDocFragment 'shell_common' from /usr/lib/python3.8/site-packages/ansible/plugins/doc_fragments/shell_common.py (found_in_cache=True, class_only=False)
187 1657807441.96856: Loaded config def from plugin (shell/sh)
187 1657807441.96878: Loading ShellModule 'sh' from /usr/lib/python3.8/site-packages/ansible/plugins/shell/sh.py (found_in_cache=True, class_only=False)
187 1657807441.97070: Loading ModuleDocFragment 'shell_common' from /usr/lib/python3.8/site-packages/ansible/plugins/doc_fragments/shell_common.py (found_in_cache=True, class_only=False)
187 1657807441.99285: Loaded config def from plugin (shell/sh)
187 1657807441.99296: Loading ShellModule 'sh' from /usr/lib/python3.8/site-packages/ansible/plugins/shell/sh.py (found_in_cache=True, class_only=False)
187 1657807441.99325: variable 'ansible_pipelining' from source: unknown
187 1657807441.99641: Loading ActionModule 'normal' from /usr/lib/python3.8/site-packages/ansible/plugins/action/normal.py (searched paths: /usr/lib/python3.8/site-packages/ansible/plugins/action/__pycache__:/usr/lib/python3.8/site-packages/ansible/plugins/action)
187 1657807441.99663: variable 'omit' from source: magic vars
187 1657807441.99683: starting attempt loop
187 1657807441.99690: running the handler
187 1657807441.99718: _low_level_execute_command(): starting
187 1657807441.99732: _low_level_execute_command(): executing: /bin/sh -c 'echo ~root && sleep 0'
187 1657807441.99751: in local.exec_command()
187 1657807441.99760: opening command with Popen()
187 1657807442.00154: done running command with Popen()
187 1657807442.00174: getting output with communicate()
187 1657807442.00397: done communicating
187 1657807442.00408: done with local.exec_command()
187 1657807442.00424: _low_level_execute_command() done: rc=0, stdout=/root, stderr=
187 1657807442.00448: _low_level_execute_command(): starting
187 1657807442.00478: _low_level_execute_command(): executing: /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1657807442.0043871-187-52252793169095 `" && echo ansible-tmp-1657807442.0043871-187-52252793169095="` echo /root/.ansible/tmp/ansible-tmp-1657807442.0043871-187-52252793169095 `" ) && sleep 0'
187 1657807442.00489: in local.exec_command()
187 1657807442.00500: opening command with Popen()
187 1657807442.00745: done running command with Popen()
187 1657807442.00766: getting output with communicate()
187 1657807442.01391: done communicating
187 1657807442.01400: done with local.exec_command()
187 1657807442.01411: _low_level_execute_command() done: rc=0, stdout=ansible-tmp-1657807442.0043871-187-52252793169095=/root/.ansible/tmp/ansible-tmp-1657807442.0043871-187-52252793169095, stderr=
187 1657807442.01651: ANSIBALLZ: Using lock for azure.azcollection.azure_rm_galleryimageversion
187 1657807442.01660: ANSIBALLZ: Acquiring lock
187 1657807442.01667: ANSIBALLZ: Lock acquired: 140584859734464
187 1657807442.01673: ANSIBALLZ: Creating module
187 1657807442.27952: ANSIBALLZ: Writing module into payload
187 1657807442.28157: ANSIBALLZ: Writing module
187 1657807442.28197: ANSIBALLZ: Renaming module
187 1657807442.28232: ANSIBALLZ: Done creating module
187 1657807442.28259: variable 'ansible_python_interpreter' from source: host vars for 'localhost'
187 1657807442.28355: transferring module to remote /root/.ansible/tmp/ansible-tmp-1657807442.0043871-187-52252793169095/AnsiballZ_azure_rm_galleryimageversion.py
187 1657807442.28491: done transferring module to remote
187 1657807442.28522: _low_level_execute_command(): starting
187 1657807442.28535: _low_level_execute_command(): executing: /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1657807442.0043871-187-52252793169095/ /root/.ansible/tmp/ansible-tmp-1657807442.0043871-187-52252793169095/AnsiballZ_azure_rm_galleryimageversion.py && sleep 0'
187 1657807442.28544: in local.exec_command()
187 1657807442.28553: opening command with Popen()
187 1657807442.28916: done running command with Popen()
187 1657807442.28940: getting output with communicate()
187 1657807442.29256: done communicating
187 1657807442.29265: done with local.exec_command()
187 1657807442.29275: _low_level_execute_command() done: rc=0, stdout=, stderr=
187 1657807442.29283: _low_level_execute_command(): starting
187 1657807442.29305: _low_level_execute_command(): executing: /bin/sh -c '/usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1657807442.0043871-187-52252793169095/AnsiballZ_azure_rm_galleryimageversion.py && sleep 0'
187 1657807442.29317: in local.exec_command()
187 1657807442.29329: opening command with Popen()
187 1657807442.29606: done running command with Popen()
187 1657807442.29628: getting output with communicate()
187 1657807444.09882: done communicating
187 1657807444.09897: done with local.exec_command()
187 1657807444.09913: _low_level_execute_command() done: rc=0, stdout={"changed": false, "invocation": {"module_args": {"gallery_name": "BASE_IMAGES", "gallery_image_name": "com.lgc.windows2012.base", "location": "southcentralus", "name": "21.02.17*", "resource_group": "MY-SUBSCRIPTION-SIG", "state": "absent", "auth_source": "msi", "cloud_environment": "AzureCloud", "api_profile": "latest", "append_tags": true, "profile": null, "subscription_id": null, "client_id": null, "secret": null, "tenant": null, "ad_user": null, "password": null, "cert_validation_mode": null, "adfs_authority_url": null, "log_mode": null, "log_path": null, "tags": null, "storage_profile": null, "publishing_profile": null}}, "warnings": ["Azure API profile latest does not define an entry for GenericRestClient"]}, stderr=
187 1657807444.09976: done with _execute_module (azure.azcollection.azure_rm_galleryimageversion, {'gallery_name': 'BASE_IMAGES', 'gallery_image_name': 'com.lgc.windows2012.base', 'location': 'southcentralus', 'name': '21.02.17*', 'resource_group': 'MY-SUBSCRIPTION-SIG', 'state': 'absent', '_ansible_check_mode': False, '_ansible_no_log': False, '_ansible_debug': True, '_ansible_diff': False, '_ansible_verbosity': 0, '_ansible_version': '2.12.7', '_ansible_module_name': 'azure.azcollection.azure_rm_galleryimageversion', '_ansible_syslog_facility': 'LOG_USER', '_ansible_selinux_special_fs': ['fuse', 'nfs', 'vboxsf', 'ramfs', '9p', 'vfat'], '_ansible_string_conversion_action': 'warn', '_ansible_socket': None, '_ansible_shell_executable': '/bin/sh', '_ansible_keep_remote_files': False, '_ansible_tmpdir': '/root/.ansible/tmp/ansible-tmp-1657807442.0043871-187-52252793169095/', '_ansible_remote_tmp': '~/.ansible/tmp'})
187 1657807444.10000: _low_level_execute_command(): starting
187 1657807444.10028: _low_level_execute_command(): executing: /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1657807442.0043871-187-52252793169095/ > /dev/null 2>&1 && sleep 0'
187 1657807444.10039: in local.exec_command()
187 1657807444.10052: opening command with Popen()
187 1657807444.10397: done running command with Popen()
187 1657807444.10422: getting output with communicate()
187 1657807444.10834: done communicating
187 1657807444.10844: done with local.exec_command()
187 1657807444.10854: _low_level_execute_command() done: rc=0, stdout=, stderr=
187 1657807444.10866: handler run complete
187 1657807444.10904: attempt loop complete, returning result
187 1657807444.11140: variable 'version_item' from source: unknown
187 1657807444.11281: dumping result to json
187 1657807444.11388: done dumping result, returning
187 1657807444.11411: done running TaskExecutor() for localhost/TASK: retire-base-images : Remove old {{ image_name }} versions [0242ac11-0003-677f-a7a8-000000000051]
187 1657807444.11422: sending task result for task 0242ac11-0003-677f-a7a8-000000000051
187 1657807444.11438: done sending task result for task 0242ac11-0003-677f-a7a8-000000000051
187 1657807444.11495: WORKER PROCESS EXITING
ok: [localhost] => (item=21.02.17)
@achevalet @jghal Thank you for submitting the problem, but I can remove it after repeated testing locally. 'OK' is returned when the image version number does not exist. Can you check if the resource exists before deleting it? Thank you very much!
Check resource exist or not:
- name: Get a simple gallery Image Version info
azure_rm_galleryimageversion_info:
resource_group: "{{ resource_group }}"
gallery_name: myGallery{{ rpfx }}
gallery_image_name: myImage
name: "{{ imageversion_name }}"
register: output
- name: Print imageverison info
debug:
var: output
If you review my code snippet you'll see the input to the azure_rm_galleryimageversion
to delete image versions is the sorted output of the azure_rm_galleryimageversion_info
task, and therefore the version must exist, but the task to delete doesn't delete it or return an error.
$ az sig image-version list -g MY-SUBSCRIPTION-SIG -r BASE_IMAGES -i com.lgc.windows2012.base --query '[].name'
[
"21.02.17",
"21.11.16",
"22.02.10",
"22.04.18"
]
@Fred-sun I was able to move forward by using the uri task to call the Azure gallery-image-version DELETE API.
@Now that it has been solved, I cannot copy the current problem. I suggest closing it temporarily and opening it when there is a new problem. Thank you very much!
The problem isn't solved, merely avoided by not using the collection's module for that task.
@jghal @achevalet However, in my local test, it can be deleted. In addition, after you delete it, wait for 10 minutes and check again, because the service needs some time to complete this operation. Could you try it again? Thank you very much!
The problem is not solved and I can't explain my use-case better than above.
@jghal I got your code snippet to work after removing the "*" after the name from this part:
name: "{{ version_item.name }}*"
so it became:
name: "{{ version_item.name }}"
@jghal The suggestion of the above comment is correct, your script multiple symbols '*'. Thank you!