Rain is what happens when you have a lot of CloudFormation
Rain is also a command line tool for working with AWS CloudFormation templates and stacks.
Join us on Discord to discuss rain and all things CloudFormation! Connect and interact with CloudFormation developers and experts, find channels to discuss rain, the CloudFormation registry, StackSets, cfn-lint, Guard and more:
Interactive deployments: With rain deploy, rain packages your CloudFormation templates, prompts you for any parameters that have not yet been defined, shows you a summary of the changes that will be made, and then displays real-time updates as your stack is being deployed. Once finished, you get a summary of the outcome along with any error messages collected along the way - including errors messages for stacks that have been rolled back and no longer exist.
Consistent formatting of CloudFormation templates: Using rain fmt, you can format your CloudFormation templates to a consistent standard or reformat a template from JSON to YAML (or YAML to JSON if you prefer). Rain preserves your comments when using YAML and switches use of intrinsic functions to use the short syntax where possible.
Combined logs for nested stacks with sensible filtering: When you run rain log, you will see a combined stream of logs from the stack you specified along with any nested stack associated with it. Rain also filters out uninteresting log messages by default so you just see the errors that require attention. You can also use rain log --chart to see a Gantt chart that shows you how long each operation took for a given stack.
Build new CloudFormation templates: rain build generates new CloudFormation templates containing skeleton resources that you specify. This saves you having to look up which properties are available and which are required vs. optional. Build skeleton templates by specifying a resource name like AWS::S3::Bucket, or enable the Bedrock Claude model in your account to use generative AI with a command like rain build --prompt "A VPC with 2 subnets". (Note that Bedrock is not free, and requires some setup). NEW Use the rain build --recommend command to pick from a list of functional templates that will pass typical compliance checks by default. These templates are great starting points for infrastructure projects.
Build policy validation files: The rain build command can now send prompts to the Bedrock Cloude3 Haiku and Sonnet models, which can write Open Policy Agent (OPA) Rego files or CloudFormation Guard files, to verify the compliance of your templates
Manipulate CloudFormation stack sets: rain stackset deploy creates a new stackset, updates an existing one or adds a stack instance(s) to an existing stack set. You can list stack sets using rain stackset ls, review stack set details with rain stackset ls <stack set name> and delete stack set and\or its instances with rain stackset rm <stack set name>
Predict deployment failures (EXPERIMENTAL): rain forecast analyzes a template and the target deployment account to predict things that might go wrong when you attempt to create, update, or delete a stack. This command speeds up development by giving you advanced notice for issues like missing permissions, resources that already exist, and a variety of other common resource-specific deployment blockers.
Modules (EXPERIMENTAL): rain pkg supports client-side module development. Rain modules are partial templates that are inserted into the parent template, with some extra functionality added to enable extending existing resource types. This feature integrates with CodeArtifact to enable package publish and install.
Content Deployment (EXPERIMENTAL): rain deploy and rain rm support metadata commands that can upload static assets to a bucket and then delete those assets when the bucket is deleted. Rain can also run build scripts before and after stack deployment to prepare content like web sites and lambda functions before uploading to S3.
Note that in order to use experimental commands, you have to add --experimental or -x as an argument.
If you have homebrew installed, brew install rain
Or you can download the appropriate binary for your system from the releases page.
Or if you're a Gopher, you can go install github.com/aws-cloudformation/rain/cmd/rain@latest
Usage:
rain [command]
Stack commands:
cat Get the CloudFormation template from a running stack
cc Interact with templates using Cloud Control API instead of CloudFormation
deploy Deploy a CloudFormation stack or changeset from a local template
logs Show the event log for the named stack
ls List running CloudFormation stacks or changesets
rm Delete a CloudFormation stack or changeset
stackset This command manipulates stack sets.
watch Display an updating view of a CloudFormation stack
Template commands:
bootstrap Creates the artifacts bucket
build Create CloudFormation templates
diff Compare CloudFormation templates
fmt Format CloudFormation templates
forecast Predict deployment failures
merge Merge two or more CloudFormation templates
module Interact with Rain modules in CodeArtifact
pkg Package local artifacts into a template
tree Find dependencies of Resources and Outputs in a local template
Other Commands:
console Login to the AWS console
help Help about any command
info Show your current configuration
You can find shell completion scripts in docs/bash_completion.sh and docs/zsh_completion.sh.
Rain is written in Go and uses the AWS SDK for Go v2.
To contribute a change to Rain, fork this repository, make your changes, and submit a Pull Request.
The README.md, documentation in docs/, the auto completion scripts and a copy of the cloudformation specification in cft/spec/cfn.go are generated through go generate.
Rain is licensed under the Apache 2.0 License.
The rain pkg command can be used as a replacement for the aws cloudformation
package CLI command. When packaging a template, rain looks for specific
directives to appear in resources.
The !Rain::Embed directive simply inserts the contents of a file into the template as a string.
The template:
Resources:
Test:
Type: AWS::CloudFormation::WaitConditionHandle
Metadata:
Comment: !Rain::Embed embed.txt
The contents of embed.txt, which is in the same directory as the template:
This is a test
The resulting packaged template:
Resources:
Test:
Type: AWS::CloudFormation::WaitConditionHandle
Metadata:
Comment: This is a test
The !Rain::Include directive parses a YAML or JSON file and inserts the object into the template.
The template:
Resources:
Test:
!Rain::Include include-file.yaml
The file to be included:
Type: AWS::S3::Bucket
Properties:
BucketName: test
The resulting packaged template:
Resources:
Test:
Type: AWS::S3::Bucket
Properties:
BucketName: test
The !Rain::Env directive reads environment variables and inserts them into the template as strings.
The template:
Resources:
Test:
Type: AWS::S3::Bucket
Properties:
BucketName: !Rain::Env BUCKET_NAME
The resulting packaged template, if you have exported an environment variable named BUCKET_NAME with value abc:
Resources:
Test:
Type: AWS::S3::Bucket
Properties:
BucketName: abc
The !Rain::S3Http directive uploads a file or directory to S3 and inserts the
HTTPS URL into the template as a string.
The template:
Resources:
Test:
Type: A::B::C
Properties:
TheS3URL: !Rain::S3Http s3http.txt
If you have a file called s3http.txt in the same directory as the template,
rain will use your current default profile to upload the file to the artifact
bucket that rain creates as a part of bootstrapping. If the path provided is a
directory and not a file, the directory will be zipped first.
Resources:
Test:
Type: A::B::C
Properties:
TheS3URL: https://rain-artifacts-012345678912-us-east-1.s3.us-east-1.amazonaws.com/a84b588aa54068ed4b027b6e06e5e0bb283f83cf0d5a6720002d36af2225dfc3
The !Rain::S3 directive is basically the same as S3Http, but it inserts the S3 URI instead of an HTTPS URL.
The template:
Resources:
Test:
Type: A::B::C
Properties:
TheS3URI: !Rain::S3 s3.txt
If you have a file called s3.txt in the same directory as the template,
rain will use your current default profile to upload the file to the artifact
bucket that rain creates as a part of bootstrapping. If the path provided is a
directory and not a file, the directory will be zipped first.
Resources:
Test:
Type: A::B::C
Properties:
TheS3URI: s3://rain-artifacts-755952356119-us-east-1/a84b588aa54068ed4b027b6e06e5e0bb283f83cf0d5a6720002d36af2225dfc3
If instead of providing a path to a file, you supply an object with properties, you can exercise more control over how the object is uploaded to S3. The following example is a common pattern for uploading Lambda function code. The optional Run property is a local script that you want Rain to run before uploading the content at Path.
Resources:
MyFunction:
Type: AWS::Lambda::Function
Properties:
Code: !Rain::S3
Path: lambda-dist
Zip: true
BucketProperty: S3Bucket
KeyProperty: S3Key
Run: buildscript.sh
The packaged template:
Resources:
MyFunction:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: rain-artifacts-012345678912-us-east-1
S3Key: 1b4844dacc843f09941c11c94f80981d3be8ae7578952c71e875ef7add37b1a7
Sometimes you require that objects uploaded to S3 have a specific extension, use the Extension property to ensure the artifact in S3 ends ..
Resources:
Test:
Type: A::B::C
Properties:
TheS3URI: !Rain::S3
Path: test
Extension: sh
The packaged template:
Resources:
Test:
Type: A::B::C
Properties:
TheS3URI: s3://rain-artifacts-012345678912-us-east-1/a84b588aa54068ed4b027b6e06e5e0bb283f83cf0d5a6720002d36af2225dfc3.sh
You can add a metadata section to an AWS::S3::Bucket resource to take additional actions during deployment, such as running pre and post build scripts, uploading content to the bucket after stack deployment completes, and emptying the contents of the bucket when the stack is deleted.
Resources:
Bucket:
Type: AWS::S3::Bucket
Metadata:
Rain:
EmptyOnDelete: true
Content: site/dist
Version: 2
DistributionLogicalId: SiteDistribution
RunBefore:
Command: buildsite.sh
Args:
- ALiteralArgument
RunAfter:
Command: buildsite.sh
Args:
- Rain::OutputValue AStackOutputKey
EmptyOnDelete: If true, the bucket's contents, including all versions, will be deleted so that the bucket itself can be deleted. This can be useful for development environments, but be careful about using it in production!
Version: Rain doesn't do anything with this, but incrementing the number can force the stack to deploy if there have been no infrastructure changes to the stack.
RunBefore: Rain will run this command before the stack deploys. Useful to run your website build script before bothering to deploy, to make sure it builds successfully.
RunAfter: Rain will run this command after deployment, and it is capable of doing stack output lookups to provide arguments to the script. This is useful if you deployed a resource like an API Gateway and need to know the stage URL to plug in to your website configuration. Use Rain::OutputValue OutputKey to pass one of the arguments to the script.
DistributionLogicalId: Supply the logical id of a CloudFront distribution to invalidate all files in it after the content upload completes.
See test/webapp/README.md for a complete example of using these commands with Rain modules.
You can use Rain to package templates with client-side modules, which gives
CloudFormation multi-file support. This feature is compatible with (upcoming)
functionality in the AWS CLI cloudformation package command. This feature is
still considered experimental, so you need to use the --experimental flag to
use it. T