Skip to content

Commit

Permalink
Upgrade copier to AWS SDK v2
Browse files Browse the repository at this point in the history
  • Loading branch information
mchv authored and Joemgru committed Dec 11, 2024
1 parent 00cf3c3 commit d39861b
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 46 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ lazy val imageCopier = (project in file("imageCopier"))
Universal / topLevelDirectory := None,
Universal / packageName := normalizedName.value,
libraryDependencies ++= Seq(
"com.amazonaws" % "aws-java-sdk-ec2" % awsV1SdkVersion,
"software.amazon.awssdk" % "ec2" % awsV2SdkVersion,
"com.amazonaws" % "aws-lambda-java-core" % "1.2.3",
"com.amazonaws" % "aws-lambda-java-events" % "3.14.0",
"io.circe" %% "circe-parser" % circeVersion,
Expand Down
91 changes: 48 additions & 43 deletions imageCopier/src/main/scala/com/gu/imageCopier/AmiActions.scala
Original file line number Diff line number Diff line change
@@ -1,74 +1,77 @@
package com.gu.imageCopier

import com.amazonaws.AmazonClientException
import com.amazonaws.services.ec2.AmazonEC2
import com.amazonaws.services.ec2.model._
import software.amazon.awssdk.core.exception.SdkServiceException
import software.amazon.awssdk.services.ec2.Ec2Client
import software.amazon.awssdk.services.ec2.model._
import com.gu.imageCopier.attempt.{Attempt, AwsSdkFailure}
import scala.jdk.CollectionConverters._

object AmiActions {
def copyAmi(amiEvent: AmiEvent, kmsArn: String)(implicit
ec2Client: AmazonEC2
ec2Client: Ec2Client
): Attempt[String] = {
Attempt.catchNonFatal {
val request = new CopyImageRequest()
.withSourceImageId(amiEvent.sourceAmi)
.withSourceRegion(amiEvent.sourceRegion)
.withKmsKeyId(kmsArn)
.withEncrypted(true)
.withName(amiEvent.name)
.withDescription(amiEvent.description)
val request = CopyImageRequest.builder
.sourceImageId(amiEvent.sourceAmi)
.sourceRegion(amiEvent.sourceRegion)
.kmsKeyId(kmsArn)
.encrypted(true)
.name(amiEvent.name)
.description(amiEvent.description)
.build()
println(s"Copying AMI with request $request")
val result = ec2Client.copyImage(request)
println(s"New AMI is ${result.getImageId}")
result.getImageId
} { case ace: AmazonClientException =>
val response = ec2Client.copyImage(request)
println(s"New AMI is ${response.imageId}")
response.imageId
} { case ace: SdkServiceException =>
AwsSdkFailure(ace)
}
}

def tagAmi(amiEvent: AmiEvent, encryptedTagValue: String, newAmiId: String)(
implicit ec2Client: AmazonEC2
): Attempt[CreateTagsResult] = {
implicit ec2Client: Ec2Client
): Attempt[CreateTagsResponse] = {
Attempt.catchNonFatal {
val tags = amiEvent.tags ++ Map(
"Encrypted" -> encryptedTagValue,
"CopiedFromAMI" -> amiEvent.sourceAmi
)
val awsTags = tags.map { case (k, v) =>
new Tag(k, v)
Tag.builder.key(k).value(v).build()
}.toList
val request = new CreateTagsRequest()
.withResources(newAmiId)
.withTags(awsTags.asJava)
val request = CreateTagsRequest.builder
.resources(newAmiId)
.tags(awsTags.asJava)
.build()
println(s"Creating tags with request $request")
val result = ec2Client.createTags(request)
val response = ec2Client.createTags(request)
println(s"Succeeded")
result
} { case ace: AmazonClientException =>
response
} { case ace: SdkServiceException =>
AwsSdkFailure(ace)
}
}

def getImagesAndEbsSnapshots(
amis: List[Ami]
)(implicit ec2Client: AmazonEC2): Attempt[List[(String, List[String])]] = {
)(implicit ec2Client: Ec2Client): Attempt[List[(String, List[String])]] = {
if (amis.nonEmpty) {
Attempt.catchNonFatal {
val request = new DescribeImagesRequest()
.withImageIds(amis.map(_.id).asJava)
val request = DescribeImagesRequest.builder
.imageIds(amis.map(_.id).asJava)
.build()
println(
s"Getting list of images and EBS snapshots with request $request"
)
val result = ec2Client.describeImages(request)
println(s"Raw result: $result")
val ids = result.getImages.asScala.map { image =>
image.getImageId -> image.getBlockDeviceMappings.asScala.toList
.flatMap(mapping => Option(mapping.getEbs).map(_.getSnapshotId))
val response = ec2Client.describeImages(request)
println(s"Raw result: $response")
val ids = response.images.asScala.map { image =>
image.imageId -> image.blockDeviceMappings.asScala.toList
.flatMap(mapping => Option(mapping.ebs).map(_.snapshotId))
}
println(s"List of AMIs and snapshots: $ids")
ids.toList
} { case ace: AmazonClientException =>
} { case ace: SdkServiceException =>
AwsSdkFailure(ace)
}
} else {
Expand All @@ -78,30 +81,32 @@ object AmiActions {

def deregisterAmi(
amiId: String
)(implicit ec2Client: AmazonEC2): Attempt[String] = {
)(implicit ec2Client: Ec2Client): Attempt[String] = {
Attempt.catchNonFatal {
val request = new DeregisterImageRequest()
.withImageId(amiId)
val request = DeregisterImageRequest.builder
.imageId(amiId)
.build()
println(s"Deregistering AMI with request $request")
val result = ec2Client.deregisterImage(request)
val response = ec2Client.deregisterImage(request)
println(s"Deregistered")
amiId
} { case ace: AmazonClientException =>
} { case ace: SdkServiceException =>
AwsSdkFailure(ace)
}
}

def deleteSnapshot(
snapshotId: String
)(implicit ec2Client: AmazonEC2): Attempt[String] = {
)(implicit ec2Client: Ec2Client): Attempt[String] = {
Attempt.catchNonFatal {
val request = new DeleteSnapshotRequest()
.withSnapshotId(snapshotId)
val request = DeleteSnapshotRequest.builder
.snapshotId(snapshotId)
.build
println(s"Deleting snapshot with request $request")
val result = ec2Client.deleteSnapshot(request)
val response = ec2Client.deleteSnapshot(request)
println(s"Deleted snapshot")
snapshotId
} { case ace: AmazonClientException =>
} { case ace: SdkServiceException =>
AwsSdkFailure(ace)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.gu.imageCopier

import com.amazonaws.services.lambda.runtime.Context
import com.amazonaws.services.lambda.runtime.events.SNSEvent
import com.amazonaws.services.ec2.{AmazonEC2, AmazonEC2ClientBuilder}
import software.amazon.awssdk.services.ec2.Ec2Client
import com.gu.imageCopier.attempt.{
Attempt,
ConfigurationFailure,
Expand All @@ -16,7 +16,7 @@ import scala.concurrent.duration._

object LambdaEntrypoint {
val configuration: Configuration = Configuration.fromEnvironment
implicit val ec2Client: AmazonEC2 = AmazonEC2ClientBuilder.defaultClient()
implicit val ec2Client: Ec2Client = Ec2Client.builder.build()
}

class LambdaEntrypoint {
Expand Down

0 comments on commit d39861b

Please sign in to comment.