• Stars
    star
    162
  • Rank 231,440 (Top 5 %)
  • Language
    Haskell
  • License
    MIT License
  • Created over 8 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Haskell EDSL and type-checker for AWS CloudFormation templates

Stratosphere: AWS CloudFormation in Haskell

CI sponsors hackage

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

THIS SHOWS UNRELEASED API, to use it use a git source while 1.0 is under development old readme.

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 takes a while ;)
STACK_YAML=stack-9.2.yaml stack build --copy-bins --test stratosphere-generator

More Repositories

1

mutant

Automated code reviews via mutation testing - semantic code coverage.
Ruby
1,947
star
2

unparser

Turn Ruby AST into semantically equivalent Ruby source
Ruby
309
star
3

anima

Object initializer from attributes hash
Ruby
173
star
4

vanguard

External validations for ruby objects
Ruby
120
star
5

concord

Mixin to ease compositions in ruby
Ruby
112
star
6

devtools

The rake ci task!
Ruby
64
star
7

inflecto

Inflector for ruby
46
star
8

auom

Algebra with units of measurement.
Ruby
27
star
9

axiom-mongo-adapter

An MongoDB adapter for Axiom
Ruby
11
star
10

esearch

A ruby driver for elasticsearch that is ONLY A DRIVER.
Ruby
11
star
11

axiom-arango-adapter

An ArangoDB adapter for Axiom
Ruby
8
star
12

mhs

Haskell tooling megarepo
Haskell
8
star
13

axiom-elasticsearch-adapter

An Elasticsearch adapter for Axiom.
Ruby
8
star
14

mprelude-rb

Ruby
7
star
15

to_source

Generator for equivalent source from rubinius AST
Ruby
7
star
16

aql

The ArangoDB AQL AST and to_source implementation
Ruby
7
star
17

ruby-cdb

Ruby cdb reader and writer
C
6
star
18

guard-mutant

Mutant integration for guard
Ruby
6
star
19

mapper

A simple mapper without a latin name. (abandoned)
Ruby
6
star
20

axiom-fuzzer

A fuzzer for axiom relations
Ruby
6
star
21

assets

Playground for a nicer asset system
Ruby
6
star
22

response

Build HTTP responses
Ruby
5
star
23

request

Abstract not only the rack env in something more nice
Ruby
5
star
24

pgt

SQL Golden Testing Tool for postgresql
Haskell
5
star
25

ffprobe

Ruby wrapper around ffprobe
Ruby
4
star
26

eventstorm

unfinished zmq based event aggregation framework
Ruby
4
star
27

tasty-mgolden

A different golden testing provider for tasty.
Haskell
4
star
28

morpher

Transformation of ruby data-structures with optionally traced evaluation
Ruby
4
star
29

rz

Ruby ZeroMQ based jobserver with truly pulling workers
Ruby
3
star
30

openapi

OpenAPI datatypes
Haskell
3
star
31

axiom-sexp

Generate and load veritas relations from / to s-expressions
Ruby
3
star
32

lht

Lambda haskell tool / builds static binaries inside alpine containers
Haskell
3
star
33

db-migrations

Haskell Database Migrations for Postgresql
Haskell
3
star
34

ducktrap

The old soon to be unmaintained ducktrap. Successor is mbj/morpher
Ruby
3
star
35

source-constraints

GHC plugins to constrain the haskell source
Haskell
3
star
36

stack-deploy

Tooling around cloudformation templates
Haskell
3
star
37

mutant-rails-example

Mutant with rails example
Ruby
2
star
38

variable

Ruby concurrency variables MVar and IVar
Ruby
2
star
39

conversions

Haskell type conversions, another one.
Haskell
2
star
40

cbt

Container backend tool
2
star
41

devtools-hs

Haskell development tooling
Haskell
2
star
42

navigation

A web navigation dry up package
Ruby
1
star
43

sitemap_xml

Incomplete sitemap xml generator
Ruby
1
star
44

sunits

Depreciated sunits repo. Only used since some of my older projects will install from here!
Ruby
1
star
45

dump-parser

Simple and dump string 2 value DSL
Ruby
1
star
46

custom-resource

Custom CloudFormation Resources
Haskell
1
star
47

tinymagick

Simple ruby wrapper around imagemagick tools "identify" and "mogrify"
Ruby
1
star
48

html

Because XSS-free HTML generation is not about String#html_safe?
Ruby
1
star
49

mprelude

Very minimal prelude
Haskell
1
star
50

dm-annoing-modificators

Modification methods that raise on failure for datamapper.
Ruby
1
star
51

apk-build

My APK overlay and builder
Shell
1
star