问题
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
回答1:
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 }}"
回答2:
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 }}"
回答3:
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)
回答4:
- 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
来源:https://stackoverflow.com/questions/41659564/ansible-get-aws-ebs-volume-id-which-already-exist