Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
ansible
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
ansible
Commits
fafb3c10
Commit
fafb3c10
authored
Jun 30, 2013
by
Michael DeHaan
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3293 from jarv/devel
Adds termination support to the ec2 module
parents
50617854
a61ec2e6
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
230 additions
and
80 deletions
+230
-80
library/cloud/ec2
+230
-80
No files found.
library/cloud/ec2
View file @
fafb3c10
...
...
@@ -17,9 +17,9 @@
DOCUMENTATION
=
'''
---
module: ec2
short_description: create an instance in ec2, return instanceid
short_description: create
or terminate
an instance in ec2, return instanceid
description:
-
creates ec2 instances an
d optionally waits for it to be 'running'. This module has a dependency on python-boto >= 2.5
-
Creates or terminates ec2 instances. When create
d optionally waits for it to be 'running'. This module has a dependency on python-boto >= 2.5
version_added: "0.9"
options:
key_name:
...
...
@@ -163,6 +163,22 @@ options:
required: false
defualt: null
aliases: []
instance_ids:
version_added: "1.3"
description:
- list of instance ids, currently only used when state='absent'
required: false
default: null
aliases: []
state:
version_added: "1.3"
description:
- create or terminate instances
required: false
default: 'present'
aliases: []
requirements: [ "boto" ]
author: Seth Vidal, Tim Gerla, Lester Wade
'''
...
...
@@ -211,6 +227,50 @@ local_action:
image: ami-6e649707
wait: yes
vpc_subnet_id: subnet-29e63245'
# Launch instances, runs some tasks
# and then terminate them
- name: Create a sandbox instance
hosts: localhost
gather_facts: False
vars:
keypair: my_keypair
instance_type: m1.small
security_group: my_securitygroup
image: my_ami_id
region: us-east-1
tasks:
- name: Launch instance
local_action: ec2 keypair=$keypair group=$security_group instance_type=$instance_type image=$image wait=true region=$region
register: ec2
- name: Add new instance to host group
local_action: add_host hostname=${item.public_ip} groupname=launched
with_items: ${ec2.instances}
- name: Wait for SSH to come up
local_action: wait_for host=${item.public_dns_name} port=22 delay=60 timeout=320 state=started
with_items: ${ec2.instances}
- name: Configure instance(s)
hosts: launched
sudo: True
gather_facts: True
roles:
- my_awesome_role
- my_awesome_test
- name: Terminate instances
hosts: localhost
connection: local
tasks:
- name: Terminate instances that were previously launched
local_action:
module: ec2
state: 'absent'
instance_ids: {{ec2.instance_ids}}
'''
import
sys
...
...
@@ -218,43 +278,59 @@ import time
try
:
import
boto.ec2
from
boto.exception
import
EC2ResponseError
except
ImportError
:
print
"failed=True msg='boto required for this module'"
sys
.
exit
(
1
)
def
main
():
module
=
AnsibleModule
(
argument_spec
=
dict
(
key_name
=
dict
(
required
=
True
,
aliases
=
[
'keypair'
]),
id
=
dict
(),
group
=
dict
(
type
=
'list'
),
group_id
=
dict
(),
region
=
dict
(
choices
=
[
'eu-west-1'
,
'sa-east-1'
,
'us-east-1'
,
'ap-northeast-1'
,
'us-west-2'
,
'us-west-1'
,
'ap-southeast-1'
,
'ap-southeast-2'
]),
zone
=
dict
(),
instance_type
=
dict
(
aliases
=
[
'type'
]),
image
=
dict
(
required
=
True
),
kernel
=
dict
(),
count
=
dict
(
default
=
'1'
),
monitoring
=
dict
(
choices
=
BOOLEANS
,
default
=
False
),
ramdisk
=
dict
(),
wait
=
dict
(
choices
=
BOOLEANS
,
default
=
False
),
wait_timeout
=
dict
(
default
=
300
),
ec2_url
=
dict
(
aliases
=
[
'EC2_URL'
]),
ec2_secret_key
=
dict
(
aliases
=
[
'EC2_SECRET_KEY'
],
no_log
=
True
),
ec2_access_key
=
dict
(
aliases
=
[
'EC2_ACCESS_KEY'
]),
placement_group
=
dict
(),
user_data
=
dict
(),
instance_tags
=
dict
(),
vpc_subnet_id
=
dict
(),
private_ip
=
dict
(),
)
)
def
get_instance_info
(
inst
):
"""
Retrieves instance information from an instance
ID and returns it as a dictionary
"""
return
({
'id'
:
inst
.
id
,
'ami_launch_index'
:
inst
.
ami_launch_index
,
'private_ip'
:
inst
.
private_ip_address
,
'private_dns_name'
:
inst
.
private_dns_name
,
'public_ip'
:
inst
.
ip_address
,
'dns_name'
:
inst
.
dns_name
,
'public_dns_name'
:
inst
.
public_dns_name
,
'state_code'
:
inst
.
state_code
,
'architecture'
:
inst
.
architecture
,
'image_id'
:
inst
.
image_id
,
'key_name'
:
inst
.
key_name
,
'virtualization_type'
:
inst
.
virtualization_type
,
'placement'
:
inst
.
placement
,
'kernel'
:
inst
.
kernel
,
'ramdisk'
:
inst
.
ramdisk
,
'launch_time'
:
inst
.
launch_time
,
'instance_type'
:
inst
.
instance_type
,
'root_device_type'
:
inst
.
root_device_type
,
'root_device_name'
:
inst
.
root_device_name
,
'state'
:
inst
.
state
,
'hypervisor'
:
inst
.
hypervisor
})
def
create_instances
(
module
,
ec2
):
"""
Creates new instances
module : AnsbileModule object
ec2: authenticated ec2 connection object
Returns:
A list of dictionaries with instance information
about the instances that were launched
"""
key_name
=
module
.
params
.
get
(
'key_name'
)
id
=
module
.
params
.
get
(
'id'
)
group_name
=
module
.
params
.
get
(
'group'
)
group_id
=
module
.
params
.
get
(
'group_id'
)
region
=
module
.
params
.
get
(
'region'
)
zone
=
module
.
params
.
get
(
'zone'
)
instance_type
=
module
.
params
.
get
(
'instance_type'
)
image
=
module
.
params
.
get
(
'image'
)
...
...
@@ -264,38 +340,12 @@ def main():
ramdisk
=
module
.
params
.
get
(
'ramdisk'
)
wait
=
module
.
params
.
get
(
'wait'
)
wait_timeout
=
int
(
module
.
params
.
get
(
'wait_timeout'
))
ec2_url
=
module
.
params
.
get
(
'ec2_url'
)
ec2_secret_key
=
module
.
params
.
get
(
'ec2_secret_key'
)
ec2_access_key
=
module
.
params
.
get
(
'ec2_access_key'
)
placement_group
=
module
.
params
.
get
(
'placement_group'
)
user_data
=
module
.
params
.
get
(
'user_data'
)
instance_tags
=
module
.
params
.
get
(
'instance_tags'
)
vpc_subnet_id
=
module
.
params
.
get
(
'vpc_subnet_id'
)
private_ip
=
module
.
params
.
get
(
'private_ip'
)
# allow eucarc environment variables to be used if ansible vars aren't set
if
not
ec2_url
and
'EC2_URL'
in
os
.
environ
:
ec2_url
=
os
.
environ
[
'EC2_URL'
]
if
not
ec2_secret_key
and
'EC2_SECRET_KEY'
in
os
.
environ
:
ec2_secret_key
=
os
.
environ
[
'EC2_SECRET_KEY'
]
if
not
ec2_access_key
and
'EC2_ACCESS_KEY'
in
os
.
environ
:
ec2_access_key
=
os
.
environ
[
'EC2_ACCESS_KEY'
]
# If we have a region specified, connect to its endpoint.
if
region
:
try
:
ec2
=
boto
.
ec2
.
connect_to_region
(
region
,
aws_access_key_id
=
ec2_access_key
,
aws_secret_access_key
=
ec2_secret_key
)
except
boto
.
exception
.
NoAuthHandlerFound
,
e
:
module
.
fail_json
(
msg
=
str
(
e
))
# Otherwise, no region so we fallback to the old connection method
else
:
try
:
if
ec2_url
:
# if we have an URL set, connect to the specified endpoint
ec2
=
boto
.
connect_ec2_endpoint
(
ec2_url
,
ec2_access_key
,
ec2_secret_key
)
else
:
# otherwise it's Amazon.
ec2
=
boto
.
connect_ec2
(
ec2_access_key
,
ec2_secret_key
)
except
boto
.
exception
.
NoAuthHandlerFound
,
e
:
module
.
fail_json
(
msg
=
str
(
e
))
# Here we try to lookup the group name from the security group id - if group_id is set.
if
group_id
and
group_name
:
...
...
@@ -398,33 +448,133 @@ def main():
running_instances
.
append
(
inst
)
instance_dict_array
=
[]
created_instance_ids
=
[]
for
inst
in
running_instances
:
d
=
{
'id'
:
inst
.
id
,
'ami_launch_index'
:
inst
.
ami_launch_index
,
'private_ip'
:
inst
.
private_ip_address
,
'private_dns_name'
:
inst
.
private_dns_name
,
'public_ip'
:
inst
.
ip_address
,
'dns_name'
:
inst
.
dns_name
,
'public_dns_name'
:
inst
.
public_dns_name
,
'state_code'
:
inst
.
state_code
,
'architecture'
:
inst
.
architecture
,
'image_id'
:
inst
.
image_id
,
'key_name'
:
inst
.
key_name
,
'virtualization_type'
:
inst
.
virtualization_type
,
'placement'
:
inst
.
placement
,
'kernel'
:
inst
.
kernel
,
'ramdisk'
:
inst
.
ramdisk
,
'launch_time'
:
inst
.
launch_time
,
'instance_type'
:
inst
.
instance_type
,
'root_device_type'
:
inst
.
root_device_type
,
'root_device_name'
:
inst
.
root_device_name
,
'state'
:
inst
.
state
,
'hypervisor'
:
inst
.
hypervisor
}
d
=
get_instance_info
(
inst
)
created_instance_ids
.
append
(
inst
.
id
)
instance_dict_array
.
append
(
d
)
module
.
exit_json
(
changed
=
True
,
instances
=
instance_dict_array
)
return
(
instance_dict_array
,
created_instance_ids
)
def
terminate_instances
(
module
,
ec2
,
instance_ids
):
"""
Terminates a list of instances
module: Ansible module object
ec2: authenticated ec2 connection object
termination_list: a list of instances to terminate in the form of
[ {id: <inst-id>}, ..]
Returns a dictionary of instance information
about the instances terminated.
If the instance to be terminated is running
"changed" will be set to False.
"""
changed
=
False
instance_dict_array
=
[]
if
not
isinstance
(
instance_ids
,
list
)
or
len
(
instance_ids
)
<
1
:
module
.
fail_json
(
msg
=
'instance_ids should be a list of instances, aborting'
)
terminated_instance_ids
=
[]
for
res
in
ec2
.
get_all_instances
(
instance_ids
):
for
inst
in
res
.
instances
:
if
inst
.
state
==
'running'
:
terminated_instance_ids
.
append
(
inst
.
id
)
instance_dict_array
.
append
(
get_instance_info
(
inst
))
try
:
ec2
.
terminate_instances
([
inst
.
id
])
except
EC2ResponseError
as
e
:
module
.
fail_json
(
msg
=
'Unable to terminate instance {0}, error: {1}'
.
format
(
inst
.
id
,
e
))
changed
=
True
return
(
changed
,
instance_dict_array
,
terminated_instance_ids
)
def
main
():
module
=
AnsibleModule
(
argument_spec
=
dict
(
key_name
=
dict
(
aliases
=
[
'keypair'
]),
id
=
dict
(),
group
=
dict
(
type
=
'list'
),
group_id
=
dict
(),
region
=
dict
(
choices
=
[
'eu-west-1'
,
'sa-east-1'
,
'us-east-1'
,
'ap-northeast-1'
,
'us-west-2'
,
'us-west-1'
,
'ap-southeast-1'
,
'ap-southeast-2'
]),
zone
=
dict
(),
instance_type
=
dict
(
aliases
=
[
'type'
]),
image
=
dict
(),
kernel
=
dict
(),
count
=
dict
(
default
=
'1'
),
monitoring
=
dict
(
choices
=
BOOLEANS
,
default
=
False
),
ramdisk
=
dict
(),
wait
=
dict
(
choices
=
BOOLEANS
,
default
=
False
),
wait_timeout
=
dict
(
default
=
300
),
ec2_url
=
dict
(
aliases
=
[
'EC2_URL'
]),
ec2_secret_key
=
dict
(
aliases
=
[
'EC2_SECRET_KEY'
],
no_log
=
True
),
ec2_access_key
=
dict
(
aliases
=
[
'EC2_ACCESS_KEY'
]),
placement_group
=
dict
(),
user_data
=
dict
(),
instance_tags
=
dict
(),
vpc_subnet_id
=
dict
(),
private_ip
=
dict
(),
instance_ids
=
dict
(
type
=
'list'
),
state
=
dict
(
default
=
'present'
),
)
)
ec2_url
=
module
.
params
.
get
(
'ec2_url'
)
ec2_secret_key
=
module
.
params
.
get
(
'ec2_secret_key'
)
ec2_access_key
=
module
.
params
.
get
(
'ec2_access_key'
)
region
=
module
.
params
.
get
(
'region'
)
termination_list
=
module
.
params
.
get
(
'termination_list'
)
# allow eucarc environment variables to be used if ansible vars aren't set
if
not
ec2_url
and
'EC2_URL'
in
os
.
environ
:
ec2_url
=
os
.
environ
[
'EC2_URL'
]
if
not
ec2_secret_key
and
'EC2_SECRET_KEY'
in
os
.
environ
:
ec2_secret_key
=
os
.
environ
[
'EC2_SECRET_KEY'
]
if
not
ec2_access_key
and
'EC2_ACCESS_KEY'
in
os
.
environ
:
ec2_access_key
=
os
.
environ
[
'EC2_ACCESS_KEY'
]
# If we have a region specified, connect to its endpoint.
if
region
:
try
:
ec2
=
boto
.
ec2
.
connect_to_region
(
region
,
aws_access_key_id
=
ec2_access_key
,
aws_secret_access_key
=
ec2_secret_key
)
except
boto
.
exception
.
NoAuthHandlerFound
,
e
:
module
.
fail_json
(
msg
=
str
(
e
))
# Otherwise, no region so we fallback to the old connection method
else
:
try
:
if
ec2_url
:
# if we have an URL set, connect to the specified endpoint
ec2
=
boto
.
connect_ec2_endpoint
(
ec2_url
,
ec2_access_key
,
ec2_secret_key
)
else
:
# otherwise it's Amazon.
ec2
=
boto
.
connect_ec2
(
ec2_access_key
,
ec2_secret_key
)
except
boto
.
exception
.
NoAuthHandlerFound
,
e
:
module
.
fail_json
(
msg
=
str
(
e
))
if
module
.
params
.
get
(
'state'
)
==
'absent'
:
instance_ids
=
module
.
params
.
get
(
'instance_ids'
)
if
not
isinstance
(
instance_ids
,
list
):
module
.
fail_json
(
msg
=
'termination_list needs to be a list of instances to terminate'
)
(
changed
,
instance_dict_array
,
new_instance_ids
)
=
terminate_instances
(
module
,
ec2
,
instance_ids
)
elif
module
.
params
.
get
(
'state'
)
==
'present'
:
# Changed is always set to true when provisioning new instances
changed
=
True
if
not
module
.
params
.
get
(
'key_name'
):
module
.
fail_json
(
msg
=
'key_name parameter is required for new instance'
)
if
not
module
.
params
.
get
(
'image'
):
module
.
fail_json
(
msg
=
'image parameter is required for new instance'
)
(
instance_dict_array
,
new_instance_ids
)
=
create_instances
(
module
,
ec2
)
module
.
exit_json
(
changed
=
True
,
instance_ids
=
new_instance_ids
,
instances
=
instance_dict_array
)
# this is magic, see lib/ansible/module_common.py
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment