stackshot

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2020 License: MIT Imports: 10 Imported by: 0

README

stackshot

stackshot is a declarative approach to managing Cloudformation Stacks. stackshot is a command line tool that consumes YAML files that create and update Cloudformation Stacks.

Below is a simple workflow to create and update a Stack using AWS's S3 bucket sample template.

mybucket.yaml is a simple Stack configuration with a Stack's name and template (the only required arguments to create a stack):

# saved as mybucket.yaml
---
Name: mybucket
TemplateURL: https://s3.amazonaws.com/cloudformation-templates-us-east-1/S3_Website_Bucket_With_Retain_On_Delete.template

To create a stack, run stackshot:

$ stackshot mybucket.yaml
2020-10-04 18:28:47.277 +0000 UTC mybucket(AWS::CloudFormation::Stack) UPDATE_IN_PROGRESS User Initiated
2020-10-04 18:28:50.968 +0000 UTC S3Bucket(AWS::S3::Bucket) UPDATE_IN_PROGRESS
2020-10-04 18:29:11.769 +0000 UTC S3Bucket(AWS::S3::Bucket) UPDATE_COMPLETE
2020-10-04 18:29:13.621 +0000 UTC mybucket(AWS::CloudFormation::Stack) UPDATE_COMPLETE_CLEANUP_IN_PROGRESS
2020-10-04 18:29:14.25 +0000 UTC mybucket(AWS::CloudFormation::Stack) UPDATE_COMPLETE

Now let's assume that template added a Parameter to set S3's AccessControl setting. You can add parameters to mybucket.yaml like so:

Name: mybucket
Template: https://s3.amazonaws.com/cloudformation-templates-us-east-1/S3_Website_Bucket_With_Retain_On_Delete.template
Parameters:
  AccessControl: Private

Running stackshot to sync the mybucket.yaml updates the existing stack in Cloudformation:

$ stackshot mybucket.yaml
2020-10-06 03:37:21.481 +0000 UTC mybucket(AWS::CloudFormation::Stack) UPDATE_IN_PROGRESS User Initiated
2020-10-06 03:37:24.811 +0000 UTC S3Bucket(AWS::S3::Bucket) UPDATE_IN_PROGRESS
2020-10-06 03:37:45.617 +0000 UTC S3Bucket(AWS::S3::Bucket) UPDATE_COMPLETE
2020-10-06 03:37:47.38 +0000 UTC mybucket(AWS::CloudFormation::Stack) UPDATE_COMPLETE

Features

  • Create/Update Cloudformation Stacks using YAML files
  • Designed for use with Continuous Integration/Delivery systems like GitHub Actions
  • Explicitly does not support dynamic YAML generation. If you'd like to add conditionals and loops in your YAML, please look to templating languages that can handle this behavior much better. e.g., jsonnet(https://jsonnet.org).

Installation

git clone git@github.com:tightlycoupled/stackshot.git
cd stackshot
make build
cp stackshot /usr/local/bin

Usage

stackshot path/to/stack_configuration.yaml

Stack Configuration YAML

You can find all available Stack settings in the commented kitchen-sink.yaml example configuration file. The settings map to create-stack and update-stack parameters.

Motivations

AWS Cloudformation is a service that allows you to manage your infrastructure as code by declaring cloud resources in JSON or YAML Templates. Given that Templates declarative, why aren't Stacks? For a handful of stacks, the lack of declarative Stack management isn't a problem. But when the stacks outnumber the possible things I can keep in my head, and the number of Parameters a template takes grows similarly, managing Stacks becomes an error-prone burden.

Therefore, I wanted two things:

  1. Store the Stack configuration in a human-readable format (YAML) that I could store in a git repository. This allows configuration review from my peers and a history of what happened to our Stacks.
  2. A tool that behaved like aws cloudformation deploy but works off of the YAML configuration instead of command line arguments.

Therefore, stackshot was built.

The Name

stackshot is a play off of a steel Misting, or better known as a Coinshot.

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EventPrinter

func EventPrinter(event *cloudformation.StackEvent) error

EventPrinter implements EventConsumer interface to print cloudformation.StackEvent to stdout.

func NoStackUpdatesToPerform

func NoStackUpdatesToPerform(err awserr.Error) bool

NoStackUpdatesToPerform inspects awserr.Error to detect if a Cloudformation Stack does not rquire any updates.

The aws-go-sdk doesn't return an easily detectable Code. UpdateStack returns a "ValidationError" error with a specific Message. This function searches for the message that indicates not updates are to be performed.

Types

type EventConsumer

type EventConsumer interface {
	Consume(*cloudformation.StackEvent) error
}

EventConsumer is an interface used by Stack.SyncAndPollEvents() to consume events polled from an updating Cloudformation Stack.

type EventConsumerFunc

type EventConsumerFunc func(*cloudformation.StackEvent) error

func (EventConsumerFunc) Consume

type Stack

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

Stack synchronizes a StackConfig with the corresponding Cloudformation Stack. Stack simplifies the Cloudformation's API by issuing CreateStack or UpdateStack depending on whether the stack name represented at StackConfig.Name exists in Cloudformation.

To synchronize a StackConfig with the Cloudformation Stack, call Sync().

If you need to wait for the Cloudformation Stack to complete creating or updating, call SyncAndPollEvents(). SyncAndPollEvents() takes an argument that implements the EventConsumer interface in which events are passed.

func LoadStack

func LoadStack(api cloudformationiface.CloudFormationAPI, config *StackConfig) (*Stack, error)

LoadStack allocates a new Stack used to synchronize a StackConfig's configuration with a new or existing Cloudformation Stack.

func (*Stack) Name

func (s *Stack) Name() string

func (*Stack) Sync

func (s *Stack) Sync() error

Sync applies the stack configuration to Cloudformation Stack. If the Cloudformation Stack does not exist, Sync will create a new Cloudformation Stack. If the Cloudformation Stack does exist, then Sync will update the Cloudformation Stack.

func (*Stack) SyncAndPollEvents

func (s *Stack) SyncAndPollEvents(consumer EventConsumer) error

Runs Sync() and then polls for StackEvents to pass to consumer. This call will block until the Cloudformation Stack has completed creating or updating a Cloudformation Stack.

StackEvents passed to consumer appear in chronological order.

type StackConfig

type StackConfig struct {
	Name         string
	TemplateURL  string
	TemplatePath string
	TemplateBody templateBody
	Parameters   map[string]string
	Tags         map[string]string
	Capabilities []string

	// Settings for CreateStack()
	DisableRollback bool

	// Settings for CreateStack()
	EnableTerminationProtection bool

	// Settings for CreateStack()
	OnFailure string
}

func NewStackFromYAML

func NewStackFromYAML(doc []byte) (*StackConfig, error)

Directories

Path Synopsis
cmds

Jump to

Keyboard shortcuts

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