GAP Documentation
GitHub Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage
Edit page

Connecting to DWH using an Stunnel (deprecated)

This method is deprecated. Refer to the connecting to DWH through a gateway guide for the currently supported method.

Introduction

Connecting to the DWH Azure DB from GAP is not straightforward, due to the firewall rules enabled on the host of the DB. These rules only allow connections from a whitelisted range of IP addresses. GAP has a pool of nodes that have whitelisted static IP addresses, thus enabling connections to the DB. The solution described here will show you how to set up an stunnel, which will run on one of the whitelisted nodes and will forward and encrypt the traffic from your Service Mesh enabled GAP application to the DWH DB host.

We are going to set up:

  • A patch file containing:
    • A Deployment containing stunnel
    • A Service for stunnel
    • A ConfigMap for stunnel
  • An Istio ServiceEntry

Stunnel patch file

Create the following patch file, and make sure to replace <application-name> and <namespace-name> with your application and namespace names respectively. This patch file defines three Kubernetes resources.

  • A Deployment: Manages the Pod running an Stunnel container. The Pod is scheduled on a whitelist node. Whitelist nodes have static IP addresses that are allowed through the DWH’s firewall.
  • A Service: Makes the Stunnel discoverable from within the Cluster.
  • A ConfigMap: Contains Stunnel’s configuration to be mounted into the container.

gap/production/gap_stunnel.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: <application-name>-dwh-stunnel
  namespace: <namespace-name>
  annotations:
    gap/daily-restart: enabled
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: <application-name>
      app.kubernetes.io/instance: dwh
  template:
    metadata:
      labels:
        app.kubernetes.io/name: <application-name>
        app.kubernetes.io/instance: dwh
    spec:
      containers:
        - name: "stunnel"
          image: eu.gcr.io/ems-gap-images/stunnel:v2
          command:
            - dumb-init
          args:
            - stunnel
            - /etc/stunnel/config
          ports:
            - containerPort: 8443
              name: stunnel
          securityContext:
            runAsUser: 100
          resources:
            requests:
              memory: 8Mi
              cpu: 100m
          volumeMounts:
            - name: config
              mountPath: "/etc/stunnel"
              readOnly: true
      restartPolicy: Always
      tolerations:
        - key: "role"
          operator: "Equal"
          value: "whitelist-internal"
          effect: "NoSchedule"
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
                - key: role
                  operator: In
                  values:
                  - whitelist-internal
      volumes:
        - name: config
          configMap:
            name: <application-name>-dwh-stunnel
            items:
              - key: config
                path: config
---
apiVersion: v1
kind: Service
metadata:
  name: <application-name>-dwh-stunnel
  namespace: <namespace-name>
  labels:
    app.kubernetes.io/name: <application-name>
    app.kubernetes.io/instance: dwh
spec:
  ports:
    - name: stunnel
      port: 8443
      protocol: TCP
      targetPort: stunnel
  selector:
    app.kubernetes.io/name: <application-name>
    app.kubernetes.io/instance: dwh
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: <application-name>-dwh-stunnel
  namespace: <namespace-name>
  labels:
    app.kubernetes.io/name: <application-name>
    app.kubernetes.io/instance: dwh
data:
  config: |
    foreground = yes
    socket = l:TCP_NODELAY=1
    socket = r:TCP_NODELAY=1

    [remote]
    client = yes
    accept = 0.0.0.0:8443
    connect = emarsyscdi.database.windows.net:1433

Istio Service Entry

This Istio service entry will tell the Istio proxy in your meshed Pod to resolve emarsyscdi.database.windows.net to the Stunnel service. Replace <stunnel-service-cluster-IP> with the Cluster IP of your Stunnel service (found by listing the services in your namespace using k9s or kubectl).

gap/production/gap_dwh_service_entry.yaml

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: stunnel
spec:
  exportTo:
    - "."  
  hosts:
    - emarsyscdi.database.windows.net
  ports:
    - number: 8443
      name: tcp-stunnel
      protocol: TCP
  location: MESH_EXTERNAL
  resolution: STATIC
  endpoints:
    - address: <stunnel-service-cluster-IP>
The spec.exportTo field is critical to have its value set to an array containing only one element, ".". This ensures that the ServiceEntry is only exported to your namespace, and not globally on GAP, which would make it clash with other ServiceEntries that affect the same hosts.