Skip to content

Instantly share code, notes, and snippets.

@dogenpunk
Forked from olivergeorge/Makefile
Created January 10, 2019 13:28
Show Gist options
  • Save dogenpunk/d9dd07afd4992546a1cd9ef4ade8260f to your computer and use it in GitHub Desktop.
Save dogenpunk/d9dd07afd4992546a1cd9ef4ade8260f to your computer and use it in GitHub Desktop.
Devops tools for simple Datomic Ions app
{:paths ["src" "resources"]
:deps {com.datomic/ion {:mvn/version "0.9.28"}
org.clojure/clojure {:mvn/version "1.9.0"}}
:mvn/repos {"datomic-cloud" {:url "s3://datomic-releases-1fc2183a/maven/releases"}}
:aliases
{:dev {:extra-paths ["dev"]
:extra-deps {org.clojure/clojure {:mvn/version "1.10.0"}
com.datomic/client-cloud {:mvn/version "0.8.71"}
com.datomic/ion-dev {:mvn/version "0.9.186"}
com.cognitect.aws/api {:mvn/version "0.8.171"}
com.cognitect.aws/endpoints {:mvn/version "1.1.11.479"}
com.cognitect.aws/cloudformation {:mvn/version "684.2.377.0"}
com.cognitect.aws/autoscaling {:mvn/version "668.2.364.0"}}}}}
(ns devops
(:require [datomic.ion.dev :as ion-dev]
[cognitect.aws.client.api :as aws]
[clojure.edn :as edn]
[clojure.java.io :as io]
[clojure.main :as cljmain]))
(def ion-config (edn/read-string (slurp (io/resource "datomic/ion-config.edn"))))
(defn where
[ms kvs]
(filter #(= kvs (select-keys % (keys kvs))) ms))
(defn find-where
[ms kvs]
(first (where ms kvs)))
(defn push
[args]
(let [push-args (select-keys args [:creds-profile :region :uname])]
(ion-dev/push push-args)))
(defn deploy
[args]
(let [deploy-args (select-keys args [:creds-profile :region :uname :group])]
(ion-dev/deploy deploy-args)))
(defn deploy-status [args]
(let [deploy-status-args (select-keys args [:execution-arn])]
(ion-dev/deploy-status deploy-status-args)))
(defn release
"Do push and deploy of app. Supports stable and unstable releases. Returns when deploy finishes running."
[req args]
(let [push-data (push args)
primary-group (-> (aws/client {:api :cloudformation})
(aws/invoke {:op :DescribeStacks :request req})
(get-in [:Stacks 0 :Outputs])
(find-where {:OutputKey "CodeDeployDeploymentGroup"})
:OutputValue)
deploy-args (merge {:group primary-group} args (select-keys push-data [:rev]))
deploy-data (deploy deploy-args)]
(loop []
(let [status-data (deploy-status deploy-data)]
(case (:code-deploy-status status-data)
"RUNNING" (do (Thread/sleep 5000) (recur))
"SUCCEEDED" status-data
(throw (ex-info "ion-release did not succeed" status-data)))))))
(defn autoscaling-groups [req]
(let [ComputeStackName (-> (aws/client {:api :cloudformation})
(aws/invoke {:op :DescribeStacks :request req})
(get-in [:Stacks 0 :Outputs])
(find-where {:OutputKey "CodeDeployDeploymentGroup"})
:OutputValue)
ComputeStackResources (-> (aws/client {:api :cloudformation})
(aws/invoke {:op :DescribeStackResources :request {:StackName ComputeStackName}})
:StackResources)
TxAutoScalingGroup (:PhysicalResourceId (find-where ComputeStackResources {:LogicalResourceId "TxAutoScalingGroup"}))
BastionAutoScalingGroup (:PhysicalResourceId (find-where ComputeStackResources {:LogicalResourceId "BastionAutoScalingGroup"}))]
{:TxAutoScalingGroup TxAutoScalingGroup
:BastionAutoScalingGroup BastionAutoScalingGroup}))
(defn cloud-off [req]
(let [{:keys [TxAutoScalingGroup BastionAutoScalingGroup]} (autoscaling-groups req)
autoscaling (aws/client {:api :autoscaling})]
(aws/invoke autoscaling {:op :UpdateAutoScalingGroup :request {:AutoScalingGroupName TxAutoScalingGroup :MinSize 0}})
(aws/invoke autoscaling {:op :SetDesiredCapacity :request {:AutoScalingGroupName TxAutoScalingGroup :DesiredCapacity 0}})
(aws/invoke autoscaling {:op :SetDesiredCapacity :request {:AutoScalingGroupName BastionAutoScalingGroup :DesiredCapacity 0}})))
(defn cloud-on [req]
(let [{:keys [TxAutoScalingGroup BastionAutoScalingGroup]} (autoscaling-groups req)
autoscaling (aws/client {:api :autoscaling})]
(aws/invoke autoscaling {:op :UpdateAutoScalingGroup :request {:AutoScalingGroupName TxAutoScalingGroup :MinSize 1}})
(aws/invoke autoscaling {:op :SetDesiredCapacity :request {:AutoScalingGroupName TxAutoScalingGroup :DesiredCapacity 1}})
(aws/invoke autoscaling {:op :SetDesiredCapacity :request {:AutoScalingGroupName BastionAutoScalingGroup :DesiredCapacity 1}})))
(defn -main [& args]
(let [cmd (first args)
edn (edn/read-string (second args))]
(try
(println
(case cmd
"release" (release {:StackName (:app-name ion-config)} edn)
"cloud-on" (cloud-on {:StackName (:app-name ion-config)})
"cloud-off" (cloud-off {:StackName (:app-name ion-config)})))
(flush)
(System/exit 0)
(catch Exception e
(println (-> e Throwable->map cljmain/ex-triage cljmain/ex-str))
(System/exit 1))
(finally
(shutdown-agents)))))
{:allow []
:lambdas {}
:app-name "XXX"}
cloud-on:
clojure -A:dev -m devops cloud-on
cloud-off:
clojure -A:dev -m devops cloud-off
release-rev:
clojure -A:dev -m devops release '{}'
release-dev:
clojure -A:dev -m devops release '{:uname "dev"}'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment