Skip to content

Instantly share code, notes, and snippets.

@jeroenvandijk
Created May 26, 2020 10:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeroenvandijk/ed497efee4f9528d5cb09ca483702172 to your computer and use it in GitHub Desktop.
Save jeroenvandijk/ed497efee4f9528d5cb09ca483702172 to your computer and use it in GitHub Desktop.
(load-file "lib.bb")
(require '[spire.transport :refer [ssh]]
'[spire.module.shell :refer [shell]]
'[spire.default :refer [set-ssh! empty!]])
(defn ssh-into! [{:keys [InstanceId] :as ec2-instance}]
(let [ec2-instance (allow-ssh! ec2-instance)]
(set-ssh! {:host-string (str "ec2-user@" (:PublicDnsName ec2-instance))
:identity SSH_FILE
:passphrase "***"
:accept-host-key true})))
;; Run ssh commands
(defn start-ami [ami]
(let [ec2-instance (-> (aws :ec2 :run-instances
{:image-id ami
:region REGION
:profile PROFILE})
(get-in [:Instances 0]))]
(ssh-into! (:InstanceId ec2-instance))))
;; Install AMI
;; sudo yum install redhat-lsb-core -y
(defn create-image [ec2-instance-id & {:as opts}]
(let [res (aws :ec2 :create-image (merge {:output :json
:region REGION
:block-device-mapping []
:name "Base AMI with lsb"
:description "AMI for spire"
:reboot nil
:instance-id ec2-instance-id
:profile PROFILE } opts))]
(get-in res [:Reservations 0 :Instances 0])))
(defn terminate-instance [ec2-instance-id]
(aws :ec2 :terminate-instances {:output :json
:region REGION
:instance-id ec2-instance-id
:profile PROFILE }))
#!/usr/bin/env bb
(load-file "script/aws/ec2/lib.bb")
(println (:PublicDnsName (allow-ssh! {:InstanceId "i-0f376810b9bce4070"})))
(require '[clojure.java.shell :as sh]
'[clojure.string :as str])
(def PROFILE "dev1")
(def REGION "eu-central-1")
(def SSH_FILE "***")
(defn format-arg [arg]
(cond
(symbol? arg) (str arg)
(seq? arg) (let [f (first arg)]
(if (and (symbol? f) (= "unquote" (name f)))
(second arg)
arg))
(nil? arg) nil
:else (pr-str arg)))
(defn generate-command [args]
(str/join " " (mapv format-arg args)))
(defn exec-command [args]
(sh/sh "bash" "-c" (generate-command args)))
(defn kw->str [x]
(if (keyword? x)
(name x)
(str x)))
;; Spire and babashka use different json libs
(defn parse-json [s]
(or (when-let [f (resolve 'cheshire.core/parse-string)]
(f s true))
(when-let [f (resolve 'clojure.data.json/read-str)]
(f s :key-fn keyword))))
(defn aws [service action {:keys [output] :as args :or {output :json}}]
(let [args (assoc args :output output)
cmd (into ['aws (name service) (name action)] (mapcat (fn [[k v]]
[(symbol (str "--" (name k)))
(kw->str v)])
args))
;_ (println (generate-command cmd))
res (exec-command cmd)]
(if (zero? (:exit res))
(if (= output :json)
(parse-json (:out res))
(:out res))
(throw (ex-info (str "Failure" (:out res) (:err res)) res)))))
(defn describe-instance [ec2-instance-id & {:as opts}]
(let [res (aws :ec2 :describe-instances (merge {:output :json
:region REGION
:instance-ids ec2-instance-id
:profile PROFILE } opts))]
(get-in res [:Reservations 0 :Instances 0])))
(defn allow-ssh! [{:keys [InstanceId] :as ec2-instance}]
(if-let [availability-zone (get-in ec2-instance [:Placement :AvailabilityZone])]
(do (aws :ec2-instance-connect :send-ssh-public-key
{:ssh-public-key (str "file://" SSH_FILE ".pub")
:instance-id InstanceId
:availability-zone availability-zone
:instance-os-user "ec2-user"
:region REGION
:profile PROFILE})
ec2-instance)
(allow-ssh! (describe-instance InstanceId))))
#!/usr/bin/env bash
HOSTNAME=$(bb script/aws/ec2/allow-ssh.bb)
ssh ec2-user@${HOSTNAME}
#!/usr/bin/env spire
(load-file "aws/ec2/lib.spire")
(ssh-into! {:InstanceId "i-0f376810b9bce4070"})
(require '[spire.module.upload :refer [upload]])
(upload {:dest "deployment"
;; Why does it need to be a relative path?
:src "deployment/docker"
:recurse true
:preserve true
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment