<p>In brief,These are the steps I have done :</p>

<ol>
<li><p>Launched <strong>2</strong> new <code>t3 - small</code> instances in aws, pre-tagged with key
<code>kubernetes.io/cluster/&lt;cluster-name&gt;</code> and value <code>member</code>.</p></li>
<li><p>Tagged the new security with same tag and opened all ports mentioned
here -
<a href="https://kubernetes.io/docs/setup/independent/install-kubeadm/#check-required-ports" rel="nofollow noreferrer">https://kubernetes.io/docs/setup/independent/install-kubeadm/#check-required-ports</a></p></li>
<li><p>Changed <code>hostname</code> to the output of <code>curl
http://169.254.169.254/latest/meta-data/local-hostname</code> and verified
with <code>hostnamectl</code></p></li>
<li><p>Rebooted</p></li>
<li><p>Configured aws with
<code>https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html</code></p></li>
<li><p>Created <code>IAM role</code> with full (<code>"*"</code>) permissions and assigned to EC2
instances.</p></li>
<li><p>Installed <code>kubelet kubeadm kubectl</code> using <code>apt-get</code></p></li>
<li><p>Created <code>/etc/default/kubelet</code> with content
<code>KUBELET_EXTRA_ARGS=--cloud-provider=aws</code></p></li>
<li><p>Ran <code>kubeadm init --pod-network-cidr=10.244.0.0/16</code> on one instance
and used output to <code>kubeadm join ...</code> other node.</p></li>
<li><p>Installed <a href="https://www.digitalocean.com/community/tutorials/how-to-install-software-on-kubernetes-clusters-with-the-helm-package-manager" rel="nofollow noreferrer">Helm</a>.</p></li>
<li><p>Installed <a href="https://akomljen.com/aws-cost-savings-by-utilizing-kubernetes-ingress-with-classic-elb/" rel="nofollow noreferrer">ingress controller</a> with default backend.</p></li>
</ol>

<p>Previously I have tried the above steps, but, installed ingress from the instructions on <a href="https://kubernetes.github.io/ingress-nginx/deploy/#aws" rel="nofollow noreferrer">kubernetes.github.io</a>. Both ended up with same status, <code>EXTERNAL-IP</code> as <code>&lt;pending&gt;</code>.</p>

<hr>

<p>Current status is :</p>

<p><code>kubectl get pods --all-namespaces -o wide</code></p>

<pre><code>NAMESPACE     NAME                                                                   IP              NODE                                           
ingress       ingress-nginx-ingress-controller-77d989fb4d-qz4f5                      10.244.1.13     ip-YYY-YY-Y-YYY.ap-south-1.compute.internal               
ingress       ingress-nginx-ingress-default-backend-7f7bf55777-dhj75                 10.244.1.12     ip-YYY-YY-Y-YYY.ap-south-1.compute.internal               
kube-system   coredns-86c58d9df4-bklt8                                               10.244.1.14     ip-YYY-YY-Y-YYY.ap-south-1.compute.internal               
kube-system   coredns-86c58d9df4-ftn8q                                               10.244.1.16     ip-YYY-YY-Y-YYY.ap-south-1.compute.internal               
kube-system   etcd-ip-XXX-XX-XX-XXX.ap-south-1.compute.internal                      172.31.12.119   ip-XXX-XX-XX-XXX.ap-south-1.compute.internal              
kube-system   kube-apiserver-ip-XXX-XX-XX-XXX.ap-south-1.compute.internal            172.31.12.119   ip-XXX-XX-XX-XXX.ap-south-1.compute.internal              
kube-system   kube-controller-manager-ip-XXX-XX-XX-XXX.ap-south-1.compute.internal   172.31.12.119   ip-XXX-XX-XX-XXX.ap-south-1.compute.internal              
kube-system   kube-flannel-ds-amd64-87k8p                                            172.31.12.119   ip-XXX-XX-XX-XXX.ap-south-1.compute.internal              
kube-system   kube-flannel-ds-amd64-f4wft                                            172.31.3.106    ip-YYY-YY-Y-YYY.ap-south-1.compute.internal               
kube-system   kube-proxy-79cp2                                                       172.31.3.106    ip-YYY-YY-Y-YYY.ap-south-1.compute.internal               
kube-system   kube-proxy-sv7md                                                       172.31.12.119   ip-XXX-XX-XX-XXX.ap-south-1.compute.internal              
kube-system   kube-scheduler-ip-XXX-XX-XX-XXX.ap-south-1.compute.internal            172.31.12.119   ip-XXX-XX-XX-XXX.ap-south-1.compute.internal              
kube-system   tiller-deploy-5b7c66d59c-fgwcp                                         10.244.1.15     ip-YYY-YY-Y-YYY.ap-south-1.compute.internal  
</code></pre>

<p><code>kubectl get svc --all-namespaces -o wide</code></p>

<pre><code>NAMESPACE     NAME                                    TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE   SELECTOR
default       kubernetes                              ClusterIP      10.96.0.1        &lt;none&gt;        443/TCP                      73m   &lt;none&gt;
ingress       ingress-nginx-ingress-controller        LoadBalancer   10.97.167.197    &lt;pending&gt;     80:32722/TCP,443:30374/TCP   59m   app=nginx-ingress,component=controller,release=ingress
ingress       ingress-nginx-ingress-default-backend   ClusterIP      10.109.198.179   &lt;none&gt;        80/TCP                       59m   app=nginx-ingress,component=default-backend,release=ingress
kube-system   kube-dns                                ClusterIP      10.96.0.10       &lt;none&gt;        53/UDP,53/TCP                73m   k8s-app=kube-dns
kube-system   tiller-deploy                           ClusterIP      10.96.216.119    &lt;none&gt;        44134/TCP                    67m   app=helm,name=tiller
</code></pre>

<hr>

<pre><code>kubectl describe service -n ingress ingress-nginx-ingress-controller
Name:                     ingress-nginx-ingress-controller
Namespace:                ingress
Labels:                   app=nginx-ingress
                          chart=nginx-ingress-1.4.0
                          component=controller
                          heritage=Tiller
                          release=ingress
Annotations:              service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: *
Selector:                 app=nginx-ingress,component=controller,release=ingress
Type:                     LoadBalancer
IP:                       10.104.55.18
Port:                     http  80/TCP
TargetPort:               http/TCP
NodePort:                 http  32318/TCP
Endpoints:                10.244.1.20:80
Port:                     https  443/TCP
TargetPort:               https/TCP
NodePort:                 https  32560/TCP
Endpoints:                10.244.1.20:443
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   &lt;none&gt;
</code></pre>

<p>attached IAM role inline policy</p>

<pre><code>{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        }
    ]
}
</code></pre>

<hr>

<p>kubectl get nodes -o wide</p>

<pre><code>NAME                                           STATUS   ROLES    AGE     VERSION   INTERNAL-IP     EXTERNAL-IP     OS-IMAGE             KERNEL-VERSION   CONTAINER-RUNTIME
ip-172-31-12-119.ap-south-1.compute.internal   Ready    master   6d19h   v1.13.4   172.31.12.119   XX.XXX.XXX.XX   Ubuntu 16.04.5 LTS   4.4.0-1077-aws   docker://18.6.3
ip-172-31-3-106.ap-south-1.compute.internal    Ready    &lt;none&gt;   6d19h   v1.13.4   172.31.3.106    XX.XXX.XX.XXX   Ubuntu 16.04.5 LTS   4.4.0-1077-aws   docker://18.6.3
</code></pre>

<hr>

<p>Could someone please point out what am I missing here, as everywhere on the internet it says a <code>Classic ELB</code> will be deployed automatically ?</p>

<p>For AWS ELB (type Classic) you have to </p>

<ol>
<li><p>Explicitly specify <code>--cloud-provider=aws</code> in kube services manifests
located in <code>/etc/kubernetes/manifests</code> on the master node:</p>

<p><code>kube-controller-manager.yaml
 kube-apiserver.yaml</code></p></li>
<li><p>Restart services:</p>

<p><code>sudo systemctl daemon-reload</code></p>

<p><code>sudo systemctl restart kubelet</code></p></li>
</ol>

<hr>

<p>Along with other commands, add at bottom or top as you wish. The result should be similar to :</p>

<p>in <em>kube-controller-manager.yaml</em> </p>

<pre><code>spec:
  containers:
  - command:
    - kube-controller-manager
    - --cloud-provider=aws
</code></pre>

<p>in <em>kube-apiserver.yaml</em> </p>

<pre><code>spec:
  containers:
  - command:
    - kube-apiserver
    - --cloud-provider=aws
</code></pre>
