Repository: getmoto/moto
Pull request #9080 (2025-07-20 01:18:18)

ELB: integrate with core response serializer
This was a fairly clean integration.  The model updates consist of just simple attribute adding/renaming--no logic has changed.   The "Fake" prefix was dropped from the LoadBalancer class, but left on other classes to avoid a noisy diff.  The responses required a few custom "transformers" to marshal some model attributes into the proper structures for serialization, but they are fully encapsulated and easy to understand.  Some very minor test updates were needed, mostly around previous incorrect serialization of `None` values.

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/getmoto/moto/pull/9080?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 92.89%. Comparing base [(`1cc4f72`)](https://app.codecov.io/gh/getmoto/moto/commit/1cc4f7297cfe12bacce94c109156016cd92be8e1?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto) to head [(`17280b5`)](https://app.codecov.io/gh/getmoto/moto/commit/17280b5f35e63552f32657d1dd105f4d61c457ee?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto).
> Report is 1 commits behind head on master.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #9080      +/-   ##
==========================================
+ Coverage   92.88%   92.89%   +0.01%     
==========================================
  Files        1287     1287              
  Lines      113767   113652     -115     
==========================================
- Hits       105669   105579      -90     
+ Misses       8098     8073      -25     
```

| [Flag](https://app.codecov.io/gh/getmoto/moto/pull/9080/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto) | Coverage Δ | |
|---|---|---|
| [servertests](https://app.codecov.io/gh/getmoto/moto/pull/9080/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto) | `28.56% <44.80%> (-0.02%)` | :arrow_down: |
| [unittests](https://app.codecov.io/gh/getmoto/moto/pull/9080/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto) | `92.87% <100.00%> (+0.01%)` | :arrow_up: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto#carryforward-flags-in-the-pull-request-comment) to find out more.

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/getmoto/moto/pull/9080?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getmoto).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>

Patch:
diff --git a/moto/core/serialize.py b/moto/core/serialize.py
index 677060583..e10abb07a 100644
--- a/moto/core/serialize.py
+++ b/moto/core/serialize.py
@@ -96,6 +96,7 @@ Serialized = MutableMapping[str, Any]
 COMMON_ERROR_CODES = [
     "InvalidParameterCombination",
     "InvalidParameterValue",
+    "ValidationError",
     "ValidationException",
 ]
 
diff --git a/moto/elb/exceptions.py b/moto/elb/exceptions.py
index 154fc348d..67a0e2526 100644
--- a/moto/elb/exceptions.py
+++ b/moto/elb/exceptions.py
@@ -1,13 +1,10 @@
 from typing import Any
 
-from moto.core.exceptions import RESTError
+from moto.core.exceptions import ServiceException
 
 
-class ELBClientError(RESTError):
-    code = 400
-
-    def __init__(self, error_type: str, message: str):
-        super().__init__(error_type, message, template="wrapped_single_error")
+class ELBClientError(ServiceException):
+    pass
 
 
 class DuplicateTagKeysError(ELBClientError):
diff --git a/moto/elb/models.py b/moto/elb/models.py
index 921ab4cb4..4266e1be4 100644
--- a/moto/elb/models.py
+++ b/moto/elb/models.py
@@ -62,6 +62,10 @@ class FakeListener(BaseModel):
         self.ssl_certificate_id = ssl_certificate_id
         self.policy_names: List[str] = []
 
+    @property
+    def instance_protocol(self) -> str:
+        return self.protocol
+
     def __repr__(self) -> str:
         return f"FakeListener(lbp: {self.load_balancer_port}, inp: {self.instance_port}, pro: {self.protocol}, cid: {self.ssl_certificate_id}, policies: {self.policy_names})"
 
@@ -75,9 +79,10 @@ class FakeBackend(BaseModel):
         return f"FakeBackend(inp: {self.instance_port}, policies: {self.policy_names})"
 
 
-class FakeLoadBalancer(CloudFormationModel):
+class LoadBalancer(CloudFormationModel):
     def __init__(
         self,
+        account_id: str,
         name: str,
         zones: List[str],
         ports: List[Dict[str, Any]],
@@ -86,16 +91,17 @@ class FakeLoadBalancer(CloudFormationModel):
         subnets: Optional[List[str]],
         security_groups: Optional[List[str]],
     ):
+        self.account_id = account_id
         self.name = name
         self.health_check: Optional[FakeHealthCheck] = None
         self.instance_sparse_ids: List[str] = []
         self.instance_autoscaling_ids: List[str] = []
-        self.zones = zones
+        self.availability_zones = zones
         self.listeners = []
         self.backends = []
         self.created_time = datetime.datetime.now(datetime.timezone.utc)
         self.scheme = scheme or "internet-facing"
-        self.attributes = FakeLoadBalancer.get_default_attributes()
+        self.attributes = LoadBalancer.get_default_attributes()
         self.policies: List[Policy] = []
         self.security_groups = security_groups or []
         self.subnets = subnets or []
@@ -123,6 +129,33 @@ class FakeLoadBalancer(CloudFormationModel):
             )
             self.backends.append(backend)
 
+    @property
+    def source_security_group(self) -> dict[str, str]:
+        return {"OwnerAlias": self.account_id, "GroupName": "default"}
+
+    @property
+    def instances(self) -> list[dict[str, str]]:
+        return [{"InstanceId": id_} for id_ in self.instance_ids]
+
+    @property
+    def backend_server_descriptions(self) -> list[FakeBackend]:
+        return [backend for backend in self.backends if backend.policy_names]
+
+    @property
+    def canonical_hosted_zone_name(self) -> str:
+        return self.dns_name
+
+    @property
+    def listener_descriptions(self) -> list[dict[str, Any]]:
+        descriptions = [
+            {
+                "PolicyNames": listener.policy_names,
+                "Listener": listener,
+            }
+            for listener in self.listeners
+        ]
+        return descriptions
+
     @property
     def instance_ids(self) -> List[str]:
         """Return all the instances attached to the ELB"""
@@ -145,7 +178,7 @@ class FakeLoadBalancer(CloudFormationModel):
         account_id: str,
         region_name: str,
         **kwargs: Any,
-    ) -> "FakeLoadBalancer":
+    ) -> "LoadBalancer":
         properties = cloudformation_json["Properties"]
 
         elb_backend = elb_backends[account_id][region_name]
@@ -203,7 +236,7 @@ class FakeLoadBalancer(CloudFormationModel):
         cloudformation_json: Any,
         account_id: str,
         region_name: str,
-    ) -> "FakeLoadBalancer":
+    ) -> "LoadBalancer":
         cls.delete_from_cloudformation_json(
             original_resource.name, cloudformation_json, account_id, region_name
         )
@@ -293,7 +326,7 @@ class FakeLoadBalancer(CloudFormationModel):
 class ELBBackend(BaseBackend):
     def __init__(self, region_name: str, account_id: str):
         super().__init__(region_name, account_id)
-        self.load_balancers: Dict[str, FakeLoadBalancer] = OrderedDict()
+        self.load_balancers: Dict[str, LoadBalancer] = OrderedDict()
 
     def create_load_balancer(
         self,
@@ -303,7 +336,7 @@ class ELBBackend(BaseBackend):
         scheme: str = "internet-facing",
         subnets: Optional[List[str]] = None,
         security_groups: Optional[List[str]] = None,
-    ) -> FakeLoadBalancer:
+    ) -> LoadBalancer:
         vpc_id = None
         ec2_backend = ec2_backends[self.account_id][self.region_name]
         if subnets:
@@ -328,7 +361,8 @@ class ELBBackend(BaseBackend):
         for security_group in security_groups:
             if ec2_backend.get_security_group_from_id(security_group) is None:
                 raise InvalidSecurityGroupError()
-        new_load_balancer = FakeLoadBalancer(
+        new_load_balancer = LoadBalancer(
+            account_id=self.account_id,
             name=name,
             zones=zones,
             ports=ports,
@@ -352,7 +386,7 @@ class ELBBackend(BaseBackend):
 
     def create_load_balancer_listeners(
         self, name: str, ports: List[Dict[str, Any]]
-    ) -> Optional[FakeLoadBalancer]:
+    ) -> Optional[LoadBalancer]:
         balancer = self.load_balancers.get(name, None)
         if balancer:
             for port in ports:
@@ -387,7 +421,7 @@ class ELBBackend(BaseBackend):
 
         return balancer
 
-    def describe_load_balancers(self, names: List[str]) -> List[FakeLoadBalancer]:
+    def describe_load_balancers(self, names: List[str]) -> List[LoadBalancer]:
         balancers = list(self.load_balancers.values())
         if names:
             matched_balancers = [
@@ -438,7 +472,7 @@ class ELBBackend(BaseBackend):
 
     def delete_load_balancer_listeners(
         self, name: str, ports: List[str]
-    ) -> Optional[FakeLoadBalancer]:
+    ) -> Optional[LoadBalancer]:
         balancer = self.get_load_balancer(name)
         listeners = []
         if balancer:
@@ -458,7 +492,7 @@ class ELBBackend(BaseBackend):
         lb = self.get_load_balancer(lb_name)
         lb.policies = [p for p in lb.policies if p.policy_name != policy_name]
 
-    def get_load_balancer(self, load_balancer_name: str) -> FakeLoadBalancer:
+    def get_load_balancer(self, load_balancer_name: str) -> LoadBalancer:
         return self.load_balancers.get(load_balancer_name)  # type: ignore[return-value]
 
     def apply_security_groups_to_load_balancer(
@@ -489,7 +523,7 @@ class ELBBackend(BaseBackend):
 
     def set_load_balancer_listener_ssl_certificate(
         self, name: str, lb_port: str, ssl_certificate_id: str
-    ) -> Optional[FakeLoadBalancer]:
+    ) -> Optional[LoadBalancer]:
         balancer = self.load_balancers.get(name, None)
         if balancer:
             for idx, listener in enumerate(balancer.listeners):
@@ -509,7 +543,7 @@ class ELBBackend(BaseBackend):
         load_balancer_name: str,
         instance_ids: Iterable[str],
         from_autoscaling: bool = False,
-    ) -> FakeLoadBalancer:
+    ) -> LoadBalancer:
         load_balancer = self.get_load_balancer(load_balancer_name)
         attr_name = (
             "instance_sparse_ids"
@@ -526,7 +560,7 @@ class ELBBackend(BaseBackend):
         load_balancer_name: str,
         instance_ids: Iterable[str],
         from_autoscaling: bool = False,
-    ) -> FakeLoadBalancer:
+    ) -> LoadBalancer:
         load_balancer = self.get_load_balancer(load_balancer_name)
         attr_name = (
             "instance_sparse_ids"
@@ -584,7 +618,7 @@ class ELBBackend(BaseBackend):
         policy_name: str,
         policy_type_name: str,
         policy_attrs: List[Dict[str, str]],
-    ) -> FakeLoadBalancer:
+    ) -> LoadBalancer:
         load_balancer = self.get_load_balancer(load_balancer_name)
         if policy_name not in [p.policy_name for p in load_balancer.policies]:
             load_balancer.policies.append(
@@ -595,7 +629,7 @@ class ELBBackend(BaseBackend):
 
     def create_app_cookie_stickiness_policy(
         self, load_balancer_name: str, policy_name: str, cookie_name: str
-    ) -> FakeLoadBalancer:
+    ) -> LoadBalancer:
         load_balancer = self.get_load_balancer(load_balancer_name)
         policy = AppCookieStickinessPolicy(policy_name, cookie_name)
         load_balancer.policies.append(policy)
@@ -606,7 +640,7 @@ class ELBBackend(BaseBackend):
         load_balancer_name: str,
         policy_name: str,
         cookie_expiration_period: Optional[int],
-    ) -> FakeLoadBalancer:
+    ) -> LoadBalancer:
         load_balancer = self.get_load_balancer(load_balancer_name)
         policy = LbCookieStickinessPolicy(policy_name, cookie_expiration_period)
         load_balancer.policies.append(policy)
@@ -614,7 +648,7 @@ class ELBBackend(BaseBackend):
 
     def set_load_balancer_policies_for_backend_server(
         self, load_balancer_name: str, instance_port: int, policies: List[str]
-    ) -> FakeLoadBalancer:
+    ) -> LoadBalancer:
         load_balancer = self.get_load_balancer(load_balancer_name)
         backend = [
             b for b in load_balancer.backends if int(b.instance_port) == instance_port
@@ -626,7 +660,7 @@ class ELBBackend(BaseBackend):
 
     def set_load_balancer_policies_of_listener(
         self, load_balancer_name: str, load_balancer_port: int, policies: List[str]
-    ) -> FakeLoadBalancer:
+    ) -> LoadBalancer:
         load_balancer = self.get_load_balancer(load_balancer_name)
         listener = [
             l_listener
@@ -642,21 +676,27 @@ class ELBBackend(BaseBackend):
         self, load_balancer_name: str, availability_zones: List[str]
     ) -> List[str]:
         load_balancer = self.get_load_balancer(load_balancer_name)
-        load_balancer.zones = sorted(
-            list(set(load_balancer.zones + availability_zones))
+        load_balancer.availability_zones = sorted(
+            list(set(load_balancer.availability_zones + availability_zones))
         )
-        return load_balancer.zones
+        return load_balancer.availability_zones
 
     def disable_availability_zones_for_load_balancer(
         self, load_balancer_name: str, availability_zones: List[str]
     ) -> List[str]:
         load_balancer = self.get_load_balancer(load_balancer_name)
-        load_balancer.zones = sorted(
+        load_balancer.availability_zones = sorted(
             list(
-                set([az for az in load_balancer.zones if az not in availability_zones])
+                set(
+                    [
+                        az
+                        for az in load_balancer.availability_zones
+                        if az not in availability_zones
+                    ]
+                )
             )
         )
-        return load_balancer.zones
+        return load_balancer.availability_zones
 
     def attach_load_balancer_to_subnets(
         self, load_balancer_name: str, subnets: List[str]
diff --git a/moto/elb/policies.py b/moto/elb/policies.py
index 0ab1c137d..91b624593 100644
--- a/moto/elb/policies.py
+++ b/moto/elb/policies.py
@@ -27,4 +27,4 @@ class OtherPolicy(Policy):
         policy_attrs: List[Dict[str, Any]],
     ):
         super().__init__(policy_name, policy_type_name=policy_type_name)
-        self.attributes = policy_attrs or []
+        self.policy_attribute_descriptions = policy_attrs or []
diff --git a/moto/elb/responses.py b/moto/elb/responses.py
index 01d2230f3..548a7747e 100644
--- a/moto/elb/responses.py
+++ b/moto/elb/responses.py
@@ -1,10 +1,49 @@
-from moto.core.responses import BaseResponse
+from collections import defaultdict
+from typing import Any
+
+from moto.core.responses import ActionResult, BaseResponse, EmptyResult
 
 from .exceptions import DuplicateTagKeysError, LoadBalancerNotFoundError
-from .models import ELBBackend, FakeLoadBalancer, elb_backends
+from .models import ELBBackend, LoadBalancer, elb_backends
+from .policies import Policy
+
+
+def transform_dict(data: dict[str, str]) -> list[dict[str, str]]:
+    transformed = [{"Key": key, "Value": value} for key, value in data.items()]
+    return transformed
+
+
+def transform_tuple_list(data: list[tuple[str, str]]) -> list[dict[str, str]]:
+    transformed = [{"Key": t[0], "Value": t[1]} for t in data]
+    return transformed
+
+
+def transform_policies(policies: list[Policy]) -> dict[str, Any]:
+    segmented_policies = defaultdict(list)
+    for policy in policies:
+        if policy.policy_type_name in [
+            "AppCookieStickinessPolicy",
+            "LbCookieStickinessPolicy",
+        ]:
+            segmented_policies[policy.policy_type_name].append(policy)
+        else:
+            segmented_policies["OtherPolicy"].append(policy)
+    transformed = {
+        "AppCookieStickinessPolicies": segmented_policies["AppCookieStickinessPolicy"],
+        "LBCookieStickinessPolicies": segmented_policies["LbCookieStickinessPolicy"],
+        "OtherPolicies": [p.policy_name for p in segmented_policies["OtherPolicy"]],
+    }
+    return transformed
 
 
 class ELBResponse(BaseResponse):
+    RESPONSE_KEY_PATH_TO_TRANSFORMER = {
+        "DescribeAccessPointsOutput.LoadBalancerDescriptions.LoadBalancerDescription.Policies": transform_policies,
+        "DescribeLoadBalancerAttributesOutput.LoadBalancerAttributes.AdditionalAttributes": transform_tuple_list,
+        "DescribeTagsOutput.TagDescriptions.TagDescription.Tags": transform_dict,
+        "ModifyLoadBalancerAttributesOutput.LoadBalancerAttributes.AdditionalAttributes": transform_tuple_list,
+    }
+
     def __init__(self) -> None:
         super().__init__(service_name="elb")
 
@@ -12,7 +51,7 @@ class ELBResponse(BaseResponse):
     def elb_backend(self) -> ELBBackend:
         return elb_backends[self.current_account][self.region]
 
-    def create_load_balancer(self) -> str:
+    def create_load_balancer(self) -> ActionResult:
         load_balancer_name = self._get_param("LoadBalancerName")
         availability_zones = self._get_multi_param("AvailabilityZones.member")
         ports = self._get_list_prefix("Listeners.member")
@@ -29,21 +68,19 @@ class ELBResponse(BaseResponse):
             security_groups=security_groups,
         )
         self._add_tags(load_balancer)
-        template = self.response_template(CREATE_LOAD_BALANCER_TEMPLATE)
-        return template.render(load_balancer=load_balancer)
+        result = {"DNSName": load_balancer.dns_name}
+        return ActionResult(result)
 
-    def create_load_balancer_listeners(self) -> str:
+    def create_load_balancer_listeners(self) -> ActionResult:
         load_balancer_name = self._get_param("LoadBalancerName")
         ports = self._get_list_prefix("Listeners.member")
 
         self.elb_backend.create_load_balancer_listeners(
             name=load_balancer_name, ports=ports
         )
+        return EmptyResult()
 
-        template = self.response_template(CREATE_LOAD_BALANCER_LISTENERS_TEMPLATE)
-        return template.render()
-
-    def describe_load_balancers(self) -> str:
+    def describe_load_balancers(self) -> ActionResult:
         names = self._get_multi_param("LoadBalancerNames.member")
         all_load_balancers = list(self.elb_backend.describe_load_balancers(names))
         marker = self._get_param("Marker")
@@ -60,48 +97,43 @@ class ELBResponse(BaseResponse):
         if len(all_load_balancers) > start + page_size:
             next_marker = load_balancers_resp[-1].name
 
-        template = self.response_template(DESCRIBE_LOAD_BALANCERS_TEMPLATE)
-        return template.render(
-            ACCOUNT_ID=self.current_account,
-            load_balancers=load_balancers_resp,
-            marker=next_marker,
-        )
+        result = {
+            "LoadBalancerDescriptions": load_balancers_resp,
+            "NextMarker": next_marker,
+        }
+        return ActionResult(result)
 
-    def delete_load_balancer_listeners(self) -> str:
+    def delete_load_balancer_listeners(self) -> ActionResult:
         load_balancer_name = self._get_param("LoadBalancerName")
         ports = self._get_multi_param("LoadBalancerPorts.member")
         ports = [int(port) for port in ports]
 
         self.elb_backend.delete_load_balancer_listeners(load_balancer_name, ports)
-        template = self.response_template(DELETE_LOAD_BALANCER_LISTENERS)
-        return template.render()
+        return EmptyResult()
 
-    def delete_load_balancer(self) -> str:
+    def delete_load_balancer(self) -> ActionResult:
         load_balancer_name = self._get_param("LoadBalancerName")
         self.elb_backend.delete_load_balancer(load_balancer_name)
-        template = self.response_template(DELETE_LOAD_BALANCER_TEMPLATE)
-        return template.render()
+        return EmptyResult()
 
-    def delete_load_balancer_policy(self) -> str:
+    def delete_load_balancer_policy(self) -> ActionResult:
         load_balancer_name = self.querystring.get("LoadBalancerName")[0]  # type: ignore
         names = self._get_param("PolicyName")
         self.elb_backend.delete_load_balancer_policy(
             lb_name=load_balancer_name, policy_name=names
         )
+        return EmptyResult()
 
-        template = self.response_template(DELETE_LOAD_BALANCER_POLICY)
-        return template.render()
-
-    def apply_security_groups_to_load_balancer(self) -> str:
+    def apply_security_groups_to_load_balancer(self) -> ActionResult:
         load_balancer_name = self._get_param("LoadBalancerName")
         security_group_ids = self._get_multi_param("SecurityGroups.member")
         self.elb_backend.apply_security_groups_to_load_balancer(
             load_balancer_name, security_group_ids
         )
-        template = self.response_template(APPLY_SECURITY_GROUPS_TEMPLATE)
-        return template.render(security_group_ids=security_group_ids)
+        result = {"SecurityGroups": security_group_ids}
+        return ActionResult(result)
 
-    def configure_health_check(self) -> str:
+    def configure_health_check(self) -> ActionResult:
         check = self.elb_backend.configure_health_check(
             load_balancer_name=self._get_param("LoadBalancerName"),
             timeout=self._get_param("HealthCheck.Timeout"),
@@ -110,22 +142,22 @@ class ELBResponse(BaseResponse):
             interval=self._get_param("HealthCheck.Interval"),
             target=self._get_param("HealthCheck.Target"),
         )
-        template = self.response_template(CONFIGURE_HEALTH_CHECK_TEMPLATE)
-        return template.render(check=check)
+        result = {"HealthCheck": check}
+        return ActionResult(result)
 
-    def register_instances_with_load_balancer(self) -> str:
+    def register_instances_with_load_balancer(self) -> ActionResult:
         load_balancer_name = self._get_param("LoadBalancerName")
         instance_ids = [
             list(param.values())[0]
             for param in self._get_list_prefix("Instances.member")
         ]
-        template = self.response_template(REGISTER_INSTANCES_TEMPLATE)
         load_balancer = self.elb_backend.register_instances(
             load_balancer_name, instance_ids
         )
-        return template.render(load_balancer=load_balancer)
+        result = {"Instances": [load_balancer.instance_ids]}
+        return ActionResult(result)
 
-    def set_load_balancer_listener_ssl_certificate(self) -> str:
+    def set_load_balancer_listener_ssl_certificate(self) -> ActionResult:
         load_balancer_name = self._get_param("LoadBalancerName")
         ssl_certificate_id = self.querystring["SSLCertificateId"][0]
         lb_port = self.querystring["LoadBalancerPort"][0]
@@ -133,29 +165,27 @@ class ELBResponse(BaseResponse):
         self.elb_backend.set_load_balancer_listener_ssl_certificate(
             load_balancer_name, lb_port, ssl_certificate_id
         )
+        return EmptyResult()
 
-        template = self.response_template(SET_LOAD_BALANCER_SSL_CERTIFICATE)
-        return template.render()
-
-    def deregister_instances_from_load_balancer(self) -> str:
+    def deregister_instances_from_load_balancer(self) -> ActionResult:
         load_balancer_name = self._get_param("LoadBalancerName")
         instance_ids = [
             list(param.values())[0]
             for param in self._get_list_prefix("Instances.member")
         ]
-        template = self.response_template(DEREGISTER_INSTANCES_TEMPLATE)
         load_balancer = self.elb_backend.deregister_instances(
             load_balancer_name, instance_ids
         )
-        return template.render(load_balancer=load_balancer)
+        result = {"Instances": [load_balancer.instance_ids]}
+        return ActionResult(result)
 
-    def describe_load_balancer_attributes(self) -> str:
+    def describe_load_balancer_attributes(self) -> ActionResult:
         load_balancer_name = self._get_param("LoadBalancerName")
         load_balancer = self.elb_backend.get_load_balancer(load_balancer_name)
-        template = self.response_template(DESCRIBE_ATTRIBUTES_TEMPLATE)
-        return template.render(attributes=load_balancer.attributes)
+        result = {"LoadBalancerAttributes": load_balancer.attributes}
+        return ActionResult(result)
 
-    def modify_load_balancer_attributes(self) -> str:
+    def modify_load_balancer_attributes(self) -> ActionResult:
         load_balancer_name = self._get_param("LoadBalancerName")
         load_balancer = self.elb_backend.get_load_balancer(load_balancer_name)
 
@@ -202,12 +232,13 @@ class ELBResponse(BaseResponse):
             self.elb_backend.modify_load_balancer_attributes(
                 load_balancer_name, additional_attributes=additional_attributes
             )
-        template = self.response_template(MODIFY_ATTRIBUTES_TEMPLATE)
-        return template.render(
-            load_balancer=load_balancer, attributes=load_balancer.attributes
-        )
+        result = {
+            "LoadBalancerName": load_balancer.name,
+            "LoadBalancerAttributes": load_balancer.attributes,
+        }
+        return ActionResult(result)
 
-    def create_load_balancer_policy(self) -> str:
+    def create_load_balancer_policy(self) -> ActionResult:
         load_balancer_name = self._get_param("LoadBalancerName")
 
         policy_name = self._get_param("PolicyName")
@@ -217,11 +248,9 @@ class ELBResponse(BaseResponse):
         self.elb_backend.create_load_balancer_policy(
             load_balancer_name, policy_name, policy_type_name, policy_attrs
         )
+        return EmptyResult()
 
-        template = self.response_template(CREATE_LOAD_BALANCER_POLICY_TEMPLATE)
-        return template.render()
-
-    def create_app_cookie_stickiness_policy(self) -> str:
+    def create_app_cookie_stickiness_policy(self) -> ActionResult:
         load_balancer_name = self._get_param("LoadBalancerName")
 
         policy_name = self._get_param("PolicyName")
@@ -230,11 +259,9 @@ class ELBResponse(BaseResponse):
         self.elb_backend.create_app_cookie_stickiness_policy(
             load_balancer_name, policy_name, cookie_name
         )
+        return EmptyResult()
 
-        template = self.response_template(CREATE_APP_COOKIE_STICKINESS_POLICY_TEMPLATE)
-        return template.render()
-
-    def create_lb_cookie_stickiness_policy(self) -> str:
+    def create_lb_cookie_stickiness_policy(self) -> ActionResult:
         load_balancer_name = self._get_param("LoadBalancerName")
 
         policy_name = self._get_param("PolicyName")
@@ -247,11 +274,9 @@ class ELBResponse(BaseResponse):
         self.elb_backend.create_lb_cookie_stickiness_policy(
             load_balancer_name, policy_name, cookie_expiration_period
         )
+        return EmptyResult()
 
-        template = self.response_template(CREATE_LB_COOKIE_STICKINESS_POLICY_TEMPLATE)
-        return template.render()
-
-    def set_load_balancer_policies_of_listener(self) -> str:
+    def set_load_balancer_policies_of_listener(self) -> ActionResult:
         load_balancer_name = self._get_param("LoadBalancerName")
         load_balancer = self.elb_backend.get_load_balancer(load_balancer_name)
         load_balancer_port = int(self._get_param("LoadBalancerPort"))
@@ -267,13 +292,9 @@ class ELBResponse(BaseResponse):
                 load_balancer_name, load_balancer_port, policies
             )
         # else: explode?
+        return EmptyResult()
 
-        template = self.response_template(
-            SET_LOAD_BALANCER_POLICIES_OF_LISTENER_TEMPLATE
-        )
-        return template.render()
-
-    def set_load_balancer_policies_for_backend_server(self) -> str:
+    def set_load_balancer_policies_for_backend_server(self) -> ActionResult:
         load_balancer_name = self.querystring.get("LoadBalancerName")[0]  # type: ignore
         load_balancer = self.elb_backend.get_load_balancer(load_balancer_name)
         instance_port = int(self.querystring.get("InstancePort")[0])  # type: ignore
@@ -288,29 +309,35 @@ class ELBResponse(BaseResponse):
             )
         # else: explode?
 
-        template = self.response_template(
-            SET_LOAD_BALANCER_POLICIES_FOR_BACKEND_SERVER_TEMPLATE
-        )
-        return template.render()
+        return EmptyResult()
 
-    def describe_load_balancer_policies(self) -> str:
+    def describe_load_balancer_policies(self) -> ActionResult:
         load_balancer_name = self.querystring.get("LoadBalancerName")[0]  # type: ignore
         names = self._get_multi_param("PolicyNames.member.")
         policies = self.elb_backend.describe_load_balancer_policies(
             lb_name=load_balancer_name, policy_names=names
         )
+        result = {"PolicyDescriptions": policies}
+        return ActionResult(result)
 
-        template = self.response_template(DESCRIBE_LOAD_BALANCER_POLICIES_TEMPLATE)
-        return template.render(policies=policies)
-
-    def describe_instance_health(self) -> str:
+    def describe_instance_health(self) -> ActionResult:
         lb_name = self._get_param("LoadBalancerName")
         instances = self._get_params().get("Instances", [])
         instances = self.elb_backend.describe_instance_health(lb_name, instances)
-        template = self.response_template(DESCRIBE_INSTANCE_HEALTH_TEMPLATE)
-        return template.render(instances=instances)
-
-    def add_tags(self) -> str:
+        result = {
+            "InstanceStates": [
+                {
+                    "Description": "N/A",
+                    "InstanceId": instance["InstanceId"],
+                    "State": instance["State"],
+                    "ReasonCode": "N/A",
+                }
+                for instance in instances
+            ]
+        }
+        return ActionResult(result)
+
+    def add_tags(self) -> ActionResult:
         for key, value in self.querystring.items():
             if "LoadBalancerNames.member" in key:
                 load_balancer_name = value[0]
@@ -320,10 +347,9 @@ class ELBResponse(BaseResponse):
 
                 self._add_tags(elb)
 
-        template = self.response_template(ADD_TAGS_TEMPLATE)
-        return template.render()
+        return EmptyResult()
 
-    def remove_tags(self) -> str:
+    def remove_tags(self) -> ActionResult:
         for key in self.querystring:
             if "LoadBalancerNames.member" in key:
                 number = key.split(".")[2]
@@ -339,10 +365,9 @@ class ELBResponse(BaseResponse):
                         if t_key.split(".")[3] == "Key":
                             elb.remove_tag(t_val[0])
 
-        template = self.response_template(REMOVE_TAGS_TEMPLATE)
-        return template.render()
+        return EmptyResult()
 
-    def describe_tags(self) -> str:
+    def describe_tags(self) -> ActionResult:
         elbs = []
         for key in self.querystring:
             if "LoadBalancerNames.member" in key:
@@ -354,11 +379,14 @@ class ELBResponse(BaseResponse):
                 if not elb:
                     raise LoadBalancerNotFoundError(load_balancer_name)
                 elbs.append(elb)
-
-        template = self.response_template(DESCRIBE_TAGS_TEMPLATE)
-        return template.render(load_balancers=elbs)
-
-    def _add_tags(self, elb: FakeLoadBalancer) -> None:
+        result = {
+            "TagDescriptions": [
+                {"LoadBalancerName": elb.name, "Tags": elb.tags} for elb in elbs
+            ]
+        }
+        return ActionResult(result)
+
+    def _add_tags(self, elb: LoadBalancer) -> None:
         tag_values = []
         tag_keys = []
 
@@ -382,7 +410,7 @@ class ELBResponse(BaseResponse):
         for tag_key, tag_value in zip(tag_keys, tag_values):
             elb.add_tag(tag_key, tag_value)
 
-    def enable_availability_zones_for_load_balancer(self) -> str:
+    def enable_availability_zones_for_load_balancer(self) -> ActionResult:
         params = self._get_params()
         load_balancer_name = params.get("LoadBalancerName")
         availability_zones = params.get("AvailabilityZones")
@@ -392,12 +420,10 @@ class ELBResponse(BaseResponse):
                 availability_zones=availability_zones,  # type: ignore[arg-type]
             )
         )
-        template = self.response_template(
-            ENABLE_AVAILABILITY_ZONES_FOR_LOAD_BALANCER_TEMPLATE
-        )
-        return template.render(availability_zones=availability_zones)
+        result = {"AvailabilityZones": availability_zones}
+        return ActionResult(result)
 
-    def disable_availability_zones_for_load_balancer(self) -> str:
+    def disable_availability_zones_for_load_balancer(self) -> ActionResult:
         params = self._get_params()
         load_balancer_name = params.get("LoadBalancerName")
         availability_zones = params.get("AvailabilityZones")
@@ -407,12 +433,10 @@ class ELBResponse(BaseResponse):
                 availability_zones=availability_zones,  # type: ignore[arg-type]
             )
         )
-        template = self.response_template(
-            DISABLE_AVAILABILITY_ZONES_FOR_LOAD_BALANCER_TEMPLATE
-        )
-        return template.render(availability_zones=availability_zones)
+        result = {"AvailabilityZones": availability_zones}
+        return ActionResult(result)
 
-    def attach_load_balancer_to_subnets(self) -> str:
+    def attach_load_balancer_to_subnets(self) -> ActionResult:
         params = self._get_params()
         load_balancer_name = params.get("LoadBalancerName")
         subnets = params.get("Subnets")
@@ -421,10 +445,10 @@ class ELBResponse(BaseResponse):
             load_balancer_name,  # type: ignore[arg-type]
             subnets,  # type: ignore[arg-type]
         )
-        template = self.response_template(ATTACH_LB_TO_SUBNETS_TEMPLATE)
-        return template.render(subnets=all_subnets)
+        result = {"Subnets": all_subnets}
+        return ActionResult(result)
 
-    def detach_load_balancer_from_subnets(self) -> str:
+    def detach_load_balancer_from_subnets(self) -> ActionResult:
         params = self._get_params()
         load_balancer_name = params.get("LoadBalancerName")
         subnets = params.get("Subnets")
@@ -433,494 +457,5 @@ class ELBResponse(BaseResponse):
             load_balancer_name,  # type: ignore[arg-type]
             subnets,  # type: ignore[arg-type]
         )
-        template = self.response_template(DETACH_LB_FROM_SUBNETS_TEMPLATE)
-        return template.render(subnets=all_subnets)
-
-
-ADD_TAGS_TEMPLATE = """<AddTagsResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <AddTagsResult/>
-  <ResponseMetadata>
-    <RequestId>360e81f7-1100-11e4-b6ed-0f30EXAMPLE</RequestId>
-  </ResponseMetadata>
-</AddTagsResponse>"""
-
-REMOVE_TAGS_TEMPLATE = """<RemoveTagsResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <RemoveTagsResult/>
-  <ResponseMetadata>
-    <RequestId>360e81f7-1100-11e4-b6ed-0f30EXAMPLE</RequestId>
-  </ResponseMetadata>
-</RemoveTagsResponse>"""
-
-DESCRIBE_TAGS_TEMPLATE = """<DescribeTagsResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <DescribeTagsResult>
-    <TagDescriptions>
-      {% for elb in load_balancers %}
-      <member>
-        <LoadBalancerName>{{ elb.name }}</LoadBalancerName>
-        <Tags>
-          {% for key, value in elb.tags.items() %}
-          <member>
-            <Value>{{ value }}</Value>
-            <Key>{{ key }}</Key>
-          </member>
-          {% endfor %}
-        </Tags>
-      </member>
-      {% endfor %}
-    </TagDescriptions>
-  </DescribeTagsResult>
-  <ResponseMetadata>
-    <RequestId>360e81f7-1100-11e4-b6ed-0f30EXAMPLE</RequestId>
-  </ResponseMetadata>
-</DescribeTagsResponse>"""
-
-
-DESCRIBE_LOAD_BALANCER_POLICIES_TEMPLATE = """<DescribeLoadBalancerPoliciesResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <DescribeLoadBalancerPoliciesResult>
-    <PolicyDescriptions>
-      {% for policy in policies %}
-      <member>
-        <PolicyName>{{ policy.policy_name }}</PolicyName>
-        <PolicyTypeName>{{ policy.policy_type_name }}</PolicyTypeName>
-        <PolicyAttributeDescriptions>
-          {% for attr in policy.attributes %}
-              <member>
-                <AttributeName>{{ attr["AttributeName"] }}</AttributeName>
-                <AttributeValue>{{ attr["AttributeValue"] }}</AttributeValue>
-              </member>
-          {% endfor %}
-        </PolicyAttributeDescriptions>
-      </member>
-      {% endfor %}
-    </PolicyDescriptions>
-  </DescribeLoadBalancerPoliciesResult>
-  <ResponseMetadata>
-    <RequestId>360e81f7-1100-11e4-b6ed-0f30EXAMPLE</RequestId>
-  </ResponseMetadata>
-</DescribeLoadBalancerPoliciesResponse>"""
-
-
-CREATE_LOAD_BALANCER_TEMPLATE = """<CreateLoadBalancerResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <CreateLoadBalancerResult>
-    <DNSName>{{ load_balancer.dns_name }}</DNSName>
-  </CreateLoadBalancerResult>
-  <ResponseMetadata>
-    <RequestId>1549581b-12b7-11e3-895e-1334aEXAMPLE</RequestId>
-  </ResponseMetadata>
-</CreateLoadBalancerResponse>"""
-
-CREATE_LOAD_BALANCER_LISTENERS_TEMPLATE = """<CreateLoadBalancerListenersResponse xmlns="http://elasticloadbalancing.amazon aws.com/doc/2012-06-01/">
-  <CreateLoadBalancerListenersResult/>
-  <ResponseMetadata>
-    <RequestId>1549581b-12b7-11e3-895e-1334aEXAMPLE</RequestId>
-  </ResponseMetadata>
-</CreateLoadBalancerListenersResponse>"""
-
-DELETE_LOAD_BALANCER_TEMPLATE = """<DeleteLoadBalancerResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <DeleteLoadBalancerResult/>
-  <ResponseMetadata>
-    <RequestId>1549581b-12b7-11e3-895e-1334aEXAMPLE</RequestId>
-  </ResponseMetadata>
-</DeleteLoadBalancerResponse>"""
-
-DESCRIBE_LOAD_BALANCERS_TEMPLATE = """<DescribeLoadBalancersResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <DescribeLoadBalancersResult>
-    <LoadBalancerDescriptions>
-      {% for load_balancer in load_balancers %}
-        <member>
-          <SecurityGroups>
-            {% for security_group_id in load_balancer.security_groups %}
-            <member>{{ security_group_id }}</member>
-            {% endfor %}
-          </SecurityGroups>
-          {% if load_balancer.vpc_id %}
-          <SourceSecurityGroup>
-              <OwnerAlias>{{ ACCOUNT_ID }}</OwnerAlias>
-              <GroupName>default</GroupName>
-          </SourceSecurityGroup>
-          {% endif %}
-          <LoadBalancerName>{{ load_balancer.name }}</LoadBalancerName>
-          <CreatedTime>{{ load_balancer.created_time.isoformat() }}</CreatedTime>
-          <HealthCheck>
-            {% if load_balancer.health_check %}
-              <Interval>{{ load_balancer.health_check.interval }}</Interval>
-              <Target>{{ load_balancer.health_check.target }}</Target>
-              <HealthyThreshold>{{ load_balancer.health_check.healthy_threshold }}</HealthyThreshold>
-              <Timeout>{{ load_balancer.health_check.timeout }}</Timeout>
-              <UnhealthyThreshold>{{ load_balancer.health_check.unhealthy_threshold }}</UnhealthyThreshold>
-            {% else %}
-              <Target></Target>
-            {% endif %}
-          </HealthCheck>
-          {% if load_balancer.vpc_id %}
-          <VPCId>{{ load_balancer.vpc_id }}</VPCId>
-          {% else %}
-          <VPCId />
-          {% endif %}
-          <ListenerDescriptions>
-            {% for listener in load_balancer.listeners %}
-              <member>
-                <PolicyNames>
-                  {% for policy_name in listener.policy_names %}
-                    <member>{{ policy_name }}</member>
-                  {% endfor %}
-                </PolicyNames>
-                <Listener>
-                  <Protocol>{{ listener.protocol }}</Protocol>
-                  <LoadBalancerPort>{{ listener.load_balancer_port }}</LoadBalancerPort>
-                  <InstanceProtocol>{{ listener.protocol }}</InstanceProtocol>
-                  <InstancePort>{{ listener.instance_port }}</InstancePort>
-                  <SSLCertificateId>{{ listener.ssl_certificate_id }}</SSLCertificateId>
-                </Listener>
-              </member>
-            {% endfor %}
-          </ListenerDescriptions>
-          <Instances>
-            {% for instance_id in load_balancer.instance_ids %}
-              <member>
-                <InstanceId>{{ instance_id }}</InstanceId>
-              </member>
-            {% endfor %}
-          </Instances>
-          <Policies>
-            <AppCookieStickinessPolicies>
-            {% for policy in load_balancer.policies %}
-                {% if policy.policy_type_name == "AppCookieStickinessPolicy" %}
-                    <member>
-                        <CookieName>{{ policy.cookie_name }}</CookieName>
-                        <PolicyName>{{ policy.policy_name }}</PolicyName>
-                    </member>
-                {% endif %}
-            {% endfor %}
-            </AppCookieStickinessPolicies>
-            <LBCookieStickinessPolicies>
-            {% for policy in load_balancer.policies %}
-                {% if policy.policy_type_name == "LbCookieStickinessPolicy" %}
-                    <member>
-                        {% if policy.cookie_expiration_period %}
-                        <CookieExpirationPeriod>{{ policy.cookie_expiration_period }}</CookieExpirationPeriod>
-                        {% endif %}
-                        <PolicyName>{{ policy.policy_name }}</PolicyName>
-                    </member>
-                {% endif %}
-            {% endfor %}
-            </LBCookieStickinessPolicies>
-            <OtherPolicies>
-            {% for policy in load_balancer.policies %}
-                {% if policy.policy_type_name not in ["AppCookieStickinessPolicy", "LbCookieStickinessPolicy"] %}
-                    <member>{{ policy.policy_name }}</member>
-                {% endif %}
-            {% endfor %}
-            </OtherPolicies>
-          </Policies>
-          <AvailabilityZones>
-            {% for zone in load_balancer.zones %}
-              <member>{{ zone }}</member>
-            {% endfor %}
-          </AvailabilityZones>
-          <CanonicalHostedZoneName>{{ load_balancer.dns_name }}</CanonicalHostedZoneName>
-          <CanonicalHostedZoneNameID>Z3ZONEID</CanonicalHostedZoneNameID>
-          <Scheme>{{ load_balancer.scheme }}</Scheme>
-          <DNSName>{{ load_balancer.dns_name }}</DNSName>
-          <BackendServerDescriptions>
-          {% for backend in load_balancer.backends %}
-            {% if backend.policy_names %}
-            <member>
-                <InstancePort>{{ backend.instance_port }}</InstancePort>
-                <PolicyNames>
-                    {% for policy in backend.policy_names %}
-                    <member>{{ policy }}</member>
-                    {% endfor %}
-                </PolicyNames>
-            </member>
-            {% endif %}
-          {% endfor %}
-          </BackendServerDescriptions>
-          <Subnets>
-          {% for subnet in load_balancer.subnets %}
-              <member>{{ subnet }}</member>
-          {% endfor %}
-          </Subnets>
-        </member>
-      {% endfor %}
-    </LoadBalancerDescriptions>
-    {% if marker %}
-    <NextMarker>{{ marker }}</NextMarker>
-    {% endif %}
-  </DescribeLoadBalancersResult>
-  <ResponseMetadata>
-    <RequestId>f9880f01-7852-629d-a6c3-3ae2-666a409287e6dc0c</RequestId>
-  </ResponseMetadata>
-</DescribeLoadBalancersResponse>"""
-
-APPLY_SECURITY_GROUPS_TEMPLATE = """<ApplySecurityGroupsToLoadBalancerResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <ApplySecurityGroupsToLoadBalancerResult>
-    <SecurityGroups>
-      {% for security_group_id in security_group_ids %}
-      <member>{{ security_group_id }}</member>
-      {% endfor %}
-    </SecurityGroups>
-  </ApplySecurityGroupsToLoadBalancerResult>
-  <ResponseMetadata>
-    <RequestId>f9880f01-7852-629d-a6c3-3ae2-666a409287e6dc0c</RequestId>
-  </ResponseMetadata>
-</ApplySecurityGroupsToLoadBalancerResponse>"""
-
-CONFIGURE_HEALTH_CHECK_TEMPLATE = """<ConfigureHealthCheckResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <ConfigureHealthCheckResult>
-    <HealthCheck>
-      <Interval>{{ check.interval }}</Interval>
-      <Target>{{ check.target }}</Target>
-      <HealthyThreshold>{{ check.healthy_threshold }}</HealthyThreshold>
-      <Timeout>{{ check.timeout }}</Timeout>
-      <UnhealthyThreshold>{{ check.unhealthy_threshold }}</UnhealthyThreshold>
-    </HealthCheck>
-  </ConfigureHealthCheckResult>
-  <ResponseMetadata>
-    <RequestId>f9880f01-7852-629d-a6c3-3ae2-666a409287e6dc0c</RequestId>
-  </ResponseMetadata>
-</ConfigureHealthCheckResponse>"""
-
-REGISTER_INSTANCES_TEMPLATE = """<RegisterInstancesWithLoadBalancerResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <RegisterInstancesWithLoadBalancerResult>
-    <Instances>
-      {% for instance_id in load_balancer.instance_ids %}
-        <member>
-          <InstanceId>{{ instance_id }}</InstanceId>
-        </member>
-      {% endfor %}
-    </Instances>
-  </RegisterInstancesWithLoadBalancerResult>
-  <ResponseMetadata>
-    <RequestId>f9880f01-7852-629d-a6c3-3ae2-666a409287e6dc0c</RequestId>
-  </ResponseMetadata>
-</RegisterInstancesWithLoadBalancerResponse>"""
-
-DEREGISTER_INSTANCES_TEMPLATE = """<DeregisterInstancesFromLoadBalancerResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <DeregisterInstancesFromLoadBalancerResult>
-    <Instances>
-      {% for instance_id in load_balancer.instance_ids %}
-        <member>
-          <InstanceId>{{ instance_id }}</InstanceId>
-        </member>
-      {% endfor %}
-    </Instances>
-  </DeregisterInstancesFromLoadBalancerResult>
-  <ResponseMetadata>
-    <RequestId>f9880f01-7852-629d-a6c3-3ae2-666a409287e6dc0c</RequestId>
-  </ResponseMetadata>
-</DeregisterInstancesFromLoadBalancerResponse>"""
-
-SET_LOAD_BALANCER_SSL_CERTIFICATE = """<SetLoadBalancerListenerSSLCertificateResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
- <SetLoadBalancerListenerSSLCertificateResult/>
-<ResponseMetadata>
-    <RequestId>83c88b9d-12b7-11e3-8b82-87b12EXAMPLE</RequestId>
-</ResponseMetadata>
-</SetLoadBalancerListenerSSLCertificateResponse>"""
-
-
-DELETE_LOAD_BALANCER_LISTENERS = """<DeleteLoadBalancerListenersResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
- <DeleteLoadBalancerListenersResult/>
-<ResponseMetadata>
-    <RequestId>83c88b9d-12b7-11e3-8b82-87b12EXAMPLE</RequestId>
-</ResponseMetadata>
-</DeleteLoadBalancerListenersResponse>"""
-
-
-DELETE_LOAD_BALANCER_POLICY = """<DeleteLoadBalancerPolicyResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
- <DeleteLoadBalancerPolicyResult/>
-<ResponseMetadata>
-    <RequestId>83c88b9d-12b7-11e3-8b82-87b12EXAMPLE</RequestId>
-</ResponseMetadata>
-</DeleteLoadBalancerPolicyResponse>"""
-
-DESCRIBE_ATTRIBUTES_TEMPLATE = """<DescribeLoadBalancerAttributesResponse  xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <DescribeLoadBalancerAttributesResult>
-    <LoadBalancerAttributes>
-      <AccessLog>
-        <Enabled>{{ attributes["access_log"]["enabled"] }}</Enabled>
-        {% if attributes["access_log"]["enabled"] == 'true' %}
-        <S3BucketName>{{ attributes["access_log"]["s3_bucket_name"] }}</S3BucketName>
-        <S3BucketPrefix>{{ attributes["access_log"]["s3_bucket_prefix"] }}</S3BucketPrefix>
-        <EmitInterval>{{ attributes["access_log"]["emit_interval"] }}</EmitInterval>
-        {% endif %}
-      </AccessLog>
-      <ConnectionSettings>
-        <IdleTimeout>{{ attributes["connection_settings"]["idle_timeout"] }}</IdleTimeout>
-      </ConnectionSettings>
-      <CrossZoneLoadBalancing>
-        <Enabled>{{ attributes.cross_zone_load_balancing.enabled }}</Enabled>
-      </CrossZoneLoadBalancing>
-      <ConnectionDraining>
-        <Enabled>{{ attributes["connection_draining"]["enabled"] }}</Enabled>
-        {% if attributes["connection_draining"]["timeout"] %}
-        <Timeout>{{ attributes["connection_draining"]["timeout"] }}</Timeout>
-        {% endif %}
-      </ConnectionDraining>
-      <AdditionalAttributes>
-        {% for attribute in attributes.additional_attributes %}
-        <member>
-          <Key>{{ attribute[0] }}</Key>
-          <Value>{{ attribute[1] }}</Value>
-        </member>
-        {% endfor %}
-      </AdditionalAttributes>
-    </LoadBalancerAttributes>
-  </DescribeLoadBalancerAttributesResult>
-  <ResponseMetadata>
-    <RequestId>83c88b9d-12b7-11e3-8b82-87b12EXAMPLE</RequestId>
-  </ResponseMetadata>
-</DescribeLoadBalancerAttributesResponse>
-"""
-
-MODIFY_ATTRIBUTES_TEMPLATE = """<ModifyLoadBalancerAttributesResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <ModifyLoadBalancerAttributesResult>
-  <LoadBalancerName>{{ load_balancer.name }}</LoadBalancerName>
-    <LoadBalancerAttributes>
-      <AccessLog>
-        <Enabled>{{ attributes["access_log"]["enabled"] == 'true' }}</Enabled>
-        {% if attributes["access_log"]["enabled"] == 'true' %}
-        <S3BucketName>{{ attributes["access_log"]["s3_bucket_name"] }}</S3BucketName>
-        <S3BucketPrefix>{{ attributes["access_log"]["s3_bucket_prefix"] }}</S3BucketPrefix>
-        <EmitInterval>{{ attributes["access_log"]["emit_interval"] }}</EmitInterval>
-        {% endif %}
-      </AccessLog>
-      <ConnectionSettings>
-        <IdleTimeout>{{ attributes["connection_settings"]["idle_timeout"] }}</IdleTimeout>
-      </ConnectionSettings>
-      <CrossZoneLoadBalancing>
-        <Enabled>{{ attributes.cross_zone_load_balancing.enabled }}</Enabled>
-      </CrossZoneLoadBalancing>
-      <ConnectionDraining>
-        {% if attributes["connection_draining"]["enabled"] == 'true' %}
-        <Enabled>true</Enabled>
-        <Timeout>{{ attributes["connection_draining"]["timeout"] }}</Timeout>
-        {% else %}
-        <Enabled>false</Enabled>
-        {% endif %}
-      </ConnectionDraining>
-      <AdditionalAttributes>
-        {% for attribute in attributes.additional_attributes %}
-        <member>
-          <Key>{{ attribute[0] }}</Key>
-          <Value>{{ attribute[1] }}</Value>
-        </member>
-        {% endfor %}
-      </AdditionalAttributes>
-    </LoadBalancerAttributes>
-  </ModifyLoadBalancerAttributesResult>
-  <ResponseMetadata>
-    <RequestId>83c88b9d-12b7-11e3-8b82-87b12EXAMPLE</RequestId>
-  </ResponseMetadata>
-</ModifyLoadBalancerAttributesResponse>
-"""
-
-CREATE_LOAD_BALANCER_POLICY_TEMPLATE = """<CreateLoadBalancerPolicyResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <CreateLoadBalancerPolicyResult/>
-  <ResponseMetadata>
-      <RequestId>83c88b9d-12b7-11e3-8b82-87b12EXAMPLE</RequestId>
-  </ResponseMetadata>
-</CreateLoadBalancerPolicyResponse>
-"""
-
-CREATE_LB_COOKIE_STICKINESS_POLICY_TEMPLATE = """<CreateLBCookieStickinessPolicyResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <CreateLBCookieStickinessPolicyResult/>
-  <ResponseMetadata>
-      <RequestId>83c88b9d-12b7-11e3-8b82-87b12EXAMPLE</RequestId>
-  </ResponseMetadata>
-</CreateLBCookieStickinessPolicyResponse>
-"""
-
-CREATE_APP_COOKIE_STICKINESS_POLICY_TEMPLATE = """<CreateAppCookieStickinessPolicyResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <CreateAppCookieStickinessPolicyResult/>
-  <ResponseMetadata>
-      <RequestId>83c88b9d-12b7-11e3-8b82-87b12EXAMPLE</RequestId>
-  </ResponseMetadata>
-</CreateAppCookieStickinessPolicyResponse>
-"""
-
-SET_LOAD_BALANCER_POLICIES_OF_LISTENER_TEMPLATE = """<SetLoadBalancerPoliciesOfListenerResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-    <SetLoadBalancerPoliciesOfListenerResult/>
-    <ResponseMetadata>
-        <RequestId>07b1ecbc-1100-11e3-acaf-dd7edEXAMPLE</RequestId>
-    </ResponseMetadata>
-</SetLoadBalancerPoliciesOfListenerResponse>
-"""
-
-SET_LOAD_BALANCER_POLICIES_FOR_BACKEND_SERVER_TEMPLATE = """<SetLoadBalancerPoliciesForBackendServerResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-    <SetLoadBalancerPoliciesForBackendServerResult/>
-    <ResponseMetadata>
-        <RequestId>0eb9b381-dde0-11e2-8d78-6ddbaEXAMPLE</RequestId>
-    </ResponseMetadata>
-</SetLoadBalancerPoliciesForBackendServerResponse>
-"""
-
-DESCRIBE_INSTANCE_HEALTH_TEMPLATE = """<DescribeInstanceHealthResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <DescribeInstanceHealthResult>
-    <InstanceStates>
-      {% for instance in instances %}
-      <member>
-        <Description>N/A</Description>
-        <InstanceId>{{ instance['InstanceId'] }}</InstanceId>
-        <State>{{ instance['State'] }}</State>
-        <ReasonCode>N/A</ReasonCode>
-      </member>
-      {% endfor %}
-    </InstanceStates>
-  </DescribeInstanceHealthResult>
-  <ResponseMetadata>
-    <RequestId>1549581b-12b7-11e3-895e-1334aEXAMPLE</RequestId>
-  </ResponseMetadata>
-</DescribeInstanceHealthResponse>"""
-
-ENABLE_AVAILABILITY_ZONES_FOR_LOAD_BALANCER_TEMPLATE = """<EnableAvailabilityZonesForLoadBalancerResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <ResponseMetadata>
-    <RequestId>1549581b-12b7-11e3-895e-1334aEXAMPLE</RequestId>
-  </ResponseMetadata>
-  <EnableAvailabilityZonesForLoadBalancerResult>
-    <AvailabilityZones>
-{% for az in availability_zones %}
-      <AvailabilityZone>{{ az }}</AvailabilityZone>
-{% endfor %}
-    </AvailabilityZones>
-  </EnableAvailabilityZonesForLoadBalancerResult>
-</EnableAvailabilityZonesForLoadBalancerResponse>"""
-
-DISABLE_AVAILABILITY_ZONES_FOR_LOAD_BALANCER_TEMPLATE = """<DisableAvailabilityZonesForLoadBalancerResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <ResponseMetadata>
-    <RequestId>1549581b-12b7-11e3-895e-1334aEXAMPLE</RequestId>
-  </ResponseMetadata>
-  <DisableAvailabilityZonesForLoadBalancerResult>
-    <AvailabilityZones>
-{% for az in availability_zones %}
-      <AvailabilityZone>{{ az }}</AvailabilityZone>
-{% endfor %}
-    </AvailabilityZones>
-  </DisableAvailabilityZonesForLoadBalancerResult>
-</DisableAvailabilityZonesForLoadBalancerResponse>"""
-
-ATTACH_LB_TO_SUBNETS_TEMPLATE = """<AttachLoadBalancerToSubnetsResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <AttachLoadBalancerToSubnetsResult>
-    <Subnets>
-      {% for subnet in subnets %}
-      <member>{{ subnet }}</member>
-      {% endfor %}
-    </Subnets>
-  </AttachLoadBalancerToSubnetsResult>
-  <ResponseMetadata>
-    <RequestId>f9880f01-7852-629d-a6c3-3ae2-666a409287e6dc0c</RequestId>
-  </ResponseMetadata>
-</AttachLoadBalancerToSubnetsResponse>"""
-
-DETACH_LB_FROM_SUBNETS_TEMPLATE = """<DetachLoadBalancerFromSubnetsResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
-  <DetachLoadBalancerFromSubnetsResult>
-    <Subnets>
-      {% for subnet in subnets %}
-      <member>{{ subnet }}</member>
-      {% endfor %}
-    </Subnets>
-  </DetachLoadBalancerFromSubnetsResult>
-  <ResponseMetadata>
-    <RequestId>f9880f01-7852-629d-a6c3-3ae2-666a409287e6dc0c</RequestId>
-  </ResponseMetadata>
-</DetachLoadBalancerFromSubnetsResponse>"""
+        result = {"Subnets": all_subnets}
+        return ActionResult(result)


Test patch:
diff --git a/tests/test_elb/test_elb.py b/tests/test_elb/test_elb.py
index 90b8ac058..5b6e7b2ec 100644
--- a/tests/test_elb/test_elb.py
+++ b/tests/test_elb/test_elb.py
@@ -64,14 +64,12 @@ def test_create_load_balancer(zones, region_name):
         "LoadBalancerPort": 80,
         "InstanceProtocol": "TCP",
         "InstancePort": 8080,
-        "SSLCertificateId": "None",
     }
     assert http == {
         "Protocol": "HTTP",
         "LoadBalancerPort": 81,
         "InstanceProtocol": "HTTP",
         "InstancePort": 9000,
-        "SSLCertificateId": "None",
     }
 
 
@@ -176,7 +174,7 @@ def test_create_load_balancer_with_invalid_certificate():
             AvailabilityZones=["us-east-2a"],
         )
     err = exc.value.response["Error"]
-    assert err["Code"] == "CertificateNotFoundException"
+    assert err["Code"] == "CertificateNotFound"
 
 
 @mock_aws
@@ -400,7 +398,7 @@ def test_create_lb_listener_with_ssl_certificate_from_acm():
     assert len(listeners) == 2
 
     assert listeners[0]["Listener"]["Protocol"] == "HTTP"
-    assert listeners[0]["Listener"]["SSLCertificateId"] == "None"
+    assert listeners[0]["Listener"].get("SSLCertificateId") is None
 
     assert listeners[1]["Listener"]["Protocol"] == "TCP"
     assert listeners[1]["Listener"]["SSLCertificateId"] == certificate_arn
@@ -440,7 +438,7 @@ def test_create_lb_listener_with_ssl_certificate_from_iam():
     assert len(listeners) == 2
 
     assert listeners[0]["Listener"]["Protocol"] == "HTTP"
-    assert listeners[0]["Listener"]["SSLCertificateId"] == "None"
+    assert listeners[0]["Listener"].get("SSLCertificateId") is None
 
     assert listeners[1]["Listener"]["Protocol"] == "TCP"
     assert listeners[1]["Listener"]["SSLCertificateId"] == certificate_arn
@@ -469,7 +467,7 @@ def test_create_lb_listener_with_invalid_ssl_certificate():
             ],
         )
     err = exc.value.response["Error"]
-    assert err["Code"] == "CertificateNotFoundException"
+    assert err["Code"] == "CertificateNotFound"
 
 
 @mock_aws
@@ -503,7 +501,7 @@ def test_set_sslcertificate():
 
     listener = elb["ListenerDescriptions"][0]["Listener"]
     assert listener["LoadBalancerPort"] == 80
-    assert listener["SSLCertificateId"] == "None"
+    assert listener.get("SSLCertificateId") is None
 
     listener = elb["ListenerDescriptions"][1]["Listener"]
     assert listener["LoadBalancerPort"] == 81