Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JetRails Craft

jrcft is a build tool for our CloudFormation templates.

Vibe Coded Claude Go macOS Linux


Overview

When AWS archived Rain, we decided to build something better suited to how we ship. jrcft is a fast, focused build tool for CloudFormation templates, and it's open for anyone to use.

We keep it lean on purpose. Rather than chase full feature parity with Rain, we implement exactly what our templates need and grow the feature set as the community asks for more.

Just as important, jrcft never talks to the AWS API. There are no credentials to wire up and no network round trips to wait on, only fast, local template transformation. That tight focus on transforming templates is what keeps it quick.

jrcft reads your templates in YAML or JSON, runs them through a set of transform passes, and writes clean output as YAML, JSON, or both. A small set of custom tags keeps everything DRY and configurable.

jrcft src/*.yml -o dist -f yml,json

Tags

Tag Description
!Craft::Env <NAME> Resolves to the value of environment variable NAME. Errors if it's unset.
!Craft::Embed <path> Inlines the contents of the file at path, relative to the template.
!Craft::Template <path> Writes the processed template into the output directory under its S3 key, and resolves to its https:// URL. Only allowed on a stack's TemplateURL.

Environment variables come from your shell or any env file you load.

!Craft::Template only works on the TemplateURL of an AWS::CloudFormation::Stack resource. It processes the template it points at first, so a nested template can use these tags too. The S3 key is a hash of the processed template, so the URL only changes when the content changes. And jrcft doesn't upload anything. It writes the processed template into the output directory alongside everything else, and you sync that directory to your bucket.

Usage

jrcft <source>... [flags] [-- KEY=VALUE ...]
Flag Description
-o, --output <dir> Directory to write into, created if it doesn't exist (default ./dist)
-n, --output-name <name> Output file name without the extension (default [name]). Supports placeholders.
-f, --format <list> Output formats: yml, json, or both, comma-separated (default yml)
--s3-bucket <bucket> S3 bucket used in the !Craft::Template URLs. Required when a template uses it.
--s3-region <region> S3 region used in the !Craft::Template URLs. Required when a template uses it.
--s3-prefix <prefix> S3 key prefix, and the subdirectory under --output. Supports placeholders.
--skip <passes> Passes to skip: craft-env, craft-template, craft-embed, craft-spacing
--env-file <files> Env file to load (default .env). Repeatable.

Placeholders

--output-name and --s3-prefix both support [...] placeholders. [name] is the input template's base name without the extension. [<anything>] is any environment variable, lowercased, so [version] pulls in VERSION.

# app.yml -> dist/app-v2.yml
VERSION=v2 jrcft app.yml -o dist -n '[name]-[version]'

Environment Files

By default jrcft loads a .env from the current directory if one is there. Those values only fill in variables that aren't already set, so your shell always wins. They feed both !Craft::Env lookups and placeholders.

Pass --env-file to load other files instead, and you can pass it more than once. It's the one option you can't set with an env var. Pointing it at a file that doesn't exist is an error.

jrcft src/app.yml --env-file base.env --env-file prod.env

Inline Variables

Anything you pass after -- is a KEY=VALUE pair that gets injected into the environment for that run. Those show up in !Craft::Env lookups and in placeholders, same as anything from your shell or an env file. This is handy in CI when you want to pass a build value straight in without exporting it first.

Inline vars win over everything. If the same key is set in your shell or an env file, the inline value takes over. The value can have = signs in it, since only the first one splits the key from the value.

# in.yml -> dist/app-abc123.yml, with Build resolving to abc123
jrcft in.yml -o dist -n 'app-[hash]' -- HASH=abc123

Configuration

Every flag except --env-file can also be set with a JRCFT_-prefixed env var. The flag wins if you pass both.

Environment Variable Flag
JRCFT_OUTPUT -o, --output
JRCFT_OUTPUT_NAME -n, --output-name
JRCFT_FORMAT -f, --format
JRCFT_S3_BUCKET --s3-bucket
JRCFT_S3_REGION --s3-region
JRCFT_S3_PREFIX --s3-prefix
JRCFT_SKIP --skip

These can live in an env file too, so a project's .env can pin its whole config.

Install

Grab a build from Releases. Swap 0.0.2 for the version you want.

Darwin

Intel & ARM

brew tap jetrails/tap
brew install --cask jrcft
Debian

amd64

curl -LO https://github.com/jetrails/jrcft/releases/download/0.0.2/jrcft_0.0.2_amd64.deb
sudo dpkg -i ./jrcft_0.0.2_amd64.deb
rm ./jrcft_0.0.2_amd64.deb

arm64

curl -LO https://github.com/jetrails/jrcft/releases/download/0.0.2/jrcft_0.0.2_arm64.deb
sudo dpkg -i ./jrcft_0.0.2_arm64.deb
rm ./jrcft_0.0.2_arm64.deb
Red Hat

aarch64

curl -LO https://github.com/jetrails/jrcft/releases/download/0.0.2/jrcft-0.0.2-1.aarch64.rpm
sudo rpm -i ./jrcft-0.0.2-1.aarch64.rpm
rm ./jrcft-0.0.2-1.aarch64.rpm

x86_64

curl -LO https://github.com/jetrails/jrcft/releases/download/0.0.2/jrcft-0.0.2-1.x86_64.rpm
sudo rpm -i ./jrcft-0.0.2-1.x86_64.rpm
rm ./jrcft-0.0.2-1.x86_64.rpm
Alpine

aarch64

curl -LO https://github.com/jetrails/jrcft/releases/download/0.0.2/jrcft_0.0.2_aarch64.apk
apk add --allow-untrusted ./jrcft_0.0.2_aarch64.apk
rm ./jrcft_0.0.2_aarch64.apk

x86_64

curl -LO https://github.com/jetrails/jrcft/releases/download/0.0.2/jrcft_0.0.2_x86_64.apk
apk add --allow-untrusted ./jrcft_0.0.2_x86_64.apk
rm ./jrcft_0.0.2_x86_64.apk
Arch

aarch64

curl -LO https://github.com/jetrails/jrcft/releases/download/0.0.2/jrcft-0.0.2-1-aarch64.pkg.tar.zst
sudo pacman -U ./jrcft-0.0.2-1-aarch64.pkg.tar.zst
rm ./jrcft-0.0.2-1-aarch64.pkg.tar.zst

x86_64

curl -LO https://github.com/jetrails/jrcft/releases/download/0.0.2/jrcft-0.0.2-1-x86_64.pkg.tar.zst
sudo pacman -U ./jrcft-0.0.2-1-x86_64.pkg.tar.zst
rm ./jrcft-0.0.2-1-x86_64.pkg.tar.zst

Build

make build

The binary lands in the dist directory, under subdirectories for the OS and architecture.

Test

Tests live in the test/ directory as .test fixtures and run through a golden-file runner. Run the suite with:

make test

If you change behavior on purpose, regenerate the expected output with UPDATE=1 make test and review the diff before you commit it.

About

A build tool for our CloudFormation templates

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages