Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
configuration
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
configuration
Commits
baadf3e3
Commit
baadf3e3
authored
May 11, 2015
by
Feanil Patel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update to latest ec2_elb_lb.
parent
87473da7
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
1 additions
and
648 deletions
+1
-648
playbooks/edx-east/edx_service.yml
+1
-1
playbooks/library/ec2_elb_lb_1.8
+0
-647
No files found.
playbooks/edx-east/edx_service.yml
View file @
baadf3e3
...
...
@@ -106,7 +106,7 @@
# target: "local" # simplifying generalization of instnace-id, gateway-id or local
-
name
:
Manage ELB
ec2_elb_lb
_1.8
:
ec2_elb_lb
:
profile
:
"
{{
profile
}}"
region
:
"
{{
aws_region
}}"
scheme
:
"
{{
elb_scheme
}}"
...
...
playbooks/library/ec2_elb_lb_1.8
deleted
100644 → 0
View file @
87473da7
#!/usr/bin/python
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
DOCUMENTATION
=
"""
---
module: ec2_elb_lb
description: Creates or destroys Amazon ELB.
short_description: Creates or destroys Amazon ELB.
- Returns information about the load balancer.
- Will be marked changed when called only if state is changed.
version_added: "1.5"
author: Jim Dalton
options:
state:
description:
- Create or destroy the ELB
required: true
name:
description:
- The name of the ELB
required: true
listeners:
description:
- List of ports/protocols for this ELB to listen on (see example)
required: false
purge_listeners:
description:
- Purge existing listeners on ELB that are not found in listeners
required: false
default: true
zones:
description:
- List of availability zones to enable on this ELB
required: false
purge_zones:
description:
- Purge existing availability zones on ELB that are not found in zones
required: false
default: false
security_group_ids:
description:
- A list of security groups to apply to the elb
require: false
default: None
version_added: "1.6"
health_check:
description:
- An associative array of health check configuration settigs (see example)
require: false
default: None
region:
description:
- The AWS region to use. If not specified then the value of the EC2_REGION environment variable, if any, is used.
required: false
aliases: ['aws_region', 'ec2_region']
subnets:
description:
- A list of VPC subnets to use when creating ELB. Zones should be empty if using this.
required: false
default: None
aliases: []
version_added: "1.6"
purge_subnets:
description:
- Purge existing subnet on ELB that are not found in subnets
required: false
default: false
scheme:
description:
- The scheme to use when creating the ELB. For a private VPC-visible ELB use 'internal'.
required: false
default: 'internet-facing'
validate_certs:
description:
- When set to "no", SSL certificates will not be validated for boto versions >= 2.6.0.
required: false
default: "yes"
choices: ["yes", "no"]
aliases: []
version_added: "1.5"
extends_documentation_fragment: aws
"""
EXAMPLES
=
"""
# Note: None of these examples set aws_access_key, aws_secret_key, or region.
# It is assumed that their matching environment variables are set.
# Basic provisioning example
- local_action:
module: ec2_elb_lb
name: "test-please-delete"
state: present
zones:
- us-east-1a
- us-east-1d
listeners:
- protocol: http # options are http, https, ssl, tcp
load_balancer_port: 80
instance_port: 80
- protocol: https
load_balancer_port: 443
instance_protocol: http # optional, defaults to value of protocol setting
instance_port: 80
# ssl certificate required for https or ssl
ssl_certificate_id: "arn:aws:iam::123456789012:server-certificate/company/servercerts/ProdServerCert"
# Basic VPC provisioning example
- local_action:
module: ec2_elb_lb
name: "test-vpc"
scheme: internal
state: present
subnets:
- subnet-abcd1234
- subnet-1a2b3c4d
listeners:
- protocol: http # options are http, https, ssl, tcp
load_balancer_port: 80
instance_port: 80
# Configure a health check
- local_action:
module: ec2_elb_lb
name: "test-please-delete"
state: present
zones:
- us-east-1d
listeners:
- protocol: http
load_balancer_port: 80
instance_port: 80
health_check:
ping_protocol: http # options are http, https, ssl, tcp
ping_port: 80
ping_path: "/index.html" # not required for tcp or ssl
response_timeout: 5 # seconds
interval: 30 # seconds
unhealthy_threshold: 2
healthy_threshold: 10
# Ensure ELB is gone
- local_action:
module: ec2_elb_lb
name: "test-please-delete"
state: absent
# Normally, this module will purge any listeners that exist on the ELB
# but aren't specified in the listeners parameter. If purge_listeners is
# false it leaves them alone
- local_action:
module: ec2_elb_lb
name: "test-please-delete"
state: present
zones:
- us-east-1a
- us-east-1d
listeners:
- protocol: http
load_balancer_port: 80
instance_port: 80
purge_listeners: no
# Normally, this module will leave availability zones that are enabled
# on the ELB alone. If purge_zones is true, then any extreneous zones
# will be removed
- local_action:
module: ec2_elb_lb
name: "test-please-delete"
state: present
zones:
- us-east-1a
- us-east-1d
listeners:
- protocol: http
load_balancer_port: 80
instance_port: 80
purge_zones: yes
# Creates a ELB and assigns a list of subnets to it.
- local_action:
module: ec2_elb_lb
state: present
name: 'New ELB'
security_group_ids: 'sg-123456, sg-67890'
region: us-west-2
subnets: 'subnet-123456, subnet-67890'
purge_subnets: yes
listeners:
- protocol: http
load_balancer_port: 80
instance_port: 80
"""
import
sys
import
os
try
:
import
boto
import
boto.ec2.elb
from
boto.ec2.elb.healthcheck
import
HealthCheck
from
boto.regioninfo
import
RegionInfo
except
ImportError
:
print
"failed=True msg='boto required for this module'"
sys
.
exit
(
1
)
class
ElbManager
(
object
):
"""Handles ELB creation and destruction"""
def
__init__
(
self
,
module
,
name
,
listeners
=
None
,
purge_listeners
=
None
,
zones
=
None
,
purge_zones
=
None
,
security_group_ids
=
None
,
health_check
=
None
,
subnets
=
None
,
purge_subnets
=
None
,
scheme
=
"internet-facing"
,
tags
=
[],
region
=
None
,
**
aws_connect_params
):
self
.
module
=
module
self
.
name
=
name
self
.
listeners
=
listeners
self
.
purge_listeners
=
purge_listeners
self
.
zones
=
zones
self
.
purge_zones
=
purge_zones
self
.
security_group_ids
=
security_group_ids
self
.
health_check
=
health_check
self
.
subnets
=
subnets
self
.
purge_subnets
=
purge_subnets
self
.
scheme
=
scheme
self
.
tags
=
tags
self
.
aws_connect_params
=
aws_connect_params
self
.
region
=
region
self
.
changed
=
False
self
.
status
=
'gone'
self
.
elb_conn
=
self
.
_get_elb_connection
()
self
.
elb
=
self
.
_get_elb
()
def
ensure_ok
(
self
):
"""Create the ELB"""
if
not
self
.
elb
:
# Zones and listeners will be added at creation
self
.
_create_elb
()
else
:
self
.
_set_zones
()
self
.
_set_security_groups
()
self
.
_set_elb_listeners
()
self
.
_set_subnets
()
self
.
_set_health_check
()
self
.
do_tags
()
def
ensure_gone
(
self
):
"""Destroy the ELB"""
if
self
.
elb
:
self
.
_delete_elb
()
def
get_info
(
self
):
try
:
check_elb
=
self
.
elb_conn
.
get_all_load_balancers
(
self
.
name
)[
0
]
except
:
check_elb
=
None
if
not
check_elb
:
info
=
{
'name'
:
self
.
name
,
'status'
:
self
.
status
}
else
:
info
=
{
'name'
:
check_elb
.
name
,
'dns_name'
:
check_elb
.
dns_name
,
'zones'
:
check_elb
.
availability_zones
,
'security_group_ids'
:
check_elb
.
security_groups
,
'status'
:
self
.
status
,
'subnets'
:
self
.
subnets
,
'scheme'
:
check_elb
.
scheme
}
if
check_elb
.
health_check
:
info
[
'health_check'
]
=
{
'target'
:
check_elb
.
health_check
.
target
,
'interval'
:
check_elb
.
health_check
.
interval
,
'timeout'
:
check_elb
.
health_check
.
timeout
,
'healthy_threshold'
:
check_elb
.
health_check
.
healthy_threshold
,
'unhealthy_threshold'
:
check_elb
.
health_check
.
unhealthy_threshold
,
}
if
check_elb
.
listeners
:
info
[
'listeners'
]
=
[
l
.
get_complex_tuple
()
for
l
in
check_elb
.
listeners
]
elif
self
.
status
==
'created'
:
# When creating a new ELB, listeners don't show in the
# immediately returned result, so just include the
# ones that were added
info
[
'listeners'
]
=
[
self
.
_listener_as_tuple
(
l
)
for
l
in
self
.
listeners
]
else
:
info
[
'listeners'
]
=
[]
return
info
def
_get_elb
(
self
):
elbs
=
self
.
elb_conn
.
get_all_load_balancers
()
for
elb
in
elbs
:
if
self
.
name
==
elb
.
name
:
self
.
status
=
'ok'
return
elb
def
_get_elb_connection
(
self
):
try
:
return
connect_to_aws
(
boto
.
ec2
.
elb
,
self
.
region
,
**
self
.
aws_connect_params
)
except
boto
.
exception
.
NoAuthHandlerFound
,
e
:
self
.
module
.
fail_json
(
msg
=
str
(
e
))
def
_delete_elb
(
self
):
# True if succeeds, exception raised if not
result
=
self
.
elb_conn
.
delete_load_balancer
(
name
=
self
.
name
)
if
result
:
self
.
changed
=
True
self
.
status
=
'deleted'
def
_create_elb
(
self
):
listeners
=
[
self
.
_listener_as_tuple
(
l
)
for
l
in
self
.
listeners
]
self
.
elb
=
self
.
elb_conn
.
create_load_balancer
(
name
=
self
.
name
,
zones
=
self
.
zones
,
security_groups
=
self
.
security_group_ids
,
complex_listeners
=
listeners
,
subnets
=
self
.
subnets
,
scheme
=
self
.
scheme
)
if
self
.
elb
:
self
.
changed
=
True
self
.
status
=
'created'
def
_create_elb_listeners
(
self
,
listeners
):
"""Takes a list of listener tuples and creates them"""
# True if succeeds, exception raised if not
self
.
changed
=
self
.
elb_conn
.
create_load_balancer_listeners
(
self
.
name
,
complex_listeners
=
listeners
)
def
_delete_elb_listeners
(
self
,
listeners
):
"""Takes a list of listener tuples and deletes them from the elb"""
ports
=
[
l
[
0
]
for
l
in
listeners
]
# True if succeeds, exception raised if not
self
.
changed
=
self
.
elb_conn
.
delete_load_balancer_listeners
(
self
.
name
,
ports
)
def
_set_elb_listeners
(
self
):
"""
Creates listeners specified by self.listeners; overwrites existing
listeners on these ports; removes extraneous listeners
"""
listeners_to_add
=
[]
listeners_to_remove
=
[]
listeners_to_keep
=
[]
# Check for any listeners we need to create or overwrite
for
listener
in
self
.
listeners
:
listener_as_tuple
=
self
.
_listener_as_tuple
(
listener
)
# First we loop through existing listeners to see if one is
# already specified for this port
existing_listener_found
=
None
for
existing_listener
in
self
.
elb
.
listeners
:
# Since ELB allows only one listener on each incoming port, a
# single match on the incomping port is all we're looking for
if
existing_listener
[
0
]
==
listener
[
'load_balancer_port'
]:
existing_listener_found
=
existing_listener
.
get_complex_tuple
()
break
if
existing_listener_found
:
# Does it match exactly?
if
listener_as_tuple
!=
existing_listener_found
:
# The ports are the same but something else is different,
# so we'll remove the exsiting one and add the new one
listeners_to_remove
.
append
(
existing_listener_found
)
listeners_to_add
.
append
(
listener_as_tuple
)
else
:
# We already have this listener, so we're going to keep it
listeners_to_keep
.
append
(
existing_listener_found
)
else
:
# We didn't find an existing listener, so just add the new one
listeners_to_add
.
append
(
listener_as_tuple
)
# Check for any extraneous listeners we need to remove, if desired
if
self
.
purge_listeners
:
for
existing_listener
in
self
.
elb
.
listeners
:
existing_listener_tuple
=
existing_listener
.
get_complex_tuple
()
if
existing_listener_tuple
in
listeners_to_remove
:
# Already queued for removal
continue
if
existing_listener_tuple
in
listeners_to_keep
:
# Keep this one around
continue
# Since we're not already removing it and we don't need to keep
# it, let's get rid of it
listeners_to_remove
.
append
(
existing_listener_tuple
)
if
listeners_to_remove
:
self
.
_delete_elb_listeners
(
listeners_to_remove
)
if
listeners_to_add
:
self
.
_create_elb_listeners
(
listeners_to_add
)
def
_listener_as_tuple
(
self
,
listener
):
"""Formats listener as a 4- or 5-tuples, in the order specified by the
ELB API"""
# N.B. string manipulations on protocols below (str(), upper()) is to
# ensure format matches output from ELB API
listener_list
=
[
listener
[
'load_balancer_port'
],
listener
[
'instance_port'
],
str
(
listener
[
'protocol'
]
.
upper
()),
]
# Instance protocol is not required by ELB API; it defaults to match
# load balancer protocol. We'll mimic that behavior here
if
'instance_protocol'
in
listener
:
listener_list
.
append
(
str
(
listener
[
'instance_protocol'
]
.
upper
()))
else
:
listener_list
.
append
(
str
(
listener
[
'protocol'
]
.
upper
()))
if
'ssl_certificate_id'
in
listener
:
listener_list
.
append
(
str
(
listener
[
'ssl_certificate_id'
]))
return
tuple
(
listener_list
)
def
_enable_zones
(
self
,
zones
):
try
:
self
.
elb
.
enable_zones
(
zones
)
except
boto
.
exception
.
BotoServerError
,
e
:
if
"Invalid Availability Zone"
in
e
.
error_message
:
self
.
module
.
fail_json
(
msg
=
e
.
error_message
)
else
:
self
.
module
.
fail_json
(
msg
=
"an unknown server error occurred, please try again later"
)
self
.
changed
=
True
def
_disable_zones
(
self
,
zones
):
try
:
self
.
elb
.
disable_zones
(
zones
)
except
boto
.
exception
.
BotoServerError
,
e
:
if
"Invalid Availability Zone"
in
e
.
error_message
:
self
.
module
.
fail_json
(
msg
=
e
.
error_message
)
else
:
self
.
module
.
fail_json
(
msg
=
"an unknown server error occurred, please try again later"
)
self
.
changed
=
True
def
_attach_subnets
(
self
,
subnets
):
self
.
elb_conn
.
attach_lb_to_subnets
(
self
.
name
,
subnets
)
self
.
changed
=
True
def
_detach_subnets
(
self
,
subnets
):
self
.
elb_conn
.
detach_lb_from_subnets
(
self
.
name
,
subnets
)
self
.
changed
=
True
def
_set_subnets
(
self
):
"""Determine which subnets need to be attached or detached on the ELB"""
if
self
.
subnets
:
if
self
.
purge_subnets
:
subnets_to_detach
=
list
(
set
(
self
.
elb
.
subnets
)
-
set
(
self
.
subnets
))
subnets_to_attach
=
list
(
set
(
self
.
subnets
)
-
set
(
self
.
elb
.
subnets
))
else
:
subnets_to_detach
=
None
subnets_to_attach
=
list
(
set
(
self
.
subnets
)
-
set
(
self
.
elb
.
subnets
))
if
subnets_to_attach
:
self
.
_attach_subnets
(
subnets_to_attach
)
if
subnets_to_detach
:
self
.
_detach_subnets
(
subnets_to_detach
)
def
_set_zones
(
self
):
"""Determine which zones need to be enabled or disabled on the ELB"""
if
self
.
zones
:
if
self
.
purge_zones
:
zones_to_disable
=
list
(
set
(
self
.
elb
.
availability_zones
)
-
set
(
self
.
zones
))
zones_to_enable
=
list
(
set
(
self
.
zones
)
-
set
(
self
.
elb
.
availability_zones
))
else
:
zones_to_disable
=
None
zones_to_enable
=
list
(
set
(
self
.
zones
)
-
set
(
self
.
elb
.
availability_zones
))
if
zones_to_enable
:
self
.
_enable_zones
(
zones_to_enable
)
# N.B. This must come second, in case it would have removed all zones
if
zones_to_disable
:
self
.
_disable_zones
(
zones_to_disable
)
def
_set_security_groups
(
self
):
if
self
.
security_group_ids
!=
None
and
set
(
self
.
elb
.
security_groups
)
!=
set
(
self
.
security_group_ids
):
self
.
elb_conn
.
apply_security_groups_to_lb
(
self
.
name
,
self
.
security_group_ids
)
self
.
Changed
=
True
def
_set_health_check
(
self
):
"""Set health check values on ELB as needed"""
if
self
.
health_check
:
# This just makes it easier to compare each of the attributes
# and look for changes. Keys are attributes of the current
# health_check; values are desired values of new health_check
health_check_config
=
{
"target"
:
self
.
_get_health_check_target
(),
"timeout"
:
self
.
health_check
[
'response_timeout'
],
"interval"
:
self
.
health_check
[
'interval'
],
"unhealthy_threshold"
:
self
.
health_check
[
'unhealthy_threshold'
],
"healthy_threshold"
:
self
.
health_check
[
'healthy_threshold'
],
}
update_health_check
=
False
# The health_check attribute is *not* set on newly created
# ELBs! So we have to create our own.
if
not
self
.
elb
.
health_check
:
self
.
elb
.
health_check
=
HealthCheck
()
for
attr
,
desired_value
in
health_check_config
.
iteritems
():
if
getattr
(
self
.
elb
.
health_check
,
attr
)
!=
desired_value
:
setattr
(
self
.
elb
.
health_check
,
attr
,
desired_value
)
update_health_check
=
True
if
update_health_check
:
self
.
elb
.
configure_health_check
(
self
.
elb
.
health_check
)
self
.
changed
=
True
def
_get_health_check_target
(
self
):
"""Compose target string from healthcheck parameters"""
protocol
=
self
.
health_check
[
'ping_protocol'
]
.
upper
()
path
=
""
if
protocol
in
[
'HTTP'
,
'HTTPS'
]
and
'ping_path'
in
self
.
health_check
:
path
=
self
.
health_check
[
'ping_path'
]
return
"
%
s:
%
s
%
s"
%
(
protocol
,
self
.
health_check
[
'ping_port'
],
path
)
## can be removed if https://github.com/ansible/ansible/pull/9113 is merged upstream
def
is_taggable
(
self
,
object
):
from
boto.ec2.ec2object
import
TaggedEC2Object
if
not
object
or
not
issubclass
(
object
.
__class__
,
TaggedEC2Object
):
return
False
return
True
def
do_tags
(
self
):
"""
General function for adding tags to objects that are subclasses
of boto.ec2.ec2object.TaggedEC2Object. Currently updates
existing tags, as the API overwrites them, but does not remove
orphans.
:param module:
:param object:
:param tags:
"""
dry_run
=
True
if
self
.
module
.
check_mode
else
False
if
(
self
.
is_taggable
(
self
.
elb
)):
tag_dict
=
{}
for
tag
in
self
.
tags
:
tag_dict
[
tag
[
'key'
]]
=
tag
[
'value'
]
self
.
elb
.
add_tags
(
tag_dict
,
dry_run
)
else
:
pass
#self.module.fail_json(msg="ELB object is not a subclass of TaggedEC2Object")
## end can be removed
def
main
():
argument_spec
=
ec2_argument_spec
()
argument_spec
.
update
(
dict
(
state
=
{
'required'
:
True
,
'choices'
:
[
'present'
,
'absent'
]},
name
=
{
'required'
:
True
},
listeners
=
{
'default'
:
None
,
'required'
:
False
,
'type'
:
'list'
},
purge_listeners
=
{
'default'
:
True
,
'required'
:
False
,
'type'
:
'bool'
},
zones
=
{
'default'
:
None
,
'required'
:
False
,
'type'
:
'list'
},
purge_zones
=
{
'default'
:
False
,
'required'
:
False
,
'type'
:
'bool'
},
security_group_ids
=
{
'default'
:
None
,
'required'
:
False
,
'type'
:
'list'
},
health_check
=
{
'default'
:
None
,
'required'
:
False
,
'type'
:
'dict'
},
subnets
=
{
'default'
:
None
,
'required'
:
False
,
'type'
:
'list'
},
purge_subnets
=
{
'default'
:
False
,
'required'
:
False
,
'type'
:
'bool'
},
scheme
=
{
'default'
:
'internet-facing'
,
'required'
:
False
},
tags
=
{
'default'
:
None
,
'required'
:
False
,
'type'
:
'list'
}
)
)
module
=
AnsibleModule
(
argument_spec
=
argument_spec
,
)
region
,
ec2_url
,
aws_connect_params
=
get_aws_connection_info
(
module
)
if
not
region
:
module
.
fail_json
(
msg
=
"Region must be specified as a parameter, in EC2_REGION or AWS_REGION environment variables or in boto configuration file"
)
name
=
module
.
params
[
'name'
]
state
=
module
.
params
[
'state'
]
listeners
=
module
.
params
[
'listeners'
]
purge_listeners
=
module
.
params
[
'purge_listeners'
]
zones
=
module
.
params
[
'zones'
]
purge_zones
=
module
.
params
[
'purge_zones'
]
security_group_ids
=
module
.
params
[
'security_group_ids'
]
health_check
=
module
.
params
[
'health_check'
]
subnets
=
module
.
params
[
'subnets'
]
purge_subnets
=
module
.
params
[
'purge_subnets'
]
scheme
=
module
.
params
[
'scheme'
]
tags
=
module
.
params
[
'tags'
]
if
state
==
'present'
and
not
listeners
:
module
.
fail_json
(
msg
=
"At least one port is required for ELB creation"
)
if
state
==
'present'
and
not
(
zones
or
subnets
):
module
.
fail_json
(
msg
=
"At least one availability zone or subnet is required for ELB creation"
)
elb_man
=
ElbManager
(
module
,
name
,
listeners
,
purge_listeners
,
zones
,
purge_zones
,
security_group_ids
,
health_check
,
subnets
,
purge_subnets
,
scheme
,
tags
,
region
=
region
,
**
aws_connect_params
)
if
state
==
'present'
:
elb_man
.
ensure_ok
()
elif
state
==
'absent'
:
elb_man
.
ensure_gone
()
ansible_facts
=
{
'ec2_elb'
:
'info'
}
ec2_facts_result
=
dict
(
changed
=
elb_man
.
changed
,
elb
=
elb_man
.
get_info
(),
ansible_facts
=
ansible_facts
)
module
.
exit_json
(
**
ec2_facts_result
)
# import module snippets
from
ansible.module_utils.basic
import
*
from
ansible.module_utils.ec2
import
*
main
()
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