// Code generated by smithy-go-codegen DO NOT EDIT.

package cloudformation

import (
	"context"
	"fmt"
	awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
	"github.com/aws/aws-sdk-go-v2/service/cloudformation/types"
	"github.com/aws/smithy-go/middleware"
	smithyhttp "github.com/aws/smithy-go/transport/http"
)

// Creates a stack as specified in the template. After the call completes
// successfully, the stack creation starts. You can check the status of the stack
// through the DescribeStacksoperation.
//
// For more information about creating a stack and monitoring stack progress, see [Managing Amazon Web Services resources as a single unit with CloudFormation stacks]
// in the CloudFormation User Guide.
//
// [Managing Amazon Web Services resources as a single unit with CloudFormation stacks]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacks.html
func (c *Client) CreateStack(ctx context.Context, params *CreateStackInput, optFns ...func(*Options)) (*CreateStackOutput, error) {
	if params == nil {
		params = &CreateStackInput{}
	}

	result, metadata, err := c.invokeOperation(ctx, "CreateStack", params, optFns, c.addOperationCreateStackMiddlewares)
	if err != nil {
		return nil, err
	}

	out := result.(*CreateStackOutput)
	out.ResultMetadata = metadata
	return out, nil
}

// The input for CreateStack action.
type CreateStackInput struct {

	// The name that's associated with the stack. The name must be unique in the
	// Region in which you are creating the stack.
	//
	// A stack name can contain only alphanumeric characters (case sensitive) and
	// hyphens. It must start with an alphabetical character and can't be longer than
	// 128 characters.
	//
	// This member is required.
	StackName *string

	// In some cases, you must explicitly acknowledge that your stack template
	// contains certain capabilities in order for CloudFormation to create the stack.
	//
	//   - CAPABILITY_IAM and CAPABILITY_NAMED_IAM
	//
	// Some stack templates might include resources that can affect permissions in
	//   your Amazon Web Services account; for example, by creating new IAM users. For
	//   those stacks, you must explicitly acknowledge this by specifying one of these
	//   capabilities.
	//
	// The following IAM resources require you to specify either the CAPABILITY_IAM or
	//   CAPABILITY_NAMED_IAM capability.
	//
	//   - If you have IAM resources, you can specify either capability.
	//
	//   - If you have IAM resources with custom names, you must specify
	//   CAPABILITY_NAMED_IAM .
	//
	//   - If you don't specify either of these capabilities, CloudFormation returns
	//   an InsufficientCapabilities error.
	//
	// If your stack template contains these resources, we recommend that you review
	//   all permissions associated with them and edit their permissions if necessary.
	//
	// [AWS::IAM::AccessKey]
	//
	// [AWS::IAM::Group]
	//
	// [AWS::IAM::InstanceProfile]
	//
	// [AWS::IAM::ManagedPolicy]
	//
	// [AWS::IAM::Policy]
	//
	// [AWS::IAM::Role]
	//
	// [AWS::IAM::User]
	//
	// [AWS::IAM::UserToGroupAddition]
	//
	// For more information, see [Acknowledging IAM resources in CloudFormation templates].
	//
	//   - CAPABILITY_AUTO_EXPAND
	//
	// Some template contain macros. Macros perform custom processing on templates;
	//   this can include simple actions like find-and-replace operations, all the way to
	//   extensive transformations of entire templates. Because of this, users typically
	//   create a change set from the processed template, so that they can review the
	//   changes resulting from the macros before actually creating the stack. If your
	//   stack template contains one or more macros, and you choose to create a stack
	//   directly from the processed template, without first reviewing the resulting
	//   changes in a change set, you must acknowledge this capability. This includes the
	//   [AWS::Include]and [AWS::Serverless]transforms, which are macros hosted by CloudFormation.
	//
	// If you want to create a stack from a stack template that contains macros and
	//   nested stacks, you must create the stack directly from the template using this
	//   capability.
	//
	// You should only create stacks directly from a stack template that contains
	//   macros if you know what processing the macro performs.
	//
	// Each macro relies on an underlying Lambda service function for processing stack
	//   templates. Be aware that the Lambda function owner can update the function
	//   operation without CloudFormation being notified.
	//
	// For more information, see [Perform custom processing on CloudFormation templates with template macros].
	//
	// Only one of the Capabilities and ResourceType parameters can be specified.
	//
	// [AWS::IAM::ManagedPolicy]: https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-managedpolicy.html
	// [AWS::IAM::AccessKey]: https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-accesskey.html
	// [AWS::Include]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/transform-aws-include.html
	// [AWS::IAM::User]: https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-user.html
	// [AWS::IAM::InstanceProfile]: https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-instanceprofile.html
	// [Acknowledging IAM resources in CloudFormation templates]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/control-access-with-iam.html#using-iam-capabilities
	// [Perform custom processing on CloudFormation templates with template macros]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-macros.html
	// [AWS::IAM::Policy]: https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-policy.html
	// [AWS::IAM::Group]: https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-group.html
	// [AWS::IAM::UserToGroupAddition]: https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-usertogroupaddition.html
	// [AWS::IAM::Role]: https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-role.html
	// [AWS::Serverless]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/transform-aws-serverless.html
	Capabilities []types.Capability

	// A unique identifier for this CreateStack request. Specify this token if you
	// plan to retry requests so that CloudFormation knows that you're not attempting
	// to create a stack with the same name. You might retry CreateStack requests to
	// ensure that CloudFormation successfully received them.
	//
	// All events initiated by a given stack operation are assigned the same client
	// request token, which you can use to track operations. For example, if you
	// execute a CreateStack operation with the token token1 , then all the StackEvents
	// generated by that operation will have ClientRequestToken set as token1 .
	//
	// In the console, stack operations display the client request token on the Events
	// tab. Stack operations that are initiated from the console use the token format
	// Console-StackOperation-ID, which helps you easily identify the stack operation .
	// For example, if you create a stack using the console, each stack event would be
	// assigned the same token in the following format:
	// Console-CreateStack-7f59c3cf-00d2-40c7-b2ff-e75db0987002 .
	ClientRequestToken *string

	// Set to true to disable rollback of the stack if stack creation failed. You can
	// specify either DisableRollback or OnFailure , but not both.
	//
	// Default: false
	DisableRollback *bool

	// Whether to enable termination protection on the specified stack. If a user
	// attempts to delete a stack with termination protection enabled, the operation
	// fails and the stack remains unchanged. For more information, see [Protect CloudFormation stacks from being deleted]in the
	// CloudFormation User Guide. Termination protection is deactivated on stacks by
	// default.
	//
	// For [nested stacks], termination protection is set on the root stack and can't be changed
	// directly on the nested stack.
	//
	// [Protect CloudFormation stacks from being deleted]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-protect-stacks.html
	// [nested stacks]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-nested-stacks.html
	EnableTerminationProtection *bool

	// The Amazon SNS topic ARNs to publish stack related events. You can find your
	// Amazon SNS topic ARNs using the Amazon SNS console or your Command Line
	// Interface (CLI).
	NotificationARNs []string

	// Determines what action will be taken if stack creation fails. This must be one
	// of: DO_NOTHING , ROLLBACK , or DELETE . You can specify either OnFailure or
	// DisableRollback , but not both.
	//
	// Although the default setting is ROLLBACK , there is one exception. This
	// exception occurs when a StackSet attempts to deploy a stack instance and the
	// stack instance fails to create successfully. In this case, the CreateStack call
	// overrides the default setting and sets the value of OnFailure to DELETE .
	//
	// Default: ROLLBACK
	OnFailure types.OnFailure

	// A list of Parameter structures that specify input parameters for the stack. For
	// more information, see the [Parameter]data type.
	//
	// [Parameter]: https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_Parameter.html
	Parameters []types.Parameter

	// Specifies which resource types you can work with, such as AWS::EC2::Instance or
	// Custom::MyCustomInstance .
	//
	// If the list of resource types doesn't include a resource that you're creating,
	// the stack creation fails. By default, CloudFormation grants permissions to all
	// resource types. IAM uses this parameter for CloudFormation-specific condition
	// keys in IAM policies. For more information, see [Control CloudFormation access with Identity and Access Management].
	//
	// Only one of the Capabilities and ResourceType parameters can be specified.
	//
	// [Control CloudFormation access with Identity and Access Management]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/control-access-with-iam.html
	ResourceTypes []string

	// When set to true , newly created resources are deleted when the operation rolls
	// back. This includes newly created resources marked with a deletion policy of
	// Retain .
	//
	// Default: false
	RetainExceptOnCreate *bool

	// The Amazon Resource Name (ARN) of an IAM role that CloudFormation assumes to
	// create the stack. CloudFormation uses the role's credentials to make calls on
	// your behalf. CloudFormation always uses this role for all future operations on
	// the stack. Provided that users have permission to operate on the stack,
	// CloudFormation uses this role even if the users don't have permission to pass
	// it. Ensure that the role grants least privilege.
	//
	// If you don't specify a value, CloudFormation uses the role that was previously
	// associated with the stack. If no role is available, CloudFormation uses a
	// temporary session that's generated from your user credentials.
	RoleARN *string

	// The rollback triggers for CloudFormation to monitor during stack creation and
	// updating operations, and for the specified monitoring period afterwards.
	RollbackConfiguration *types.RollbackConfiguration

	// Structure that contains the stack policy body. For more information, see [Prevent updates to stack resources] in
	// the CloudFormation User Guide. You can specify either the StackPolicyBody or
	// the StackPolicyURL parameter, but not both.
	//
	// [Prevent updates to stack resources]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/protect-stack-resources.html
	StackPolicyBody *string

	// Location of a file that contains the stack policy. The URL must point to a
	// policy (maximum size: 16 KB) located in an S3 bucket in the same Region as the
	// stack. The location for an Amazon S3 bucket must start with https:// . URLs from
	// S3 static websites are not supported.
	//
	// You can specify either the StackPolicyBody or the StackPolicyURL parameter, but
	// not both.
	StackPolicyURL *string

	// Key-value pairs to associate with this stack. CloudFormation also propagates
	// these tags to the resources created in the stack. A maximum number of 50 tags
	// can be specified.
	Tags []types.Tag

	// Structure that contains the template body with a minimum length of 1 byte and a
	// maximum length of 51,200 bytes.
	//
	// Conditional: You must specify either TemplateBody or TemplateURL , but not both.
	TemplateBody *string

	// The URL of a file that contains the template body. The URL must point to a
	// template (max size: 1 MB) that's located in an Amazon S3 bucket or a Systems
	// Manager document. The location for an Amazon S3 bucket must start with https://
	// . URLs from S3 static websites are not supported.
	//
	// Conditional: You must specify either the TemplateBody or the TemplateURL
	// parameter, but not both.
	TemplateURL *string

	// The amount of time that can pass before the stack status becomes CREATE_FAILED ;
	// if DisableRollback is not set or is set to false , the stack will be rolled back.
	TimeoutInMinutes *int32

	noSmithyDocumentSerde
}

// The output for a CreateStack action.
type CreateStackOutput struct {

	// A unique identifier for this stack operation that can be used to track the
	// operation's progress and events.
	OperationId *string

	// Unique identifier of the stack.
	StackId *string

	// Metadata pertaining to the operation's result.
	ResultMetadata middleware.Metadata

	noSmithyDocumentSerde
}

func (c *Client) addOperationCreateStackMiddlewares(stack *middleware.Stack, options Options) (err error) {
	if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil {
		return err
	}
	err = stack.Serialize.Add(&awsAwsquery_serializeOpCreateStack{}, middleware.After)
	if err != nil {
		return err
	}
	err = stack.Deserialize.Add(&awsAwsquery_deserializeOpCreateStack{}, middleware.After)
	if err != nil {
		return err
	}
	if err := addProtocolFinalizerMiddlewares(stack, options, "CreateStack"); err != nil {
		return fmt.Errorf("add protocol finalizers: %v", err)
	}

	if err = addlegacyEndpointContextSetter(stack, options); err != nil {
		return err
	}
	if err = addSetLoggerMiddleware(stack, options); err != nil {
		return err
	}
	if err = addClientRequestID(stack); err != nil {
		return err
	}
	if err = addComputeContentLength(stack); err != nil {
		return err
	}
	if err = addResolveEndpointMiddleware(stack, options); err != nil {
		return err
	}
	if err = addComputePayloadSHA256(stack); err != nil {
		return err
	}
	if err = addRetry(stack, options); err != nil {
		return err
	}
	if err = addRawResponseToMetadata(stack); err != nil {
		return err
	}
	if err = addRecordResponseTiming(stack); err != nil {
		return err
	}
	if err = addSpanRetryLoop(stack, options); err != nil {
		return err
	}
	if err = addClientUserAgent(stack, options); err != nil {
		return err
	}
	if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
		return err
	}
	if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
		return err
	}
	if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil {
		return err
	}
	if err = addTimeOffsetBuild(stack, c); err != nil {
		return err
	}
	if err = addUserAgentRetryMode(stack, options); err != nil {
		return err
	}
	if err = addCredentialSource(stack, options); err != nil {
		return err
	}
	if err = addOpCreateStackValidationMiddleware(stack); err != nil {
		return err
	}
	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateStack(options.Region), middleware.Before); err != nil {
		return err
	}
	if err = addRecursionDetection(stack); err != nil {
		return err
	}
	if err = addRequestIDRetrieverMiddleware(stack); err != nil {
		return err
	}
	if err = addResponseErrorMiddleware(stack); err != nil {
		return err
	}
	if err = addRequestResponseLogging(stack, options); err != nil {
		return err
	}
	if err = addDisableHTTPSMiddleware(stack, options); err != nil {
		return err
	}
	if err = addInterceptBeforeRetryLoop(stack, options); err != nil {
		return err
	}
	if err = addInterceptAttempt(stack, options); err != nil {
		return err
	}
	if err = addInterceptors(stack, options); err != nil {
		return err
	}
	return nil
}

func newServiceMetadataMiddleware_opCreateStack(region string) *awsmiddleware.RegisterServiceMetadata {
	return &awsmiddleware.RegisterServiceMetadata{
		Region:        region,
		ServiceID:     ServiceID,
		OperationName: "CreateStack",
	}
}
