Repository: getmoto/moto (python)

Issue:
EC2 subnet references str variable instead of self
moto/ec2/models/elastic_network_interfaces.py
Under the class NetworkInterface on line 135 and 137, the code references
"subnet.vpc_id" but subnet is a str. Changing code to "self.subnet.vpc_id" fixes the issue.

moto version "5.0.10.dev12"


Pull request description:
ECS: Tasks can now be created with unknown security groups
Fixes #8011 

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/elastic_network_interfaces.py b/moto/ec2/models/elastic_network_interfaces.py
index 9c12986d1..8b6b05437 100644
--- a/moto/ec2/models/elastic_network_interfaces.py
+++ b/moto/ec2/models/elastic_network_interfaces.py
@@ -133,9 +133,9 @@ class NetworkInterface(TaggedEC2Resource, CloudFormationModel):
                         group_id,
                         group_id,
                         group_id,
-                        vpc_id=subnet.vpc_id,
+                        vpc_id=self.subnet.vpc_id,
                     )
-                    self.ec2_backend.groups[subnet.vpc_id][group_id] = group
+                    self.ec2_backend.groups[self.subnet.vpc_id][group_id] = group
                 if group:
                     self._group_set.append(group)
         if not group_ids:
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
diff --git a/tests/test_ecs/test_ecs_boto3.py b/tests/test_ecs/test_ecs_boto3.py
index eb3ea0e13..0aaec121d 100644
--- a/tests/test_ecs/test_ecs_boto3.py
+++ b/tests/test_ecs/test_ecs_boto3.py
@@ -2093,6 +2093,43 @@ def test_run_task_awsvpc_network():
     assert {"name": "macAddress", "value": eni["MacAddress"]} in details
 
 
+@mock_aws
+def test_run_task_awsvpc_network__unknown_sec_group():
+    # Setup
+    client = boto3.client("ecs", region_name=ECS_REGION)
+    ec2_client = boto3.client("ec2", region_name=ECS_REGION)
+    ec2 = boto3.resource("ec2", region_name=ECS_REGION)
+
+    # ECS setup
+    setup_resources = setup_ecs(client, ec2)
+
+    # Execute
+    task = client.run_task(
+        cluster="test_ecs_cluster",
+        overrides={},
+        taskDefinition="test_ecs_task",
+        startedBy="moto",
+        launchType="FARGATE",
+        networkConfiguration={
+            "awsvpcConfiguration": {
+                "subnets": [setup_resources[0].id],
+                "securityGroups": ["unknown_sg"],
+            }
+        },
+    )["tasks"][0]
+    eni_id = next(
+        t["value"]
+        for t in task["attachments"][0]["details"]
+        if t["name"] == "networkInterfaceId"
+    )
+
+    eni = ec2_client.describe_network_interfaces(NetworkInterfaceIds=[eni_id])[
+        "NetworkInterfaces"
+    ][0]
+    # Unknown SecurityGroup is created for us
+    assert eni["Groups"] == [{"GroupId": "unknown_sg", "GroupName": "unknown_sg"}]
+
+
 @mock_aws
 def test_run_task_awsvpc_network_error():
     # Setup