
com.atlassian.maven.plugins.aws.it.Provisioner.kt Maven / Gradle / Ivy
package com.atlassian.maven.plugins.aws.it
import com.amazonaws.services.cloudformation.AmazonCloudFormation
import com.amazonaws.services.cloudformation.AmazonCloudFormationClientBuilder
import com.amazonaws.services.cloudformation.model.*
import com.amazonaws.services.ec2.AmazonEC2
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder
import com.amazonaws.services.ec2.model.CreateKeyPairRequest
import com.amazonaws.services.ec2.model.DescribeInstancesRequest
import com.amazonaws.services.ec2.model.KeyPair
import com.amazonaws.services.ec2.model.Reservation
import com.google.gson.Gson
import org.apache.commons.io.FileUtils.readFileToString
import org.apache.commons.io.FileUtils.writeStringToFile
import org.apache.maven.plugin.logging.Log
import java.io.File
import java.util.UUID.randomUUID
class Provisioner(
private val awsRegion: String,
private val cloudFormationTemplate: File,
private val buildDirectory: File,
private val log: Log
) {
fun provision() {
val id = "aws-integration-test-plugin-" + randomUUID().toString()
val keyPairName = id
val stackName = id
val keyPair = createEc2Client().createKeyPair(CreateKeyPairRequest(keyPairName)).keyPair
writeKeyPairToFile(keyPairName, keyPair)
provisionStack(keyPairName, getCloudFormationTemplate(), stackName)
writeStackResources(stackName, keyPairName)
}
private fun writeStackResources(stackName: String, keyPairName: String) {
val ec2 = createEc2Client()
val cloudFormation = createCloudFormationClient()
val stacks = cloudFormation.listStackResources(
ListStackResourcesRequest()
.withStackName(stackName))
val ec2InstanceIds = stacks.stackResourceSummaries
.filter({ it.resourceType == "AWS::EC2::Instance" })
.map({ it.physicalResourceId })
val instances = ec2.describeInstances(DescribeInstancesRequest().withInstanceIds(ec2InstanceIds))
.reservations
.flatMap(Reservation::getInstances)
val stackInfo = StackInfo(
awsRegion,
stackName,
keyPairName,
instances
)
writeStackJson(stackInfo)
}
private fun provisionStack(keyPairName: String, cloudFormationTemplateBody: String, stackName: String) {
val cloudFormationClient = createCloudFormationClient()
val parameters = listOf(
Parameter().withParameterKey("KeyName").withParameterValue(keyPairName)
)
cloudFormationClient.createStack(
CreateStackRequest()
.withTags(listOf(
Tag().withKey("Name").withValue("aws-integration-test-plugin"),
Tag().withKey("service_name").withValue("aws-integration-test-plugin"),
Tag().withKey("business_unit").withValue("Engineering-Server"),
Tag().withKey("resource_owner").withValue("mkwidzinski")
))
.withStackName(stackName)
.withTemplateBody(cloudFormationTemplateBody)
.withParameters(parameters)
)
waitForStackStartup(stackName)
}
private fun waitForStackStartup(stackName: String) {
val cloudFormation = createCloudFormationClient()
while (true) {
val result = cloudFormation.describeStacks(DescribeStacksRequest().withStackName(stackName))
val status = result.stacks[0].stackStatus
when (status) {
"CREATE_IN_PROGRESS" -> {
log.info("Waiting for stack $stackName startup, current status: $status")
Thread.sleep(5000)
}
"CREATE_COMPLETE" -> {
log.info("Stack $stackName successfully created")
return
}
else -> throw RuntimeException("Stack $stackName creation failed, status: $status")
}
}
}
private fun writeStackJson(stackInfo: StackInfo) {
val json = Gson().toJson(stackInfo)
writeStringToFile(File(buildDirectory, "stack.json"), json)
}
private fun getCloudFormationTemplate(): String {
return readFileToString(cloudFormationTemplate)
}
private fun writeKeyPairToFile(keyPairName: String, keyPair: KeyPair) {
val file = File(buildDirectory, "$keyPairName.pem")
writeStringToFile(file, keyPair.keyMaterial)
log.info("Private key location: ${file.absolutePath}")
}
private fun createEc2Client(): AmazonEC2 {
return AmazonEC2ClientBuilder.standard()
.withRegion(awsRegion)
.build()
}
private fun createCloudFormationClient(): AmazonCloudFormation {
return AmazonCloudFormationClientBuilder.standard()
.withRegion(awsRegion)
.build()
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy