All Projects → brabster → Crucible

brabster / Crucible

Licence: epl-1.0
AWS CloudFormation templates built with Clojure

Programming Languages

clojure
4091 projects

Projects that are alternatives of or similar to Crucible

Cfn nag
Linting tool for CloudFormation templates
Stars: ✭ 808 (+1124.24%)
Mutual labels:  cloudformation
Mu
A full-stack DevOps on AWS framework
Stars: ✭ 948 (+1336.36%)
Mutual labels:  cloudformation
Serverless
This is intended to be a repo containing all of the official AWS Serverless architecture patterns built with CDK for developers to use. All patterns come in Typescript and Python with the exported CloudFormation also included.
Stars: ✭ 1,048 (+1487.88%)
Mutual labels:  cloudformation
Ansible Modules
Custom ansible modules
Stars: ✭ 17 (-74.24%)
Mutual labels:  cloudformation
Cloudmagick
CloudMagick is a serverless application which provides a dynamic image transformation like the small light module of apache2
Stars: ✭ 11 (-83.33%)
Mutual labels:  cloudformation
Shorty.sls
Serverless URL shortener written in Python3 using the serverless framework
Stars: ✭ 35 (-46.97%)
Mutual labels:  cloudformation
Taskcat
Test all the CloudFormation things! (with TaskCat)
Stars: ✭ 799 (+1110.61%)
Mutual labels:  cloudformation
Cfn Create Or Update
Create or update CloudFormation stack also if no updates are to be performed.
Stars: ✭ 59 (-10.61%)
Mutual labels:  cloudformation
Aws Auto Terminate Idle Emr
AWS Auto Terminate Idle AWS EMR Clusters Framework is an AWS based solution using AWS CloudWatch and AWS Lambda using a Python script that is using Boto3 to terminate AWS EMR clusters that have been idle for a specified period of time.
Stars: ✭ 21 (-68.18%)
Mutual labels:  cloudformation
Aws Data Replication Hub
Seamless User Interface for replicating data into AWS.
Stars: ✭ 40 (-39.39%)
Mutual labels:  cloudformation
Serverless Aws Lambda Node Postgres
Serverless AWS Lambda with Node.js,Postgres Rest API with Sequelize.
Stars: ✭ 18 (-72.73%)
Mutual labels:  cloudformation
Cfn Generic Custom Resource
CloudFormation generic custom resource provider
Stars: ✭ 26 (-60.61%)
Mutual labels:  cloudformation
Aws Unifi Controller
Example of a Ubiquiti Unifi Controller in AWS using Network Load Balancer for TLS termination
Stars: ✭ 37 (-43.94%)
Mutual labels:  cloudformation
Aws Toolkit Vscode
AWS Toolkit for Visual Studio Code, an extension for working with AWS services including AWS Lambda.
Stars: ✭ 823 (+1146.97%)
Mutual labels:  cloudformation
Serverless Application
🍤 ALIS Media - Serverless Application
Stars: ✭ 52 (-21.21%)
Mutual labels:  cloudformation
Aws Cloudformation Coverage Roadmap
The AWS CloudFormation Public Coverage Roadmap
Stars: ✭ 800 (+1112.12%)
Mutual labels:  cloudformation
Aws Scalable Big Blue Button Example
Demonstration of how to deploy a scalable video conference solution based on Big Blue Button
Stars: ✭ 29 (-56.06%)
Mutual labels:  cloudformation
Aws Iot Certificate Vending Machine
The CVM allows a device to apply for its own certificate and installation.
Stars: ✭ 64 (-3.03%)
Mutual labels:  cloudformation
Quickstart Taskcat Ci
AWS Quick Start Team
Stars: ✭ 57 (-13.64%)
Mutual labels:  cloudformation
Webapp Revieee
Stars: ✭ 39 (-40.91%)
Mutual labels:  cloudformation

crucible

Create better cloudformation templates with Clojure

Travis Build CII Best Practices

Installation

Crucible depends on clojure.spec, currently available in Clojure 1.9 alpha 10+ (breaking changes in spec around alpha 9)

Clojars Latest Version

Examples

(ns crucible.examples-test
  (:require [crucible.core :refer [template parameter resource output xref encode join]]
            [crucible.aws.ec2 :as ec2]))

(def simple (template "A simple sample template"
                      :my-vpc-cidr (parameter)
                      :my-vpc (ec2/vpc {::ec2/cidr-block (xref :my-vpc-cidr)})
                      :vpc (output (join "/" ["foo" (xref :my-vpc)]))))

repl> (clojure.pprint/pprint (encode simple))
{"AWSTemplateFormatVersion" "2010-09-09"
 "Description" "A simple sample template"
 "Parameters" {"MyVpcCidr" {"Type" "String"}}
 "Resources" {"MyVpc"
              {"Type" "AWS::EC2::VPC",
               "Properties" {"CidrBlock" {"Ref" "MyVpcCidr"}}}},
 "Outputs" {"Vpc" {"Value" {"Fn::Join" ["/" ["foo" {"Ref" "MyVpc"}]]}}}}

Alternative template construction function accepts map and string arguments for building a template from partials, for example:

(def simple (-> {:my-vpc-cidr (parameter)}
                (assoc :igw (ec2/internet-gateway {}))
                (assoc :my-vpc (ec2/vpc {::ec2/cidr-block (xref :my-vpc-cidr)}))
                (assoc :vpc (output (join "/" ["foo" (xref :my-vpc)])))
                (template "A simple sample template")))

Parameter Options

See crucible.parameters namespace, required as param in this example:

:my-vpc-cidr (parameter ::param/type ::param/number
                        ::param/description "A demonstration of parameter options"
                        ::param/allowed-values [1 2 3]
                        ::param/no-echo true)

Resource Policies

See crucible.policies namespace, required as policies in this example:

:my-vpc (ec2/vpc {::ec2/cidr-block (xref :my-vpc-cidr)}
                 (policies/deletion ::policies/retain)
                 (policies/depends-on :my-vpc-cidr))

Resource Types

Standard AWS resource types can be found as children of the crucible.aws namespace.

Examples of resource type usage can be found in the tests.

  • AWS::EC2::* partial coverage
  • AWS::ElasticLoadBalancingV2::*
  • AWS::ApiGateway::*
  • AWS::DynamoDB::Table
  • AWS::CloudWatch::Alarm
  • AWS::Lambda::Function
  • AWS::Lambda::EventSourceMapping
  • AWS::IAM::Role (basic support for Lambda applications)
  • AWS::ECR::Repository
  • AWS::S3::Bucket
  • AWS::CloudFormation::Stack
  • AWS::Kinesis::Stream
  • AWS::KinesisFirehose::DeliveryStream
  • AWS::Route53::RecordSet
  • AWS::SNS::Topic
  • AWS::SNS::TopicPolicy
  • AWS::SQS::Queue
  • AWS::Events::Rule
  • AWS::AutoScaling::AutoScalingGroup/LaunchConfiguration
  • Custom::* custom resources

Writing your own resource type

The easiest way is to use defresource and spec-or-ref from the crucible.resources namespace, eg.

(ns crucible.aws.ec2
  "Resources in AWS::EC2::*"
  (:require [crucible.resources :refer [spec-or-ref defresource] :as res]
            [clojure.spec :as s]))

;; spec-or-ref applies your spec if a literal value is given,
;; but also allows a parameter or function to be given instead of a literal.
(s/def ::cidr-block (spec-or-ref string?))

;; ::res/tags reuses the tags spec defined in the crucible/resources namespace
(s/def ::vpc (s/keys :req [::cidr-block]
                     :opt [::enable-dns-support
                           ::enable-dns-hostnames
                           ::instance-tenancy
                           ::res/tags]))

;; creates resource factory crucible.aws.ec2/vpc with type "AWS::EC2::VPC" 
;; and validates the data structure using the ::vpc spec
(defresource  vpc "AWS::EC2::VPC" ::vpc)

Pull requests to add or enhance resource types available in Crucible will be welcomed. If it's a standard AWS type please place it in the crucible.aws namespace and use defresource as it documents the resource type for you. At lest one test for the update would be great!

Testing a Resource Type

Although you can test a resource by testing the data structure and validity directly, testing the conversion from the crucible code to a map ready to encode as CloudFormation-valid JSON is good minimal coverage. The default clojure.test behaviour does not pretty-print the ex-data map on validation exceptions, which makes testing and debugging validation failures painful. A custom assertion crucible.assertion/resource= is available to ensure any failure map is pretty-printed. See the resource tests for examples.

Overriding JSON Keys

Crucible uses camel-snake-kebab's ->PascalCase function to convert Clojure map keys into JSON map keys. That takes care of most translations between Clojure-style :keyword-key and JSON/CloudFormation-style KeywordKey. To handle the occasional mistranslation, typically due to capitalisation, clojure.encoding.keys exposes a ->key multimethod, allowing overriding of the translation. For example, this problem occurs in AWS::CloudFormation::Stack, where a required key is TemplateURL. The following overrides the natural translation of :template-url to TemplateUrl.


(ns crucible.aws.cloudformation
  (:require [crucible.encoding.keys :refer [->key]]))

(defmethod ->key :template-url [_] "TemplateURL")

Note, these translations take place during the final JSON encoding step and do not see keyword namespacing.

Severless Application Model templates

The AWS Serverless Application Model (SAM) is supported by using SAM resources and the SAM encoder. All CloudFormation resources are valid SAM resources and they can be combined in the same template. The crucible.core/template function can be used to generate a template data structure for SAM resources.

Globals

AWS SAM supports global properties for functions and APIs. There is a two-arity version of build and encode in the SAM encoder that accepts a template and a globals object.

Example

In the example below, the second argument to encoding.sam/build can be omitted if globals are not used.

(ns crucible.sam-example
  (:require [crucible.aws.kinesis :as k]
            [crucible.aws.serverless.function :as f]
            [crucible.aws.serverless.function.event-source :as es]
            [crucible.aws.serverless.function.event-source.kinesis :as es.k]
            [crucible.aws.serverless.globals :as g]
            [crucible.core :refer [template xref]]
            [crucible.encoding.serverless :as encoding.sam]))

(-> {:stream-processor (f/function
                        {::f/handler "index.handler"
                         ::f/runtime "nodejs6.10"
                         ::f/code-uri "src/"
                         ::f/events {:stream {::es/type "Kinesis"
                                              ::es.k/properties {::es.k/stream (xref :stream :arn)
                                                                 ::es.k/starting-position "TRIM_HORIZON"}}}})
     :stream (k/stream {::k/shard-count 1})}
    (template "A function that processes data from a Kinesis stream.")
    (encoding.sam/build (g/globals {::g/function {::f/memory-size 1024
                                                  ::f/timeout 15}})))

CLI Support

Basic CLI support, intended for use with Leiningen, is provided in the crucible.encoding.main/-main function. Running this function will reload the namespaces available in the project, then enumerate any vars that have a metadata tag provided by the crucible.core/template function. These vars are then encoded into CloudFormation templates and exported to the local filesystem. They can then be used directly or uploaded to S3 for use with CloudFormation.

Flag -h for help. Templates are exported to target/templates by default, override with -o output-dir. Namespaces are converted to filesystem locations by replacing . characters with / characters.

I create a templates directory within my project and then add it as a source-path and crucible as a dependency to the dev profile. Then I can work at the repl, write tests for my templates and use this tooling without having my template code or crucible mixed with my source code.

demo-project is an example of setting up a project with crucible templates defined alongside the code. The templates can see the code to verify any references they might have, but not the other way round. Run lein templates in the demo project to generate templates.

:aliases {"templates" ["run" "-m" crucible.encoding.main]} 
:profiles {:dev {:source-paths ["templates"]
                 :dependencies [[crucible "0.10.0-SNAPSHOT"]]}}

Helping Out

Any help appreciated! Happy to receive any issues and pull requests. See CONTRIBUTING.md.

License

Distributed under the Eclipse Public License

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].