Skip to content

Instantly share code, notes, and snippets.

@scoates
Last active September 30, 2015 02:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save scoates/b103d607ee7f10b4b253 to your computer and use it in GitHub Desktop.
Save scoates/b103d607ee7f10b4b253 to your computer and use it in GitHub Desktop.
VPC peering
# …
def _get_not_deleted_peering_connections(name, vpc_conn):
unfiltered_peers = vpc_conn.get_all_vpc_peering_connections(filters={'tag:Name': name})
peers = []
for this_peer in unfiltered_peers:
if this_peer.status_code != u'deleted':
peers.append(this_peer)
return peers
def _serialize_vpc_peering_connection(vpc_peering_connection):
if not vpc_peering_connection:
return {}
ret = {}
for k in ['id', 'status_code']:
ret[k] = getattr(vpc_peering_connection, k)
for k in ['accepter_vpc_info', 'requester_vpc_info']:
info = getattr(vpc_peering_connection, k)
ret[k] = {
'owner_id': info.owner_id,
'cidr_block': info.cidr_block,
}
return ret
def _wait_for_status_change(name, vpc_conn, wait_until_not, max=10, wait=1):
# wait until peer is no longer {wait_until_not}
# try up to {max} times, with a {wait} sec delay
for i in range(max):
peer = _get_not_deleted_peering_connections(name, vpc_conn)[0]
status_code = peer.status_code
if status_code == wait_until_not:
sleep(wait)
else:
return peer
return False
def ensure_peering_connection(name, local_vpc_id, peered_vpc_id,
local_route_table_id, peered_route_table_id, local_routes, peered_routes,
region=None, key=None, keyid=None, profile=None, ret={}):
vpc_conn = __utils__['boto.get_connection']('vpc', region=region, key=key, keyid=keyid, profile=profile)
existing_peers = _get_not_deleted_peering_connections(name, vpc_conn)
if existing_peers:
pre_peer = existing_peers[0]
peer = existing_peers[0]
else:
pre_peer = None
peer = vpc_conn.create_vpc_peering_connection(local_vpc_id, peered_vpc_id)
peer.add_tags({'Name': name})
peer = _wait_for_status_change(name, vpc_conn, u'initiating-request')
if not peer:
ret['comment'] = 'Timed out waiting for status to change from "initiating-request"'
ret['result'] = False
return ret
if peer.status_code == u'pending-acceptance':
vpc_conn.accept_vpc_peering_connection(peer.id)
peer = _wait_for_status_change(name, vpc_conn, u'pending-acceptance')
if not peer:
ret['comment'] = 'Timed out waiting for status to change from "pending-acceptance"'
ret['result'] = False
return ret
ret['changes']['peering_connection'] = {
'old': _serialize_vpc_peering_connection(pre_peer),
'new': _serialize_vpc_peering_connection(peer)
}
if str(ret['changes']['peering_connection']['old']) == str(ret['changes']['peering_connection']['new']):
# no changes
del ret['changes']['peering_connection']
if local_routes:
old_route = __salt__['boto_vpc.describe_route_table'](
route_table_id=local_route_table_id,
region=region, key=key, keyid=keyid, profile=profile
)
for route in local_routes:
__salt__['boto_vpc.create_route'](
route_table_id=local_route_table_id,
destination_cidr_block=route, gateway_id=peer.id,
region=region, key=key, keyid=keyid, profile=profile
)
ret['changes']['local_routing_table'] = {
'old': old_route,
'new': __salt__['boto_vpc.describe_route_table'](
route_table_id=local_route_table_id,
region=region, key=key, keyid=keyid, profile=profile
)
}
if str(ret['changes']['local_routing_table']['old']) == str(ret['changes']['local_routing_table']['new']):
# no changes
del ret['changes']['local_routing_table']
if peered_routes:
old_route = __salt__['boto_vpc.describe_route_table'](
route_table_id=peered_route_table_id,
region=region, key=key, keyid=keyid, profile=profile
)
for route in peered_routes:
__salt__['boto_vpc.create_route'](
route_table_id=peered_route_table_id,
destination_cidr_block=route, gateway_id=peer.id,
region=region, key=key, keyid=keyid, profile=profile
)
ret['changes']['peered_routing_table'] = {
'old': old_route,
'new': __salt__['boto_vpc.describe_route_table'](
route_table_id=peered_route_table_id,
region=region, key=key, keyid=keyid, profile=profile
)
}
if str(ret['changes']['peered_routing_table']['old']) == str(ret['changes']['peered_routing_table']['new']):
# no changes
del ret['changes']['peered_routing_table']
ret['result'] = True
return ret
# …
def peering_connection_exists(name, local_vpc_id=None, local_vpc_name=None,
peered_vpc_id=None, peered_vpc_name=None,
local_route_table_id=None, local_route_table_name=None, local_routes=[],
peered_route_table_id=None, peered_route_table_name=None, peered_routes=[],
region=None, key=None, keyid=None, profile=None):
'''
Ensures that a VPC peering connection exists. Need one of id or name for
each of the two VPCs (same for route table)
name
the peering connection name
local_vpc_id
vpc id of the local VPC
local_vpc_name
vpc name of the local VPC
peered_vpc_id
vpc id of the peered VPC
peered_vpc_name
vpc name of the peered VPC
local_route_table_id
local routing table ID
local_route_table_name
local routing table name
peered_route_table_id
peered routing table ID
peered_route_table_name
peered routing table name
routes
List of CIDRs to apply to the routing table for this peering connection
region
Region to connect to.
key
Secret key to be used.
keyid
Access key to be used.
profile
A dict with region, key and keyid, or a pillar key (string) that
contains a dict with region, key and keyid.
'''
if local_vpc_id is None:
local_vpc_id = __salt__['boto_vpc.check_vpc'](
vpc_name=local_vpc_name,
region=region, key=key, keyid=keyid, profile=profile
)
if peered_vpc_id is None:
peered_vpc_id = __salt__['boto_vpc.check_vpc'](
vpc_name=peered_vpc_name,
region=region, key=key, keyid=keyid, profile=profile
)
if local_route_table_id is None:
local_route_table_id = __salt__['boto_vpc.describe_route_table'](
route_table_name=local_route_table_name,
region=region, key=key, keyid=keyid, profile=profile
)['id']
if peered_route_table_id is None:
peered_route_table_id = __salt__['boto_vpc.describe_route_table'](
route_table_name=peered_route_table_name,
region=region, key=key, keyid=keyid, profile=profile
)['id']
ret = {
'name': name,
'result': True,
'comment': '',
'changes': {}
}
ret = __salt__['boto_fk.ensure_peering_connection'](
name, local_vpc_id, peered_vpc_id, local_route_table_id,
peered_route_table_id, local_routes, peered_routes,
region=region, key=key, keyid=keyid, profile=profile,
ret=ret
)
return ret
vpcpeer-qa-ops:
boto_fk.peering_connection_exists:
- local_vpc_name: qa
- peered_vpc_name: ops
- local_route_table_name: qavpc-routingtable
- peered_route_table_name: opsvpc-routingtable
- local_routes:
- 10.{{pillar['group_nums']['ops']}}.0.0/16
- peered_routes:
- 10.{{pillar['group_nums']['qa']}}.0.0/16
- require:
- boto_vpc: qa
- boto_vpc: qavpc-routingtable
- boto_vpc: ops
- boto_vpc: opsvpc-routingtable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment