def deploy(
        self,
        stack_name,
        template_str,
        parameters,
        capabilities,
        no_execute_changeset,
        role_arn,
        notification_arns,
        s3_uploader,
        tags,
        region,
        fail_on_empty_changeset=True,
        confirm_changeset=False,
    ):

        auth_required_per_resource = auth_per_resource(
            sanitize_parameter_overrides(self.parameter_overrides),
            get_template_data(self.template_file))

        for resource, authorization_required in auth_required_per_resource:
            if not authorization_required:
                click.secho(f"{resource} may not have authorization defined.",
                            fg="yellow")

        try:
            result, changeset_type = self.deployer.create_and_wait_for_changeset(
                stack_name=stack_name,
                cfn_template=template_str,
                parameter_values=parameters,
                capabilities=capabilities,
                role_arn=role_arn,
                notification_arns=notification_arns,
                s3_uploader=s3_uploader,
                tags=tags,
            )
            click.echo(
                self.MSG_SHOWCASE_CHANGESET.format(changeset_id=result["Id"]))

            if no_execute_changeset:
                return

            if confirm_changeset:
                click.secho(self.MSG_CONFIRM_CHANGESET_HEADER, fg="yellow")
                click.secho("=" * len(self.MSG_CONFIRM_CHANGESET_HEADER),
                            fg="yellow")
                if not click.confirm(f"{self.MSG_CONFIRM_CHANGESET}",
                                     default=False):
                    return

            self.deployer.execute_changeset(result["Id"], stack_name)
            self.deployer.wait_for_execute(stack_name, changeset_type)
            click.echo(
                self.MSG_EXECUTE_SUCCESS.format(stack_name=stack_name,
                                                region=region))

        except deploy_exceptions.ChangeEmptyError as ex:
            if fail_on_empty_changeset:
                raise
            click.echo(str(ex))
    def guided_prompts(self, parameter_override_keys):
        default_stack_name = self.stack_name or "sam-app"
        default_region = self.region or get_session().get_config_variable(
            "region") or "us-east-1"
        default_capabilities = self.capabilities[0] or ("CAPABILITY_IAM", )
        default_config_env = self.config_env or DEFAULT_ENV
        default_config_file = self.config_file or DEFAULT_CONFIG_FILE_NAME
        input_capabilities = None
        config_env = None
        config_file = None

        click.echo(
            self.color.yellow(
                "\n\tSetting default arguments for 'sam deploy'\n\t========================================="
            ))

        stack_name = prompt(f"\t{self.start_bold}Stack Name{self.end_bold}",
                            default=default_stack_name,
                            type=click.STRING)
        region = prompt(f"\t{self.start_bold}AWS Region{self.end_bold}",
                        default=default_region,
                        type=click.STRING)
        input_parameter_overrides = self.prompt_parameters(
            parameter_override_keys, self.parameter_overrides_from_cmdline,
            self.start_bold, self.end_bold)
        stacks = SamLocalStackProvider.get_stacks(
            self.template_file,
            parameter_overrides=sanitize_parameter_overrides(
                input_parameter_overrides))
        image_repositories = self.prompt_image_repository(stacks)

        click.secho(
            "\t#Shows you resources changes to be deployed and require a 'Y' to initiate deploy"
        )
        confirm_changeset = confirm(
            f"\t{self.start_bold}Confirm changes before deploy{self.end_bold}",
            default=self.confirm_changeset)
        click.secho(
            "\t#SAM needs permission to be able to create roles to connect to the resources in your template"
        )
        capabilities_confirm = confirm(
            f"\t{self.start_bold}Allow SAM CLI IAM role creation{self.end_bold}",
            default=True)

        if not capabilities_confirm:
            input_capabilities = prompt(
                f"\t{self.start_bold}Capabilities{self.end_bold}",
                default=list(default_capabilities),
                type=FuncParamType(func=_space_separated_list_func_type),
            )

        self.prompt_authorization(stacks)
        self.prompt_code_signing_settings(stacks)

        save_to_config = confirm(
            f"\t{self.start_bold}Save arguments to configuration file{self.end_bold}",
            default=True)
        if save_to_config:
            config_file = prompt(
                f"\t{self.start_bold}SAM configuration file{self.end_bold}",
                default=default_config_file,
                type=click.STRING,
            )
            config_env = prompt(
                f"\t{self.start_bold}SAM configuration environment{self.end_bold}",
                default=default_config_env,
                type=click.STRING,
            )

        s3_bucket = manage_stack(profile=self.profile, region=region)
        click.echo(f"\n\t\tManaged S3 bucket: {s3_bucket}")
        click.echo(
            "\t\tA different default S3 bucket can be set in samconfig.toml")

        self.guided_stack_name = stack_name
        self.guided_s3_bucket = s3_bucket
        self.guided_image_repositories = image_repositories
        self.guided_s3_prefix = stack_name
        self.guided_region = region
        self.guided_profile = self.profile
        self._capabilities = input_capabilities if input_capabilities else default_capabilities
        self._parameter_overrides = (input_parameter_overrides
                                     if input_parameter_overrides else
                                     self.parameter_overrides_from_cmdline)
        self.save_to_config = save_to_config
        self.config_env = config_env if config_env else default_config_env
        self.config_file = config_file if config_file else default_config_file
        self.confirm_changeset = confirm_changeset
def do_cli(
    template_file,
    stack_name,
    s3_bucket,
    force_upload,
    s3_prefix,
    kms_key_id,
    parameter_overrides,
    capabilities,
    no_execute_changeset,
    role_arn,
    notification_arns,
    fail_on_empty_changeset,
    use_json,
    tags,
    metadata,
    guided,
    confirm_changeset,
    region,
    profile,
):
    from samcli.commands.package.package_context import PackageContext
    from samcli.commands.deploy.deploy_context import DeployContext
    from samcli.commands.deploy.guided_context import GuidedContext

    if guided:
        # Allow for a guided deploy to prompt and save those details.
        guided_context = GuidedContext(
            template_file=template_file,
            stack_name=stack_name,
            s3_bucket=s3_bucket,
            s3_prefix=s3_prefix,
            region=region,
            profile=profile,
            confirm_changeset=confirm_changeset,
            capabilities=capabilities,
            parameter_overrides=parameter_overrides,
            config_section=CONFIG_SECTION,
        )
        guided_context.run()

    print_deploy_args(
        stack_name=guided_context.guided_stack_name if guided else stack_name,
        s3_bucket=guided_context.guided_s3_bucket if guided else s3_bucket,
        region=guided_context.guided_region if guided else region,
        capabilities=guided_context.guided_capabilities
        if guided else capabilities,
        parameter_overrides=guided_context.guided_parameter_overrides
        if guided else parameter_overrides,
        confirm_changeset=guided_context.confirm_changeset
        if guided else confirm_changeset,
    )

    with osutils.tempfile_platform_independent() as output_template_file:

        with PackageContext(
                template_file=template_file,
                s3_bucket=guided_context.guided_s3_bucket
                if guided else s3_bucket,
                s3_prefix=guided_context.guided_s3_prefix
                if guided else s3_prefix,
                output_template_file=output_template_file.name,
                kms_key_id=kms_key_id,
                use_json=use_json,
                force_upload=force_upload,
                metadata=metadata,
                on_deploy=True,
                region=guided_context.guided_region if guided else region,
                profile=profile,
        ) as package_context:
            package_context.run()

        with DeployContext(
                template_file=output_template_file.name,
                stack_name=guided_context.guided_stack_name
                if guided else stack_name,
                s3_bucket=guided_context.guided_s3_bucket
                if guided else s3_bucket,
                force_upload=force_upload,
                s3_prefix=guided_context.guided_s3_prefix
                if guided else s3_prefix,
                kms_key_id=kms_key_id,
                parameter_overrides=sanitize_parameter_overrides(
                    guided_context.guided_parameter_overrides)
                if guided else parameter_overrides,
                capabilities=guided_context.guided_capabilities
                if guided else capabilities,
                no_execute_changeset=no_execute_changeset,
                role_arn=role_arn,
                notification_arns=notification_arns,
                fail_on_empty_changeset=fail_on_empty_changeset,
                tags=tags,
                region=guided_context.guided_region if guided else region,
                profile=profile,
                confirm_changeset=guided_context.confirm_changeset
                if guided else confirm_changeset,
        ) as deploy_context:
            deploy_context.run()
Example #4
0
def do_cli(
    template_file,
    stack_name,
    s3_bucket,
    force_upload,
    no_progressbar,
    s3_prefix,
    kms_key_id,
    parameter_overrides,
    capabilities,
    no_execute_changeset,
    role_arn,
    notification_arns,
    fail_on_empty_changeset,
    use_json,
    tags,
    metadata,
    guided,
    confirm_changeset,
    region,
    profile,
    signing_profiles,
    resolve_s3,
    config_file,
    config_env,
):
    from samcli.commands.package.package_context import PackageContext
    from samcli.commands.deploy.deploy_context import DeployContext
    from samcli.commands.deploy.guided_context import GuidedContext
    from samcli.commands.deploy.exceptions import DeployResolveS3AndS3SetError

    if guided:
        # Allow for a guided deploy to prompt and save those details.
        guided_context = GuidedContext(
            template_file=template_file,
            stack_name=stack_name,
            s3_bucket=s3_bucket,
            s3_prefix=s3_prefix,
            region=region,
            profile=profile,
            confirm_changeset=confirm_changeset,
            capabilities=capabilities,
            signing_profiles=signing_profiles,
            parameter_overrides=parameter_overrides,
            config_section=CONFIG_SECTION,
            config_env=config_env,
            config_file=config_file,
        )
        guided_context.run()
    elif resolve_s3 and bool(s3_bucket):
        raise DeployResolveS3AndS3SetError()
    elif resolve_s3:
        s3_bucket = manage_stack(profile=profile, region=region)
        click.echo(f"\n\t\tManaged S3 bucket: {s3_bucket}")
        click.echo(
            "\t\tA different default S3 bucket can be set in samconfig.toml")
        click.echo("\t\tOr by specifying --s3-bucket explicitly.")

    with osutils.tempfile_platform_independent() as output_template_file:

        with PackageContext(
                template_file=template_file,
                s3_bucket=guided_context.guided_s3_bucket
                if guided else s3_bucket,
                s3_prefix=guided_context.guided_s3_prefix
                if guided else s3_prefix,
                output_template_file=output_template_file.name,
                kms_key_id=kms_key_id,
                use_json=use_json,
                force_upload=force_upload,
                no_progressbar=no_progressbar,
                metadata=metadata,
                on_deploy=True,
                region=guided_context.guided_region if guided else region,
                profile=profile,
                signing_profiles=guided_context.signing_profiles
                if guided else signing_profiles,
        ) as package_context:
            package_context.run()

        with DeployContext(
                template_file=output_template_file.name,
                stack_name=guided_context.guided_stack_name
                if guided else stack_name,
                s3_bucket=guided_context.guided_s3_bucket
                if guided else s3_bucket,
                force_upload=force_upload,
                no_progressbar=no_progressbar,
                s3_prefix=guided_context.guided_s3_prefix
                if guided else s3_prefix,
                kms_key_id=kms_key_id,
                parameter_overrides=sanitize_parameter_overrides(
                    guided_context.guided_parameter_overrides)
                if guided else parameter_overrides,
                capabilities=guided_context.guided_capabilities
                if guided else capabilities,
                no_execute_changeset=no_execute_changeset,
                role_arn=role_arn,
                notification_arns=notification_arns,
                fail_on_empty_changeset=fail_on_empty_changeset,
                tags=tags,
                region=guided_context.guided_region if guided else region,
                profile=profile,
                confirm_changeset=guided_context.confirm_changeset
                if guided else confirm_changeset,
                signing_profiles=guided_context.signing_profiles
                if guided else signing_profiles,
        ) as deploy_context:
            deploy_context.run()
Example #5
0
    def deploy(
        self,
        stack_name,
        template_str,
        parameters,
        capabilities,
        no_execute_changeset,
        role_arn,
        notification_arns,
        s3_uploader,
        tags,
        region,
        fail_on_empty_changeset=True,
        confirm_changeset=False,
    ):
        """
        Deploy the stack to cloudformation.
        - if changeset needs confirmation, it will prompt for customers to confirm.
        - if no_execute_changeset is True, the changeset won't be executed.

        Parameters
        ----------
        stack_name : str
            name of the stack
        template_str : str
            the string content of the template
        parameters : List[Dict]
            List of parameters
        capabilities : List[str]
            List of capabilities
        no_execute_changeset : bool
            A bool indicating whether to execute changeset
        role_arn : str
            the Arn of the role to create changeset
        notification_arns : List[str]
            Arns for sending notifications
        s3_uploader : S3Uploader
            S3Uploader object to upload files to S3 buckets
        tags : List[str]
            List of tags passed to CloudFormation
        region : str
            AWS region to deploy the stack to
        fail_on_empty_changeset : bool
            Should fail when changeset is empty
        confirm_changeset : bool
            Should wait for customer's confirm before executing the changeset
        """
        stacks, _ = SamLocalStackProvider.get_stacks(
            self.template_file,
            parameter_overrides=sanitize_parameter_overrides(
                self.parameter_overrides))
        auth_required_per_resource = auth_per_resource(stacks)

        for resource, authorization_required in auth_required_per_resource:
            if not authorization_required:
                click.secho(f"{resource} may not have authorization defined.",
                            fg="yellow")

        try:
            result, changeset_type = self.deployer.create_and_wait_for_changeset(
                stack_name=stack_name,
                cfn_template=template_str,
                parameter_values=parameters,
                capabilities=capabilities,
                role_arn=role_arn,
                notification_arns=notification_arns,
                s3_uploader=s3_uploader,
                tags=tags,
            )
            click.echo(
                self.MSG_SHOWCASE_CHANGESET.format(changeset_id=result["Id"]))

            if no_execute_changeset:
                return

            if confirm_changeset:
                click.secho(self.MSG_CONFIRM_CHANGESET_HEADER, fg="yellow")
                click.secho("=" * len(self.MSG_CONFIRM_CHANGESET_HEADER),
                            fg="yellow")
                if not click.confirm(f"{self.MSG_CONFIRM_CHANGESET}",
                                     default=False):
                    return

            self.deployer.execute_changeset(result["Id"], stack_name)
            self.deployer.wait_for_execute(stack_name, changeset_type)
            click.echo(
                self.MSG_EXECUTE_SUCCESS.format(stack_name=stack_name,
                                                region=region))

        except deploy_exceptions.ChangeEmptyError as ex:
            if fail_on_empty_changeset:
                raise
            click.echo(str(ex))
    def guided_prompts(self, parameter_override_keys):
        default_stack_name = self.stack_name or "sam-app"
        default_region = self.region or "us-east-1"
        default_capabilities = self.capabilities[0] or ("CAPABILITY_IAM", )
        input_capabilities = None

        click.echo(
            self.color.yellow(
                "\n\tSetting default arguments for 'sam deploy'\n\t========================================="
            ))

        stack_name = prompt(f"\t{self.start_bold}Stack Name{self.end_bold}",
                            default=default_stack_name,
                            type=click.STRING)
        region = prompt(f"\t{self.start_bold}AWS Region{self.end_bold}",
                        default=default_region,
                        type=click.STRING)
        input_parameter_overrides = self.prompt_parameters(
            parameter_override_keys, self.start_bold, self.end_bold)

        click.secho(
            "\t#Shows you resources changes to be deployed and require a 'Y' to initiate deploy"
        )
        confirm_changeset = confirm(
            f"\t{self.start_bold}Confirm changes before deploy{self.end_bold}",
            default=self.confirm_changeset)
        click.secho(
            "\t#SAM needs permission to be able to create roles to connect to the resources in your template"
        )
        capabilities_confirm = confirm(
            f"\t{self.start_bold}Allow SAM CLI IAM role creation{self.end_bold}",
            default=True)

        if not capabilities_confirm:
            input_capabilities = prompt(
                f"\t{self.start_bold}Capabilities{self.end_bold}",
                default=list(default_capabilities),
                type=FuncParamType(func=_space_separated_list_func_type),
            )

        self.prompt_authorization(
            sanitize_parameter_overrides(input_parameter_overrides))

        save_to_config = confirm(
            f"\t{self.start_bold}Save arguments to samconfig.toml{self.end_bold}",
            default=True)

        s3_bucket = manage_stack(profile=self.profile, region=region)
        click.echo(f"\n\t\tManaged S3 bucket: {s3_bucket}")
        click.echo(
            "\t\tA different default S3 bucket can be set in samconfig.toml")

        self.guided_stack_name = stack_name
        self.guided_s3_bucket = s3_bucket
        self.guided_s3_prefix = stack_name
        self.guided_region = region
        self.guided_profile = self.profile
        self._capabilities = input_capabilities if input_capabilities else default_capabilities
        self._parameter_overrides = input_parameter_overrides if input_parameter_overrides else self.parameter_overrides
        self.save_to_config = save_to_config
        self.confirm_changeset = confirm_changeset