Properties
Formas can be parameterized by properties. Properties not only allow to add more flexibility for forma application, but also to abstract infrastructure for developers, for example in Platform Engineering settings. Let's look at an example of how to achieve that:
Declaration of a parameterized service
properties {
team = new formae.Prop {
flag = "team"
}
size = new formae.Prop {
flag = "size"
default = "xs"
}
}
local _vpc = new vpc_resources.VpcResources {
team = properties.team.value
}
local _database = new database_resources.DatabaseResources {
team = properties.team.value
size = properties.size.value
vpc = _vpc.vpc
subnet1 = _vpc.subnet1
subnet2 = _vpc.subnet2
}
The above code declares a service and parameterizes it with two properties:
- team: some team name
- size: database size, expressed as t-shirt size
All the low-level details are hidden behind the service, so that consumers of that service - for example, developer teams, don't need to ever see the underlying details, while the platform team can easily change them according to changing non-functional requirements.
Making sure properties are type and value safe
Properties can be easily constrained, ensuring total type- and value-safety. For example:
typealias Team = "team-a" | "team-b"
function RegionFromTeam(team: Team): aws.Region = (
if (team == "team-a")
"us-east-1"
else if (team == "team-b")
"us-west-1"
else
throw("Unknown team: \(team)")
)
typealias DbRawSize = "db.t3.micro" | "db.t3.small"
typealias DbSize = String((str) -> (
str.matches(Regex(#"(?i)^(XS|S)"#))
))
function DbRawSizeFromSize(size: DbSize): DbRawSize = (
if (size.toLowerCase() == "xs")
"db.t3.micro"
else if (size.toLowerCase() == "s")
"db.t3.small"
else
throw("Unknown size: \(size)")
)
In the above code, team and database size are constrained to just a few values. If the consumer of the service is not providing correct values of their correct type, the forma will not be applicable.
Setting properties when applying a forma
The consumer - be it a developer or even a CI/CD job - only needs to provide properties of a forma when running the apply command. No need to understand the forma itself.
To see available properties for a forma, use the --help
flag:
formae apply --help examples/complete/services/database.pkl
...
Properties:
--size property: size [default: "xs"]
--team property: team [required]
Try it yourself
formae is shipped with a few examples. Refer to the services
example
to see properties in action.