Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Salt: Auto-assign public IPs in VPC subnets
# -*- coding: utf-8 -*-
'''
TODO
'''
# keep lint from choking on _get_conn and _cache_id
#pylint: disable=E0602
# Import Python libs
from __future__ import absolute_import
import logging
from distutils.version import LooseVersion as _LooseVersion # pylint: disable=import-error,no-name-in-module
# Import Salt libs
import salt.utils.boto
import salt.utils.compat
log = logging.getLogger(__name__)
# Import third party libs
# pylint: disable=import-error
try:
#pylint: disable=unused-import
import boto
#pylint: enable=unused-import
from boto.exception import BotoServerError
logging.getLogger('boto').setLevel(logging.CRITICAL)
HAS_BOTO = True
except ImportError:
HAS_BOTO = False
# pylint: enable=import-error
def __virtual__():
'''
Only load if boto libraries exist and if boto libraries are greater than
a given version.
'''
required_boto_version = '2.8.0'
# the boto_vpc execution module relies on the connect_to_region() method
# which was added in boto 2.8.0
# https://github.com/boto/boto/commit/33ac26b416fbb48a60602542b4ce15dcc7029f12
if not HAS_BOTO:
return False
elif _LooseVersion(boto.__version__) < _LooseVersion(required_boto_version):
return False
else:
return True
def __init__(opts):
salt.utils.compat.pack_dunder(__name__)
if HAS_BOTO:
__utils__['boto.assign_funcs'](__name__, 'ec2')
def set_auto_assign_ips(subnet_id, value=True,
region=None, key=None, keyid=None, profile=None):
# yay APIs
if value:
value = "true"
else:
value = "false"
ec2_conn = __utils__['boto.get_connection']('ec2', region=region, key=key, keyid=keyid, profile=profile)
orig_api_version = ec2_conn.APIVersion
ec2_conn.APIVersion = '2014-06-15'
result = ec2_conn.get_status(
'ModifySubnetAttribute',
{'SubnetId': subnet_id, 'MapPublicIpOnLaunch.Value': value},
verb='POST')
ec2_conn.APIVersion = orig_api_version
return result
# -*- coding: utf-8 -*-
'''
TODO
'''
# Import Python Libs
from __future__ import absolute_import
import logging
log = logging.getLogger(__name__)
def __virtual__():
'''
Only load if boto is available.
(We use VPC here because it's already available if this is going to work.)
'''
return 'boto_fk' if 'boto_vpc.exists' in __salt__ else False
def subnet_public_ips(name, subnet_id=None, vpc_name=None, vpc_id=None,
region=None, key=None, keyid=None, profile=None):
'''
Ensure subnet has 'Auto Assign Public IP' turned on
name
Name of the VPC.
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.
'''
ret = {'name': name,
'result': True,
'comment': '',
'changes': {}
}
if vpc_id is None:
vpc_id = __salt__['boto_vpc.check_vpc'](vpc_name=vpc_name)
if not vpc_id:
ret['result'] = False
ret['comment'] = 'Could not find VPC: id={} name={}'.format(vpc_id, vpc_name)
return ret
if subnet_id is None:
subnets_desc = __salt__['boto_vpc.describe_subnets'](
subnet_names=name,
vpc_id=vpc_id
)
if not subnets_desc:
ret['result'] = False
ret['comment'] = 'Could not find subnet: name={}'.format(name)
return ret
subnet_id = subnets_desc['subnets'][0]['id']
ret['result'] = __salt__['boto_fk.set_auto_assign_ips'](
subnet_id, region=region, key=key, keyid=keyid, profile=profile
)
return ret
opsvpc:
boto_vpc.present:
- name: ops
- cidr_block: {{aws['vpc-cidr-prefix']}}.0.0/16
- dns_hostnames: True
{%for index in range(aws['vpc-availability-zones']|length)%}
opsvpc-subnet{{index}}:
boto_vpc.subnet_present:
- vpc_name: ops
- cidr_block: {{aws['vpc-cidr-prefix']}}.{{index}}.0/24
- availability_zone: {{aws['vpc-availability-zones'][index]}}
- require:
- boto_vpc: ops
## HERE IS THE MAGIC
boto_fk.subnet_public_ips:
- vpc_name: ops
{%endfor%}
opsvpc-igw:
boto_vpc.internet_gateway_present:
- vpc_name: ops
- require:
- boto_vpc: ops
opsvpc-routingtable:
boto_vpc.route_table_present:
- vpc_name: ops
- subnet_names:
{%for index in range(aws['vpc-availability-zones']|length)%}
- opsvpc-subnet{{index}}
{%endfor%}
- routes:
- destination_cidr_block: 0.0.0.0/0
internet_gateway_name: opsvpc-igw
- require:
- boto_vpc: ops
- boto_vpc: opsvpc-igw
{%for index in range(aws['vpc-availability-zones']|length)%}
- boto_vpc: opsvpc-subnet{{index}}
{%endfor%}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment