Skip to content

Commit 82d5986

Browse files
twarnockMark Beacom
authored andcommitted
Cross region support for copy_and_split. gen_terraform fixes (#43)
1 parent 6d7cb36 commit 82d5986

7 files changed

Lines changed: 90 additions & 75 deletions

File tree

cloudendure/cloudendure.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,7 @@ def gen_terraform(
743743
# Access the image
744744
image: str = _ec2_res.Image(image_id)
745745
base_template_data = {
746+
"image_id": image_id,
746747
"name": name,
747748
"keypair": keypair,
748749
"uppercase_name": name.upper(),
@@ -771,9 +772,11 @@ def gen_terraform(
771772

772773
drive_template_data = {
773774
**base_template_data,
775+
"drive": drive,
774776
"drive_name": drive_name,
777+
"snapshot_id": drive_info.get("SnapshotId", ""),
775778
"volume_size": drive_info.get("VolumeSize", "2"),
776-
"volume_type": drive_info.driveget("VolumeType", "gp2"),
779+
"volume_type": drive_info.get("VolumeType", "gp2"),
777780
}
778781

779782
drive_template = TerraformTemplate.VOLUME_TEMPLATE.format(

cloudendure/templates.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class TerraformTemplate:
5858
type = "{volume_type}"
5959
size = {volume_size}
6060
encrypted = true
61-
snapshot_id = "{drive_info.get('SnapshotId', '')}"
61+
snapshot_id = "{snapshot_id}"
6262
6363
tags = {{
6464
Name = "ap-vol-{name}-{drive_name}-sg"

step/lambdas.tf

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,12 @@ resource "aws_lambda_function" "lambda_split_image" {
8585
depends_on = ["data.archive_file.lambdas"]
8686
}
8787

88-
resource "aws_lambda_function" "lambda_image_cleanup" {
89-
filename = "lambdas.zip"
90-
function_name = "tf-image-cleanup"
91-
role = "${aws_iam_role.iam_for_lambda.arn}"
92-
handler = "image_cleanup.lambda_handler"
93-
source_code_hash = "${data.archive_file.lambdas.output_base64sha256}"
94-
runtime = "python3.7"
95-
depends_on = ["data.archive_file.lambdas"]
96-
}
88+
// resource "aws_lambda_function" "lambda_image_cleanup" {
89+
// filename = "lambdas.zip"
90+
// function_name = "tf-image-cleanup"
91+
// role = "${aws_iam_role.iam_for_lambda.arn}"
92+
// handler = "image_cleanup.lambda_handler"
93+
// source_code_hash = "${data.archive_file.lambdas.output_base64sha256}"
94+
// runtime = "python3.7"
95+
// depends_on = ["data.archive_file.lambdas"]
96+
// }

step/lambdas/copy_image.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
ec2_client = boto3.client("ec2")
1515

1616
# {
17-
# "ami_id" : "ami-123456",
18-
# "kms_id" : "GUID",
19-
# "wait_time": 60
17+
# "ami_id" : "ami-123456",
18+
# "kms_id" : "GUID",
19+
# "wait_time" : 60,
20+
# "region" : "optional destination region"
2021
# }
2122

2223

@@ -26,13 +27,19 @@ def lambda_handler(event: Dict[str, Any], context: Any) -> str:
2627

2728
ami_id: str = event["ami_id"]
2829
kms_id: str = event["kms_id"]
29-
30-
new_image: Dict[str, Any] = ec2_client.copy_image(
31-
SourceImageId=ami_id,
32-
SourceRegion=os.environ.get("AWS_REGION", "us-east-1"),
33-
Name=f"copied-{ami_id}",
34-
Encrypted=True,
35-
KmsKeyId=kms_id,
36-
)
30+
region: str = event.get("region")
31+
if region:
32+
ec2_client = boto3.client("ec2", region)
33+
try:
34+
new_image: Dict[str, Any] = ec2_client.copy_image(
35+
SourceImageId=ami_id,
36+
SourceRegion=os.environ.get("AWS_REGION", "us-east-1"),
37+
Name=f"copied-{ami_id}",
38+
Encrypted=True,
39+
KmsKeyId=kms_id,
40+
)
41+
except Exception as e:
42+
print(e)
43+
return ""
3744

3845
return new_image.get("ImageId", "")

step/lambdas/get_copy_status.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
# "wait_time": timeout in seconds,
1919
# "copy_ami": "copied AMI",
2020
# "status": "pending if it came from the copy complete? choice"
21+
# "region": "different region"
2122
# }
2223

2324

@@ -26,7 +27,14 @@ def lambda_handler(event: Dict[str, Any], context: Any) -> str:
2627
print("Received event: " + json.dumps(event, indent=2))
2728

2829
copy_ami: str = event["copy_ami"]
29-
30-
ami_state: Dict[str, Any] = ec2_client.describe_images(ImageIds=[copy_ami])
30+
region: str = event.get("region")
31+
if region:
32+
ec2_client = boto3.client("ec2", region)
33+
34+
try:
35+
ami_state: Dict[str, Any] = ec2_client.describe_images(ImageIds=[copy_ami])
36+
except Exception as e:
37+
print(e)
38+
return "error"
3139

3240
return ami_state["Images"][0]["State"]

step/lambdas/split_image.py

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
# {
1616
# "copy_ami" : "ami-123456",
1717
# "kms_id" : "GUID",
18-
# "wait_time": 60
18+
# "wait_time": 60,
19+
# "region" : optional region
1920
# }
2021

2122

@@ -24,42 +25,52 @@ def lambda_handler(event: Dict[str, Any], context: Any) -> str:
2425
print("Received event: " + json.dumps(event, indent=2))
2526

2627
copy_ami: str = event["copy_ami"]
27-
28-
# Access the image that needs to be split
29-
image = ec2_res.Image(copy_ami)
30-
31-
root_drive: Dict[str, Any] = {}
32-
drives: Dict[str, Any] = {}
33-
34-
# separate the root drive from the other drives
35-
devices: List[Any] = image.block_device_mappings
36-
for device in devices:
37-
if "Ebs" in device:
38-
if device["DeviceName"] == image.root_device_name:
39-
print(f"Found Root! {device}")
40-
root_drive: Dict[str, Any] = device
41-
else:
42-
drives[device["DeviceName"]] = device["Ebs"]
43-
44-
# have to remove the encrypted flag
45-
del root_drive["Ebs"]["Encrypted"]
46-
47-
# create a new AMI with only the root
48-
response = ec2_res.register_image(
49-
Architecture=image.architecture,
50-
BlockDeviceMappings=[root_drive],
51-
Name=f"root-{copy_ami}",
52-
RootDeviceName=image.root_device_name,
53-
VirtualizationType=image.virtualization_type,
54-
)
55-
56-
root_ami = response.id
57-
58-
for drive in drives:
59-
print(drives[drive])
60-
ec2_res.create_tags(
61-
Resources=[root_ami],
62-
Tags=[{"Key": f"Drive-{drive}", "Value": json.dumps(drives[drive])}],
28+
region: str = event.get("region")
29+
if region:
30+
ec2_res = boto3.resource("ec2", region)
31+
32+
try:
33+
# Access the image that needs to be split
34+
image = ec2_res.Image(copy_ami)
35+
36+
root_drive: Dict[str, Any] = {}
37+
drives: Dict[str, Any] = {}
38+
39+
# separate the root drive from the other drives
40+
devices: List[Any] = image.block_device_mappings
41+
for device in devices:
42+
if "Ebs" in device:
43+
if device["DeviceName"] == image.root_device_name:
44+
print(f"Found Root! {device}")
45+
root_drive: Dict[str, Any] = device
46+
else:
47+
drives[device["DeviceName"]] = device["Ebs"]
48+
49+
# have to remove the encrypted flag
50+
del root_drive["Ebs"]["Encrypted"]
51+
52+
# create a new AMI with only the root
53+
response = ec2_res.register_image(
54+
Architecture=image.architecture,
55+
BlockDeviceMappings=[root_drive],
56+
Name=f"root-{copy_ami}",
57+
RootDeviceName=image.root_device_name,
58+
VirtualizationType=image.virtualization_type,
6359
)
6460

61+
root_ami = response.id
62+
63+
for drive in drives:
64+
print(drives[drive])
65+
ec2_res.create_tags(
66+
Resources=[root_ami],
67+
Tags=[{"Key": f"Drive-{drive}", "Value": json.dumps(drives[drive])}],
68+
)
69+
70+
# clean up original image
71+
image.deregister()
72+
except Exception as e:
73+
print(e)
74+
return ""
75+
6576
return root_ami

step/step-function.tf

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -242,20 +242,6 @@ resource "aws_sfn_state_machine" "copy_and_split" {
242242
"Type": "Task",
243243
"Resource": "${aws_lambda_function.lambda_split_image.arn}",
244244
"ResultPath": "$.split_ami_id",
245-
"Next": "Image Cleanup",
246-
"Retry": [
247-
{
248-
"ErrorEquals": ["States.ALL"],
249-
"IntervalSeconds": 1,
250-
"MaxAttempts": 3,
251-
"BackoffRate": 2
252-
}
253-
]
254-
},
255-
"Image Cleanup": {
256-
"Type": "Task",
257-
"Resource": "${aws_lambda_function.lambda_image_cleanup.arn}",
258-
"ResultPath": "$.cleanup",
259245
"End": true,
260246
"Retry": [
261247
{

0 commit comments

Comments
 (0)