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

Commit

Permalink
Merge 1df9b52 into 30c648c
Browse files Browse the repository at this point in the history
  • Loading branch information
yufangzhang committed Aug 8, 2016
2 parents 30c648c + 1df9b52 commit ef870c3
Show file tree
Hide file tree
Showing 8 changed files with 928 additions and 107 deletions.
36 changes: 34 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,52 @@ If your ``$CWD`` is anywhere else, you need to pass in a path to particular fabr
Multiple Stacks
===============

Each environment can have multiple stacks.
Stack tagged with ``active`` points to host's entry point.

If you want to run multiple stacks with the same name and environment place the following in the yaml configuration::

master_zone:
my-zone.dsd.io

cfn_create
++++++++++

Then when you create a stack you can specify a tag before cfn_create, like::

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

NB active is the default.

set_active_stack(tag_name)
++++++++++++++++++++++++++

NB active is the default. You can also set other stack as active using another fab task ``set_active_stack(tag_name)``::

fab application:courtfinder aws:my_project_prod environment:dev config:/path/to/courtfinder-dev.yaml set_active_stack:[tag_name]

cfn_delete
++++++++++

You can also delete any stack you want no more by specifying the tag::

fab application:courtfinder aws:my_project_prod environment:dev config:/path/to/courtfinder-dev.yaml tag:[tag_name] cfn_delete

NB ``tag_name`` can be any created tag. active is the default.
When deleting an active stack, only active DNS records are removed. Otherwise whole stack is removed.


swap_tags
+++++++++

Then you can refer to this stack by its tag in the future. In this way it is easier to bring up two stacks from the same config. If you want to swap the names of the stacks you can do the following::

fab application:courtfinder aws:my_project_prod environment:dev config:/path/to/courtfinder-dev.yaml swap_tags:inactive,active
fab application:courtfinder aws:my_project_prod environment:dev config:/path/to/courtfinder-dev.yaml swap_tags:inactive, active


others
++++++

There are also some fab tasks for example ``get_active_stack`` that returns active stack for this application and environment; ``get_stack_list`` returns any related stacks.

Example Configuration
=====================
Expand Down
10 changes: 8 additions & 2 deletions bootstrap_cfn/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class ConfigParser(object):
def __init__(self, data, stack_name, environment=None, application=None):
self.stack_name = stack_name
self.data = data

self.stack_id = self.stack_name.split('-')[-1]
# Some things possibly used in user data templates
self.environment = environment
self.application = application
Expand Down Expand Up @@ -551,6 +551,12 @@ def rds(self, template):
if 'db-engine' in self.data['rds'] and self.data['rds']['db-engine'].startswith("sqlserver"):
required_fields.pop('db-name')

if 'identifier' in self.data['rds']:
# update identifier name
self.data['rds']['identifier'] = "{}-{}".format(self.data['rds']['identifier'], self.stack_id)
logging.info("identifier was updated to {}".format(self.data['rds']['identifier']))
print "identifier was updated to {}".format(self.data['rds']['identifier'])

# TEST FOR REQUIRED FIELDS AND EXIT IF MISSING ANY
for yaml_key, rds_prop in required_fields.iteritems():
if yaml_key not in self.data['rds']:
Expand Down Expand Up @@ -813,7 +819,7 @@ def elb(self, template):
RecordSets=[
RecordSet(
"TitleIsIgnoredForThisResource",
Name="%s.%s" % (elb['name'], elb['hosted_zone']),
Name="%s-%s.%s" % (elb['name'], self.stack_id, elb['hosted_zone']),
Type="A",
AliasTarget=AliasTarget(
GetAtt(load_balancer, "CanonicalHostedZoneNameID"),
Expand Down
36 changes: 36 additions & 0 deletions bootstrap_cfn/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,39 @@ def __init__(self, autoscaling_group, expected_instance_count, instances):
"Could not find {} instances in autoscaling group {}. Actual state is {} instances, {}"
.format(expected_instance_count, autoscaling_group, len(instances), instances)
)


class TagRecordExistConflictError(BootstrapCfnError):
def __init__(self, stack_tag):
msg = ("An {} record already exists. ".format(stack_tag))
super(TagRecordExistConflictError, self).__init__(msg)


class ActiveTagExistConflictError(BootstrapCfnError):
def __init__(self, stack_id):
msg = ("An active record already exists in {}. ".format(stack_id))
super(ActiveTagExistConflictError, self).__init__(msg)


class TagRecordNotFoundError(BootstrapCfnError):
def __init__(self, tag):
msg = ("Could not find a dns record for tag '{}'. ".format(tag))
super(TagRecordNotFoundError, self).__init__(msg)


class PublicELBNotFoundError(BootstrapCfnError):
def __init__(self):
msg = "Could not find an internet facing ELB according to cloudformation configuration. "
super(PublicELBNotFoundError, self).__init__(msg)


class StackRecordNotFoundError(BootstrapCfnError):
def __init__(self, stack_record_name):
msg = ("Could not find a dns record for stack '{}'. ".format(stack_record_name))
super(StackRecordNotFoundError, self).__init__(msg)


class UpdateDNSRecordError(BootstrapCfnError):
def __init__(self):
msg = "Error updating dns record. "
super(UpdateDNSRecordError, self).__init__(msg)
Loading

0 comments on commit ef870c3

Please sign in to comment.