Terraframe
Terraframe is a processor for a domain-specific language that outputs to the Terraform specification format.
Terraform is a cool infrastructure-as-code system with a boatload of functionality and a really awesome core that makes building out entire clouds on AWS super easy and super fun. I am a fan.
But. But but but. It's not perfect. And personally, ever since HashiCorp went away from Ruby DSLs as configuration, I have been sad. And worse than sad, I have been unproductive as all hell. I'm just not satisfied with the state of the Terraform description language. The configuration, while not CloudFormation-bad, is static and limited, and I came close to ditching Terraform because it was really hard to write. I got halfway through some ERB templating monstrosity before I learned of a better way: Terraform supports JSON as a declaration notation, and that makes it really easy to build an external DSL that can be exported for use in Terraform. So everybody wins!
Installation
Terraframe is distributed as a RubyGem.
gem install terraframe
Usage
- You'll need to have Terraform installed to actually use the output of Terraframe.
- Check
terraframe --help
for exhaustive usage details.
Syntax
For the most part, the Terraframe syntax directly parallels the Terraform syntax, but has been Rubified. At present, most of this is a wrapper around method_missing
, and so it's a little rocky when dealing with nested data types.
You can easily wire up outputs via id_of(resource_type, resource_name)
and output_of(resource_type, resource_name, output_name)
, to make things a little less crazy.
Variables can be passed in via the -v
flag in as many YAML files (which will be deep-merged) as you would like. They are exposed to scripts via the vars
hash.
Examples: TBD. To get you started, here's the supported invocations:
provider :provider_type {}
resource :resource_type, "resource_name" {}
resource_type "resource_name {}
The latter deserves special attention, because any attempted invocation other than provider
, variable
, resource
, or provisioner
will be interpreted as a resource. (resource :resource_type, "resource_name"
is supported for people who like the Terraform syntax.)
Future Work
Right now, Terraframe is being extended as I need it. Pull requests very gratefully accepted for
- Variable interpolation in YAML variable files (or possibly Ruby variable files that must emit a hash, a la Chef). This will be soon, I'll need it.
- Supporting
variable
andprovisioner
blocks, neither are hard but they have to get done. - Script linting (checking for id existence, only allowing valid keys, etc.) before starting up Terraform. Very low priority, as that's what Terraform itself does.
- Test coverage.
Contributing
- Fork it ( https://github.com/eropple/terraframe/fork )
- Create your feature branch under the
feature/
prefix, as with git-flow (git flow feature start my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin feature/my-new-feature
). Please don't change the version number and please make README changes in a separate commit to make everything comprehensible for me. - Make a pull request!
Thanks
- My employer, Leaf, for encouraging the development and use of Terraframe. (We're hiring!)
- William Lee, my platform engineering co-conspirator at Leaf.
- HashiCorp, 'cause Terraform is fundamentally an awesome project and we're all better because you guys made this.