Skip to content
This repository has been archived by the owner on Jan 19, 2022. It is now read-only.

Commit

Permalink
Merge df061b0 into aecbe0f
Browse files Browse the repository at this point in the history
  • Loading branch information
ashb committed Mar 24, 2015
2 parents aecbe0f + df061b0 commit fd113a6
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 131 deletions.
28 changes: 13 additions & 15 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ Installation
Developing and running tests
=============================

The test suite can be run via setup.py as follows:
::
The test suite can be run via setup.py as follows::

python -m unittest discover
or

or::

python setup.py test


Expand All @@ -40,7 +40,7 @@ Example Usage

Bootstrap-cfn uses `fabric <http://www.fabfile.org/>`_, so if your ``$CWD`` is the root directory of bootstrap-cfn then you can run::

fab application:courtfinder aws:prod environment:dev config:/path/to/courtfinder-dev.yaml cfn_create
fab application:courtfinder aws:my_project_prod environment:dev config:/path/to/courtfinder-dev.yaml cfn_create


If your ``$CWD`` is anywhere else, you need to pass in a path to particular fabric file::
Expand All @@ -63,17 +63,15 @@ Example Configuration
AWS Account Configuration
++++++++++++++++++++++++++

This tool can support many AWS accounts, for example, you may have separate *development* and *production* accounts, however you still want to deploy the same stack to each, this can be achieved by adding multiple accounts to the ``~/.config.yaml`` file. You'll notice from the **Example Usage** section above the ``aws:dev`` flag, this can be changed accordingly.
This tool needs AWS credentials to create stacks and the credentials should be placed in the ``~/.aws/credentials`` file (which is the same one used by the AWS CLI tools). You should create named profiles like this (and the section names should match up with what you specify to the fabric command with the ``aws:my_project_prod`` flag) ::

::

provider_zones:
dev:
aws_access_key_id: 'AKIAI***********'
aws_secret_access_key: '*******************************************'
prod:
aws_access_key_id: 'AKIAI***********'
aws_secret_access_key: '*******************************************'
[my_project_dev]
aws_access_key_id = AKIAI***********
aws_secret_access_key = *******************************************
[my_project_prod]
aws_access_key_id = AKIAI***********
aws_secret_access_key = *******************************************


Project specific YAML file
Expand Down
25 changes: 11 additions & 14 deletions bootstrap_cfn/cloudformation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,20 @@
import boto.cloudformation
import boto.ec2
from boto.ec2 import autoscale
from boto.exception import NoAuthHandlerFound
from boto.provider import ProfileNotFoundError
from bootstrap_cfn import utils

class Cloudformation:

conn_cfn = None
config = None
aws_region_name = None
aws_profile_name = None

def __init__(self, config):
self.config = config
if self.config.aws_access is not None and self.config.aws_secret is not None:
self.conn_cfn = boto.cloudformation.connect_to_region(
region_name=self.config.aws_region,
aws_access_key_id=self.config.aws_access,
aws_secret_access_key=self.config.aws_secret)
else:
print "[ERROR] No AWS credentials"
sys.exit(1)
def __init__(self, aws_profile_name, aws_region_name='eu-west-1'):
self.aws_profile_name = aws_profile_name
self.aws_region_name = aws_region_name
self.conn_cfn = utils.connect_to_aws(boto.cloudformation, self)

