Repository: getmoto/moto (python)

Issue:
Autoscaling groups do not pass launch template to EC2 instances.
When creating an Auto Scaling Group using moto, the launch template argument is ignored when creating instances in the autoscaling group (only launch config is taken into account). This means that any properties of instances managed by the AutoScaling group and set in the launch template are not transferred to the instance. (In `moto.autoscaling.models.FakeAutoScalingGroup.replace_autoscaling_group_instances`, we see that only the launch config is used to pass configuration to the created instances and not the launch template). 

moto version: 5.0.12 installed using poetry.



Pull request description:
Autoscaling: LaunchTemplate tags are now propagated to EC2 instances
Fixes #7979 

Patch:
diff --git a/moto/autoscaling/models.py b/moto/autoscaling/models.py
index 7ff98b502..4880b0a4e 100644
--- a/moto/autoscaling/models.py
+++ b/moto/autoscaling/models.py
@@ -720,6 +720,13 @@ class FakeAutoScalingGroup(CloudFormationModel):
 
         return self.launch_config.security_groups  # type: ignore[union-attr]
 
+    @property
+    def instance_tags(self) -> Dict[str, str]:
+        if self.launch_template:
+            version = self.launch_template.get_version(self.launch_template_version)
+            return version.instance_tags
+        return {}
+
     def update(
         self,
         availability_zones: List[str],
@@ -815,6 +822,7 @@ class FakeAutoScalingGroup(CloudFormationModel):
         self, count_needed: int, propagated_tags: Dict[str, str]
     ) -> None:
         propagated_tags[ASG_NAME_TAG] = self.name
+        propagated_tags.update(self.instance_tags)
 
         # VPCZoneIdentifier:
         # A comma-separated list of subnet IDs for a virtual private cloud (VPC) where instances in the Auto Scaling group can be created.
diff --git a/moto/ec2/models/launch_templates.py b/moto/ec2/models/launch_templates.py
index bc01434e3..7a1c9d05d 100644
--- a/moto/ec2/models/launch_templates.py
+++ b/moto/ec2/models/launch_templates.py
@@ -32,6 +32,9 @@ class LaunchTemplateVersion:
         self.data = data
         self.description = description
         self.create_time = utc_date_and_time()
+        self.instance_tags = convert_tag_spec(data.get("TagSpecification", [])).get(
+            "instance", {}
+        )
 
     @property
     def image_id(self) -> str:


Test patch:
diff --git a/tests/test_autoscaling/test_autoscaling_groups.py b/tests/test_autoscaling/test_autoscaling_groups.py
index 680c959a7..70fa2504b 100644
--- a/tests/test_autoscaling/test_autoscaling_groups.py
+++ b/tests/test_autoscaling/test_autoscaling_groups.py
@@ -255,3 +255,45 @@ class TestAutoScalingGroup(TestCase):
             LaunchConfigurationName=self.lc_name,
             VPCZoneIdentifier=self.mocked_networking["subnet1"],
         )
+
+
+@mock_aws
+def test_launch_template_with_tags():
+    mocked_networking = setup_networking()
+
+    ec2_client = boto3.client("ec2", region_name="us-east-1")
+    template = ec2_client.create_launch_template(
+        LaunchTemplateName="test_launch_template",
+        LaunchTemplateData={
+            "ImageId": EXAMPLE_AMI_ID,
+            "InstanceType": "t2.micro",
+            "TagSpecifications": [
+                {
+                    "ResourceType": "instance",
+                    "Tags": [{"Key": "from_lt", "Value": "val"}],
+                }
+            ],
+        },
+    )["LaunchTemplate"]
+
+    as_client = boto3.client("autoscaling", region_name="us-east-1")
+    as_client.create_auto_scaling_group(
+        AutoScalingGroupName="myasgroup",
+        MinSize=1,
+        MaxSize=2,
+        LaunchTemplate={"LaunchTemplateId": template["LaunchTemplateId"]},
+        VPCZoneIdentifier=mocked_networking["subnet1"],
+        Tags=[
+            {
+                "PropagateAtLaunch": True,
+                "Key": "TestTagKey1",
+                "Value": "TestTagValue1",
+            }
+        ],
+    )
+
+    instances = ec2_client.describe_instances()
+
+    tags = instances["Reservations"][0]["Instances"][0]["Tags"]
+    assert {"Value": "TestTagValue1", "Key": "TestTagKey1"} in tags
+    assert {"Key": "from_lt", "Value": "val"} in tags