title: How to assign a public IP to container running in AWS ECS cluster in EC2 mode
body: <p>I am trying to implement a multi-service ECS cluster using service discovery between the services.  I'm attempting to follow the tutorial <a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-cli-tutorial-servicediscovery.html" rel="noreferrer">Creating an Amazon ECS Service That Uses Service Discovery Using the Amazon ECS CLI</a>.  However, it doesn't include a complete working example</p>
  <p>What I've done is define two services, defined by using:</p>
  <ul>
  <li><code>docker-compose.yml</code></li>
  <li><code>ecs-params.yml</code></li>
  </ul>
  <p>I can easily bring up the ECS cluster and the two services.  Everything looks right.  But one of the services needs a public IP address.  So in the corresponding <code>ecs-params.yml</code> file, I put <code>assign_public_ip: ENABLED</code>.  But no public IP address gets assigned.  In the ECS console, the service details says <code>Auto-assign public IP DISABLED</code>, and for the Task it lists a private IP address and no public IP address.</p>
  <p>Unfortunately, it seems this might not be possible according to the documentation on <a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-networking.html" rel="noreferrer">Task Networking with the <code>awsvpc</code> Network Mode</a>:</p>
  <blockquote>
  <p>The <code>awsvpc</code> network mode does not provide task ENIs with public IP addresses for tasks that use the EC2 launch type. To access the internet, tasks that use the EC2 launch type should be launched in a private subnet that is configured to use a NAT gateway. For more information, see <a href="https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html" rel="noreferrer">NAT Gateways</a> in the <em>Amazon VPC User Guide</em>. Inbound network access must be from within the VPC using the private IP address or routed through a load balancer from within the VPC. Tasks launched within public subnets do not have access to the internet.</p>
  </blockquote>
  <p><strong>Question</strong>: How can I  work around this limitation of AWS ECS EC2 launch type?</p>
  <p>I don't understand why the EC2 launch type would not support public IP addresses?  Or - do I use a different networking mode and then a public IP address would be assigned?  Why isn't the AWS documentation be clearer about this?</p>
  <h3>Source Code</h3>
  <p>The cluster is created using:</p>
  <pre class="lang-sh prettyprint-override"><code>ecs-cli up --cluster-config ecs-service-discovery-stack --ecs-profile ecs-service-discovery-stack --keypair notes-app-key-pair --instance-type t2.micro --capability-iam --force --size 2
  </code></pre>
  <p>There are two services defined, as suggested by the above tutorial.  The <code>backend</code> (a simple Node.js app in a container) and <code>frontend</code> (a simple NGINX server configured to proxy to the backend) services are each in their own directory.  In each directory is <code>docker-compose.yml</code> and <code>ecs-params.yml</code> files.</p>
  <p>The frontend service is brought up using:</p>
  <pre class="lang-sh prettyprint-override"><code>ecs-cli compose --project-name frontend service up --private-dns-namespace tutorial --vpc ${VPC_ID}  --enable-service-discovery --container-port 80 --cluster ecs-service-discovery-stack --force-deployment
  </code></pre>
  <p>Its <code>docker-compose.yml</code> is:</p>
  <pre class="lang-yaml prettyprint-override"><code>version: '3'
  
  services:
      nginx:
          image: USER-ID.dkr.ecr.REGION.amazonaws.com/nginx-ecs-service-discovery
          container_name: nginx
          ports:
              - '80:80'
          logging:
              driver: awslogs
              options: 
                  awslogs-group: simple-stack-app
                  awslogs-region: REGION
                  awslogs-stream-prefix: nginx
  </code></pre>
  <p>And the <code>ecs-params.yml</code> is:</p>
  <pre><code>version: 1
  task_definition:
      task_execution_role: ecsTaskExecutionRole
      ecs_network_mode: awsvpc
      task_size:
          mem_limit: 0.5GB
          cpu_limit: 256
  run_params:
      network_configuration:
          awsvpc_configuration:
              subnets:
                  - &quot;subnet-00928d3fc1339b27b&quot;
                  - &quot;subnet-0ad961884e5f93fb1&quot;
              security_groups:
                  - &quot;sg-0c9c95c6f02597546&quot;
          # assign_public_ip: ENABLED
  </code></pre>
  <p>The backend service is brought up using a similar command and similar <code>docker-compose.yml</code> and <code>ecs-params.yml</code> files.</p>