forecast

package
v1.8.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 2, 2024 License: Apache-2.0 Imports: 28 Imported by: 0

README

Rain Forecast

The experimental rain forecast command makes API calls into your account to try to predict things that might fail during stack create, update, and delete operations. This command is not meant to be a substitute for the CloudFormation Linter (cfn-lint), which ideally is already an integral part of your development process.

In order to use this command, supply the -x argument to recognize the fact that this feature is currently experimental could change with minor version upgrades.

rain forecast -x --skip-iam my-template.yaml my-stack-name 

You can also supply a CLI profile with the --profile argument to assume a different role for the checks you make against the template.

Generic checks

This command currently makes a few generic checks for a wide range of resources:

  • The resource already exists (for stack creation with hard coded resource names)
  • IAM permissions to interact with the resource. Keep in mind that this is a slow operation and can be suppressed with the --skip-iam argument. It is also not guaranteed to be 100% accurate, due to the difficulty with predicting the exact ARNs for all possible resources that are involved with the resource provider.

Specific checks

  • For a delete operation, the S3 bucket is not empty
  • An S3 bucket policy has an invalid principal
  • Make sure RDS cluster configuration makes sense for the chosen engine

Estimates

The forecast command also tries to estimate how long it thinks your stack will take to deploy.

Roadmap

You can view the issues list for the forecast command here.

Please feel free to create an issue here whenever you get a stack failure that you think could have been prevented by one of these checks.

In the near term, we're going to add the ability to suppress specific checks by giving each of them a code.

Checks we plan to implement:

  • DynamoDB global table replica region requirements
  • Prefix list does not exist
  • Flow Log format errors
  • SES identity not verified
  • SES sending pool does not exist
  • EIP limit
  • Function version does not exist
  • Warn on resource replacements for active traffic
  • API gateway account trust permission
  • Security group exists
  • Is an EC2 instance type available in the AZ

Documentation

Overview

Forecast looks at your account and tries to predict things that will go wrong when you attempt to CREATE, UPDATE, or DELETE a stack

Index

Constants

This section is empty.

Variables

View Source
var Cmd = &cobra.Command{
	Use:   "forecast --experimental <template> [stackName]",
	Short: "Predict deployment failures",
	Long: `Outputs warnings about potential deployment failures due to constraints in 
the account or misconfigurations in the template related to dependencies in 
the account.

NOTE: This is an experimental feature!

To use this command, add --experimental or -x as an argument.

This command is not a linter! Use cfn-lint for that. The forecast command 
is concerned with things that could go wrong during deployment, after the 
template has been checked to make sure it has a valid syntax.

This command checks for some common issues across all resources:

- The resource already exists
- You do not have permissions to create/update/delete the resource
- (More to come.. service quotas, drift issues)

Resource-specific checks:

- S3 bucket is not empty
- S3 bucket policy has an invalid principal
- (Many more to come...)
`,
	Args:                  cobra.RangeArgs(1, 2),
	DisableFlagsInUseLine: true,
	Run: func(cmd *cobra.Command, args []string) {
		fn := args[0]
		base := filepath.Base(fn)
		var suppliedStackName string

		if len(args) == 2 {
			suppliedStackName = args[1]
		} else {
			suppliedStackName = ""
		}

		if !Experimental {
			panic("Please add the --experimental arg to use this feature")
		}
		pkg.Experimental = Experimental

		config.Debugf("Generating forecast for %v", fn)

		source, err := pkg.File(fn)
		if err != nil {
			panic(err)
		}

		content := format.CftToYaml(source)
		source, err = parse.String(content)
		if err != nil {
			panic(err)
		}

		stackName := dc.GetStackName(suppliedStackName, base)

		spinner.Push(fmt.Sprintf("Checking current status of stack '%s'", stackName))
		stack, stackExists := deploy.CheckStack(stackName)
		spinner.Pop()

		msg := ""
		if stackExists {
			msg = "exists"
		} else {
			msg = "does not exist"
		}
		config.Debugf("Stack %v %v", stackName, msg)

		dc, err := dc.GetDeployConfig(tags, params, configFilePath, base,
			source, stack, stackExists, true, false)
		if err != nil {
			panic(err)
		}

		if !predict(source, stackName, stack, stackExists, dc) {
			os.Exit(1)
		}

	},
}

Cmd is the forecast command's entrypoint

View Source
var Estimates map[string]ResourceEstimate

Estimates is a map of resource type name to ResourceEstimates, which are based on historical averages

View Source
var Experimental bool

This is an experimental feature that might break between minor releases

View Source
var LineNumber int

The current line number in the template

View Source
var ResourceType string

The resource type to check (optional --type to limit checks to one type)

View Source
var RoleArn string

The role name to use for the IAM policy simulator (optional --role)

View Source
var SkipIAM bool

If true, don't perform permissions checks to save time

Functions

func FormatEstimate added in v1.7.0

func FormatEstimate(total int) string

FormatEstimate returns a string in human readable format to represent the number of seconds. For example, 61 would return "0h, 1m, 1s"

func GetResourceEstimate added in v1.7.0

func GetResourceEstimate(resourceType string, action StackAction) (int, error)

GetResourceEstimate returns the estimated time an action will take for the given resource type

func InitEstimates added in v1.7.0

func InitEstimates()

init initializes the Estimates map for all AWS resource types

func PredictTotalEstimate added in v1.7.0

func PredictTotalEstimate(t cft.Template, stackExists bool) int

PredictTotalEstimate returns the total number of seconds expected to deploy the stack. This function takes into account resources that will be deployed in parallel.

Types

type Env added in v1.4.4

type Env struct {
	// contains filtered or unexported fields
}

type Forecast

type Forecast struct {
	TypeName  string
	LogicalId string
	Passed    []string
	Failed    []string
}

Forecast represents predictions for a single resource in the template

func (*Forecast) Add

func (f *Forecast) Add(passed bool, message string)

Add adds a pass or fail message, formatting it to include the type name and logical id

func (*Forecast) Append

func (f *Forecast) Append(forecast Forecast)

func (*Forecast) GetNumChecked

func (f *Forecast) GetNumChecked() int

func (*Forecast) GetNumFailed

func (f *Forecast) GetNumFailed() int

func (*Forecast) GetNumPassed

func (f *Forecast) GetNumPassed() int

type PredictionInput

type PredictionInput struct {
	// contains filtered or unexported fields
}

Input to forecast prediction functions

type ResourceEstimate added in v1.7.0

type ResourceEstimate struct {
	Name   string
	Create int
	Update int
	Delete int
}

ResourceEstimate stores the estimated time, in seconds, to create, update, or delete a specific resource type. The Name is something like "AWS::S3::Bucket"

func NewResourceEstimate added in v1.7.0

func NewResourceEstimate(name string, create int, update int, del int) ResourceEstimate

NewResourceEstimate creates a new instance of ResourceEstimate

type StackAction added in v1.7.0

type StackAction string
const (
	Create StackAction = "create"
	Update StackAction = "update"
	Delete StackAction = "delete"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL