Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
(:require [ :as json]))
(defn apply-stack-fn
[create-fn update-fn]
(fn apply-stack
(create-fn payload)
(catch AlreadyExistsException e
(update-fn payload)))))
(defn expand-params
(fn [[key value]]
(zipmap [:parameter-key :parameter-value]
[key value]))
(defn deploy-stack-fn
(fn deploy-stack
[stack-name template-hash params-hash]
(apply-fn :stack-name stack-name
:template-body (json/write-str template-hash)
:parameters (expand-params params-hash))))
(:require [ :as factory]
[ :as cloudformation])) ; side-effecty AWS SDK
(def apply-stack
(factory/apply-stack-fn cloudformation/create-stack
(def deploy-stack
(factory/deploy-stack-fn apply-stack))
(:require [clojure.test :refer :all]
[ :as factory]))
(deftest apply-stack-fn-test
(testing "applies create-fn with payload"
(let [payload {:stack-name "example"}
create-fn (spy)
update-fn (spy)]
((factory/apply-stack-fn create-fn update-fn) payload)
(is (called? (create-fn payload)))))
(testing "when stack already exists"
(testing "applies update-fn with payload"
(let [payload {:stack-name "example"}
create-fn (fn [& args] (throw (AlreadyExistsException.)))
update-fn (spy)]
((factory/apply-stack-fn create-fn update-fn) payload)
(is (called? (update-fn payload)))))))
(deftest deploy-stack-fn
(testing "applies apply-fn with constructed payload"
(let [apply-fn (spy)]
((factory/deploy-stack-fn apply-fn) "example"
{:Description "Example"}
{:port "8080"})
(is (called? (apply-fn {:stack-name "example"
:template-body "{\"Description\":\"Example\"}"
:parameters [{:parameter-key :port
:parameter-value "8080"}]}))))))
// example/factory/aws/cloudformation.js
module.exports.applyStackFunc = function(createFunc, updateFunc){
return function(payload) {
try {
return createFunc(payload);
} catch (e if e instanceof AlreadyExistsException) {
return updateFunc(payload);
module.exports.deployStackFunc = function(applyFunc) {
return function(stackName, template, params) {
return applyFunc({
stackName: stackName,
templateBody: JSON.stringify(template),
parameters: expandParams(params)
// example/aws/cloudformation.js
var factory = require('example/factory/aws/cloudformation')
, AWS = require('aws-sdk')
var cloudformation = new AWS.CloudFormation();
module.exports.applyStack = factory.applyStackFunc(
module.exports.deployStack = factory.deployStackFunc(
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.