I am using the following JSON to represent our infrastructure. This is a greatly simplified version.
{
"us-east-1": {
"qa": {
"etcd": {}
}
},
"eu-central-1": {
"dev": {
"etcd": {}
}
},
"eu-west-1": {
"prod": {
"etcd": {}
}
}
}
This can be mapped to folders and it is easy to handle from code.
#!/usr/bin/env python
import json
import os, sys
with open('infrastructure.json', 'r') as read_file: infra = json.load(read_file)
regions = infra.keys()
for region in regions:
stages = infra[region].keys()
for stage in stages:
apps = infra[region][stage].keys()
for app in apps:
os.makedirs(os.path.join('infra', region, stage, app), 0o750, exist_ok=True)
print('region: {}, stage: {}, app: {}'.format(region, stage, app))
However, I would like to generate this file using Dhall to restrict the possible keys to lists.
Dhall has support for this:
let AwsRegions : Type = < us-east-1 | eu-central-1 | eu-west-1 >
let Stages : Type = < dev | qa | prod >
let Applications : Type = < etcd | postgresql | hadoop >
The only problem is that I could not find support to have a record key as an empty type, only the values can be restricted to those.
This makes me have our infra the following way:
let infrastructure :
List { region: AwsRegions, stage: Stages,
applications: List Applications } =
[ { region = AwsRegions.us-east-1,
stage = Stages.dev,
applications = [
Applications.hadoop,
Applications.etcd ] },
{ region = AwsRegions.eu-west-1,
stage = Stages.dev,
applications = [
Applications.hadoop,
Applications.etcd ] },
{ region = AwsRegions.eu-central-1,
stage = Stages.dev,
applications = [
Applications.hadoop,
Applications.etcd ] },
{ region = AwsRegions.eu-west-1,
stage = Stages.qa,
applications = [
Applications.hadoop,
Applications.etcd ] },
{ region = AwsRegions.eu-west-1,
stage = Stages.prod,
applications = [
Applications.hadoop,
Applications.etcd ] } ]
in infrastructure
The generated JSON is a bit harder to handle from code and I cannot easily reference subset of our infra like with the other representation.
Is there a way to have keys like enums (a union for empty types) with Dhall?
This would be the idiomatic way to generate nested JSON records whose keys were restricted to enums:
... which renders as the following JSON: