SAS Viya Configuration Overwriter
SAS Viya has an extensive configuration system that allows you to modify the environment to your specific needs. These are stored as key-value pairs in the SAS Configuration Server. The Viya configuration can be managed in two main ways, through SAS Environment Manager and through the configuration plugin in the SAS Viya CLI. When managing multiple environments you may want to automate and standardize the configuration of an environment. The default way of achieving this is to use a sitedefault file to bulk-load configuration settings. Using the sitedefault file has its drawbacks though:
Configuration is only loaded upon starting Consul
Configuration in sitedefault will never overwrite changes made through SAS Environment Manager or the CLI
Configuration settings cannot be changed using sitedefault, only new settings can be added
So if you want to enforce that an environment is configured with a specific set of configuration settings you will need an alternative way to handle this.
To this end, I created a Kubernetes CronJob that uses the Viya CLI container image to automate the writing of configuration settings based on your existing sitedefault file. Because this CronJob uses the CLI and is independent of Consul, it removes the two limitations mentioned above. It forcefully overwrites the configuration in Consul so that it matches with the defined settings in the sitedefault file. As the process only uses SAS-provided and documented interfaces, it can be used in any environment.
The process is visually shown below:
The CronJob is deployed using an Azure DevOps pipeline that also converts the sitedefault file from YAML to JSON so that it can be parsed using the jq binary included in the SAS Viya CLI image. Although I used Azure DevOps to deploy it, the steps in the pipeline can easily be converted and used with other automation tools or scripts.
Once the sitedefault file is converted, the pipeline creates a configmap out of it. The only manual step is to register client credentials with which the Configuration Overwriter can access to Viya environment. Please ensure that SASAdministrators is added as an "authority" for the client credentials in order to allow the oauth client to change all configuration settings.
You can find the pipeline and CronJob definition attached to this post. I will highlight the critical parts of both below.
The pipeline uses Azure DevOps specific tasks de convert the sitedefault file and deploy it as a configmap, but essentially executes the following commands:
yq site-config/sitedefault.yaml -o json > sitedefault.json
kubectl create configmap sitedefault \
--from-file sitedefault.json \
--dry-run=client -o yaml > sitedefault_cm.yaml
kubectl apply -f sitedefault_cm.yaml
After this has been completed, it deploys a CronJob with the following job template:
jobTemplate:
spec:
template:
spec:
volumes:
- name: sitedefault
configMap:
name: sitedefault
containers:
- name: configuration-overwriter
image: <acr name>.azurecr.io/viya-4-x64_oci_linux_2-docker/sas-viya-cli:<cli version>
command: ["/bin/bash","-c"]
args:
- |
#1 export OAUTH_TOKEN=$(curl -k -X POST 'https://<environment fqdn>/SASLogon/oauth/token' -H 'Content-Type: application/x-www-form-urlencoded' -d 'grant_type=client_credentials' -u $client_id:$client_secret | jq .access_token --raw-output)
#2 for service in $(cat /sitedefault/sitedefault.json | jq -r '.config | keys[]'); do
#3 for definition in $(cat /sitedefault/sitedefault.json | jq --arg service "$service" -r '.config[$service] | keys[]'); do
#4 for setting in $(cat /sitedefault/sitedefault.json | jq --arg service "$service" --arg definition "$definition" -r '.config[$service][$definition] | keys[]'); do
if [ "$service" == "application" ]; then applied_service="GLOBAL"; else applied_service="$service"; fi
#5 update_value=$(cat /sitedefault/sitedefault.json | jq --arg service "$service" --arg definition "$definition" --arg setting "$setting" '.config[$service][$definition][$setting]');
#6 ./sas-viya --quiet configuration configurations download --definition-name $definition --service $applied_service --target ${definition}_${applied_service}.json
#7 current_value=$(jq --arg setting "$setting" '(.items[0][$setting])' ${definition}_${applied_service}.json)
if [ "$update_value" == "$current_value" ];
then
echo "Not updating $applied_service definition $definition. Setting $setting is already configured as $update_value"
else
echo "Updating $applied_service definition $definition. Changing setting $setting from $current_value to $update_value"
jq --arg setting "$setting" --argjson update_value "$update_value" '(.items[0][$setting]) = $update_value' ${definition}_$applied_service.json > ${definition}_${applied_service}_update.json
./sas-viya configuration configurations update --file ${definition}_${applied_service}_update.json
fi
done
done
done
env:
#8 - name: SAS_SERVICES_ENDPOINT
value: "https://<environment fqdn>"
#9 - name: SAS_SKIP_OAUTH_EXPIRY_CHECK
value: "true"
envFrom:
#10 - secretRef:
name: configuration-overwriter-secret
#11 volumeMounts:
- name: sitedefault
mountPath: /sitedefault
A little explanation on the highlighted lines in the code:
Obtain an oauth token using client credentials.
Loop through all services defined in sitedefault
Loop through all definitions for a particular service
Loop through all settings for a particular definition
Retrieve the value to set for that particular setting
Download the current configuration definition for the service
Retrieve the current value of the setting from the downloaded configuration
We need to set SAS_SERVICE_ENDPOINT
By default, SAS checks whether a user is logged on by looking at stored credentials. As we do not log on to the environment, but use OAUTH_TOKEN variable directly, we need to set SAS_SKIP_OAUTH_EXPIRY_CHECK.
The client credentials required by the Configuration Overwriter should be stored in a secret within the SAS Viya namespace prior to deployment.
Here we mount the converted sitedefault file so it can be read by the Configuration Overwriter.
I hope this utility proves helpful and allows you to improve the stability and consistency of your Viya environments. It allows for a quick and consistent way to apply configuration settings to your environment and makes it much easier to deploy the same set of configuration over multiple environment with no chance of user error.
... View more