Reputation: 21
I'm trying to tackle how to list and do something with EC2 stopped instances. ec2_remote_facts is my friend and I can get results from it. But as an ansible noob I cannot for the life of me work out how to get at the 'id' componenent of the returned object. The documentation is sketchy and does not cover what type of thing is returned nor how to use it.
Here is the very basic playbook I'm experimenting with:
---
- name: remote facts
hosts: localhost
tasks:
- ec2_remote_facts:
region: ap-southeast-2
register: info
- name: print
debug: var=info
This works just fine.
This also works:
---
- name: remote facts
hosts: localhost
tasks:
- ec2_remote_facts:
region: ap-southeast-2
register: info
- name: print
debug: var=info.instances[0].id
What I can't get my head around is the incantation to give me just the 'id' element for all current instances (3) so I can do something else with all of them--remove, configure, start, whatever. I've had a look at all the looping constructs and with_* options and I can't get any of them to do what I want.
No doubt this will be a 'd'oh!' problem to anyone who knows the answer but I'm afraid at the moment I just don't get it. The returned object looks like this:
ok: [localhost] => {
"info": {
"changed": false,
"instances": [
{
"ami_launch_index": "0",
"architecture": "x86_64",
"client_token": "vpOGxxxxxxxxxxxxxx",
"ebs_optimized": false,
"groups": [
{
"id": "sg-xxxxxxxx",
"name": "launch-wizard-3"
}
],
"hypervisor": "xen",
"id": "i-01xxxxxxxxxxxxxxxx",
[...]
"tags": {},
"virtualization_type": "hvm",
"vpc_id": "vpc-xxxxxxxx"
},
{
"ami_launch_index": "1",
"architecture": "x86_64",
[snip, 2 more instances]
Any thoughts people?
Upvotes: 2
Views: 2299
Reputation: 330
Thanks @hit3k
I have changed a little of your code to make it working under Ansible 2.7.10
- name: print the variable name
debug: msg= "{{ item.0 }}"
with_items: "{{ ec2_metadata.instances|map(attribute='instance_id')|list }}"
Results:
ok: [vpc.prod.dr] => (item=i-0739f6a14abc1e7d9) => {}
ok: [vpc.prod.dr] => (item=i-04dd1eab60bc03488) => {}
ok: [vpc.prod.dr] => (item=i-09702b90ed31cf00f) => {}
ok: [vpc.prod.dr] => (item=i-05bcaf44b1598aadd) => {}
ok: [vpc.prod.dr] => (item=i-085bfe50d2c6e5c88) => {}
ok: [vpc.prod.dr] => (item=i-0237a96d2e8869d13) => {}
ok: [vpc.prod.dr] => (item=i-0769c21225acfac01) => {}
ok: [vpc.prod.dr] => (item=i-09c55f3c6776ff263) => {}
ok: [vpc.prod.dr] => (item=i-0e8faa6ffb085558f) => {}
ok: [vpc.prod.dr] => (item=i-07e68c8c201fc6021) => {}
ok: [vpc.prod.dr] => (item=i-011a94a276e70d92c) => {}
ok: [vpc.prod.dr] => (item=i-05672115214b129bd) => {}
ok: [vpc.prod.dr] => (item=i-0cbe6652ee855f14d) => {}
ok: [vpc.prod.dr] => (item=i-055ff968821cca086) => {}
ok: [vpc.prod.dr] => (item=i-0c9a7db7a8142c240) => {}
ok: [vpc.prod.dr] => (item=i-02ca647fe24ad6c56) => {}
ok: [vpc.prod.dr] => (item=i-054542fcef48629a0) => {}
ok: [vpc.prod.dr] => (item=i-0a095641b04538a73) => {}
ok: [vpc.prod.dr] => (item=i-05434bac67259041c) => {}
Upvotes: 0
Reputation: 1
Spent a lot of time looking into this and it is actually very simple using Ansible Jinja2 filters.
this should work:
- name: DEBUG
debug:
var: info |json_query('instances[*].id')
Some very usefull Filtering described here: http://docs.ansible.com/ansible/latest/playbooks_filters.html#other-useful-filters
Upvotes: 0
Reputation: 1493
This should be working:
tasks:
- ec2_remote_facts:
region: ap-southeast-2
register: thefacts
- debug: var=item.id
with_items: "{{thefacts.instances}}"
but produces a lot of unnecessary debug output, for, like, no reason. So let's filter it out:
tasks:
- ec2_remote_facts:
region: ap-southeast-2
register: thefacts
- debug: var=item.0
with_together:
- "{{ thefacts.instances|map(attribute='id')|list }}"
Upvotes: 1
Reputation: 925
You had it on your second attempt, funnily enough I had the exact same issue but it took your JSON experience for me to see it.
Your second code snippet:
---
- name: remote facts
hosts: localhost
tasks:
- ec2_remote_facts:
region: ap-southeast-2
register: info
- name: print
debug: var=info.instances[0].id
My addition:
---
- name: remote facts
hosts: localhost
tasks:
- ec2_remote_facts:
region: ap-southeast-2
register: info
- name: print
debug: var=info.instances[0].id
- name: Create AMI from Instance ID
ec2_ami:
aws_access_key: "{{ aws_access_key }}"
aws_secret_key: "{{ aws_secret_key }}"
region: "{{ region }}"
instance_id: "{{ ec2_remote_facts.instances[0].id }}"
Cheers for helping me work this one out haha.
Output from Ansible:
(ansible27) user@user:/etc/ansible/playbooks$ sudo ansible-playbook ec2_facts.yml
[WARNING]: Found both group and host with same name: localhost
PLAY [localhost] ***************************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [EC2 Remote Facts.] *******************************************************
ok: [localhost]
TASK [Display results in JSON format.] *****************************************
ok: [localhost] => {
"changed": false,
"msg": "Most upto date instance is: i-1234567abcdefg "
}
TASK [Create AMI from instance ID.] ********************************************
changed: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=4 changed=1 unreachable=0 failed=0
For your problem of the loop, I assume it will just be a case of passing in the [1] and [2] element specifiers.
Upvotes: 0
Reputation: 11
It's a bit late, I suspect, but I think that you've simply forgotten to add the "{{ }}" around your with_items variable. Works for me if I do, so:
ec2_remote_facts:
region: "{{ vpc_region }}"
filters:
instance-state-name: running
vpc-id: "{{ vpc_id }}"
register: ec2_info
Then:
set_fact:
jenkins_master_instances: "{{ jenkins_master_instances|default([]) + [ item.id ]}}"
with_items: "{{ ec2_info.instances }}"
seems to work for me.
Upvotes: 1
Reputation: 1032
Try this it should work :
- ec2_remote_facts:
region: ap-southeast-2
register: info
- name: print
debug: var=item.id
with_items: info_instances
If doesn't share the complete output of debug: var=info
. So that i can tell you the exact code.
Also if you want to use it any task like ec2
for stopping instance use it as a variable {{item.instances.id}}
with same loop with_items: info_instances
Upvotes: 0