stratosphere
EDSL for AWS CloudFormation
https://github.com/mbj/stratosphere#readme
| LTS Haskell 24.19: | 0.60.0 |
| Stackage Nightly 2025-11-08: | 1.0.1 |
| Latest on Hackage: | 1.0.1 |
stratosphere-1.0.1@sha256:1b00e45befafa8671188329a3cdcb333af1d0e8f5e74b2d273a21d0b8c66dfb7,4320Module documentation for 1.0.1
- Paths_stratosphere
- Stratosphere
- Stratosphere.Check
- Stratosphere.NamedItem
- Stratosphere.Output
- Stratosphere.Parameter
- Stratosphere.Prelude
- Stratosphere.Property
- Stratosphere.Resource
- Stratosphere.ResourceAttributes
- Stratosphere.ResourceAttributes.AutoScalingReplacingUpdatePolicy
- Stratosphere.ResourceAttributes.AutoScalingRollingUpdatePolicy
- Stratosphere.ResourceAttributes.AutoScalingScheduledActionPolicy
- Stratosphere.ResourceAttributes.CreationPolicy
- Stratosphere.ResourceAttributes.ResourceSignal
- Stratosphere.ResourceAttributes.UpdatePolicy
- Stratosphere.ResourceProperties
- Stratosphere.Tag
- Stratosphere.Template
- Stratosphere.Value
Stratosphere: AWS CloudFormation in Haskell
AWS CloudFormation is a system that provisions and updates Amazon Web Services (AWS) resources based on declarative templates. Common criticisms of CloudFormation include the use of JSON as the template language and limited error-checking, often only available in the form of run-time errors and stack rollbacks. By wrapping templates in Haskell, it is possible to easily construct them and help ensure correctness.
The goals of stratosphere are to:
- Build a Haskell EDSL to specify CloudFormation templates. Since it is embedded in Haskell, it is type-checked and generally much easier to work with than raw JSON/YAML.
- Have a simple checking/linting system outside of the types that can find common errors in templates.
Funding / Sponsoring
This library is maintained by mbj and any pledge is greatly apprechiated.
Example
Here is an example of a Template that creates an EC2 instance, along with the
JSON output:
module Main where
import Stratosphere
import qualified Data.ByteString.Lazy.Char8 as B
main :: IO ()
main = B.putStrLn $ encodeTemplate template
template :: Template
template
= mkTemplate [ec2Instance]
& set @"Description" "EC2 Example template"
& set @"Parameters" [keyName]
keyName :: Parameter
keyName
= mkParameter "KeyName" "AWS::EC2::KeyPair::KeyName"
& set @"Description" "Name of an existing EC2 KeyPair to enable SSH access to the instance"
& set @"ConstraintDescription" "Must be the name of an existing EC2 KeyPair."
ec2Instance :: Resource
ec2Instance
= set @"DeletionPolicy" Retain
. resource "EC2Instance"
$ EC2.mkInstance
& set @"ImageId" "ami-22111148"
& set @"KeyName" (toRef keyName)
{
"Description": "EC2 Example template",
"Parameters": {
"KeyName": {
"Description": "Name of an existing EC2 KeyPair to enable SSH access to the instance",
"ConstraintDescription": "Must be the name of an existing EC2 KeyPair.",
"Type": "AWS::EC2::KeyPair::KeyName"
}
},
"Resources": {
"EC2Instance": {
"DeletionPolicy": "Retain",
"Properties": {
"ImageId": "ami-22111148",
"KeyName": {
"Ref": "KeyName"
}
},
"Type": "AWS::EC2::Instance"
}
}
}
Please see the examples directory for more in-depth
examples (including this one). The stratosphere-example package produces a same named
binary with a minimal CLI for exploration.
Its encouraged to use it as a playground while exploring this library.
STACK_YAML=stack-9.2.yaml stack build --copy-bins --test stratosphere-examples
Value Types
CloudFormation resource parameters can be literals (strings, integers, etc),
references to another resource or a Parameter, or the result of some function
call. We encapsulate all of these possibilities in the Value a type.
It is recommend using the OverloadedStrings and OverloadedLists extensions to reduce
the number of Literals that have to be written.
Optional and required properties
Almost every CloudFormation resource has a handful of required arguments, and
many more optional arguments. Each resource is represented as a record type
with optional arguments wrapped in Maybe. Each resource also comes with a
builder that accepts required resource properties as arguments. This allows
the user to succinctly specify the resource properties they actually use
without adding too much noise to their code.
To specify optional arguments, stratosphere exposes the set function that takes
the type level symbol of the property to set and the value as argument. Its recommended to use the
& function to chain these updates. See examples.
Auto-generation
All of the resources and resource properties are auto-generated from
a
JSON schema file and
are placed in services/. The generator/ directory contains the auto-generator package stratosphere-generator
code and the JSON model file. The services/ directory is included in git so
the build process is simplified. To build stratosphere-generator from scratch and
then build all of stratosphere, build the stratosphere-generator package via stack and execute the stratosphere-generator binary from the project root.
Contributing
Feel free to raise any issues, or even just make suggestions, by filing a Github issue.
Future Work
- Implement basic checker for things like undefined Refs and duplicate field names. This stuff would be too unwieldy to do in types, and performing a checking pass over a template should be pretty straightforward.
Development Build
# Warning this takes a while ;)
# Compile all packages
STACK_YAML=stack-9.12.yaml stack test
# Run the generator
STACK_YAML=stack-9.12.yaml stack build stratosphere-manager
STACK_YAML=stack-9.12.yaml stack exec stratosphere-manager -- generate
Changes
Change Log
1.0.1 2025-11-07
Fix misleading note in readme about old API.
1.0 2025-11-07
TLDR: Loads of breaking changes, with good reasons.
Overall this release is meant to serve the future, not the past. So this release has many “bunched up” breaking changes which should reduce the need for breakng changes in the future, and improve maintainability and thus release frequency dramatically.
-
Drop generated field prefixes, making usage of the library way more natural. Especially its now possible to use this library just from the AWS provided cloudformation documentation without having to lookup the field prefixes in a second tab.
-
Drop support for GHC < 9.2. This simplifies the generator significantly. If you need older GHCs use the old versions of stratosphere. Dependency of dropping field prefixes. This library relies now on
NoFieldSelectorsinternally. -
Fully re-written generator, which works directly on the raw, un-preprocessed AWS specification, this should increase maintainabiltiy and release frequency.
-
Re-aligned generated module / builder function structure, removing all manual overwrites for dismabiguation.
-
Drop of the lens dependency, replaced with the
set @"PropertyName" valueidiom. -
Split to one package per AWS service. This induces a small overhead on the user to select the packages the user needs, but reduces compilation time significantly. Also this works around limitations on OSX linker issues on many modules. Fixes: #111 #102
-
Change
ValtoValue, its recommended to include stratosphere qualified where it clashes withaesonimports. -
Remove support for custom enum types stratosphere used to tag on to the raw spec. Fixes: #195
-
Update resource specification document to version 112.0.0 and re-generate all services. Fixes: #140
0.60.0
- Add and require aeson-2 support
- Maintainer change to Markus Schirp
- Drop support for pre GHC 9.0, user older releases if you are on these GHCs. This reduces maintainer overhead.
- Add github actions based CI
0.59.1
- Fix missing
.cabalfile in distribution
0.59.0
- Update resource specification document to version 18.2.0
0.58.0
- Update resource specification document to version 17.0.0
- Added
.cabalfiles to repo (#179) - Added
PATCHconstructor forHttpMethod(#176)
0.57.0
- Update resource specification document to version 16.3.0
0.56.0
- Update resource specification document to version 16.2.0
0.55.0
- Update resource specification document to version 15.3.0
0.54.0
- Update resource specification document to version 15.1.0
0.53.0
- Update resource specification document to version 14.3.0
- Update CI for GHC 8.8
0.52.0
- Update resource specification document to version 12.3.0
0.51.0
- Update resource specification document to version 11.6.0
0.50.0
- Update resource specification document to version 11.4.0
0.49.0
- Fixed
ImportValuenot allowingValas argument (thanks @mbj!) - Update resource specification document to version 10.4.0
0.48.0
- Update resource specification document to version 10.3.0
0.47.0
- Update resource specification document to version 10.2.0
0.46.0
- Update resource specification document to version 8.1.0
0.45.0
- Update lambda runtimes list
0.44.0
- Update resource specification document to version 7.1.0
- Added NodeJS10x Lambda runtime (@Gosha)
0.43.0
- Update resource specification document to version 6.3.0
0.42.0
- Update resource specification document to version 6.0.0
0.41.0
- Update resource specification document to version 5.0.0
0.40.0
- Update resource specification document to version 4.1.0
0.39.0
- Update resource specification document to version 3.4.0
0.38.0
- Update resource specification document to version 3.3.0
0.37.0
- Update resource specification document to version 3.0.0
0.36.0
- Update resource specification document to version 2.29.0
0.35.0
- Use a GADT for
Val aso it is properly typed. This shouldn’t break any programs that produced valid CloudFormation templates, but it should increase safety for templates that use intrinsic functions. This also allows us to properly implement some more intrinsic functions, likeNot. See https://github.com/freckle/stratosphere/pull/120 - Added the
Fn::Notintrinsic function. Fixes https://github.com/freckle/stratosphere/issues/80
0.34.0
- Don’t encode
Bool,Int, andDoublevalues as strings in JSON. See: - Use
-O0when compilingstratosphere - Update resource specification document to version 2.28.0
0.33.0
-
BREAKING CHANGE: We nuked the huge
ResourcePropertiessum type, which greatly reduced compile times, memory usage, and binary sizes for programs that depend onstratosphere. See:- https://github.com/frontrowed/stratosphere/issues/95
- https://github.com/frontrowed/stratosphere/pull/121
To migrate to this version, you should just have to remove any uses of the old
ResourcePropertiessum type and pass your resource configuration directly intoResource:@@ -32,7 +32,6 @@ dbTemplate = rdsMaster :: Resource rdsMaster = resource "RDSMaster" $ - RDSDBInstanceProperties $ rdsdbInstance "db.t2.micro"
0.32.0
- BREAKING CHANGE: We removed all
FromJSONinstances to reduce compile time and memory, and also to allow us to make other improvements thatFromJSONwas blocking. See https://github.com/frontrowed/stratosphere/issues/117
0.31.0
- Update resource specification document to version 2.25.0
- Added
Conditionfield to resources
0.30.1
- Update resource specification document to version 2.21.0
0.30.0
- Update resource specification document to version 2.19.0
0.29.1
- Update resource specification document to version 2.18.1
0.29.0
- Update resource specification document to version 2.18.0
0.28.1
- Update resource specification document to version 2.16.0
0.28.0
- Update resource specification document to version 2.15.0
0.27.0
- Update resource specification document to version 2.12.0
0.26.2
- Update resource specification document to version 2.10.0
0.26.1
- Remove dependency on
aeson-qq
0.26.0
- Update resource specification document to version 2.8.0
0.25.0
- Update resource specification document to version 2.6.0
0.24.4
- Update resource specification document to new unspecified version
0.24.3
- Update resource specification document to new unspecified version
0.24.2
- Update resource specification document to version 2.5.0
0.24.1
- Update resource specification document to support EKS
0.24.0
- Update resource specification document to version 2.4.0
0.23.0
- Update resource specification document to version 2.3.0
0.22.3
- Update resource specification document to new unspecified version
0.22.2
- Update resource specification document to version 2.2.0
0.22.1
- Update resource specification document to version 2.1.0
0.22.0
- Bug fix:
AWSTemplateFormatVersionwas being formatted incorrectly in JSON.
0.21.0
- Update resource specification document to some new unspecified version.
- Add new
nodejs8.10to lambda
0.20.0
- Fix name of
AutoScalingRollingUpdatePolicySuspendProcessesparameter - Update list of AWS Lambda
Runtimevalues
0.19.1
- Add compatibility with GHC 8.4.1
0.19.0
- Fix
Equalsfunction requiringVal Boolarguments instead ofVal a - Add
Metadatafield toResourcetype
0.18.0
- Update resource specification document to version 2.0.0
- Fix missing
AWS::ElasticLoadBalancingV2::ListenerCertificateresource
0.17.0
- Fix JSON instances for non-codegen code.
- Allow the
Splitfunction to useVal ain its second argument.
0.16.0
- BREAKING CHANGE: Renamed lenses for non-generated code to match naming conventions of generated code.
- Update resource specification document to 1.14.0
0.15.2
- Update resource specification document to some unspecified new version.
stratospherenow compiles with no warnings.
0.15.1
- Update resource specification document to version 1.13.0
0.15.0
- Update resource specification document to some unspecified new version.
0.14.0
- Update resource specification document to version 1.12.0
0.13.0
- Update resource specification document to version 1.11.0
0.12.0
- Update resource specification document to version 1.10.0
0.11.0
- Update resource specification document to version 1.8.0
0.10.0
- Update resource specification document to version 1.7.0
0.9.0
- Update resource specification document to version 1.6.0
0.8.0
- Update resource specification document (no version given in doc)
- GHC 8.2.1 compatibility
0.7.1
- Add
Exportfield to theOutputtype. This allows you to declare cross-stack references.
0.7.0
- Made
ValandValListmore type-safe by moving some constructors toValListand being more specific with types in functions that only acceptTextparameters. Specific examples include:JoinandSelectnow require aValListargumentBase64andJoinnow work only onVal Text, notVal aGetAZsandSplitare now inValList, notVal
- Created
ImportValueListas aValListalternative toImportValue. - Added support for
Fn::Subintrinsic function.
0.6.0
-
BREAKING CHANGE: Added
ValListtype. This new type allows you to reference parameters that are already list types. Previously you had to use some kludgy workarounds. For example, you can nowRefa parameter of typeList<AWS::EC2::AvailabilityZone::Name>.Every type that used to be
[Val a]is nowValList a. If you use theOverloadedListspragma, you might not have to change any of your code. Otherwise, you must wrap existing lists in theValListconstructor. -
BREAKING CHANGE: The newtype wrappers
Integer',Bool', andDouble'are no longer required. CloudFormation expects numbers and bools to be JSON strings. These newtypes used to be necessary so we didn’t use JSON numbers/bools. Now the conversion is handled internally, and users don’t need to worry about this when usingstratosphere.
0.5.0
- Update resource specification document (no version given)
0.4.4
- Update the resource specification document to version
1.4.2
0.4.3
- Update the resource specification document to version
1.4.1
0.4.2
- Update the resource specification document to version
1.2.1
0.4.1
- Manually write out all JSON instances to speed up compilation
- Fix bug in CloudFormation specification where
EvaluationPeriodswas accidentally set toDouble.
0.4.0
- Derive the
Eqtype class for everything. This is useful when comparing two templates. - Added the new
Fn::Splitfunction. - Fix error in resource specification document where
AWS::AutoScaling::AutoScalingGroup.Tagswas mistakenly calledAsTags. - Fix error in resource specification document where the two properties
ImageandNameinAWS::ECS::TaskDefinition.ContainerDefinitionwere incorrectly marked as not required, even though they are required. - Fix JSON instances for auto scaling group update policies
0.3.1
- Updated resource specification document to version 1.1.1.
0.3.0
- Backwards-incompatible: We now use the official AWS JSON spec document to auto-generate types. This means there is no more Python scraper and custom JSON schemas. The behavior of the library is exactly the same, but a ton of resource names changed to match official the official AWS names. On the plus side, we now have 100% service coverage!
0.2.2
- Fixed a test suite failure caused by bleeding edge HLint version.
0.2.1
- Added Dynamo DB table resources (@ababkin)
- Fix the Python docs scraper mishandling the
requiredvalue in some cases, and also missing some properties of resources (@amar47shah) - Added a ton of SNS and SQS resources (@ababkin)
- Added a experimental checker for duplicate resource names (@amar47shah)
0.2.0
- Breaking change: The
DependsOnproperty previously allowed lists ofVal Text, when in fact CloudFormation only accepts literalTextvalues. The new type ofDependsOnisMaybe [Text]. - Added
AWS::ElastiCache::CacheClusterresource (@MichaelXavier) - Added many
AWS::Lambdaresources and associated resource properties (@ababkin) - Added new
ImportValueCloudFormation function (@timmytofu) - Added tons of AWS Kineses resources (@MichaelXavier)
- Added a lot of Api Gateway resources (@ababkin)
- Allow setting
LensPrefixin JSON model files to avoid name collisions (https://github.com/frontrowed/stratosphere/issues/27)
0.1.6
- Fix Haddock parsing for
FindInMap. We now run haddock in CircleCI so we shouldn’t see a regression like this in the future.
0.1.5
- Added S3 buckets and bucket policies
- Added CloudTrail Trail (Thanks @timmytofu!)
- Added the
FindInMapintrinsic function. (Thanks @MichaelXavier!) - Added
SecurityGroupEgressandSecurityGroupIngressrules. (Thanks @MichaelXavier!) - Fixed type of ELB policy using the more specific
NameAndValuetype. (Thanks @MichaelXavier!)
0.1.4
- Added
UserNameproperty to the IAM User resource. (Thanks @timmytofu!) - Added IAM Group and Role name parameters. (Thanks again @timmytofu!)
0.1.3
- Update
aeson-prettyto version 0.8 so we can stay in stackage nightly. - Fix not exporting resource name lens.
0.1.2.1
- Removed some dependencies that crept in so we can build against stackage
nightly and use GHC 8. These were actually dependencies of
stratosphere-genand aren’t needed forstratosphere.
0.1.2
- Added all of the resources and resource properties for Auto Scaling Groups.
- New AutoScalingGroup example
- Added UpdatePolicy, CreationPolicy, and DependsOn
0.1.1
- Small bug fix for “style” test when using the cabal distribution
0.1 (initial release)
- Initial release with all Template components implemented along with a huge set of Resources.