<p>I am learning kubernetes and trying to setup letsencrypt for my web app.</p>
<p>I have bought a domain from amazon route 53. Lets just called it <code>example.com</code></p>
<p>Then I go and create a cluster in azure, install all applications that needed:</p>
<ol>
<li>Install helm <code>choco install kubernetes-helm</code></li>
<li><code>helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx</code></li>
<li><code>helm repo update</code></li>
<li>Apply <code>deployment.yml</code> file</li>
</ol>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp1-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp1
  template:
    metadata:
      name: myapp1-pod
      labels: # Dictionary 
        app: myapp1       
    spec:
      containers: # List
        - name: myapp1-container
          image: stacksimplify/kubenginx:1.0.0
          ports:
            - containerPort: 80
</code></pre>
<ol start="5">
<li>Apply <code>service.yml</code></li>
</ol>
<pre><code>apiVersion: v1
kind: Service
metadata:
  name: myapp1-loadbalancer
  labels: 
    app: myapp1
spec:  
  selector:
    app: myapp1
  ports: 
    - port: 80
      targetPort: 80
</code></pre>
<ol start="6">
<li>Apply <code>ingress.yml</code></li>
</ol>
<pre><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress-demo
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: cluster-issuer-name
    cert-manager.io/acme-challenge-type: http01
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:  
  rules:  
  - host: &quot;example.com&quot;
    http:
      paths:
      - path: /   
        pathType: Prefix     
        backend:
          service:
            name: myapp1-loadbalancer
            port:
              number: 80
  tls:
    - hosts:
      - example.com
      secretName: secret-name
</code></pre>
<ol start="7">
<li><p>In Azure portal, look for public Ip that is associated with the cluster that you created at the beginning. By default, when an k8 cluster is created, azure will create one public ip associated to this cluster. Look for it, go to front end configuration, and take note of the ip.</p>
</li>
<li><p>Run this command below, replace the ip that you have</p>
</li>
</ol>
<pre><code># Use Helm to deploy an NGINX ingress controller
helm install ingress-nginx ingress-nginx/ingress-nginx
    --set controller.replicaCount=2 \
    --set controller.nodeSelector.&quot;beta\.kubernetes\.io/os&quot;=linux \
    --set defaultBackend.nodeSelector.&quot;beta\.kubernetes\.io/os&quot;=linux \
    --set controller.service.externalTrafficPolicy=Local \
    --set controller.service.loadBalancerIP=&quot;YOUR IP&quot; 
</code></pre>
<pre><code>9. If done correctly, you should have load balancer service running now. Verify it with kubernetes: `kubectl get svc`. Take note of this ip address for the load balancer
</code></pre>
<ol start="10">
<li><p>Go to Amazon route 53 dashboard, add a record with the ip address that you have at step 9 for your domain name that you have in <code>ingress.yml</code></p>
</li>
<li><p>Enjoy your work :)</p>
</li>
</ol>
<p>Thank you</p>
<p><strong>I have update my questions with steps on how to product the result. Thanks SOF for awesome support. Hopefully that if someone run into this issue again, they know how to configure it properly.</strong></p>

Hoang Minh
<p>You are missing few minor things which you might need to do and try updating once again.</p>
<p>URL in cluster issue is not for Prod you are using staging, i would recommend using the prod URL only for any case instead of the staging.</p>
<pre><code>apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging  
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: abc@abc.com
    privateKeySecretRef:
      name: letsencrypt-staging
    solvers:
    - http01:
        ingress:
          class: nginx
</code></pre>
<p>Use : <strong><a href="https://acme-v02.api.letsencrypt.org/directory" rel="nofollow noreferrer">https://acme-v02.api.letsencrypt.org/directory</a></strong></p>
<p><strong>Second</strong> :</p>
<p>You have not attached your secret to ingress which ideally will be storing your TLS cert.</p>
<p>How process work is like,</p>
<p>cert-manager get the certificate and store it inside the kubernetes secret, in your case it will be, <strong>letsencrypt-staging</strong> you have mentioned in <strong>clusterissuer</strong>.</p>
<p>This secret also should be attached to ingress so that when anyone hits endpoint ingress use this cert for <strong>HTTPS</strong> traffic.</p>
<p>Full reference example:</p>
<pre><code>apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: cluster-issuer-name
  namespace: development
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: harsh@example.com
    privateKeySecretRef:
      name: secret-name
    solvers:
    - http01:
        ingress:
          class: nginx-class-name
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx-class-name
    cert-manager.io/cluster-issuer: cluster-issuer-name
    nginx.ingress.kubernetes.io/rewrite-target: /
  name: example-ingress
spec:
  rules:
  - host: sub.example.com
    http:
      paths:
      - path: /api
        backend:
          serviceName: service-name
          servicePort: 80
  tls:
  - hosts:
    - sub.example.com
    secretName: secret-name
</code></pre>
<p>in above example i have used the annotatino in ingress : <code>cert-manager.io/cluster-issuer: cluster-issuer-name</code></p>
<p>it will trigger <strong>clusterissuer</strong> to generate cert whenever ingress is created, once cert is created it will be stored in K8s secret. so to attach SSL/TLS cert secret with ingress i have added <strong>TLS</strong> block at last of ingress YAML.</p>
<p>If you are applying my suggested changes you wont need to create this</p>
<pre><code>apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: ssl-cert-staging
  namespace: default
spec:
  secretName: ssl-cert-staging
  issuerRef:
    name: letsencrypt-staging
    kind: ClusterIssuer  
  dnsNames:
  - example.com
</code></pre>
<p>cert-manager will auto-create for you, you can remove this also and just apply above example snippet with minor changes required of name and etc.</p>
