Repository: getmoto/moto

Issue:
ECS/create_service should support Load Balancers
## Feature description

As [the documentation says](http://boto3.readthedocs.io/en/latest/reference/services/ecs.html#ECS.Client.create_service), 

> you can optionally run your service behind a load balancer

The function in `boto3` accepts a parameter called `loadBalancers`, containing an array of dicts.

## Current implementation

As of the current version of moto (1.3.3), when I call `create_service()`:

- the parameter `loadBalancers`  is ignored
- the response of this call always contain an empty array for the key `"loadBalancers"`

I'm going to create a PR to support this feature ASAP, together with a new test scenario.


Discussion:

Resolving patch:
diff --git a/moto/ecs/models.py b/moto/ecs/models.py
--- a/moto/ecs/models.py
+++ b/moto/ecs/models.py
@@ -177,7 +177,7 @@ def response_object(self):
 
 class Service(BaseObject):
 
-    def __init__(self, cluster, service_name, task_definition, desired_count):
+    def __init__(self, cluster, service_name, task_definition, desired_count, load_balancers=None):
         self.cluster_arn = cluster.arn
         self.arn = 'arn:aws:ecs:us-east-1:012345678910:service/{0}'.format(
             service_name)
@@ -199,7 +199,7 @@ def __init__(self, cluster, service_name, task_definition, desired_count):
                 'updatedAt': datetime.now(pytz.utc),
             }
         ]
-        self.load_balancers = []
+        self.load_balancers = load_balancers if load_balancers is not None else []
         self.pending_count = 0
 
     @property
@@ -652,7 +652,7 @@ def stop_task(self, cluster_str, task_str, reason):
         raise Exception("Could not find task {} on cluster {}".format(
             task_str, cluster_name))
 
-    def create_service(self, cluster_str, service_name, task_definition_str, desired_count):
+    def create_service(self, cluster_str, service_name, task_definition_str, desired_count, load_balancers=None):
         cluster_name = cluster_str.split('/')[-1]
         if cluster_name in self.clusters:
             cluster = self.clusters[cluster_name]
@@ -660,10 +660,12 @@ def create_service(self, cluster_str, service_name, task_definition_str, desired
             raise Exception("{0} is not a cluster".format(cluster_name))
         task_definition = self.describe_task_definition(task_definition_str)
         desired_count = desired_count if desired_count is not None else 0
+
         service = Service(cluster, service_name,
-                          task_definition, desired_count)
+                          task_definition, desired_count, load_balancers)
         cluster_service_pair = '{0}:{1}'.format(cluster_name, service_name)
         self.services[cluster_service_pair] = service
+
         return service
 
     def list_services(self, cluster_str):
diff --git a/moto/ecs/responses.py b/moto/ecs/responses.py
--- a/moto/ecs/responses.py
+++ b/moto/ecs/responses.py
@@ -153,8 +153,9 @@ def create_service(self):
         service_name = self._get_param('serviceName')
         task_definition_str = self._get_param('taskDefinition')
         desired_count = self._get_int_param('desiredCount')
+        load_balancers = self._get_param('loadBalancers')
         service = self.ecs_backend.create_service(
-            cluster_str, service_name, task_definition_str, desired_count)
+            cluster_str, service_name, task_definition_str, desired_count, load_balancers)
         return json.dumps({
             'service': service.response_object
         })


Test patch:
diff --git a/tests/test_ecs/test_ecs_boto3.py b/tests/test_ecs/test_ecs_boto3.py
--- a/tests/test_ecs/test_ecs_boto3.py
+++ b/tests/test_ecs/test_ecs_boto3.py
@@ -8,7 +8,7 @@
 from moto.ec2 import utils as ec2_utils
 from uuid import UUID
 
-from moto import mock_cloudformation
+from moto import mock_cloudformation, mock_elbv2
 from moto import mock_ecs
 from moto import mock_ec2
 from nose.tools import assert_raises
@@ -2015,3 +2015,62 @@ def _fetch_container_instance_resources(container_instance_description):
     registered_resources['PORTS'] = \
     [x['stringSetValue'] for x in registered_resources_list if x['name'] == 'PORTS'][0]
     return remaining_resources, registered_resources
+
+
+@mock_ecs
+def test_create_service_load_balancing():
+    client = boto3.client('ecs', region_name='us-east-1')
+    client.create_cluster(
+        clusterName='test_ecs_cluster'
+    )
+    client.register_task_definition(
+        family='test_ecs_task',
+        containerDefinitions=[
+            {
+                'name': 'hello_world',
+                'image': 'docker/hello-world:latest',
+                'cpu': 1024,
+                'memory': 400,
+                'essential': True,
+                'environment': [{
+                    'name': 'AWS_ACCESS_KEY_ID',
+                    'value': 'SOME_ACCESS_KEY'
+                }],
+                'logConfiguration': {'logDriver': 'json-file'}
+            }
+        ]
+    )
+    response = client.create_service(
+        cluster='test_ecs_cluster',
+        serviceName='test_ecs_service',
+        taskDefinition='test_ecs_task',
+        desiredCount=2,
+        loadBalancers=[
+            {
+                'targetGroupArn': 'test_target_group_arn',
+                'loadBalancerName': 'test_load_balancer_name',
+                'containerName': 'test_container_name',
+                'containerPort': 123
+            }
+        ]
+    )
+    response['service']['clusterArn'].should.equal(
+        'arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster')
+    response['service']['desiredCount'].should.equal(2)
+    len(response['service']['events']).should.equal(0)
+    len(response['service']['loadBalancers']).should.equal(1)
+    response['service']['loadBalancers'][0]['targetGroupArn'].should.equal(
+        'test_target_group_arn')
+    response['service']['loadBalancers'][0]['loadBalancerName'].should.equal(
+        'test_load_balancer_name')
+    response['service']['loadBalancers'][0]['containerName'].should.equal(
+        'test_container_name')
+    response['service']['loadBalancers'][0]['containerPort'].should.equal(123)
+    response['service']['pendingCount'].should.equal(0)
+    response['service']['runningCount'].should.equal(0)
+    response['service']['serviceArn'].should.equal(
+        'arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service')
+    response['service']['serviceName'].should.equal('test_ecs_service')
+    response['service']['status'].should.equal('ACTIVE')
+    response['service']['taskDefinition'].should.equal(
+        'arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1')