I need to replace my EBS volumes but need to keep the tags. I have to use aws cli.- I basically have problem to feed the tag information from one aws command output to the other aws command input due to differences of expected format.
I first loop through the volumes with describe-volumes command and collect the tags for each volumes. Something like this
- name: Tags of my EBS volumes
become: yes
shell: |
aws ec2 describe-volumes --volume-ids {{ item.stdout }} --query "Volumes[*].Tags" --output json
with_items: "{{ ebsvolumeids.results }}"
register: ebsvolumetags
This will give a similar formatted output:
"stdout": "[\n [\n {\n \"Key\": \"cost-center\",\n \"Value\": \"22222223222\"\n },\n {\n \"Key\": \"LastBackup\",\n \"Value\": \"2022.01.01\"\n }\n ]\n]",
When I want to create a new replacement volume from a snapshot and want to apply the tags the command would like this:
shell:
aws ec2 create-volume --snapshot-id <snap-xxxxxxxx> \
--volume-type gp2 --tag-specifications \
'ResourceType=volume,Tags={{ item.stdout }}'
with_items: "{{ ebsvolumetags.results }}"
where I would loop through the output of the previous command. However create-volume command expects a format for Tags like this:
[{Key=LastBackup,Value=2022.01.01},{Key=cost-center,Value=22222223222}]
So for example the correct syntax would be:
aws ec2 create-volume --snapshot-id <snap-xxxxxxxx> --volume-type gp2 --tag-specifications \
'ResourceType=volume,Tags=[{Key=LastBackup,Value=2022.01.01},{Key=cost-center,Value=22222223222}]'
No double quotes. No colons just equal signs. One less deep structure because output had too many [] brackets.
I tried to shape the output of the first command with different ways, for the second to accept but no luck:
Anybody has an idea how to achieve this? Thanks
Ansible shell module should only be used as a last resort. That being said, It appears this is a data formatting issue as "Tags" cannot be passed as json to the command "aws ec2 create-volume".
A workaround would be to convert the tags from json to the correct format (which follows the pattern: [{Key=key1,Value=value1},{Key=key2,Value=value2},{Key=key3,Value=value3},...]) and pass it as a string literal to the aws command. Please refer to the playbook below:
---
- hosts: localhost
gather_facts: no
vars:
tags: ''
tasks:
- name: Tags of my EBS volumes
become: yes
shell: |
aws ec2 describe-volumes --volume-ids {{ item.stdout }} --query "Volumes[*].Tags" \
--output json
register: ebsvolumetags
- name: Create tags variable
set_fact:
tags: "{{ tags + '{Key=' + item.Key + ',' + 'Value=' + item.Value + '},' }}"
loop: "{{ ebsvolumetags.stdout | from_json | first }}"
- name: Create EBS volume with the same tags
become: yes
shell: |
aws ec2 create-volume --snapshot-id <snap-xxxxxxx> --volume-type gp2 \
--tag-specifications 'ResourceType=volume,Tags=[{{ tags[:-1] }}]' \
--availability-zone <us-east-xx>