Beispiel #1
0
def format_stack_events(stack, limit=None):
    if hasattr(stack, 'describe_events'):
        events = stack.describe_events()
    else:
        cfn = boto.connect_cloudformation()
        events = cfn.describe_stack_events(stack.stack_name)

    cfn = boto.connect_cloudformation()
    events = list(cfn.describe_stack_events(stack.stack_name))

    if limit is None:
        limit = len(events)

    tab = PrettyTable(['Time', 'Type', 'Logical ID', 'Status', 'Reason'])
    tab.align = 'l'

    for e in events:
        reason = e.resource_status_reason

        tab.add_row([
            local_date(e.timestamp), e.resource_type, e.logical_resource_id,
            e.resource_status, reason if reason is not None else ''
        ])

    return tab.get_string(end=limit)
Beispiel #2
0
def format_stack_events(stack, limit=None):
    if hasattr(stack, 'describe_events'):
        events = stack.describe_events()
    else:
        cfn = boto.connect_cloudformation()
        events = cfn.describe_stack_events(stack.stack_name)

    cfn = boto.connect_cloudformation()
    events = list(cfn.describe_stack_events(stack.stack_name))

    if limit is None:
        limit = len(events)

    tab = PrettyTable(['Time', 'Type', 'Logical ID', 'Status', 'Reason'])
    tab.align = 'l'

    for e in events:
        reason = e.resource_status_reason

        tab.add_row([
            local_date(e.timestamp),
            e.resource_type,
            e.logical_resource_id,
            e.resource_status,
            reason if reason is not None else ''
            ])

    return tab.get_string(end=limit)
Beispiel #3
0
def create_stack(stack_name, template, region='us-east-1', blocking=True, temp_bucket='edx-sandbox-devops'):
    cfn = boto.connect_cloudformation()

    # Upload the template to s3
    key_name = 'cloudformation/auto/{}_{}'.format(stack_name, basename(template))
    template_url = upload_file(template, temp_bucket, key_name)

    # Reference the stack.
    try:
        stack_id = cfn.create_stack(stack_name,
            template_url=template_url,
            capabilities=['CAPABILITY_IAM'],
            tags={'autostack':'true'},
            parameters=[('KeyName', 'continuous-integration')])
    except Exception as e:
        print(e.message)
        raise e

   
    status = None 
    while blocking:
        sleep(5)
        stack_instance = cfn.describe_stacks(stack_id)[0]
        status = stack_instance.stack_status
        print(status)
        if 'COMPLETE' in status:
            break

    if status in FAILURE_STATES:
        raise Exception('Creation Failed. Stack Status: {}, ID:{}'.format(
            status, stack_id))

    return stack_id
Beispiel #4
0
def main():
    parser = OptionParser(usage="usage: %prog [options] stackname template")
    parser.add_option('-d','--debug',help="Debug level",default=0)
    parser.add_option('-g','--user',help="VPN User",default='user-00')
    (options,args) = parser.parse_args()

    if len(args) < 2:
        parser.print_help()
        sys.exit(1)

    (stackin, templatein) = args

    try:
        templin = open (templatein,'r').read()
    except IOError:
        sys.stderr.write("File "+templatein+" Does not exist!\n")
        parser.print_help()
        sys.exit(1)

    NEXTSTACK = options.user + "Stack"

    cfn = boto.connect_cloudformation()

    cfn_template = render_jinja(templatein)

    try:
        cfn.validate_template(cfn_template)
    except boto.exception.BotoServerError, e:
        print e.error_message
 def test_do_poll_true_create_returns_false_on_non_existing_stack(self):
     cfno = AWSCFNOutput()
     cfn = boto.connect_cloudformation(
         aws_access_key_id='access',
         aws_secret_access_key='secret'
     )
     assert_equals(False, cfno.do_poll(cfn, 'test', True, 'create'))
Beispiel #6
0
def format_stack_resources(stack):
    if hasattr(stack, 'describe_resources'):
        resources = stack.describe_resources()
    else:
        cfn = boto.connect_cloudformation()
        resources = cfn.describe_stack_resources(stack.stack_name)

    tab = PrettyTable(['Type', 'Status', 'Logical ID', 'Physical ID'])
    tab.align = 'l'
    tab.sortby = 'Type'

    for r in resources:
        # TODO: generalize this
        if r.resource_type == 'AWS::CloudFormation::WaitConditionHandle':
            physical_resource_id = r.physical_resource_id[0:45] + '...'
        else:
            physical_resource_id = r.physical_resource_id

        tab.add_row([
            r.resource_type,
            r.resource_status,
            r.logical_resource_id,
            physical_resource_id
            ])

    return tab.get_string()
def test_create_stack_kinesis():
    conn = boto.connect_cloudformation()
    dummy_template = {
        "AWSTemplateFormatVersion": "2010-09-09",
        "Description": "Stack Kinesis Test 1",
        "Parameters": {},
        "Resources": {
            "stream1": {
                "Type" : "AWS::Kinesis::Stream",
                "Properties" : {
                    "Name": "stream1",
                    "ShardCount": 2
                }
            }
        }
    }
    conn.create_stack(
        "test_stack_kinesis_1",
        template_body=json.dumps(dummy_template),
        parameters={}.items()
    )

    stack = conn.describe_stacks()[0]
    resources = stack.list_resources()
    assert len(resources) == 1
 def test__stack_exists_nonexistant(self):
     cfno = AWSCFNOutput()
     cfn = boto.connect_cloudformation(
         aws_access_key_id='access',
         aws_secret_access_key='secret'
     )
     assert_equals(False, cfno._stack_exists(cfn, 'test'))
Beispiel #9
0
def main():
    vpc = get_vpc()
    if vpc is None:
        raise LookupError("Unable to connect to VPC.")

    subnets = get_all_subnets(vpc)

    template = get_template(vpc, subnets)

    cfn = boto.connect_cloudformation()

    print("Creating CloudFormation stack in AWS.")
    cfn.create_stack(
        'thunder',
        template_body=template,
        template_url=None,
        parameters=[],
        notification_arns=[],
        disable_rollback=False,
        timeout_in_minutes=None,
        capabilities=["CAPABILITY_IAM"],
        tags=dict(
            application="thunder",
            environment="test"
        )
    )
    print("Stack creation complete.")
Beispiel #10
0
def test_describe_stack_events_shows_create_update_and_delete():
    conn = boto.connect_cloudformation()
    stack_id = conn.create_stack("test_stack", template_body=dummy_template_json)
    conn.update_stack(stack_id, template_body=dummy_template_json2)
    conn.delete_stack(stack_id)

    # assert begins and ends with stack events
    events = conn.describe_stack_events(stack_id)
    events[0].resource_type.should.equal("AWS::CloudFormation::Stack")
    events[-1].resource_type.should.equal("AWS::CloudFormation::Stack")

    # testing ordering of stack events without assuming resource events will not exist
    stack_events_to_look_for = iter([
        ("CREATE_IN_PROGRESS", "User Initiated"), ("CREATE_COMPLETE", None),
        ("UPDATE_IN_PROGRESS", "User Initiated"), ("UPDATE_COMPLETE", None),
        ("DELETE_IN_PROGRESS", "User Initiated"), ("DELETE_COMPLETE", None)])
    try:
        for event in events:
            event.stack_id.should.equal(stack_id)
            event.stack_name.should.equal("test_stack")

            if event.resource_type == "AWS::CloudFormation::Stack":
                event.logical_resource_id.should.equal("test_stack")
                event.physical_resource_id.should.equal(stack_id)

                status_to_look_for, reason_to_look_for = next(stack_events_to_look_for)
                event.resource_status.should.equal(status_to_look_for)
                if reason_to_look_for is not None:
                    event.resource_status_reason.should.equal(reason_to_look_for)
    except StopIteration:
        assert False, "Too many stack events"

    list(stack_events_to_look_for).should.be.empty
def test_stack_sqs_integration():
    sqs_template = {
        "AWSTemplateFormatVersion": "2010-09-09",
        "Resources": {
            "QueueGroup": {

                "Type": "AWS::SQS::Queue",
                "Properties": {
                    "QueueName": "my-queue",
                    "VisibilityTimeout": 60,
                }
            },
        },
    }
    sqs_template_json = json.dumps(sqs_template)

    conn = boto.connect_cloudformation()
    conn.create_stack(
        "test_stack",
        template_body=sqs_template_json,
    )

    stack = conn.describe_stacks()[0]
    queue = stack.describe_resources()[0]
    queue.resource_type.should.equal('AWS::SQS::Queue')
    queue.logical_resource_id.should.equal("QueueGroup")
    queue.physical_resource_id.should.equal("my-queue")
def test_stack_ec2_integration():
    ec2_template = {
        "AWSTemplateFormatVersion": "2010-09-09",
        "Resources": {
            "WebServerGroup": {
                "Type": "AWS::EC2::Instance",
                "Properties": {
                    "ImageId": "ami-1234abcd",
                    "UserData": "some user data",
                }
            },
        },
    }
    ec2_template_json = json.dumps(ec2_template)

    conn = boto.connect_cloudformation()
    conn.create_stack(
        "ec2_stack",
        template_body=ec2_template_json,
    )

    ec2_conn = boto.connect_ec2()
    reservation = ec2_conn.get_all_instances()[0]
    ec2_instance = reservation.instances[0]

    stack = conn.describe_stacks()[0]
    instance = stack.describe_resources()[0]
    instance.resource_type.should.equal('AWS::EC2::Instance')
    instance.logical_resource_id.should.equal("WebServerGroup")
    instance.physical_resource_id.should.equal(ec2_instance.id)
 def test__get_difference_no_difference(self):
     cfno = AWSCFNOutput()
     cfn = boto.connect_cloudformation(
         aws_access_key_id='access',
         aws_secret_access_key='secret'
     )
     assert_equals([], cfno._get_difference(cfn, 'test', '{"a": "b"}'))
def test_delete_stack_by_name():
    conn = boto.connect_cloudformation()
    conn.create_stack("test_stack", template_body=dummy_template_json)

    conn.list_stacks().should.have.length_of(1)
    conn.delete_stack("test_stack")
    conn.list_stacks().should.have.length_of(0)
def test_create_stack():
    conn = boto.connect_cloudformation()
    conn.create_stack("test_stack", template_body=dummy_template_json)

    stack = conn.describe_stacks()[0]
    stack.stack_name.should.equal("test_stack")
    stack.get_template().should.equal(dummy_template)
 def test__stack_updatable_limit_exceeded_does_not_exist(self):
     cfno = AWSCFNOutput()
     cfn = boto.connect_cloudformation(
         aws_access_key_id='access',
         aws_secret_access_key='secret'
     )
     assert_equals(False, cfno._stack_updatable(cfn, 'test'))
def update_config(region_name, stack_params, config_file):
    parser = SafeConfigParser()
    parser.read(config_file)

    print 'Validating resource creation . . . '
    try:
        cfn = boto.connect_cloudformation()
        cfn = boto.cloudformation.connect_to_region(region_name)
        stack = cfn.describe_stacks(stack_params['vpc_stack_name'])[0]
        vpc_id = 'undef'
        publicroute_id = 'undef'
        privateroute_id = 'undef'
        for output in stack.outputs:
            if output.key == 'VpcId':
               vpc_id = output.value
            elif output.key == 'PublicRouteTable':
                publicroute_id = output.value
            elif output.key == 'PrivateRouteTable':
                privateroute_id = output.value
        if vpc_id == 'undef':
            raise UndefError('VpcId')
        if publicroute_id == 'undef':
            raise UndefError('PublicRouteTable')
        if privateroute_id == 'undef':
            raise UndefError('PrivateRouteTable')
        print('Updating ' + config_file  + ' with ' + stack_params['vpc_stack_name'] + ' stack information')
        parser.set('prod', 'vpc_id', vpc_id)
        parser.set('prod', 'public_subnet_route_table', publicroute_id)
        parser.set('prod', 'private_subnet_route_table', privateroute_id)
        config_output = open(config_file, 'w')
        parser.write(config_output)
    except UndefError as e:
        print 'Error updating configuration. Stack output not defined:', e.value
    except boto.exception.BotoServerError as e:
        print e.error_message
def test_update_stack_with_parameters():
    dummy_template = {
        "AWSTemplateFormatVersion": "2010-09-09",
        "Description": "Stack",
        "Resources": {
            "VPC": {
                "Properties": {
                    "CidrBlock": {
                        "Ref": "Bar"
                    }
                },
                "Type": "AWS::EC2::VPC",
            }
        },
        "Parameters": {
            "Bar": {
                "Type": "String"
            }
        },
    }
    dummy_template_json = json.dumps(dummy_template)
    conn = boto.connect_cloudformation()
    conn.create_stack(
        "test_stack",
        template_body=dummy_template_json,
        parameters=[("Bar", "192.168.0.0/16")],
    )
    conn.update_stack(
        "test_stack",
        template_body=dummy_template_json,
        parameters=[("Bar", "192.168.0.1/16")],
    )

    stack = conn.describe_stacks()[0]
    assert stack.parameters[0].value == "192.168.0.1/16"
Beispiel #19
0
 def describe(self):
     if self.pargs.stack_name == None:
         print 'Please provide a stack name'
         sys.exit(1)
         
     try:
         conn = boto.connect_cloudformation()
         stacks = conn.describe_stacks(self.pargs.stack_name)
         stack = None
         if len(stacks) == 0:
             raise Exception("No stacks found matching '%s'" % self.pargs.stack_name)
         else:
             stack = stacks[0]
             
         stack_events = conn.describe_stack_events(self.pargs.stack_name)
         
         print '%s [%s]:' % (self.pargs.stack_name, stack.stack_status)
         print 'Creation Time\t: %s' % stack.creation_time
         print 'Description\t: %s' % stack.description
         if len(stack.outputs) > 0:
             print 'Outputs\t:'
             for output in stack.outputs:
                 print '\t%s: %s' % (output.key, output.value)
                 
         if len(stack_events) > 0:
             print 'Events\t:'
             for stack_event in stack_events:
                 print '[%s]\t\t\t\t\t[%s] \n\t%s %s \n\t%s \n\tReason: %s \n_________________________________________________________________________________'% (
                   stack_event.timestamp, stack_event.resource_status, 
                   stack_event.resource_type, stack_event.logical_resource_id, 
                   stack_event.physical_resource_id, 
                   stack_event.resource_status_reason)
     except Exception as e:
         self.log.error(e)
         sys.exit(1)
