def test_read_from_site_packages(mocked_open):
    # setup
    from servicecatalog_puppet import asset_helpers as sut

    expected_param = os.path.sep.join(
        [os.path.dirname(os.path.abspath(__file__)), "foo"])

    # exercise
    sut.read_from_site_packages("foo")

    # verify
    assert mocked_open.call_count == 1
    assert mocked_open.call_args == call(expected_param, "r")
Exemplo n.º 2
0
def _do_bootstrap_spoke(puppet_account_id, cloudformation, puppet_version):
    logger.info('Starting bootstrap of spoke')
    template = asset_helpers.read_from_site_packages(
        '{}-spoke.template.yaml'.format(constants.BOOTSTRAP_STACK_NAME))
    template = Template(template).render(VERSION=puppet_version)
    args = {
        'StackName':
        "{}-spoke".format(constants.BOOTSTRAP_STACK_NAME),
        'TemplateBody':
        template,
        'Capabilities': ['CAPABILITY_NAMED_IAM'],
        'Parameters': [
            {
                'ParameterKey': 'PuppetAccountId',
                'ParameterValue': str(puppet_account_id),
            },
            {
                'ParameterKey': 'Version',
                'ParameterValue': puppet_version,
                'UsePreviousValue': False,
            },
        ],
        'Tags': [{
            "Key": "ServiceCatalogPuppet:Actor",
            "Value": "Framework",
        }]
    }
    cloudformation.create_or_update(**args)
    logger.info('Finished bootstrap of spoke')
def _do_bootstrap_spoke(puppet_account_id, cloudformation, puppet_version,
                        permission_boundary):
    logger.info("Starting bootstrap of spoke")
    template = asset_helpers.read_from_site_packages(
        "{}-spoke.template.yaml".format(constants.BOOTSTRAP_STACK_NAME))
    template = Template(template).render(VERSION=puppet_version)
    args = {
        "StackName":
        "{}-spoke".format(constants.BOOTSTRAP_STACK_NAME),
        "TemplateBody":
        template,
        "Capabilities": ["CAPABILITY_NAMED_IAM"],
        "Parameters": [
            {
                "ParameterKey": "PuppetAccountId",
                "ParameterValue": str(puppet_account_id),
            },
            {
                "ParameterKey": "PermissionBoundary",
                "ParameterValue": permission_boundary,
                "UsePreviousValue": False,
            },
            {
                "ParameterKey": "Version",
                "ParameterValue": puppet_version,
                "UsePreviousValue": False,
            },
        ],
        "Tags": [{
            "Key": "ServiceCatalogPuppet:Actor",
            "Value": "Framework",
        }],
    }
    cloudformation.create_or_update(**args)
    logger.info("Finished bootstrap of spoke")
def quick_start():
    click.echo("Quick Start running...")
    puppet_version = cli_command_helpers.get_puppet_version()
    with betterboto_client.ClientContextManager('sts') as sts:
        puppet_account_id = sts.get_caller_identity().get('Account')
        click.echo(
            "Going to use puppet_account_id: {}".format(puppet_account_id))
    click.echo("Bootstrapping account as a spoke")
    with betterboto_client.ClientContextManager(
            'cloudformation') as cloudformation:
        cli_command_helpers._do_bootstrap_spoke(puppet_account_id,
                                                cloudformation, puppet_version)

    click.echo("Setting the config")
    content = yaml.safe_dump(
        {"regions": ['eu-west-1', 'eu-west-2', 'eu-west-3']})
    with betterboto_client.ClientContextManager('ssm') as ssm:
        ssm.put_parameter(
            Name=constants.CONFIG_PARAM_NAME,
            Type='String',
            Value=content,
            Overwrite=True,
        )
        click.echo("Bootstrapping account as the master")
        org_iam_role_arn = cli_command_helpers._do_bootstrap_org_master(
            puppet_account_id, cloudformation, puppet_version)
        ssm.put_parameter(
            Name=constants.CONFIG_PARAM_NAME_ORG_IAM_ROLE_ARN,
            Type='String',
            Value=org_iam_role_arn,
            Overwrite=True,
        )
    click.echo("Bootstrapping the account now!")
    cli_command_helpers._do_bootstrap(puppet_version)

    if os.path.exists('ServiceCatalogPuppet'):
        click.echo("Found ServiceCatalogPuppet so not cloning or seeding")
    else:
        click.echo("Cloning for you")
        command = "git clone " \
                  "--config 'credential.helper=!aws codecommit credential-helper $@' " \
                  "--config 'credential.UseHttpPath=true' " \
                  "https://git-codecommit.{}.amazonaws.com/v1/repos/ServiceCatalogPuppet".format(
            os.environ.get("AWS_DEFAULT_REGION")
        )
        os.system(command)
        click.echo("Seeding")
        manifest = Template(
            asset_helpers.read_from_site_packages(
                os.path.sep.join(["manifests", "manifest-quickstart.yaml"
                                  ]))).render(ACCOUNT_ID=puppet_account_id)
        open(os.path.sep.join(["ServiceCatalogPuppet", "manifest.yaml"]),
             'w').write(manifest)
        click.echo("Pushing manifest")
        os.system(
            "cd ServiceCatalogPuppet && git add manifest.yaml && git commit -am 'initial add' && git push"
        )

    click.echo("All done!")
Exemplo n.º 5
0
def bootstrap_org_master(puppet_account_id):
    with betterboto_client.ClientContextManager(
            'cloudformation', ) as cloudformation:
        org_iam_role_arn = None
        puppet_version = config.get_puppet_version()
        logger.info('Starting bootstrap of org master')
        stack_name = f"{constants.BOOTSTRAP_STACK_NAME}-org-master-{puppet_account_id}"
        template = asset_helpers.read_from_site_packages(
            f'{constants.BOOTSTRAP_STACK_NAME}-org-master.template.yaml')
        template = Template(template).render(
            VERSION=puppet_version, puppet_account_id=puppet_account_id)
        args = {
            'StackName':
            stack_name,
            'TemplateBody':
            template,
            'Capabilities': ['CAPABILITY_NAMED_IAM'],
            'Parameters': [
                {
                    'ParameterKey': 'PuppetAccountId',
                    'ParameterValue': str(puppet_account_id),
                },
                {
                    'ParameterKey': 'Version',
                    'ParameterValue': puppet_version,
                    'UsePreviousValue': False,
                },
            ],
            'Tags': [{
                "Key": "ServiceCatalogPuppet:Actor",
                "Value": "Framework",
            }]
        }
        cloudformation.create_or_update(**args)
        response = cloudformation.describe_stacks(StackName=stack_name)
        if len(response.get('Stacks')) != 1:
            raise Exception(
                "Expected there to be only one {} stack".format(stack_name))
        stack = response.get('Stacks')[0]

        for output in stack.get('Outputs'):
            if output.get(
                    'OutputKey') == constants.PUPPET_ORG_ROLE_FOR_EXPANDS_ARN:
                logger.info('Finished bootstrap of org-master')
                org_iam_role_arn = output.get("OutputValue")

        if org_iam_role_arn is None:
            raise Exception("Could not find output: {} in stack: {}".format(
                constants.PUPPET_ORG_ROLE_FOR_EXPANDS_ARN, stack_name))

    click.echo("Bootstrapped org master, org-iam-role-arn: {}".format(
        org_iam_role_arn))
def bootstrap_org_master(puppet_account_id):
    with betterboto_client.ClientContextManager(
            "cloudformation", ) as cloudformation:
        org_iam_role_arn = None
        logger.info("Starting bootstrap of org master")
        stack_name = f"{constants.BOOTSTRAP_STACK_NAME}-org-master-{puppet_account_id}"
        template = asset_helpers.read_from_site_packages(
            f"{constants.BOOTSTRAP_STACK_NAME}-org-master.template.yaml")
        template = Template(template).render(
            VERSION=constants.VERSION, puppet_account_id=puppet_account_id)
        args = {
            "StackName":
            stack_name,
            "TemplateBody":
            template,
            "Capabilities": ["CAPABILITY_NAMED_IAM"],
            "Parameters": [
                {
                    "ParameterKey": "PuppetAccountId",
                    "ParameterValue": str(puppet_account_id),
                },
                {
                    "ParameterKey": "Version",
                    "ParameterValue": constants.VERSION,
                    "UsePreviousValue": False,
                },
            ],
            "Tags": [{
                "Key": "ServiceCatalogPuppet:Actor",
                "Value": "Framework",
            }],
        }
        cloudformation.create_or_update(**args)
        response = cloudformation.describe_stacks(StackName=stack_name)
        if len(response.get("Stacks")) != 1:
            raise Exception(
                "Expected there to be only one {} stack".format(stack_name))
        stack = response.get("Stacks")[0]

        for output in stack.get("Outputs"):
            if output.get(
                    "OutputKey") == constants.PUPPET_ORG_ROLE_FOR_EXPANDS_ARN:
                logger.info("Finished bootstrap of org-master")
                org_iam_role_arn = output.get("OutputValue")

        if org_iam_role_arn is None:
            raise Exception("Could not find output: {} in stack: {}".format(
                constants.PUPPET_ORG_ROLE_FOR_EXPANDS_ARN, stack_name))

    click.echo("Bootstrapped org master, org-iam-role-arn: {}".format(
        org_iam_role_arn))
Exemplo n.º 7
0
def _do_bootstrap_org_master(puppet_account_id, cloudformation,
                             puppet_version):
    logger.info('Starting bootstrap of org master')
    stack_name = "{}-org-master".format(constants.BOOTSTRAP_STACK_NAME)
    template = asset_helpers.read_from_site_packages(
        '{}.template.yaml'.format(stack_name))
    template = Template(template).render(VERSION=puppet_version)
    args = {
        'StackName':
        stack_name,
        'TemplateBody':
        template,
        'Capabilities': ['CAPABILITY_NAMED_IAM'],
        'Parameters': [
            {
                'ParameterKey': 'PuppetAccountId',
                'ParameterValue': str(puppet_account_id),
            },
            {
                'ParameterKey': 'Version',
                'ParameterValue': puppet_version,
                'UsePreviousValue': False,
            },
        ],
        'Tags': [{
            "Key": "ServiceCatalogPuppet:Actor",
            "Value": "Framework",
        }]
    }
    cloudformation.create_or_update(**args)
    response = cloudformation.describe_stacks(StackName=stack_name)
    if len(response.get('Stacks')) != 1:
        raise Exception(
            "Expected there to be only one {} stack".format(stack_name))
    stack = response.get('Stacks')[0]

    for output in stack.get('Outputs'):
        if output.get(
                'OutputKey') == constants.PUPPET_ORG_ROLE_FOR_EXPANDS_ARN:
            logger.info('Finished bootstrap of org-master')
            return output.get("OutputValue")

    raise Exception("Could not find output: {} in stack: {}".format(
        constants.PUPPET_ORG_ROLE_FOR_EXPANDS_ARN, stack_name))
Exemplo n.º 8
0
def _do_bootstrap(puppet_version, with_manual_approvals):
    click.echo('Starting bootstrap')
    ALL_REGIONS = get_regions(os.environ.get("AWS_DEFAULT_REGION"))
    with betterboto_client.MultiRegionClientContextManager(
            'cloudformation', ALL_REGIONS) as clients:
        click.echo('Creating {}-regional'.format(
            constants.BOOTSTRAP_STACK_NAME))
        threads = []
        template = asset_helpers.read_from_site_packages(
            '{}.template.yaml'.format('{}-regional'.format(
                constants.BOOTSTRAP_STACK_NAME)))
        template = Template(template).render(VERSION=puppet_version)
        args = {
            'StackName':
            '{}-regional'.format(constants.BOOTSTRAP_STACK_NAME),
            'TemplateBody':
            template,
            'Capabilities': ['CAPABILITY_IAM'],
            'Parameters': [
                {
                    'ParameterKey': 'Version',
                    'ParameterValue': puppet_version,
                    'UsePreviousValue': False,
                },
                {
                    'ParameterKey': 'DefaultRegionValue',
                    'ParameterValue': os.environ.get('AWS_DEFAULT_REGION'),
                    'UsePreviousValue': False,
                },
            ],
            'Tags': [{
                "Key": "ServiceCatalogPuppet:Actor",
                "Value": "Framework",
            }]
        }
        for client_region, client in clients.items():
            process = Thread(name=client_region,
                             target=client.create_or_update,
                             kwargs=args)
            process.start()
            threads.append(process)
        for process in threads:
            process.join()
        click.echo('Finished creating {}-regional'.format(
            constants.BOOTSTRAP_STACK_NAME))

    with betterboto_client.ClientContextManager(
            'cloudformation') as cloudformation:
        click.echo('Creating {}'.format(constants.BOOTSTRAP_STACK_NAME))
        template = asset_helpers.read_from_site_packages(
            '{}.template.yaml'.format(constants.BOOTSTRAP_STACK_NAME))
        template = Template(template).render(VERSION=puppet_version,
                                             ALL_REGIONS=ALL_REGIONS)
        args = {
            'StackName':
            constants.BOOTSTRAP_STACK_NAME,
            'TemplateBody':
            template,
            'Capabilities': ['CAPABILITY_NAMED_IAM'],
            'Parameters': [
                {
                    'ParameterKey': 'Version',
                    'ParameterValue': puppet_version,
                    'UsePreviousValue': False,
                },
                {
                    'ParameterKey': 'OrgIamRoleArn',
                    'ParameterValue': str(get_org_iam_role_arn()),
                    'UsePreviousValue': False,
                },
                {
                    'ParameterKey': 'WithManualApprovals',
                    'ParameterValue': "Yes" if with_manual_approvals else "No",
                    'UsePreviousValue': False,
                },
            ],
        }
        cloudformation.create_or_update(**args)

    click.echo('Finished creating {}.'.format(constants.BOOTSTRAP_STACK_NAME))
    with betterboto_client.ClientContextManager('codecommit') as codecommit:
        response = codecommit.get_repository(
            repositoryName=constants.SERVICE_CATALOG_PUPPET_REPO_NAME)
        clone_url = response.get('repositoryMetadata').get('cloneUrlHttp')
        clone_command = "git clone --config 'credential.helper=!aws codecommit credential-helper $@' " \
                        "--config 'credential.UseHttpPath=true' {}".format(clone_url)
        click.echo(
            'You need to clone your newly created repo now and will then need to seed it: \n{}'
            .format(clone_command))
Exemplo n.º 9
0
def _do_bootstrap(
        puppet_version,
        with_manual_approvals,
        puppet_code_pipeline_role_permission_boundary,
        source_role_permissions_boundary,
        puppet_generate_role_permission_boundary,
        puppet_deploy_role_permission_boundary,
        puppet_provisioning_role_permissions_boundary,
        cloud_formation_deploy_role_permissions_boundary,
        deploy_environment_compute_type="BUILD_GENERAL1_SMALL",
        deploy_num_workers=10,
):
    click.echo('Starting bootstrap')

    should_use_eventbridge = config.get_should_use_eventbridge(os.environ.get("AWS_DEFAULT_REGION"))
    if should_use_eventbridge:
        with betterboto_client.ClientContextManager('events') as events:
            try:
                events.describe_event_bus(Name=constants.EVENT_BUS_NAME)
            except events.exceptions.ResourceNotFoundException:
                events.create_event_bus(
                    Name=constants.EVENT_BUS_NAME,
                )

    all_regions = config.get_regions(os.environ.get("AWS_DEFAULT_REGION"))
    with betterboto_client.MultiRegionClientContextManager('cloudformation', all_regions) as clients:
        click.echo('Creating {}-regional'.format(constants.BOOTSTRAP_STACK_NAME))
        threads = []
        template = asset_helpers.read_from_site_packages(
            '{}.template.yaml'.format('{}-regional'.format(constants.BOOTSTRAP_STACK_NAME)))
        template = Template(template).render(VERSION=puppet_version)
        args = {
            'StackName': '{}-regional'.format(constants.BOOTSTRAP_STACK_NAME),
            'TemplateBody': template,
            'Capabilities': ['CAPABILITY_IAM'],
            'Parameters': [
                {
                    'ParameterKey': 'Version',
                    'ParameterValue': puppet_version,
                    'UsePreviousValue': False,
                },
                {
                    'ParameterKey': 'DefaultRegionValue',
                    'ParameterValue': os.environ.get('AWS_DEFAULT_REGION'),
                    'UsePreviousValue': False,
                },
            ],
            'Tags': [
                {
                    "Key": "ServiceCatalogPuppet:Actor",
                    "Value": "Framework",
                }
            ]
        }
        for client_region, client in clients.items():
            process = Thread(name=client_region, target=client.create_or_update, kwargs=args)
            process.start()
            threads.append(process)
        for process in threads:
            process.join()
        click.echo('Finished creating {}-regional'.format(constants.BOOTSTRAP_STACK_NAME))

    with betterboto_client.ClientContextManager('cloudformation') as cloudformation:
        click.echo('Creating {}'.format(constants.BOOTSTRAP_STACK_NAME))
        template = asset_helpers.read_from_site_packages('{}.template.yaml'.format(constants.BOOTSTRAP_STACK_NAME))
        template = Template(template).render(VERSION=puppet_version, ALL_REGIONS=all_regions)
        args = {
            'StackName': constants.BOOTSTRAP_STACK_NAME,
            'TemplateBody': template,
            'Capabilities': ['CAPABILITY_NAMED_IAM'],
            'Parameters': [
                {
                    'ParameterKey': 'Version',
                    'ParameterValue': puppet_version,
                    'UsePreviousValue': False,
                },
                {
                    'ParameterKey': 'OrgIamRoleArn',
                    'ParameterValue': str(config.get_org_iam_role_arn()),
                    'UsePreviousValue': False,
                },
                {
                    'ParameterKey': 'WithManualApprovals',
                    'ParameterValue': "Yes" if with_manual_approvals else "No",
                    'UsePreviousValue': False,
                },
                {
                    'ParameterKey': 'PuppetCodePipelineRolePermissionBoundary',
                    'ParameterValue': puppet_code_pipeline_role_permission_boundary,
                    'UsePreviousValue': False,
                },
                {
                    'ParameterKey': 'SourceRolePermissionsBoundary',
                    'ParameterValue': source_role_permissions_boundary,
                    'UsePreviousValue': False,
                },
                {
                    'ParameterKey': 'PuppetGenerateRolePermissionBoundary',
                    'ParameterValue': puppet_generate_role_permission_boundary,
                    'UsePreviousValue': False,
                },
                {
                    'ParameterKey': 'PuppetDeployRolePermissionBoundary',
                    'ParameterValue': puppet_deploy_role_permission_boundary,
                    'UsePreviousValue': False,
                },
                {
                    'ParameterKey': 'PuppetProvisioningRolePermissionsBoundary',
                    'ParameterValue': puppet_provisioning_role_permissions_boundary,
                    'UsePreviousValue': False,
                },
                {
                    'ParameterKey': 'CloudFormationDeployRolePermissionsBoundary',
                    'ParameterValue': cloud_formation_deploy_role_permissions_boundary,
                    'UsePreviousValue': False,
                },
                {
                    'ParameterKey': 'DeployEnvironmentComputeType',
                    'ParameterValue': deploy_environment_compute_type,
                    'UsePreviousValue': False,
                },
                {
                    'ParameterKey': 'DeployNumWorkers',
                    'ParameterValue': str(deploy_num_workers),
                    'UsePreviousValue': False,
                },
            ],
        }
        cloudformation.create_or_update(**args)

    click.echo('Finished creating {}.'.format(constants.BOOTSTRAP_STACK_NAME))
    with betterboto_client.ClientContextManager('codecommit') as codecommit:
        response = codecommit.get_repository(repositoryName=constants.SERVICE_CATALOG_PUPPET_REPO_NAME)
        clone_url = response.get('repositoryMetadata').get('cloneUrlHttp')
        clone_command = "git clone --config 'credential.helper=!aws codecommit credential-helper $@' " \
                        "--config 'credential.UseHttpPath=true' {}".format(clone_url)
        click.echo(
            'You need to clone your newly created repo now and will then need to seed it: \n{}'.format(
                clone_command
            )
        )
Exemplo n.º 10
0
def _do_bootstrap(
    puppet_version,
    puppet_account_id,
    with_manual_approvals,
    puppet_code_pipeline_role_permission_boundary,
    source_role_permissions_boundary,
    puppet_generate_role_permission_boundary,
    puppet_deploy_role_permission_boundary,
    puppet_provisioning_role_permissions_boundary,
    cloud_formation_deploy_role_permissions_boundary,
    deploy_environment_compute_type="BUILD_GENERAL1_SMALL",
    deploy_num_workers=10,
    source_provider=None,
    owner=None,
    repo=None,
    branch=None,
    poll_for_source_changes=None,
    webhook_secret=None,
):
    click.echo("Starting bootstrap")
    should_use_eventbridge = config.get_should_use_eventbridge(
        puppet_account_id, os.environ.get("AWS_DEFAULT_REGION"))
    if should_use_eventbridge:
        with betterboto_client.ClientContextManager("events") as events:
            try:
                events.describe_event_bus(Name=constants.EVENT_BUS_NAME)
            except events.exceptions.ResourceNotFoundException:
                events.create_event_bus(Name=constants.EVENT_BUS_NAME, )

    all_regions = config.get_regions(puppet_account_id,
                                     os.environ.get("AWS_DEFAULT_REGION"))
    with betterboto_client.MultiRegionClientContextManager(
            "cloudformation", all_regions) as clients:
        click.echo("Creating {}-regional".format(
            constants.BOOTSTRAP_STACK_NAME))
        threads = []
        template = asset_helpers.read_from_site_packages(
            "{}.template.yaml".format("{}-regional".format(
                constants.BOOTSTRAP_STACK_NAME)))
        template = Template(template).render(VERSION=puppet_version)
        args = {
            "StackName":
            "{}-regional".format(constants.BOOTSTRAP_STACK_NAME),
            "TemplateBody":
            template,
            "Capabilities": ["CAPABILITY_IAM"],
            "Parameters": [
                {
                    "ParameterKey": "Version",
                    "ParameterValue": puppet_version,
                    "UsePreviousValue": False,
                },
                {
                    "ParameterKey": "DefaultRegionValue",
                    "ParameterValue": os.environ.get("AWS_DEFAULT_REGION"),
                    "UsePreviousValue": False,
                },
            ],
            "Tags": [{
                "Key": "ServiceCatalogPuppet:Actor",
                "Value": "Framework",
            }],
        }
        for client_region, client in clients.items():
            process = Thread(name=client_region,
                             target=client.create_or_update,
                             kwargs=args)
            process.start()
            threads.append(process)
        for process in threads:
            process.join()
        click.echo("Finished creating {}-regional".format(
            constants.BOOTSTRAP_STACK_NAME))

    source_args = {"Provider": source_provider}
    if source_provider == "CodeCommit":
        source_args.update({
            "Configuration": {
                "RepositoryName": repo,
                "BranchName": branch,
            },
        })
    elif source_provider == "GitHub":
        source_args.update({
            "Configuration": {
                "Owner": owner,
                "Repo": repo,
                "Branch": branch,
                "PollForSourceChanges": poll_for_source_changes,
                "SecretsManagerSecret": webhook_secret,
            },
        })

    with betterboto_client.ClientContextManager(
            "cloudformation") as cloudformation:
        click.echo("Creating {}".format(constants.BOOTSTRAP_STACK_NAME))
        template = asset_helpers.read_from_site_packages(
            "{}.template.yaml".format(constants.BOOTSTRAP_STACK_NAME))
        template = Template(template).render(VERSION=puppet_version,
                                             ALL_REGIONS=all_regions,
                                             Source=source_args)
        template = Template(template).render(VERSION=puppet_version,
                                             ALL_REGIONS=all_regions,
                                             Source=source_args)
        args = {
            "StackName":
            constants.BOOTSTRAP_STACK_NAME,
            "TemplateBody":
            template,
            "Capabilities": ["CAPABILITY_NAMED_IAM"],
            "Parameters": [
                {
                    "ParameterKey": "Version",
                    "ParameterValue": puppet_version,
                    "UsePreviousValue": False,
                },
                {
                    "ParameterKey":
                    "OrgIamRoleArn",
                    "ParameterValue":
                    str(config.get_org_iam_role_arn(puppet_account_id)),
                    "UsePreviousValue":
                    False,
                },
                {
                    "ParameterKey": "WithManualApprovals",
                    "ParameterValue": "Yes" if with_manual_approvals else "No",
                    "UsePreviousValue": False,
                },
                {
                    "ParameterKey": "PuppetCodePipelineRolePermissionBoundary",
                    "ParameterValue":
                    puppet_code_pipeline_role_permission_boundary,
                    "UsePreviousValue": False,
                },
                {
                    "ParameterKey": "SourceRolePermissionsBoundary",
                    "ParameterValue": source_role_permissions_boundary,
                    "UsePreviousValue": False,
                },
                {
                    "ParameterKey": "PuppetGenerateRolePermissionBoundary",
                    "ParameterValue": puppet_generate_role_permission_boundary,
                    "UsePreviousValue": False,
                },
                {
                    "ParameterKey": "PuppetDeployRolePermissionBoundary",
                    "ParameterValue": puppet_deploy_role_permission_boundary,
                    "UsePreviousValue": False,
                },
                {
                    "ParameterKey":
                    "PuppetProvisioningRolePermissionsBoundary",
                    "ParameterValue":
                    puppet_provisioning_role_permissions_boundary,
                    "UsePreviousValue": False,
                },
                {
                    "ParameterKey":
                    "CloudFormationDeployRolePermissionsBoundary",
                    "ParameterValue":
                    cloud_formation_deploy_role_permissions_boundary,
                    "UsePreviousValue": False,
                },
                {
                    "ParameterKey": "DeployEnvironmentComputeType",
                    "ParameterValue": deploy_environment_compute_type,
                    "UsePreviousValue": False,
                },
                {
                    "ParameterKey": "DeployNumWorkers",
                    "ParameterValue": str(deploy_num_workers),
                    "UsePreviousValue": False,
                },
            ],
        }
        cloudformation.create_or_update(**args)

    click.echo("Finished creating {}.".format(constants.BOOTSTRAP_STACK_NAME))
    if source_provider == "CodeCommit":
        with betterboto_client.ClientContextManager(
                "codecommit") as codecommit:
            response = codecommit.get_repository(repositoryName=repo)
            clone_url = response.get("repositoryMetadata").get("cloneUrlHttp")
            clone_command = (
                "git clone --config 'credential.helper=!aws codecommit credential-helper $@' "
                "--config 'credential.UseHttpPath=true' {}".format(clone_url))
            click.echo(
                "You need to clone your newly created repo now and will then need to seed it: \n{}"
                .format(clone_command))