Templating language for lookups
Something we talked about briefly internally. The current syntax for specifying lookups looks something like this:
variables:
VpcId: ${output vpc::VpcId}
It allows you to nest outputs, but with some caveats.
It could be nice to support a more sophisticated templating language. Specifically, it would be nice to be able to perform simple transformations on config/outputs before providing them as a variable (e.g. conditionals, math, etc). Not unlike terraform's interpolation: https://www.terraform.io/docs/configuration/interpolation.html#conditionals.
On a similar note, at times I've felt it would be easier to describe everything in Python, rather than YAML. That would easily allow for transformations, conditions, and math using regular python without having to go the full on templating route. It's a trade off, because you'd loose some static analysis that you get from YAML, but could be nice for building out more sophisticated meta stacks. Given a yaml config like this:
stacks:
- name: vpc
class_path: blueprints.Vpc
- name: bastion
class_path: blueprints.Bastion
variables:
VpcId: ${output vpc::VpcId}
- name: cluster
class_path: blueprints.Cluster
variables:
MinSize: ${cluster_min_size}
VpcId: ${output vpc::VpcId}
I'd expect a simple Python API like so:
from stacker import Stack, Config
import blueprints
def config(environment):
vpc = Stack(
"vpc",
blueprints.Vpc)
bastion = Stack(
"bastion",
blueprints.Bastion,
requires=[vpc],
variables={
"VpcId": lambda: vpc.Output("VpcId")})
cluster = Stack(
"cluster",
blueprints.Cluster,
requires=[vpc],
variables={
"MinSize": environment["cluster_min_size"],
"VpcId": lambda: vpc.Output("VpcId")})
return Config(stacks=[vpc, bastion, cluster])
So you could just point stacker at a .py file, instead of .yaml, and it'd execute the config function within it to get a compiled Config.
At the very least, even if this wasn't exposed to the stacker command, this could simplify the process of going from a yaml to a compiled Config that can be executed.