Beispiel #20
0
def validate_url(bucket_base_name):
    """
    Validate templates via URLs of S3 objects.
    """
    regions = boto.cloudformation.regions()
    for region in regions:
        bucket_name = bucket_base_name + '-' + region.name
        try:
            cfn = boto.connect_cloudformation(region=region)
            for dirpath, dirnames, filenames in os.walk(sfn.TEMPLATES_DIR):
                # upload only *.template files
                filenames = [ filename for filename in filenames if filename.endswith('.template') ]

                print "Validating ", len(filenames), "templates in ", bucket_name, " ..."
                for filename in filenames:
                    keyname = os.path.relpath(os.path.join(dirpath, filename)).replace('\\', '/')
                    template_url = "http://s3"
                    # handle S3 legacy issue regarding region 'US Standard', see e.g. 
                    # https://forums.aws.amazon.com/message.jspa?messageID=185820
                    if region.name != 'us-east-1':
                        template_url += ('-' + region.name)
                    template_url += ('.amazonaws.com/' + bucket_name + '/' + keyname)
                    log.info("... validating {0} ...".format(keyname))
                    template = cfn.validate_template(template_url=template_url)
        except boto.exception.BotoServerError, e:
            log.error(e.error_message)
Beispiel #21
0
    def setup_cfn_connection(self, endpoint=None, region=None, aws_access_key_id=None, aws_secret_access_key=None, path="/",port=443, is_secure=True, boto_debug=0):
        cfn_region = RegionInfo()
        if region:
            self.debug("Check region: " + str(region))
            try:
                if not endpoint:
                    cfn_region.endpoint = "cloudformation.{0}.amazonaws.com".format(region)
                else:
                    cfn_region.endpoint = endpoint
            except KeyError:
                raise Exception( 'Unknown region: %s' % region)
        else:
            cfn_region.name = 'eucalyptus'
            if endpoint:
                cfn_region.endpoint = endpoint
            else:
                cfn_region.endpoint = self.get_cfn_ip()

        try:
            cfn_connection_args = { 'aws_access_key_id' : aws_access_key_id,
                                    'aws_secret_access_key': aws_secret_access_key,
                                    'is_secure': is_secure,
                                    'debug':boto_debug,
                                    'port' : port,
                                    'path' : path,
                                    'region' : cfn_region}
            self.debug("Attempting to create cloudformation connection to " + self.get_cfn_ip() + ':' + str(port) + path)
            self.cloudformation = boto.connect_cloudformation(**cfn_connection_args)
        except Exception, e:
            self.critical("Was unable to create cloudformation connection because of exception: " + str(e))
def test_update_stack_with_parameters():
    dummy_template = {
        "AWSTemplateFormatVersion": "2010-09-09",
        "Description": "Stack",
        "Resources": {
            "VPC": {
                "Properties": {
                    "CidrBlock": {"Ref": "Bar"}
            },
            "Type": "AWS::EC2::VPC"
            }
        },
        "Parameters": {
            "Bar": {
                "Type": "String"
            }
        }
    }
    dummy_template_json = json.dumps(dummy_template)
    conn = boto.connect_cloudformation()
    conn.create_stack(
        "test_stack",
        template_body=dummy_template_json,
        parameters=[("Bar", "192.168.0.0/16")]
    )
    conn.update_stack(
        "test_stack",
        template_body=dummy_template_json,
        parameters=[("Bar", "192.168.0.1/16")]
    )

    stack = conn.describe_stacks()[0]
    assert stack.parameters[0].value == "192.168.0.1/16"
def test_create_stack_kinesis():
    conn = boto.connect_cloudformation()
    dummy_template = {
        "AWSTemplateFormatVersion": "2010-09-09",
        "Description": "Stack Kinesis Test 1",
        "Parameters": {},
        "Resources": {
            "stream1": {
                "Type": "AWS::Kinesis::Stream",
                "Properties": {
                    "Name": "stream1",
                    "ShardCount": 2
                },
            }
        },
    }
    conn.create_stack(
        "test_stack_kinesis_1",
        template_body=json.dumps(dummy_template),
        parameters={}.items(),
    )

    stack = conn.describe_stacks()[0]
    resources = stack.list_resources()
    assert len(resources) == 1
 def test_do_poll_true_returns_true_multiple_loops(self):
     cfno = AWSCFNOutput()
     cfn = boto.connect_cloudformation(
         aws_access_key_id='access',
         aws_secret_access_key='secret'
     )
     assert_equals(True, cfno.do_poll(cfn, 'test', True, 'create'))
def test_cloudformation_params():
    dummy_template = {
        "AWSTemplateFormatVersion": "2010-09-09",
        "Description": "Stack 1",
        "Resources": {},
        "Parameters": {
            "APPNAME": {
                "Default": "app-name",
                "Description": "The name of the app",
                "Type": "String",
            }
        },
    }
    dummy_template_json = json.dumps(dummy_template)
    cfn = boto.connect_cloudformation()
    cfn.create_stack(
        "test_stack1",
        template_body=dummy_template_json,
        parameters=[("APPNAME", "testing123")],
    )
    stack = cfn.describe_stacks("test_stack1")[0]
    stack.parameters.should.have.length_of(1)
    param = stack.parameters[0]
    param.key.should.equal("APPNAME")
    param.value.should.equal("testing123")
 def test_do_poll_true_delete_catches_rate_limit(self):
     cfno = AWSCFNOutput()
     cfn = boto.connect_cloudformation(
         aws_access_key_id='access',
         aws_secret_access_key='secret'
     )
     assert_equals(True, cfno.do_poll(cfn, 'test', True, 'delete'))
def test_delete_stack_with_resource_missing_delete_attr():
    conn = boto.connect_cloudformation()
    conn.create_stack("test_stack", template_body=dummy_template_json3)

    conn.describe_stacks().should.have.length_of(1)
    conn.delete_stack("test_stack")
    conn.describe_stacks().should.have.length_of(0)
 def test__stack_updatable_exists(self):
     cfno = AWSCFNOutput()
     cfn = boto.connect_cloudformation(
         aws_access_key_id='access',
         aws_secret_access_key='secret'
     )
     assert_equals(True, cfno._stack_updatable(cfn, 'test'))
def test_delete_stack_by_name():
    conn = boto.connect_cloudformation()
    conn.create_stack("test_stack", template_body=dummy_template_json)

    conn.describe_stacks().should.have.length_of(1)
    conn.delete_stack("test_stack")
    conn.describe_stacks().should.have.length_of(0)
def test_cloudformation_params_conditions_and_resources_are_distinct():
    dummy_template = {
        "AWSTemplateFormatVersion": "2010-09-09",
        "Description": "Stack 1",
        "Conditions": {
            "FooEnabled": {"Fn::Equals": [{"Ref": "FooEnabled"}, "true"]},
            "FooDisabled": {
                "Fn::Not": [{"Fn::Equals": [{"Ref": "FooEnabled"}, "true"]}]
            },
        },
        "Parameters": {
            "FooEnabled": {"Type": "String", "AllowedValues": ["true", "false"]}
        },
        "Resources": {
            "Bar": {
                "Properties": {"CidrBlock": "192.168.0.0/16"},
                "Condition": "FooDisabled",
                "Type": "AWS::EC2::VPC",
            }
        },
    }
    dummy_template_json = json.dumps(dummy_template)
    cfn = boto.connect_cloudformation()
    cfn.create_stack(
        "test_stack1",
        template_body=dummy_template_json,
        parameters=[("FooEnabled", "true")],
    )
    stack = cfn.describe_stacks("test_stack1")[0]
    resources = stack.list_resources()
    assert not [
        resource for resource in resources if resource.logical_resource_id == "Bar"
    ]
 def test__show_prompt_no_difference(self):
     cfno = AWSCFNOutput()
     cfn = boto.connect_cloudformation(
         aws_access_key_id='access',
         aws_secret_access_key='secret'
     )
     assert_equals(False, cfno._show_prompt(cfn, 'test', '{"a": "b"}', _mock_allowed_update(self)))
Beispiel #32
0
    def deploy_stack(self,
                     stack_name,
                     template_string_or_url,
                     capabilities=['CAPABILITY_IAM'],
                     parameters=None,
                     aws_region=None,
                     wait_for_complete=True):
        """
        Method takes a CloudFormation template string or S3 url and deploys the stack to the specified AWS region.
        @param stack_name [string] - name to use when deploying the CloudFormation stack.
        @param template_string_or_url [string] - S3 URL or CloudFormation template body to be deployed.
        @param capabiltiies [list(str)] - List of CloudFormation template capabilities to be granted to the deployed stack.
        @param parameters [dict] - dictionary of key value pairs containing overrides to template parameter defaults.
        @param aws_region [string] - AWS-specific region name to start when querying the AWS APIs
        @param wait_for_complete [boolean] - boolean indicating whether to poll for success or failure before completing the deploy process.
        """
        if aws_region is None:
            aws_region = self.configuration.get('boto', {}).get(
                'region_name', 'us-east-1')
            logging.debug(
                'Setting default AWS Region for API access from overall configuration ['
                + aws_region + ']')

        logging.info('Connecting to CloudFormation in region [' + aws_region +
                     ']')
        cf_conn = boto.connect_cloudformation(aws_region)
        logging.info('Starting deploy of stack [' + stack_name +
                     '] to AWS in region [' + aws_region + ']')

        command_args = {'capabilities': capabilities}

        try:
            if type(template_string_or_url) == dict:
                command_args['template_body'] = json.dumps(
                    template_string_or_url)
            else:
                template_dict = json.loads(template_string_or_url)
                command_args['template_body'] = template_string_or_url
        except:
            command_args['template_s3_url'] = template_string_or_url

        logging.debug('Calling stack deploy for [' + stack_name +
                      '] with arguments: ' + json.dumps(command_args))
        cf_conn.create_stack(stack_name, **command_args)

        if wait_for_complete:
            if self.wait_for_stack(cf_conn, stack_name):
                logging.info('Stack [' + stack_name +
                             '] successfully deployed to AWS in region [' +
                             aws_region + ']')
                return True
            else:
                message = 'Stack [%s] failed to deploy to AWS in region [%s] with status [%s]' % (
                    stack_name, aws_region,
                    self.get_stack_status(cf_conn, stack_name))
                logging.warn(message)
                return False
        else:
            return True
def test_list_stacks():
    conn = boto.connect_cloudformation()
    conn.create_stack("test_stack", template_body=dummy_template_json)
    conn.create_stack("test_stack2", template_body=dummy_template_json)

    stacks = conn.list_stacks()
    stacks.should.have.length_of(2)
    stacks[0].template_description.should.equal("Stack 1")
Beispiel #34
0
 def orchestration_connection(self):
     if self._orchestration_connection is None:
         region = self._region(self._cfn_regions())
         self._orchestration_connection = boto.connect_cloudformation(
             region=region,
             **config.CLOUD['ORCHESTRATION_CREDENTIALS']
         )
     return self._orchestration_connection
def test_describe_stack_by_stack_id():
    conn = boto.connect_cloudformation()
    conn.create_stack("test_stack", template_body=dummy_template_json)

    stack = conn.describe_stacks("test_stack")[0]
    stack_by_id = conn.describe_stacks(stack.stack_id)[0]
    stack_by_id.stack_id.should.equal(stack.stack_id)
    stack_by_id.stack_name.should.equal("test_stack")
def test_describe_stack_by_stack_id():
    conn = boto.connect_cloudformation()
    conn.create_stack("test_stack", template_body=dummy_template_json)

    stack = conn.describe_stacks("test_stack")[0]
    stack_by_id = conn.describe_stacks(stack.stack_id)[0]
    stack_by_id.stack_id.should.equal(stack.stack_id)
    stack_by_id.stack_name.should.equal("test_stack")
 def test__show_prompt_difference_yes(self):
     cfno = AWSCFNOutput()
     cfn = boto.connect_cloudformation(
         aws_access_key_id='access',
         aws_secret_access_key='secret'
     )
     sys.stdout = open('/dev/null', 'w')
     assert_equals(True, cfno._show_prompt(cfn, 'test', '{"a": "c"}', _mock_allowed_update(self)))
def test_list_stacks():
    conn = boto.connect_cloudformation()
    conn.create_stack("test_stack", template_body=dummy_template_json)
    conn.create_stack("test_stack2", template_body=dummy_template_json)

    stacks = conn.list_stacks()
    stacks.should.have.length_of(2)
    stacks[0].template_description.should.equal("Stack 1")
Beispiel #39
0
def validate_cloudformation_template(template_body):
    """Validates the JSON of a CloudFormation template produced by Troposphere
    Arguments
    :param template_body: The string representation of CloudFormation template
                          JSON
    """
    c = boto.connect_cloudformation()

    return c.validate_template(template_body=template_body)
def test_get_template_by_name():
    conn = boto.connect_cloudformation()
    conn.create_stack(
        "test_stack",
        template_body=dummy_template_json,
    )

    template = conn.get_template("test_stack")
    template.should.equal(dummy_template)
def test_delete_stack_dynamo_template():
    conn = boto.connect_cloudformation()
    db_conn = boto.dynamodb2.connect_to_region("us-east-1")
    #
    conn.create_stack("test_stack", template_body=dummy_template_json4)
    db_conn.list_tables()["TableNames"].should.have.length_of(1)
    #
    conn.delete_stack("test_stack")
    db_conn.list_tables()["TableNames"].should.have.length_of(0)
Beispiel #42
0
def validate_cloudformation_template(template_body):
    """Validates the JSON of a CloudFormation template produced by Troposphere
    Arguments
    :param template_body: The string representation of CloudFormation template
                          JSON
    """
    c = boto.connect_cloudformation()

    return c.validate_template(template_body=template_body)
def test_list_stacks_with_filter():
    conn = boto.connect_cloudformation()
    conn.create_stack("test_stack", template_body=dummy_template_json)
    conn.create_stack("test_stack2", template_body=dummy_template_json)
    conn.update_stack("test_stack", template_body=dummy_template_json2)
    stacks = conn.list_stacks("CREATE_COMPLETE")
    stacks.should.have.length_of(1)
    stacks[0].template_description.should.equal("Stack 1")
    stacks = conn.list_stacks("UPDATE_COMPLETE")
    stacks.should.have.length_of(1)
Beispiel #44
0
def test_stack_tags():
    conn = boto.connect_cloudformation()
    conn.create_stack(
        "test_stack",
        template_body=dummy_template_json,
        tags={"foo": "bar", "baz": "bleh"},
    )

    stack = conn.describe_stacks()[0]
    dict(stack.tags).should.equal({"foo": "bar", "baz": "bleh"})
def test_delete_stack_by_id():
    conn = boto.connect_cloudformation()
    stack_id = conn.create_stack(
        "test_stack",
        template_body=dummy_template_json,
    )

    conn.list_stacks().should.have.length_of(1)
    conn.delete_stack(stack_id)
    conn.list_stacks().should.have.length_of(0)
def test_create_stack():
    conn = boto.connect_cloudformation()
    conn.create_stack(
        "test_stack",
        template_body=dummy_template_json,
    )

    stack = conn.describe_stacks()[0]
    stack.stack_name.should.equal('test_stack')
    stack.get_template().should.equal(dummy_template)
Beispiel #47
0
def test_create_stack_with_notification_arn():
    conn = boto.connect_cloudformation()
    conn.create_stack(
        "test_stack_with_notifications",
        template_body=dummy_template_json,
        notification_arns='arn:aws:sns:us-east-1:123456789012:fake-queue'
    )

    stack = conn.describe_stacks()[0]
    [n.value for n in stack.notification_arns].should.contain('arn:aws:sns:us-east-1:123456789012:fake-queue')
def test_delete_stack_dynamo_template():
    conn = boto.connect_cloudformation()
    dynamodb_client = boto3.client("dynamodb", region_name="us-east-1")
    conn.create_stack("test_stack", template_body=dummy_template4)
    table_desc = dynamodb_client.list_tables()
    len(table_desc.get("TableNames")).should.equal(1)
    conn.delete_stack("test_stack")
    table_desc = dynamodb_client.list_tables()
    len(table_desc.get("TableNames")).should.equal(0)
    conn.create_stack("test_stack", template_body=dummy_template4)
Beispiel #49
0
def status(args):
    """List the status of the instances and ELB."""
    stacks = find_stacks(args.stack_name)

    cfn = boto.connect_cloudformation()

    for stack in stacks:
        fullstack = cfn.describe_stacks(stack.stack_name)[0]
        yield "\nStack %s" % fullstack.stack_name
        yield format_autoscale_instances(fullstack)
Beispiel #50
0
def test_stack_elb_integration_with_attached_ec2_instances():
    elb_template = {
        "AWSTemplateFormatVersion": "2010-09-09",
        "Resources": {
            "MyELB": {
                "Type": "AWS::ElasticLoadBalancing::LoadBalancer",
                "Instances": [{
                    "Ref": "Ec2Instance1"
                }],
                "Properties": {
                    "LoadBalancerName": "test-elb",
                    "AvailabilityZones": ['us-east1'],
                }
            },
            "Ec2Instance1": {
                "Type": "AWS::EC2::Instance",
                "Properties": {
                    "ImageId": "ami-1234abcd",
                    "UserData": "some user data",
                }
            },
        },
    }
    elb_template_json = json.dumps(elb_template)

    conn = boto.connect_cloudformation()
    conn.create_stack(
        "elb_stack",
        template_body=elb_template_json,
    )

    elb_conn = boto.connect_elb()
    load_balancer = elb_conn.get_all_load_balancers()[0]

    ec2_conn = boto.connect_ec2()
    reservation = ec2_conn.get_all_instances()[0]
    ec2_instance = reservation.instances[0]
    instance_id = ec2_instance.id

    load_balancer.instances[0].id.should.equal(ec2_instance.id)
    list(load_balancer.availability_zones).should.equal(['us-east1'])
    load_balancer_name = load_balancer.name

    stack = conn.describe_stacks()[0]
    stack_resources = stack.describe_resources()
    stack_resources.should.have.length_of(2)
    for resource in stack_resources:
        if resource.resource_type == 'AWS::ElasticLoadBalancing::LoadBalancer':
            load_balancer = resource
        else:
            ec2_instance = resource

    load_balancer.logical_resource_id.should.equal("MyELB")
    load_balancer.physical_resource_id.should.equal(load_balancer_name)
    ec2_instance.physical_resource_id.should.equal(instance_id)
def test_delete_stack_by_id():
    conn = boto.connect_cloudformation()
    stack_id = conn.create_stack("test_stack", template_body=dummy_template_json)

    conn.describe_stacks().should.have.length_of(1)
    conn.delete_stack(stack_id)
    conn.describe_stacks().should.have.length_of(0)
    with assert_raises(BotoServerError):
        conn.describe_stacks("test_stack")

    conn.describe_stacks(stack_id).should.have.length_of(1)
def test_describe_deleted_stack():
    conn = boto.connect_cloudformation()
    conn.create_stack("test_stack", template_body=dummy_template_json)

    stack = conn.describe_stacks("test_stack")[0]
    stack_id = stack.stack_id
    conn.delete_stack(stack.stack_id)
    stack_by_id = conn.describe_stacks(stack_id)[0]
    stack_by_id.stack_id.should.equal(stack.stack_id)
    stack_by_id.stack_name.should.equal("test_stack")
    stack_by_id.stack_status.should.equal("DELETE_COMPLETE")
def test_create_stack_with_notification_arn():
    conn = boto.connect_cloudformation()
    conn.create_stack(
        "test_stack_with_notifications",
        template_body=dummy_template_json,
        notification_arns="arn:aws:sns:us-east-1:{}:fake-queue".format(
            ACCOUNT_ID),
    )

    stack = conn.describe_stacks()[0]
    [n.value for n in stack.notification_arns
     ].should.contain("arn:aws:sns:us-east-1:{}:fake-queue".format(ACCOUNT_ID))
def test_describe_stack_events_shows_create_update_and_delete():
    conn = boto.connect_cloudformation()
    stack_id = conn.create_stack("test_stack",
                                 template_body=dummy_template_json)
    conn.update_stack(stack_id, template_body=dummy_template_json2)
    conn.delete_stack(stack_id)

    # assert begins and ends with stack events
    events = conn.describe_stack_events(stack_id)
    events[0].resource_type.should.equal("AWS::CloudFormation::Stack")
    events[-1].resource_type.should.equal("AWS::CloudFormation::Stack")

    # testing ordering of stack events without assuming resource events will not exist
    # the AWS API returns events in reverse chronological order
    stack_events_to_look_for = iter([
        ("DELETE_COMPLETE", None),
        ("DELETE_IN_PROGRESS", "User Initiated"),
        ("UPDATE_COMPLETE", None),
        ("UPDATE_IN_PROGRESS", "User Initiated"),
        ("CREATE_COMPLETE", None),
        ("CREATE_IN_PROGRESS", "User Initiated"),
    ])
    try:
        for event in events:
            event.stack_id.should.equal(stack_id)
            event.stack_name.should.equal("test_stack")
            event.event_id.should.match(
                r"[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}")

            if event.resource_type == "AWS::CloudFormation::Stack":
                event.logical_resource_id.should.equal("test_stack")
                event.physical_resource_id.should.equal(stack_id)

                status_to_look_for, reason_to_look_for = next(
                    stack_events_to_look_for)
                event.resource_status.should.equal(status_to_look_for)
                if reason_to_look_for is not None:
                    event.resource_status_reason.should.equal(
                        reason_to_look_for)
    except StopIteration:
        assert False, "Too many stack events"

    list(stack_events_to_look_for).should.be.empty

    with pytest.raises(BotoServerError) as exp:
        conn.describe_stack_events("non_existing_stack")
    err = exp.value
    err.message.should.equal("Stack with id non_existing_stack does not exist")
    err.body.should.match(r"Stack with id non_existing_stack does not exist")
    err.error_code.should.equal("ValidationError")
    err.reason.should.equal("Bad Request")
    err.status.should.equal(400)
def test_update_stack_replace_tags():
    conn = boto.connect_cloudformation()
    conn.create_stack("test_stack",
                      template_body=dummy_template_json,
                      tags={"foo": "bar"})
    conn.update_stack("test_stack",
                      template_body=dummy_template_json,
                      tags={"foo": "baz"})

    stack = conn.describe_stacks()[0]
    stack.stack_status.should.equal("UPDATE_COMPLETE")
    # since there is one tag it doesn't come out as a list
    dict(stack.tags).should.equal({"foo": "baz"})