LoginSignup
1
1

More than 5 years have passed since last update.

amazonicaとAWS Lambdaで定期的にEBSのスナップショットを作成する

Last updated at Posted at 2015-12-21

この記事はClojure Advent Calendar 2015の21日目の記事です。

ClojureとAWS Lambdaを使って何かできないかを考えるのがマイブームなのですが、amazonicaを使うとAWSのリソースに簡単にアクセスできるのが分かったので、amazonicaを使って定期的にEBSスナップショットを作成するLambda Functionを作ってみます。

EBSスナップショット関連のamazonicaの関数

amazonicaのgithubには代表的な関数の呼び出し方の例は記載されていますが、包括的なリファレンスがどこにあるのか分からない!ということで、Lambda Functionを作る前に、replであたりをつけます。

EBSスナップショットを作成。

(def cred {:access-key "YOUR_ACCESS_KEY"
           :secret-key "YOUR_SECRET_KEY"
           :endpoint   "ap-northeast-1"})

(amazonica.aws.ec2/create-snapshot cred :volume-id "vol-a1b2c3d4" 
                                        :description "vol-a1b2c3d4-snapshot-2015-12-21-16-50")

スナップショットにタグをつける。

(amazonica.aws.ec2/create-tags cred :resources ["snap-a1b2c3d4"]
                                    :tags [{:key "Name"
                                            :value "vol-a1b2c3d4-snapshot-2015-12-21-16-50"}])

スナップショットを削除。

(amazonica.aws.ec2/delete-snapshot cred :snapshot-id "snap-a1b2c3d4")

Lambda Functionを登録してみる。

とりあえず意図したとおりにLambda Functionの定期実行でスナップショットをとれるかどうかを確認するため、AWSのアクセスキーや対象のVolume IDはハードコードしてしまってLambda Functionを登録してみます。

; src/lambdabackup/ec2.clj
(ns lambdabackup.ec2
  (:gen-class
   :implements [com.amazonaws.services.lambda.runtime.RequestStreamHandler])
  (:require [clojure.java.io :as io]
            [amazonica.aws.ec2 :as ec2]))

(def cred {:access-key "YOUR_ACCESS_KEY"
           :secret-key "YOUR_SECRET_KEY"
           :endpoint   "ap-northeast-1"})

(def volume-id "vol-a1b2c3d4")

(defn -handleRequest [this is os context]
  (let [name "test-backup"
        snapshot (ec2/create-snapshot cred
                                      :volume-id volume-id
                                      :description name)
        snapshot-id (get-in snapshot [:snapshot :snapshot-id])]
    (ec2/create-tags cred
                     :resources [snapshot-id]
                     :tags [{:key "Name" :value name}])
    (let [w (io/writer os)]
      (.write w snapshot-id)
      (.flush w))))

project.cljはこんな感じ。

(defproject lambdabackup "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.7.0"]
                 [com.amazonaws/aws-lambda-java-core "1.0.0"]
                 [amazonica "0.3.41"]]
  :aot :all)

standaloneなjarを作成。

$ lein ubarjar

jarをアップロードし、Lambda Functionを新規作成。--roleこの記事を書いたときに作ったRoleを再利用しました。

$ aws lambda create-function --function-name ebs-create-snapshot --handler lambdabackup.ec2::handleRequest --runtime java8 --memory 512 --timeout 60 --role arn:aws:iam::AWS_ACCOUNT_ID:sandbox-lambda-exec-role --zip-file fileb://./target/lambdabackup-0.1.0-SNAPSHOT-standalone.jar

jarを更新する場合には、

$ lein ubarjar
$ aws lambda update-function-code --function-name ebs-create-snapshot --zip-file fileb://./target/lambdabackup-0.1.0-SNAPSHOT-standalone.jar

AWS LambdaのWebコンソールでテストを実行したところ、スナップショットを作成することはできているようなので、同じくWebコンソールのLambda > Functions > FUNCTION_NAME > Scheduled Eventを登録しました。(本当はCLIでやりたかったが方法がぱっと分からず。)

TODO

Clojure力とAWS Lambda力が低すぎて、アドベントカレンダーの期日までには解決できなかったことがたくさん残っています。

  • AWSのアクセストークンをハードコードしているのは何とかならないか?
    • Lambdaを実行しているRoleに権限を付与すれば消せるだろうか?
  • Volume IDをハードコードしているのは何とかならないか?
    • LambdaのScheduled Eventに任意の引数を含められれば消せそうだが、そういう機能はなさそう。
  • 毎回com.amazonaws.services.lambda.runtime.RequestStreamHandlerを実装するは無駄なので、もう少し省エネでハンドラーを書きたい。
  • スナップショット作成に失敗した場合の処理をなんとかしたい。
  • 保持するスナップショット数を一定の世代数に制限して、不要になったスナップショットを削除するLambda Functionもamazonicaで実装したい。

参考URL

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1