dhall-awsdac
May 30, 2026 · View on GitHub
A Dhall library for awsdac (awslabs/diagram-as-code). Describe AWS architecture diagrams in type-safe Dhall, convert to awsdac-compatible YAML with dhall-to-yaml, then render to PNG with the awsdac CLI.
diagram.dhall ──dhall-to-yaml──► diagram.yaml ──awsdac──► diagram.png
Requirements
| Tool | Purpose | Notes |
|---|---|---|
dhall | Type-checking and hashing | brew install dhall |
dhall-to-yaml or dhall-to-yaml-ng | YAML conversion | brew install dhall-yaml (provides dhall-to-yaml-ng) |
awsdac | Render YAML to PNG | submodule HEAD is recommended — TitleFillColor, SpanResources, etc. landed after the 0.23 release |
Build awsdac from the vendored submodule:
cd diagram-as-code && go build -o /usr/local/bin/awsdac ./cmd/awsdac
Quick start
-- diagram.dhall
let awsdac = ./package.dhall
let D = awsdac.Defaults
let AWS = awsdac.AWS.Types
let P = awsdac.AWS.Presets
let Dir = awsdac.Direction
let DF = awsdac.DefinitionFile
let entry = awsdac.Schema.entry
in D.Diagram
:: { Diagram =
{ DefinitionFiles = [ DF.awsLightIcons ]
, Resources =
[ entry "Canvas" D.Resource::{
, Type = AWS.Diagram.Canvas
, Direction = Dir.Vertical
, Children = [ "VPC" ]
}
, entry "VPC" D.Resource::{
, Type = AWS.EC2.VPC
, Preset = P.AWSCloudNoLogo
}
]
, Links = [] : List awsdac.Schema.Link
}
}
dhall-to-yaml --omit-empty --file diagram.dhall > diagram.yaml
awsdac diagram.yaml -o diagram.png
Full examples: examples/alb-ec2.dhall, examples/vpc-natgw.dhall, examples/cloudfront-ecs-rds.dhall (CloudFront / S3 / ALB / ECS / RDS / ElastiCache with locally-composed helpers).
URL import
Pin via SHA256:
let awsdac =
https://raw.githubusercontent.com/<owner>/dhall-awsdac/<tag>/package.dhall
sha256:<hash>
The SHA256 for each tagged release is published on the Releases page (also attached as package.dhall.sha256). To recompute locally:
dhall hash --file package.dhall
Expect breaking changes during the v0.x series.
Layout
| Directory | Contents |
|---|---|
schema/ | Dhall types in 1:1 correspondence with the awsdac YAML schema |
defaults/ | Default records for the :: operator — write only the required fields |
types/ | Text constants for Position / Direction / Align / etc. |
helpers/ | Color.rgba builders, DefinitionFile variant constructors, Arrow presets |
aws/ | AWS::* type constants generated from the upstream awsdac icon definitions (~145 resource-level + ~184 service-level), plus preset names |
examples/ | Sample diagrams |
test/ | Round-trip tests |
package.dhall | Public API entry point |
API surface
let awsdac = ./package.dhall
awsdac.Schema.{Diagram, Resource, Link, ..., entry} -- types + `entry` resource-map helper
awsdac.Defaults.{Diagram, Resource, Link, Label} -- :: defaults
awsdac.{Position, Direction, Align, HeaderAlign, BorderType, LineStyle, LinkType, ArrowHeadType, IconFillType}
awsdac.Color.{rgba, rgb, rgbaClamped, rgbClamped, clamp255, transparent, black, white}
awsdac.DefinitionFile.{url, localFile, embed, awsLightIcons} -- embed takes a Schema.Embed (DefinitionStructure)
awsdac.Arrow.{open, default}
awsdac.Layout.{hstack, vstack} -- HorizontalStack / VerticalStack from a List Text of child names
awsdac.Link.{link, arrow} -- link s sp t tp (no arrowhead); arrow s sp t tp (Arrow.open on target)
awsdac.AWS.Types.{Diagram, EC2, ElasticLoadBalancingV2, AutoScaling, RDS, Lambda, S3, IAM, DynamoDB, SQS, SNS, CloudFront, Route53, ApiGatewayV2, CloudWatch, ECS, ...} -- ~145 resources; see aws/Types.dhall
awsdac.AWS.Services.{S3, EC2, CloudFront, Region, ...} -- ~184 service-level icons; see aws/Services.dhall
awsdac.AWS.Presets.{AWSCloudNoLogo, PublicSubnet, PrivateSubnet, ApplicationLoadBalancer, NetworkLoadBalancer, User, BlankGroup, Empty}
Tests
Verifies that each Dhall example produces a byte-identical PNG to the upstream YAML sample:
bash test/render.sh
# Override the awsdac binary with $AWSDAC (defaults to the one on $PATH)
AWSDAC=/tmp/awsdac-head bash test/render.sh
test/render.sh performs:
dhall type --file package.dhall(schema type-check)dhall hash --file package.dhall(prints the pinned SHA256)- For each example: render
dhall → yaml → pngandupstream yaml → png, compare withcmp
limitations
- AWS type constants are mechanically generated from the upstream awsdac icon-definition YAML (~145 resource-level entries in
aws/Types.dhall, ~184 service-level entries inaws/Services.dhall). Anything upstream doesn't define can be written as a literal"AWS::Foo::Bar"string; awsdac falls back to the service-level icon when a resource type isn't recognised. Re-runpython3 tools/gen-aws-types.pyto refresh from upstream. DefinitionFile.Embedis hand-translated from awsdac'sdefinition.DefinitionGo struct. Drift from upstream must be tracked manually (no CI check yet).- No high-level abstractions like "create a VPC with public/private subnets" — users compose their own helpers.
Color.rgba/rgbcannot enforce the 0–255 range at the Dhall type level (documented as a contract). UseColor.rgbaClamped/rgbClampedfor runtime-saturating variants when constructing colors from arithmetic.- Semantic awsdac constraints (e.g. Canvas must exist) are not expressible in Dhall and surface as awsdac runtime errors.
dhall-to-yamlemits record fields in alphabetical order, soTypeis not at the top of each resource. Functionally harmless, just less readable.
License
Apache License 2.0. See LICENSE.