BookmarkSubscribeRSS Feed

External Binary Access to CAS: Leveraging Automation

Started 5 hours ago by
Modified 5 hours ago by
Views 44

This is the second article of a series presenting how to enable external binary access to SAS Cloud Analytics Services (CAS) by applying core connectivity principles: a valid network route, proper DNS resolution, and trusted TLS certificates.

 

In the first article you can find a description of the architecture, requirements and preliminary checks; here we present a practical walkthrough using the automation provided by cloud environments and the CAS Operator to provision a Kubernetes LoadBalancer Service.

 

The post includes client‑side verification steps, and a connection example using the Python SWAT package, demonstrating end‑to‑end connectivity from an external environment.

 

The core objective is to show the “happy path” for managed/cloud-like environments where Kubernetes can provision a LoadBalancer and possibly assign a DNS record automatically.

 

 

High-level steps

 

  1. Configure: copy and edit the cas-enable-external-services.yaml PatchTransformer template to
    • enable CAS external services
    • configure a service template of type LoadBalancer, optionally including additional security parameters
    • specify the DNS alias optionally used by select cloud providers to automatically configure a DNS record for the load balancer
  2. Apply: reference the new yaml file in the kustomization.yam manifest and apply it to the SAS Viya environment with the same method used for the initial deployment. This triggers the automatic creation of all required artifacts: load balancer service, server TLS certificate, and, if supported by your infrastructure, the DNS alias. When using manual commands, remember to restart the CAS server.
  3. Validate: check the new load balancer external address, verify that its DNS alias resolves correctly, confirm the validity of the server TLS certificate.
  4. Use: from an external client, use the Python SWAT package to open a binary connection to CAS.

 

In short: PatchTransformer → kustomization.yaml → build/apply → restart CAS → validate (Service/DNS/SAN) → client test.

 

 

When this pattern fits

 

You can use a LoadBalancer service as the gateway between external clients and CAS when the Kubernetes environment supports exposing a service through a network load balancer, for example on cloud platforms.

 

As we have seen in the first article, when you define a Kubernetes service of type LoadBalancer on cloud platforms, the Kubernetes cluster triggers the cloud infrastructure to provision a network load balancer configured to route the incoming connections to the CAS controller pod.

 

The CAS Operator can automate the creation of the LoadBalancer service and include the service name in the CAS server TLS certificate, all though simple declarative configuration settings.

 

If the environment has been properly configured, it can also automatically create a DNS record that resolves to the load balancer frontend.

 

01_ER_20260414_01_CAS_Binary_External_Access.png

Select any image to see a larger version.
Mobile users: To view the images, select the "Full" version at the bottom of the page.

 

 

Configuration workflow

 

Start from the example transformer

 

You can find the steps to perform this configuration in the Configure External Access to CAS section of the Optional Customizations page in the “SAS® Viya® Platform: Deployment Guide”.

 

Copy the sample file included with the SAS Viya deployment assets to the working directory, and change its permissions so that you can modify it:

 

cd $deploy;
cp ./sas-bases/examples/cas/configure/cas-enable-external-services.yaml \
   ./site-config/cas-enable-external-services.yaml
chmod +w ./site-config/cas-enable-external-services.yaml

 

This file includes a patch to the CASDeployment custom resource and, if you use it "as it is", it enables a binary connection via a new NodePort service. To get a LoadBalancer service, you must edit the file and add a serviceTemplate section. Also, according to the online documentation, you can add an additional key named publishExtHostnameSuffix so that the CAS Operator will automatically add a corresponding subject alternative name (SAN) to the CAS TLS certificate that is created by the SAS certificate framework. For example, if you specify a publishExtHostnameSuffix value of “.myviya.example.com”, then the TLS certificate will include the full name sas-cas-server-default-bin.myviya.example.com. Notice how we placed a trailing dot in the publishExtHostnameSuffix value: the CAS Operator prepends the service name to this value, and the end result is a full DNS name.

 

Your file should be similar to the following - possibly with a different DNS subdomain value.

 

---
apiVersion: builtin
  kind: PatchTransformer
  metadata:
    name: cas-enable-external-services
  patch: |-
    - op: add
      path: /spec/publishBinaryService
      value: true
    - op: add
      path: /spec/serviceTemplate
      value:
        spec:
          type: LoadBalancer
    - op: add
      path: /spec/publishExtHostnameSuffix
      value: .myviya.example.com
  target:
    group: viya.sas.com
    kind: CASDeployment
    name: .*
    version: v1alpha1

 

Since this is a yaml file, double check that the lines are indented correctly.

 

As with most CAS configuration files, this patch applies to all CAS servers that you might have created in your SAS Viya namespace. If you have multiple CAS servers and only want to enable external connectivity to select instances, then modify accordingly the name selector in the target section.

 

Security considerations

 

You can add additional fields to the serviceTemplate section to further customize the LoadBalancer service that the CAS Operator will create. Typical use cases include security options, such as loadBalancerSourceRanges to restrict traffic through the cloud-provider load balancer to the specified client IP ranges, and custom annotations that instruct the cloud provider to create an internal load balancer (i.e. a load balancer without a public IP address, thus only reachable by clients on an internal network). Here is an example serviceTemplate section that includes additional fields:

 

  - op: add
    path: /spec/serviceTemplate
    value:
      metadata:
        annotations:
          service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "300"       
          service.beta.kubernetes.io/aws-load-balancer-internal: "true"
      spec:
        type: LoadBalancer
  # loadBalancerSourceRanges are optional and depend on your requirements
        loadBalancerSourceRanges:
        - 192.168.0.0/16
        - 10.0.0.0/8

 

Please be aware that within this serviceTemplate you cannot use most of the keys that would be valid for a Kubernetes Service object. SAS Viya official documentation notes that many keys are not supported, for a simple reason: the serviceTemplate defined in this file is applied to every Kubernetes Service created by the CAS Operator. For example, if you add a ports field, the same load balancer port could be defined in multiple Services, which can prevent connectivity.

 

 

Reference the transformer in kustomization.yaml, build, apply, restart

 

After customizing the new patch transformer file, reference it in the transformers block of the kustomization.yaml file, then use the same steps as the initial deployment to create and apply the updated site.yaml manifest to your Kubernetes cluster.

 

If there are no syntax errors, the CAS Operator will immediately create the new service. No restarts are required. Yet, you still need to restart the CAS server pods so that CAS picks up the updated TLS certificate that includes the external DNS alias for the load balancer.

 

 

DNS resolution

 

Since this article focuses on automation, we run our tests in Azure AKS. Why? The publishExtHostnameSuffix key in the serviceTemplate has an additional effect; it instructs the CAS Operator to add the following annotation to the new service: service.beta.kubernetes.io/azure-dns-label-name. This label is used by Azure AKS clusters to automatically create a corresponding DNS entry for the newly-created load balancer.

 

This label is still present, but ignored, on any other Kubernetes platform. On those platforms, it’s up to your IT team to create a DNS entry that correctly resolves the hostname alias/CNAME record for the load balancer.

 

Some solutions can automate the creation of this DNS entry. For example, on OpenShift clusters, Red Hat provides the External DNS Operator, that leverages the open source ExternalDNS project. Once installed and integrated with your DNS server, it can monitor the Kubernetes cluster and automatically register DNS entries for Kubernetes services as soon as they are created.

 

Finally, example manual instructions for AWS clusters are provided at Configure External Access to Amazon Web Services CAS Services.

 

 

Validation checklist

 

It’s finally time to validate the new settings. You should verify all 3 high-level requirements discussed in the previous article: a valid network route (i.e. the new load balancer), proper name and address resolution (i.e. the DNS alias), and TLS trust (i.e. the CAS server certificate).

 

  1. Confirm that the new external service exists

 

After applying the new configuration, check that the namespace contains the expected external service:

 

NS=gelcorp
kubectl -n ${NS} get service sas-cas-server-default-bin

 

Your output should be similar to the following. Verify that the service of type LoadBalancer has been assigned an external IP (or, on AWS, an external DNS name).

 

NAME                         TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)          AGE
sas-cas-server-default-bin   LoadBalancer   172.30.21.88   20.1.248.130   5570:32209/TCP   80s

 

Note: The service name sas-cas-server-default-bin and the frontend port 5570 are fixed by the CAS Operator and cannot be changed. The internal service port (in this example 32209) is randomly assigned by the Kubernetes cluster and cannot be specified, as well.

 

  1. Validate the service DNS alias

 

Validate that the chosen hostname you intend clients to use resolves to the external load balancer IP address.

 

# this corresponds to the value set in publishExtHostnameSuffix
MY_SUBDOMAIN=".myviya.example.com"
echo Looking for the IP address of: "sas-cas-server-default-bin""${MY_SUBDOMAIN}"
dig +short "sas-cas-server-default-bin""${MY_SUBDOMAIN}"

 

You should get the same IP address that was returned in the previous check as the Load Balancer external IP, for example 20.1.248.130.

 

  1. Confirm that the TLS certificate Subject Alternative Name key includes the external hostname and IP

 

You can use the following command to list all the aliases that the CAS Operator has automatically defined for the CAS server certificate:

 

NS=gelcorp
kubectl  -n ${NS} get secret sas-cas-server-default-controller -o jsonpath="{.data['tls\.crt']}" | base64 -d | openssl x509 -text -noout | grep -B 1 "sas-cas-server-default-bin"

 

You should get a result similar to the following. Nested with many other aliases and IP addresses, you should recognize both the full DNS name and the external IP highlighted in the previous steps (in this example, sas-cas-server-default-bin.myviya.example.com and 20.1.248.130) :

 

X509v3 Subject Alternative Name:

DNS:myviya-worker-1, DNS:controller, DNS:controller.sas-cas-server-default, DNS:controller.sas-cas-server-default.gelcorp, DNS:controller.sas-cas-server-default.gelcorp.svc.cluster.local, DNS:gelcorp.myviya.example.com, DNS:localhost, DNS:sas-cas-server-default, DNS:sas-cas-server-default-bin, DNS:sas-cas-server-default-bin.myviya.example.com, DNS:sas-cas-server-default-client, DNS:sas-cas-server-default-controller, IP Address:10.0.1.7, IP Address:10.128.2.64, IP Address:127.0.0.1, IP Address:172.30.196.203, IP Address:172.30.79.248, IP Address:20.1.248.130

 

 

Connecting from a client

 

Now that all the configuration and verification steps have been performed, it's time to start a connection from an external client! For example, you can use a python script from a Windows client.

 

  1. Launch Windows PowerShell from the Windows Start menu
  2. If you do not have it yet, install the python swat package, which provides the required classes to connect to SAS Viya: pip install swat
  3. Launch python and submit the following code, making sure to fill in the server variable the DNS name of the load balancer verified above (i.e. sas-cas-server-default-bin.myviya.example.com)

 

import swat
from pathlib import Path
username = "MyUserName"
password = "MySecretPassword"
### Insert your DNS alias here!
server = "sas-cas-server-default-bin.myviya.example.com"
### Connect to CAS
if server == "sas-cas-server-default-bin.myviya.example.com":
    raise ValueError(f"Please enter *your* DNS server alias in the server variable and try again")
else:
    conn = swat.CAS(server, 5570, username, password)
    print(conn.serverStatus())

 

If you get a printout similar to the following, you have a successful connection:

 

NOTE: Grid node action status report: 3 nodes, 8 total actions executed.

[About]
{'CAS': 'Cloud Analytic Services', 'Version': '4.00', 'VersionLong': 'V.04.00M0P09082025', 'Viya Release': '20260214.1771047480056', 'Viya Version': 'Long-Term Support 2025.09', 'Copyright': 'Copyright © 2014-2025 SAS Institute Inc. All Rights Reserved.', 'ServerTime': '2026-02-16T17:22:51Z', 'System': {'Hostname': 'controller.sas-cas-server-default.gelcorp.svc.cluster.local', 'OS Name': 'Linux', 'OS Family': 'LIN X64', 'OS Release': '5.14.0-427.107.1.el9_4.x86_64', 'OS Version': '#1 SMP PREEMPT_DYNAMIC Wed Jan 14 07:05:59 EST 2026', 'Model Number': 'x86_64', 'Linux Distribution': 'Red Hat Enterprise Linux release 8.10 (Ootpa)'}, 'license': {'site': '(SIMPLE) THIS ORDER IS FOR SAS INTERNAL USE ONLY', 'siteNum': 70180938, 'expires': '20Mar2026:00:00:00', 'gracePeriod': 0, 'warningPeriod': 15}, 'CASHostAccountRequired': 'OPTIONAL', 'Transferred': 'NO', 'GlobalReadOnlyMode': 'NO', 'CASCacheLocation': 'CAS Disk Cache'}

[server]
Server Status
nodes  actions
0      3        8

[nodestatus]
Node Status
                                               name        role  uptime  running  stalled
0  worker-0.sas-cas-server-default.gelcorp.svc.c...      worker  34.958        0        0
1  worker-1.sas-cas-server-default.gelcorp.svc.c...      worker  34.958        0        0
2  controller.sas-cas-server-default.gelcorp.svc...  controller  35.016        0        0

+ Elapsed: 0.00614s, user: 0.00141s, sys: 0.00145s, mem: 1.05mb

 

Conclusion – and what’s next

 

Successfully configuring external binary access to your CAS server requires proper network connectivity, DNS resolution and attention to TLS certificate trust. In this article we have seen how you can use the CAS Operator and infrastructure automation to ensure that all prerequisites are met. These tools not only reduce manual effort but also ensure consistency across deployments, enabling faster identification and resolution of issues. On the other hand, they require certain assumptions and limit some choices; for example, you cannot change the service name and port. In the next article, you will see how to leverage manual steps to get custom choices, using a NodePort service with an external load balancer and TLS certificate customization. And, since with great powers come great failures, the series will end with comprehensive troubleshooting.

 

 

Find more articles from SAS Global Enablement and Learning here.

Contributors
Version history
Last update:
5 hours ago
Updated by:

Catch up on SAS Innovate 2026

Nearly 200 sessions are now available on demand with the SAS Innovate Digital Pass.

Explore Now →

SAS AI and Machine Learning Courses

The rapid growth of AI technologies is driving an AI skills gap and demand for AI talent. Ready to grow your AI literacy? SAS offers free ways to get started for beginners, business leaders, and analytics professionals of all skill levels. Your future self will thank you.

Get started

Article Tags