def create(self, stack_name, template_body):
stack = self.conn_cfn.create_stack(stack_name=stack_name,
Expand Down Expand Up @@ -56,9 +53,9 @@ def get_stack_instances(self, stack_name_or_id):
print 'No scaling group found'
return []
scaling_group_id = scaling_group[0].physical_resource_id
asc = autoscale.connect_to_region(self.config.aws_region,
aws_access_key_id=self.config.aws_access,
aws_secret_access_key=self.config.aws_secret)

asc = utils.connect_to_aws(autoscale, self)

# get the instance IDs for all instances in the scaling group
instances = asc.get_all_groups(names=[scaling_group_id])[0].instances
return instances
Expand Down
25 changes: 0 additions & 25 deletions bootstrap_cfn/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,6 @@
import bootstrap_cfn.errors as errors
from copy import deepcopy


class AWSConfig:

aws_access = None
aws_secret = None
aws_region = 'eu-west-1'

def __init__(self, account, fp=None):
if fp:
if os.path.exists(fp):
f = open(fp).read()
else:
raise IOError
else:
f = open(os.path.expanduser("~") + "/.config.yaml").read()

try:
if f:
d = yaml.load(f)['provider_zones']
self.aws_access = d[account]['aws_access_key_id']
self.aws_secret = d[account]['aws_secret_access_key']
except KeyError:
raise


class ProjectConfig:

config = None
Expand Down
29 changes: 16 additions & 13 deletions bootstrap_cfn/ec2.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import sys
import boto.ec2
from boto.exception import NoAuthHandlerFound
from boto.provider import ProfileNotFoundError

from bootstrap_cfn import cloudformation
from bootstrap_cfn import ssh
from bootstrap_cfn import utils

class EC2:

conn_cfn = None
config = None

def __init__(self, config):
self.config = config
if self.config.aws_access is not None and self.config.aws_secret is not None:
self.conn_ec2 = boto.ec2.connect_to_region(
region_name=self.config.aws_region,
aws_access_key_id=self.config.aws_access,
aws_secret_access_key=self.config.aws_secret)
else:
print "[ERROR] No AWS credentials"
sys.exit(1)
self.cfn = cloudformation.Cloudformation(config)
aws_region_name = None
aws_profile_name = None

def __init__(self, aws_profile_name, aws_region_name='eu-west-1'):
self.aws_profile_name = aws_profile_name
self.aws_region_name = aws_region_name

self.conn_ec2 = utils.connect_to_aws(boto.ec2, self)

self.cfn = cloudformation.Cloudformation(
aws_profile_name=aws_profile_name,
aws_region_name=aws_region_name
)

def get_instance_public_ips(self, instance_id_list):
if not instance_id_list:
Expand Down
8 changes: 5 additions & 3 deletions bootstrap_cfn/fab_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import sys
import random
from bootstrap_cfn.config import AWSConfig, ProjectConfig, ConfigParser
from bootstrap_cfn.config import ProjectConfig, ConfigParser
from bootstrap_cfn.cloudformation import Cloudformation
from bootstrap_cfn.ec2 import EC2
from bootstrap_cfn.iam import IAM
Expand Down Expand Up @@ -85,6 +85,9 @@ def _validate_fabric_env():
if not hasattr(env, 'stack_passwords'):
env.stack_passwords = {}

if not hasattr(env, 'aws_region'):
env.aws_region = 'eu-west-1'


def get_config():
_validate_fabric_env()
Expand All @@ -99,8 +102,7 @@ def get_config():

def get_connection(klass):
_validate_fabric_env()
aws_config = AWSConfig(env.aws)
return klass(aws_config)
return klass(env.aws, env.aws_region)


@task
Expand Down
22 changes: 11 additions & 11 deletions bootstrap_cfn/iam.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import boto.iam
from boto.exception import NoAuthHandlerFound
from boto.provider import ProfileNotFoundError

from bootstrap_cfn import utils

class IAM:

conn_cfn = None
config = None
aws_region_name = None
aws_profile_name = None

def __init__(self, aws_profile_name, aws_region_name='eu-west-1'):
self.aws_profile_name = aws_profile_name
self.aws_region_name = aws_region_name

def __init__(self, config):
self.config = config
if self.config.aws_access is not None and self.config.aws_secret is not None:
self.conn_iam = boto.iam.connect_to_region(
region_name=self.config.aws_region,
aws_access_key_id=self.config.aws_access,
aws_secret_access_key=self.config.aws_secret)
else:
print "[ERROR] No AWS credentials"
sys.exit(1)
self.conn_iam = utils.connect_to_aws(boto.iam, self)

def upload_ssl_certificate(self, ssl_config, stack_name):
for cert_name, ssl_data in ssl_config.items():
Expand Down
16 changes: 16 additions & 0 deletions bootstrap_cfn/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,19 @@ def wrapper(*args, **kwargs):
time.sleep(interval)
return wrapper
return decorate

def connect_to_aws(module, instance):
try:
conn = module.connect_to_region(
region_name=instance.aws_region_name,
profile_name=instance.aws_profile_name
)
return conn
except NoAuthHandlerFound:
print "[ERROR] No AWS credentials"
print "Create an ~/.aws/credentials file by following this layout:\n\n" + \
" http://boto.readthedocs.org/en/latest/boto_config_tut.html#credentials"
sys.exit(1)
except ProfileNotFoundError, e:
print e
sys.exit(1)
Loading

0 comments on commit fd113a6

Please sign in to comment.