dsaydon
dsaydon

Reputation: 4769

ansible get aws ebs volume id which already exist

I'm trying to get the aws volume id which already exist and attached to ec2 instance using ansible. I have a lookup task using the ec2_remote_facts module that get details of the ec2 instance including the volume id details the task:

- name: lookup ec2 virtual machines
  ec2_remote_facts:
    aws_access_key: "{{aws_access_key}}"
    aws_secret_key: "{{aws_secret_key}}"
    region: "{{ec2_region}}"
    filters:
      instance-state-name: running
      "tag:Name": "{{server_name}}"
      "tag:Environment": "{{environment_type}}"
      "tag:App": "{{app_name}}"
      "tag:Role": "{{role_type}}"
  register: ec2_info

example output:

    "msg": [
        {
            "ami_launch_index": "0",
            "architecture": "x86_64",
            "block_device_mapping": [
                {
                    "attach_time": "2017-01-12T17:24:17.000Z",
                    "delete_on_termination": true,
                    "device_name": "/dev/sda1",
                    "status": "attached",
                    "volume_id": "vol-123456789"
                }
            ],
            "client_token": "",
            "ebs_optimized": false,
            "groups": [
                {
                    "id": "sg-123456789",
                    "name": "BE-VPC"
                }
            ],
..... and more

now I need to get only the block device mapping -> volume_id but I don't know how to get only the ID

I have tried several tasks that didn't work to get only the volume id like:

-  debug: msg="{{item | map(attribute='block_device_mapping') | map('regex_search','volume_id') | select('string') | list }}"
   with_items: "{{ec2_info.instances | from_json}}"

this didn't work as well:

- name: get associated vols
  ec2_vol:
    aws_access_key: "{{aws_access_key}}"
    aws_secret_key: "{{aws_secret_key}}"
    region:  "{{ec2_region}}"
    instance: "{{ ec2_info.isntances.id }}"
    state: list
    region: "{{ region }}"
  register: ec2_vol_lookup


- name: tag the volumes
  ec2_tag:
    aws_access_key: "{{aws_access_key}}"
    aws_secret_key: "{{aws_secret_key}}"
    region:  "{{ec2_region}}"
    resource: "{{ item.id }}"
    region:  "{{ region }}"
    tags:
      Environment: "{{environment_type}}"
      Groups: "{{group_name}}"
      Name: "vol_{{server_name}}"
      Role: "{{role_type}}"
  with_items: "{{ ec2_vol_lookup.volumes | default([]) }}"

any idea?

ansible version: 2.2.0.0

Upvotes: 5

Views: 4597

Answers (5)

nettie
nettie

Reputation: 692

Here is what I had to do to get volume_id (ansible 2.9.X):

- name: gather ec2 remote facts
  ec2_instance_info:
    filters:
      vpc-id: "{{ vpc }}"
      subnet-id: "{{subnet}}"
      "tag:Name": "my_instance_name"
    region: "{{ region }}"
  register: ec2_instance_info


- debug:
    msg: "index: {{item.1.tags.Name}} volume info: {{item.1.block_device_mappings[0].ebs.volume_id}}"
  with_indexed_items:
    - "{{ ec2_instance_info.instances }}"

Upvotes: 2

UFO
UFO

Reputation: 1

- name: Get instances list
  ec2_instance_facts:
    filters:
      "tag:instance": "{{ instance_inventory | map(attribute='instance_id') | list }}"

^ there could be any method, with which you could get instance_id

    region: us-east-1
  register: ec2_sets

- name: Delete instance' volume(s)
  ec2_vol:
    id: '{{ item }}'
    state: absent
  loop: "{{ ec2_sets.instances | sum(attribute='block_device_mappings', start=[]) | map(attribute='ebs.volume_id') | list }}"
  when: ( ec2_sets.instances | sum(attribute='block_device_mappings', start=[]) | map(attribute='ebs.volume_id') | list | length )

^ when condition for testing task idempotent

Upvotes: -3

Val F.
Val F.

Reputation: 1466

To tag all volumes attached to AWS ec2 instances, I've used the following :

- name: Get instance ec2 facts
  ec2_remote_facts:
    region: "{{ aws_region }}"
    filters:
      "private_ip_address": "{{ inventory_hostname }}"
  register: ec2_info

- name: Tag volumes
  ec2_tag:
    region: "{{ aws_region }}"
    resource: "{{ item.volume_id }}"
    state: present
    tags:
      Name: "{{ ec2_info.instances[0].tags.Name }} - {{ item.device_name}}"
  with_items:
    - "{{ ec2_info.instances[0].block_device_mapping }}"

The volume tag will be composed of the instance tag Name and the device name (ie. /dev/sdf)

Upvotes: 1

Zoltán
Zoltán

Reputation: 22156

If you can identify the volume by name, or another tag you set on it, you can use the ec2_vol_facts module:

ec2_vol_facts:
  region: <your-ec2-region>
  filters:
    "tag:Name": <your-volume-name>
    "tag:Role": <e.g. db-data>
register: ec2_vol

debug:
  msg: "Ids: {{ ec2_vol.volumes | map(attribute='id') | list | to_nice_json }}"

Upvotes: 1

Konstantin Suvorov
Konstantin Suvorov

Reputation: 68269

If you have single instance and single block device, use:

- debug: msg="{{ ec2_info.instances[0].block_device_mapping[0].volume_id }}"

If you have many instances and many block devices:

- debug: msg="{{ item.block_device_mapping | map(attribute='volume_id') | list }}"
  with_items: "{{ ec2_info.instances }}"

In case of single instance and many devices:

- debug: msg="{{ ec2_info.instances[0].block_device_mapping | map(attribute='volume_id') | list }}"

Upvotes: 4

Related Questions