With the shipment of Stable 2020.1.4 (mid-March 2021) the preferred method of deploying SAS Viya is to use the SAS Viya Deployment Operator, or it should be going forward. In this article we will explore the deployment operator and position it relative to the Lifecycle Operations Tool.
Please note, it is still possible to do a manual install (deployment), but the operator is here to simplify the deployment process and will be the best approach for many or most customer sites.
So, what is the SAS Viya Deployment Operator?
The SAS Viya Deployment Operator is a Kubernetes operator that automates many of the manual tasks that are required to deploy and update the Viya software. The deployment operator can automate SAS Viya deployments in a single namespace or across multiple namespaces within a single Kubernetes cluster.
In the documentation this is referred to as running the operator in namespace mode and cluster-wide mode. This is illustrated below.
Select any image to see a larger version.
Mobile users: To view the images, select the "Full" version at the bottom of the page.
There is also the Orchestration Tool, this is different to the deployment operator. The deployment operator is used to deploy a Viya environment and upgrade it. While the Orchestration Tool is used for what is called “lifecycle operations”. This includes starting and stopping the Viya deployment and other administration tasks.
A Kubernetes operator is an application-specific controller that extends the functionality of the Kubernetes API to create, configure, and manage instances of complex applications on behalf of a Kubernetes user.
In addition to the SAS Viya Deployment Operator, SAS has created other operators to assist with the deployment and operations of the Viya components. For example, the CAS Operator and the SAS Event Stream Processing (ESP) Operator.
We also make use of operators developed by other parties, for example the Crunchy Data Operator. This is illustrated in the figure below. The operators are depicted with the lightning bolt icons.
As previously stated, the operator can run in two modes, namespace mode and cluster-wide mode. The operator is watching for custom resource updates, objects of the type (kind) SASDeployment, when running in cluster-wide mode this can be a CR update in any SAS Viya namespace.
Therefore, it is important that you do NOT run the operator in a mixed mode. That is, having one or more instances of the operator deployed in namespace mode and an operator running in cluster-wide mode. You either need to run a single operator in cluster-wide mode OR deploy the operator to each SAS Viya namespace, but NOT both.
Taking this a step further, I would recommend using the operator in cluster-wide mode for the following reasons:
This approach is illustrated below. In this example, the ‘sas-ops’ namespace is being used for the deployment operator and the Orchestration Tool.
The deployment operator image is pulled from the SAS Container Registry (cr.sas.com), which means you first need to retrieve the deployment assets (the TGZ file) from the my.sas.com portal. Then, there is a simple process to configure and deploy the operator.
As previously stated, the SAS Viya Deployment Operator watches the cluster for SASDeployment custom resource objects. The data in the SASDeployment custom resource is used by the operator when deploying SAS Viya. The operator needs your Viya configuration as input, it doesn’t magically create this, you still must provide the kustomization files.
There are two ways to provide the Viya configuration:
As the name suggests, when using the in-line method, the input YAML files are provided “in-line” in the custom resource YAML. As you can imagine this can very quickly get unmanageable, let alone fraught with YAML indentation problems, and the fact that you may have passwords stored in plain text (it’s in there if you look closely)!
Here is an example of an inline configuration for SAS Viya running in a namespace called 'lab'.
Example 1. Inline configuration method
apiVersion: orchestration.sas.com/v1alpha1
kind: SASDeployment
metadata:
name: lab-inline-sasdeployment
spec:
cadenceName: "stable"
cadenceVersion: "2020.1.4"
cadenceRelease: ""
# The following is an example of how to specify inline user content.
# See documentation for specifying license, client certificate,
# and certificate authority certificate.
userContent:
files:
"kustomization.yaml": |-
---
namespace: lab
resources:
- sas-bases/base
- sas-bases/overlays/cert-manager-issuer # TLS
- sas-bases/overlays/network/ingress
- sas-bases/overlays/network/ingress/security # TLS
- sas-bases/overlays/internal-postgres
- sas-bases/overlays/crunchydata
- sas-bases/overlays/cas-server
- sas-bases/overlays/update-checker # added update checker
- sas-bases/overlays/cas-server/auto-resources # CAS-related
configurations:
- sas-bases/overlays/required/kustomizeconfig.yaml # required for 0.6
transformers:
- sas-bases/overlays/network/ingress/security/transformers/product-tls-transformers.yaml # TLS
- sas-bases/overlays/network/ingress/security/transformers/ingress-tls-transformers.yaml # TLS
- sas-bases/overlays/network/ingress/security/transformers/backend-tls-transformers.yaml # TLS
- sas-bases/overlays/required/transformers.yaml
- sas-bases/overlays/internal-postgres/internal-postgres-transformer.yaml
- site-config/security/cert-manager-provided-ingress-certificate.yaml # TLS
- sas-bases/overlays/cas-server/auto-resources/remove-resources.yaml # CAS-related
#- sas-bases/overlays/scaling/zero-scale/phase-0-transformer.yaml
#- sas-bases/overlays/scaling/zero-scale/phase-1-transformer.yaml
configMapGenerator:
- name: ingress-input
behavior: merge
literals:
- INGRESS_HOST=lab.my-organisation.com
- name: sas-shared-config
behavior: merge
literals:
- SAS_SERVICES_URL=https://lab.my-organisation.com
- name: sas-consul-config ## This injects content into consul. You can add, but not replace
behavior: merge
files:
- SITEDEFAULT_CONF=sitedefault.yaml
# # This is to fix an issue that only appears in RACE Exnet.
# # Do not do this at a customer site
- name: sas-go-config
behavior: merge
literals:
- SAS_BOOTSTRAP_HTTP_CLIENT_TIMEOUT_REQUEST='5m'
generators:
- postgres-custom-config.yaml
"sitedefault.yaml": |-
---
config:
application:
sas.logon.initial:
user: sasboot
password: lnxsas
"postgres-custom-config.yaml": |-
---
apiVersion: builtin
kind: ConfigMapGenerator
metadata:
name: postgresql-custom
behavior: merge
literals:
- |
postgres-ha.yaml=
---
bootstrap:
dcs:
loop_wait: 10 # Added through SAS provided kustomize configMapGenerator
ttl: 30 # Added through SAS provided kustomize configMapGenerator
master_start_timeout: 0 # Added through SAS provided kustomize configMapGenerator
postgresql:
parameters:
archive_timeout: 60 # Added through SAS provided kustomize configMapGenerator
checkpoint_completion_target: 0.9 # Added through SAS provided kustomize configMapGenerator
effective_cache_size: 4GB # Added through SAS provided kustomize configMapGenerator
hot_standby: on # Added through SAS provided kustomize configMapGenerator
log_filename: 'postgresql_%Y%m%d%H%M%S.log' # Added through SAS provided kustomize configMapGenerator
log_line_prefix: '%m' # Added through SAS provided kustomize configMapGenerator
log_min_duration_statement: -1 # Added through SAS provided kustomize configMapGenerator
log_statement: 'none' # Added through SAS provided kustomize configMapGenerator
log_truncate_on_rotation: on # Added through SAS provided kustomize configMapGenerator
logging_collector: on # Added through SAS provided kustomize configMapGenerator
maintenance_work_mem: 128MB # Added through SAS provided kustomize configMapGenerator
max_connections: 1280 # Added through SAS provided kustomize configMapGenerator
max_prepared_transactions: 1280 # Added through SAS provided kustomize configMapGenerator
max_wal_senders: 8 # Added through SAS provided kustomize configMapGenerator
max_wal_size: 2GB # Added through SAS provided kustomize configMapGenerator
min_wal_size: 80MB # Added through SAS provided kustomize configMapGenerator
password_encryption: scram-sha-256 # Added through SAS provided kustomize configMapGenerator
shared_buffers: 4GB # Added through SAS provided kustomize configMapGenerator
ssl_ciphers: 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384' # Added through SAS provided kustomize configMapGenerator
ssl_prefer_server_ciphers: on # Added through SAS provided kustomize configMapGenerator
synchronous_standby_names: '' # Added through SAS provided kustomize configMapGenerator
wal_buffers: 16MB # Added through SAS provided kustomize configMapGenerator
wal_keep_segments: 1000 # Added through SAS provided kustomize configMapGenerator
wal_level: hot_standby # Added through SAS provided kustomize configMapGenerator
wal_log_hints: on # Added through SAS provided kustomize configMapGenerator
work_mem: 16MB # Added through SAS provided kustomize configMapGenerator
initdb:
- encoding: UTF8
- no-locale
postgresql:
pg_hba:
- local all postgres peer
- local all all trust
- local all crunchyadm peer
- hostssl replication primaryuser 0.0.0.0/0 scram-sha-256
- hostssl all all 127.0.0.1/32 scram-sha-256
- hostssl all all 0.0.0.0/0 scram-sha-256
"site-config/security/cert-manager-provided-ingress-certificate.yaml": |-
---
apiVersion: builtin
kind: PatchTransformer
metadata:
name: sas-cert-manager-ingress-annotation-transformer
patch: |-
- op: add
path: /metadata/annotations/cert-manager.io~1issuer
value: sas-viya-issuer # name of the cert-manager issuer that will supply the Ingress cert, such as sas-viya-issuer
target:
kind: Ingress
name: .*
license:
secretKeyRef:
name: order-secrets
key: license
clientCertificate:
secretKeyRef:
name: order-secrets
key: certificate
caCertificate:
secretKeyRef:
name: order-secrets
key: cacertificate
Compare this to the Git method, using a GitLab server called 'gitlab.devops.my-organisation.com'. The 'discovery' project was created by a user called 'cloud-user'.
Example 2. Using GitLab
apiVersion: orchestration.sas.com/v1alpha1
kind: SASDeployment
metadata:
annotations:
environment.orchestration.sas.com/readOnlyRootFilesystem: "false"
operator.sas.com/checksum: ""
name: discovery-sasdeployment
spec:
cadenceName: "stable"
cadenceVersion: "2020.1.4"
cadenceRelease: ""
repositoryWarehouse:
url: https://ses.sas.download/ses ## this is the default value
updatePolicy: Never ## this is the default value. The alternative is 'Releases'
# The following is an example of using URLs to specify user
# content, a license, a client certificate, and a CA certiciate.
userContent:
# See HashiCorp's Go Getter "URL Format" documentation for details:
# https://pkg.go.dev/github.com/hashicorp/go-getter@v1.4.1?tab=overview#url-format
url: git::http://gitlab.devops.my-organisation.com/cloud-user/discovery.git
license:
url: http://gitlab.devops.my-organisation.com/cloud-user/discovery/-/raw/master/secrets/license/SASViyaV4_license.jwt
clientCertificate:
url: http://gitlab.devops.my-organisation.com/cloud-user/discovery/-/raw/master/secrets/entitlement-certificates/entitlement_certificate.pem
caCertificate:
url: http://gitlab.devops.my-organisation.com/cloud-user/discovery/-/raw/master/secrets/ca-certificates/SAS_CA_Certificate.pem
While the Orchestration Tool can be used to create the SASDeployment CR, it is definitely a lot simpler to manage and understand the SASDeployment CR when using the Git method.
Therefore, the other recommendation that I will make is to use a source code repository, such as Git, to place all the configuration files and the custom resource file under version control.
The following diagram illustrates using GitLab and the high-level process flow that happens when using the deployment operator.
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
Data Literacy is for all, even absolute beginners. Jump on board with this free e-learning and boost your career prospects.