LoginSignup
3
3

More than 5 years have passed since last update.

sbtとLambdaを使ってCodeDeployを少しだけ自動化する

Last updated at Posted at 2015-09-30

前提

手順

  • Lambda側
    基本的にはAWSブログと同じなので差分だけ

    • 必要なRoleはExecution Roleだけ
    • Lambdaの設定は少し画面が変わっている
    • Lambda関数の設定
      • Select blueprintはSkip
      • Name, Descriptionは適当に。RuntimeはNode.js
      • CodeはAWSブログからコピー。必要に応じて修正する
      • Handlerはデフォルトのindex.handler
      • Roleは先ほど作ったRoleを設定
    • Event Sourceの設定
      • event sourceタブを選択
      • Event source typeをS3にして、Bucketを選ぶ
      • Event typeはObject Created

ここまでで、aws deploy pushすると勝手にデプロイしてくれるようになっているはず。

  • sbt側
    今回はsbtのタスクとして作成。

    • project/plugins.sbtに以下を追加
    libraryDependencies += "com.amazonaws" % "aws-java-sdk" % "1.10.20"
    
    libraryDependencies += "com.amazonaws" % "aws-java-sdk-s3" % "1.10.20"
    
    • build.sbtにタスクキーの設定を行う(SettingKeyは必要に応じて)
    lazy val bucketName = settingKey[String]("S3 Bucket Name")
    
    lazy val key = settingKey[String]("S3 Key Name")
    
    lazy val appName = settingKey[String]("CodeDeploy Application Name")
    
    lazy val dirName = settingKey[String]("Source directory name")
    
    lazy val push = taskKey[Unit]("push zip to S3 for CodeDeploy")
    
    bucketName := <Bucket Name>
    
    key := <S3 Key Name>
    
    appName := <Application Name>
    
    dirName := <デプロイするアプリケーションがあるディレクトリ>
    
    lazy val push = taskKey[Unit]("push zip to S3 for CodeDeploy")
    
    push := {
        DeployPush.push(dirName.value, bucketName.value, key.value, appName.value)
    }
    
    • project/DeployPush.scalaにコードを設定
    import com.amazonaws.regions._
    import com.amazonaws.services.codedeploy.AmazonCodeDeployClient
    import com.amazonaws.services.codedeploy.model._
    import com.amazonaws.services.s3.AmazonS3Client
    import com.amazonaws.services.s3.model.{PutObjectRequest, PutObjectResult}
    import sbt._
    
    object DeployPush {
        def push(dir: String, bucketName: String, key: String, appName: String): Unit = {
            val s3Client: AmazonS3Client = new AmazonS3Client()
            s3Client.setRegion(Region.getRegion(Regions.AP_NORTHEAST_1))
            val depClient: AmazonCodeDeployClient = new AmazonCodeDeployClient()
            verifySetting(depClient, appName)
    
            val zipFile: File = java.io.File.createTempFile(appName + "-", ".zip")
            IO.zip(sbt.Path.allSubpaths(new File(dir)), zipFile)
            val key: String = zipFile.getName
    
            val req: PutObjectRequest = new PutObjectRequest(bucketName, key, zipFile)
            println("put Object to S3 : " + zipFile.getName)
            val res: PutObjectResult = s3Client.putObject(req)
    
            val s3Loc: S3Location =
                new S3Location().
                withBucket(bucketName).
                withKey(key).
                withBundleType(BundleType.Zip).
                withETag(res.getETag)
            println("Location: " + s3Loc.getKey)
            println("Version: " + s3Loc.getVersion)
            println("ETag: " + s3Loc.getETag)
    
            val revLoc: RevisionLocation =
                new RevisionLocation().
                withRevisionType(RevisionLocationType.S3).
                withS3Location(s3Loc)
    
            val revReq: RegisterApplicationRevisionRequest =
                new RegisterApplicationRevisionRequest().
                withApplicationName(appName).
                withRevision(revLoc)
            depClient.registerApplicationRevision(revReq)
        }
    
        private def verifySetting(depClient: AmazonCodeDeployClient, appName: String) {
            val applications: ListApplicationsResult = depClient.listApplications
            if (!applications.getApplications.contains(appName)) {
                println("applicationName(" + appName + ") not found")
                throw new Exception()
            }
        }
    }
    

デプロイ手順

  • sbt clean assembly
  • こんな感じのディレクトリ階層を用意しておく(build.sbtでassemblyJarNameを設定して、該当ディレクトリに作成するようにすると少し幸せ)

    ├── appspec.yml
    ├── content
    │   └── hogehoge.jar
    └── scripts
    ├── start_server.sh
    └── stop_server.sh
    
  • sbt push

これでLambdaが気がついてデプロイされる

きになるところ

  • SettingKeyを"appName in Push"とかにしたかったんだけど、どうやって設定するのかよくわからない
3
3
0

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
3
3