Skip to content

Instantly share code, notes, and snippets.

@tkawachi
Last active August 29, 2015 14:23
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tkawachi/7c2d2a81a84dec763723 to your computer and use it in GitHub Desktop.
Save tkawachi/7c2d2a81a84dec763723 to your computer and use it in GitHub Desktop.
import java.nio.charset.Charset
import java.text.SimpleDateFormat
import java.util.Date
import com.amazonaws.services.elasticbeanstalk.AWSElasticBeanstalkClient
import com.amazonaws.services.elasticbeanstalk.model.{UpdateEnvironmentRequest, S3Location, CreateApplicationVersionRequest}
import com.amazonaws.services.s3.AmazonS3Client
import com.amazonaws.services.s3.model.Region
import com.typesafe.sbt.packager.docker.DockerPlugin
import com.typesafe.sbt.packager.docker.DockerPlugin.autoImport.{Docker, dockerExposedPorts}
import com.typesafe.sbt.packager.universal.UniversalPlugin
import com.typesafe.sbt.packager.universal.UniversalPlugin.autoImport.{stage, stagingDirectory}
import play.sbt.Play
import play.sbt.PlayImport.PlayKeys
import sbt._, Keys._
object EbDockerPlugin extends AutoPlugin {
object autoImport {
val EbDocker = config("ebdocker") extend Docker
val ebDockerContainerPort = settingKey[Int]("Container port for Elastic beanstalk with Docker")
val ebDockerrunVersion = settingKey[Int]("AWSEBDockerrunVersion in Dockerrun.aws.json")
val ebDockerOutputFile = settingKey[File]("Output file of Elastic beanstalk with Docker")
val ebDockerVersionLabel = taskKey[String]("Create a version label")
val ebDockerApplicationName = settingKey[String]("Elastic beanstalk with Docker application name")
val ebDockerS3Bucket = settingKey[String]("S3 bucket name to store Elastic beanstalk application files")
val ebDockerEnvironmentId = settingKey[Option[String]]("Elastic beanstalk Environment Id to deploy")
val ebDockerRegion = settingKey[Region]("Elastic beanstalk region")
}
import autoImport._
override def requires = Play && DockerPlugin && UniversalPlugin
override def trigger = allRequirements
final val ChangeMe: String = "ChangeMe"
val ebDockerDefaultSettings = Seq(
ebDockerContainerPort := PlayKeys.playDefaultPort.value,
dockerExposedPorts := (dockerExposedPorts.value :+ ebDockerContainerPort.value).distinct,
ebDockerOutputFile := target.value / (name.value + "-" + version.value + ".zip"),
ebDockerApplicationName := ChangeMe,
ebDockerS3Bucket := ChangeMe,
ebDockerEnvironmentId := None,
ebDockerRegion := Region.US_Standard,
packageBin in EbDocker := {
// run docker:stage
(stage in Docker).value
val stageDir = (stagingDirectory in Docker).value
// Write Dockerrun.aws.json
writeDockerrunAwsJson(ebDockerrunVersion.value, ebDockerContainerPort.value, stageDir)
// Create a zip file
// Using an external zip command.
val zipFile: File = ebDockerOutputFile.value
val zipContents: Array[String] = stageDir.listFiles().flatMap(_.relativeTo(stageDir)).map(_.toString)
Process(Seq("zip", "-q", "-r", zipFile.absolutePath) ++ zipContents, stageDir) ! streams.value.log
val printPath = zipFile.relativeTo(baseDirectory.value).getOrElse(zipFile.absolutePath)
streams.value.log.info(s"Upload $printPath to Elastic beanstalk")
zipFile
},
Keys.`package` in EbDocker := (packageBin in EbDocker).value,
ebDockerVersionLabel := {
val fmt = new SimpleDateFormat("yyyyMMddHHmmss")
val now = new Date()
val nowString = fmt.format(now)
val gitTag =
(Process(Seq("git", "describe", "--always"), baseDirectory.value) !! streams.value.log)
.stripLineEnd
Seq(gitTag, nowString).mkString("_")
},
publish in EbDocker := {
val zipFile: File = (packageBin in EbDocker).value
val versionLabel: String = ebDockerVersionLabel.value
val s3Key = s"$versionLabel/${zipFile.name}"
val s3Client = new AmazonS3Client()
s3Client.putObject(ebDockerS3Bucket.value, s3Key, zipFile)
val ebClient = new AWSElasticBeanstalkClient()
ebClient.withRegion(ebDockerRegion.value.toAWSRegion)
val createRequest = new CreateApplicationVersionRequest()
.withApplicationName(ebDockerApplicationName.value)
.withVersionLabel(versionLabel)
.withSourceBundle(new S3Location(ebDockerS3Bucket.value, s3Key))
ebClient.createApplicationVersion(createRequest)
streams.value.log.info(s"Published as version $versionLabel")
ebDockerEnvironmentId.value.foreach { envId =>
val updateRequest = new UpdateEnvironmentRequest()
.withEnvironmentId(envId)
.withVersionLabel(versionLabel)
ebClient.updateEnvironment(updateRequest)
streams.value.log.info(s"Environment $envId has been updated to $versionLabel")
}
},
ebDockerrunVersion := 1
)
override lazy val projectSettings = ebDockerDefaultSettings
private def writeDockerrunAwsJson(ebDockerrunVersion: Int, ebContainerPort: Int, stagingDir: File): Unit = {
val json =
s"""{
| "AWSEBDockerrunVersion": "$ebDockerrunVersion",
| "Ports": [{
| "ContainerPort": "$ebContainerPort"
| }]
|}
|""".stripMargin
val dockerrun: File = new File(stagingDir, "Dockerrun.aws.json")
IO.write(dockerrun, json, Charset.forName("UTF-8"))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment