<p>I'm trying to proxy_pass the traffic based on user-agent. Tried to use server-snippet / configuration-snippet for it, but ingress doesn't allow me. (Forbids to use proxy_pass in server-snippet and argues about duplicates in configuration-snippet)</p>

<p>I can't just use the "backend" as I have to dynamically pass the traffic myself based on user-agent.
Any chances I could do it? Not working configuration example below (without user-agent yet)</p>

<pre><code>apiVersion: extensions/v1beta1
kind: Ingress

spec:
  rules:
  - host: m-rm-qa.yadayadayada
    http:
      paths:
      - path: /
        backend:
          serviceName: frontend-svc
          servicePort: 80
metadata:
  name: rm-frontend-ingress
  namespace: rm-qa
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/server-snippet: |
      proxy_pass http://prerender-service:3000;
      rewrite .* /$scheme://$host$request_uri? break;
</code></pre>

<p>I've tried to reproduce your scenario using Nginx Ingress but without success using <code>server-snippet</code> and <code>configuration-snippet</code>.</p>

<p>I did some researches and see that <code>Nginx Plus</code> there's a snippet called <code>location-snippet</code> that should work. See <a href="https://docs.nginx.com/nginx-ingress-controller/configuration/ingress-resources/advanced-configuration-with-annotations/#snippets-and-custom-templates" rel="nofollow noreferrer">here.</a></p>

<p>Alternatively, I've created a custom Nginx deployment with a Service type <code>LoadBalancer</code> and created a <code>configMap</code> with a custom Nginx configuration, and it's works! </p>

<p>If you want to try, you need to create a <code>configMap</code> with your custom <code>default.conf</code> file, it's looks like this:</p>

<blockquote>
  <p>I'm using the namespace: <code>default</code> for this example, but you can create a custom namespace if you want.</p>
</blockquote>

<p><strong>nginx-custom-config.yaml:</strong></p>

<pre><code>---
apiVersion: v1
kind: ConfigMap
metadata:
  name: custom-nginx-config
  namespace: default
data:
  default.conf: |
    upstream my-svc {
        server echo-svc.default.svc.cluster.local;
    }

    server {
        listen       80;
        server_name  localhost;

        location / {

            root   /usr/share/nginx/html;
            index  index.html index.htm;

            if ($http_user_agent ~* "iPhone|iPad" ) {
                add_header X-Vendor "Apple";
                proxy_pass  http://my-svc;
            }
            if ($http_user_agent ~ Chrome ) {
                add_header X-Vendor "OpenSource";
                proxy_pass  http://my-svc;
            }

            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
        }
        error_page   500 502 503 504  /50x.html;

        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
</code></pre>

<p>Apply to Kubernetes:</p>

<pre><code>kubectl apply -f nginx-custom-config.yaml
</code></pre>

<ul>
<li>I've created <code>upstream</code> called <code>my-svc</code> pointing to my destination service <code>echo-svc.default.svc.cluster.local</code>.</li>
<li>In my <code>location: /</code> there's a condition that matches the <code>User-agent</code>, in this case, if a request was made from a Apple device <code>"iPhone|iPad"</code> a header named <code>X-Vendor</code> with value <code>Apple</code> will be created and redirected the request to my destination service <code>my-svc</code>. The same will happen if the request was made from "Chrome", but the header will be <code>X-Vendor: "OpenSource"</code>.</li>
<li>If the request was made from another browser, like firefox, curl etc... them the Nginx default page will be displayed.</li>
</ul>

<p>After that you need to create a <code>deployment</code> of a Nginx image mounting our <code>configMap</code> as a file inside the containers, like this:</p>

<p><strong>custom-nginx-deployment.yaml:</strong></p>

<pre><code>---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: custom-nginx
spec:
  selector:
    matchLabels:
      app: custom-nginx
  template:
    metadata:
      labels:
        app: custom-nginx
    spec:
      containers:
      - name: custom-nginx
        image: nginx
        volumeMounts:
        - name: custom-nginx-config
          mountPath: /etc/nginx/conf.d
        ports:
        - name: http
          containerPort: 80
        imagePullPolicy: IfNotPresent
      volumes:
        - name: custom-nginx-config
          configMap:
            name: custom-nginx-config
</code></pre>

<p><code>kubectl apply -f custom-nginx-deployment.yaml</code></p>

<p>And finally, creating a <code>LoadBalancer</code> Service to received the requests:</p>

<p><strong>custom-nginx-svc.yaml:</strong></p>

<pre><code>---
apiVersion: v1
kind: Service
metadata:
  name: custom-nginx-svc
  labels:
    app: custom-nginx
spec:
  selector:
    app: custom-nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer
</code></pre>

<p><code>kubectl apply -f custom-nginx-svc.yaml</code></p>

<p>You can check if the container and service was successfully deployed using the commands:</p>

<pre><code>kubectl get pods -l app=custom-nginx
kubectl get svc -l app=custom-nginx
</code></pre>

<p>Hope that helps!</p>
