diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md index d345c17db..ccb36ef80 100644 --- a/IMPLEMENTATION_COVERAGE.md +++ b/IMPLEMENTATION_COVERAGE.md @@ -2191,7 +2191,7 @@ - [ ] get_ipam_pool_allocations - [ ] get_ipam_pool_cidrs - [ ] get_ipam_resource_cidrs -- [ ] get_launch_template_data +- [x] get_launch_template_data - [ ] get_managed_prefix_list_associations - [X] get_managed_prefix_list_entries - [ ] get_network_insights_access_scope_analysis_findings @@ -7056,4 +7056,4 @@ - workspaces - workspaces-web - xray - \ No newline at end of file + diff --git a/moto/ec2/responses/launch_templates.py b/moto/ec2/responses/launch_templates.py index efb3ceda5..ce30c985a 100644 --- a/moto/ec2/responses/launch_templates.py +++ b/moto/ec2/responses/launch_templates.py @@ -258,3 +258,110 @@ class LaunchTemplates(EC2BaseResponse): ) return pretty_xml(tree) + + def get_launch_template_data(self) -> str: + instance_id = self._get_param("InstanceId") + instance = self.ec2_backend.get_instance(instance_id) + template = self.response_template(GET_LAUNCH_TEMPLATE_DATA_RESPONSE) + return template.render(i=instance) + + +GET_LAUNCH_TEMPLATE_DATA_RESPONSE = """ + 801986a5-0ee2-46bd-be02-abcde1234567 + + + {% for device_name, device in i.block_device_mapping.items() %} + + {{ device_name }} + + {{ device.delete_on_termination }} + {{ device.encrypted }} + {{ device.snapshot_id }} + {{ device.size }} + {{ device.volume_type }} + + + {% endfor %} + + + open + + + standard + + {{ i.disable_api_stop }} + {{ i.disable_api_termination }} + {{ i.ebs_optimised }} + + false + + + false + + {{ i.image_id }} + {{ i.instance_initiated_shutdown_behavior }} + {{ i.instance_type }} + {{ i.key_name }} + + default + + + enabled + disabled + 1 + optional + disabled + + + {{ i.monitored }} + + + {% for nic_index, nic in i.nics.items() %} + + true + {{ nic.delete_on_termination }} + + {{ nic.device_index }} + + {{ nic.group_set[0].group_id if nic.group_set }} + + {{ nic.interface_type }} + + {{ nic_index }} + + {% for addr in nic.private_ip_addresses %} + + {{ addr["Primary"] }} + {{ addr["PrivateIpAddress"] }} + + {% endfor %} + + {{ nic.subnet.id }} + + {% endfor %} + + + {{ i.placement }} + + default + + + false + true + ip-name + + + {% for tag in i.tags %} + + instance + + + {{ tag.key }} + {{ tag.value }} + + + + {% endfor %} + + +""" diff --git a/tests/test_ec2/test_launch_templates.py b/tests/test_ec2/test_launch_templates.py index 9b98c1e25..e775a0460 100644 --- a/tests/test_ec2/test_launch_templates.py +++ b/tests/test_ec2/test_launch_templates.py @@ -7,6 +7,8 @@ from botocore.client import ClientError from moto import mock_ec2, settings from uuid import uuid4 +from tests import EXAMPLE_AMI_ID + @mock_ec2 def test_launch_template_create(): @@ -500,6 +502,28 @@ def test_create_launch_template_with_tag_spec(): ) +@mock_ec2 +def test_get_launch_template_data(): + client = boto3.client("ec2", region_name="us-east-1") + + reservation = client.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1) + instance = reservation["Instances"][0] + + launch_template_data = client.get_launch_template_data( + InstanceId=instance["InstanceId"] + )["LaunchTemplateData"] + + # Ensure launch template data matches instance + launch_template_data["ImageId"].should.equal(instance["ImageId"]) + launch_template_data["InstanceType"].should.equal(instance["InstanceType"]) + + # Ensure a launch template can be created from this data + client.create_launch_template( + LaunchTemplateName=str(uuid4()), + LaunchTemplateData=launch_template_data, + ) + + @mock_ec2 def test_delete_launch_template__dryrun(): cli = boto3.client("ec2", region_name="us-east-1")