skip to Main Content

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:

  • chain of replace filters
  • using of from_json on the stdout but still didn’t like it
  • have the output as text and replacing n and t

Anybody has an idea how to achieve this?
Thanks

2

Answers


  1. Using shell and the AWS CLI is a poor practice in Ansible, as there are already modules available to execute those operations:

    • the ec2_vol_info will allow you to retrieve the information of the volumes attached to EC2 instances, this will be similar to aws ec2 describe-volumes

    • the ec2_vol will allow you to create and configure volumes, this will be similar to aws ec2 create-volume

    • additionally, there is the ec2_tag module, which allows to add, update or delete tags for the EC2 artifacts.

    Modules have a better error and idem-potency handling, as they already have the logic to verify if the change is needed before applying it, this will allow to execute several times the same playbook if needed.

    Login or Signup to reply.
  2. 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>                         
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search