In the world of immutable infrastructure and desired state configuration, it is essential to keep the number of variables in your environment to an absolute minimum. In this blog we categorize the different types of variables you may encounter, and give you rules on how to minimize them.
A long time ago, we were at a customer who used XLDeploy to manage their application deployments across four different environments. And they were struggling whenever they needed to add a new application. When I examined their variables, We found more than 150 variables for four different environments. This ment that they potentially had to manage 600(!) different values. As you can imagine, this was way too much for a human brain. How could this be simplified?
types of environment specific variables
When we analysed the different environment specific variables in this system, we found five different types:
- Network endpoints
Hostnames, IP addresses and port number of services that your application connects to.
API keys, username/passwords, and other proof of identity your application uses to authenticate itself with to the services it connects to. Credentials can be split into
credentials given by a third party, or credentials which are part of the system’s scope.
- Feature toggles
Values that change the run-time behaviour of the application.
- Global context
Values that describe the global context of your application: Its external DNS domain name, environment name, target Cloud accounts, external service endpoints and credentials to name a few.
Just review all your configuration variables. Did you find other categories? Let us know. Now check the values of each of the variables for different environments. If a variable has the same value in two or more environments, it might be that your system is deployed with dependencies across environments. This is a sign of infrastructure smell.
how to minimize the number of variables
Of these five categories, only the global context and the credentials should be different per environment. Of these, the global context should be specified as variables in source code. Credentials should be generated and deployed per environment. For each of the categories, we will tell you what to do.
- Replace network endpoints with unqualified DNS names.
Now the environment resolves the appropriate network endpoint to connect to. You no longer need a variable.
You can register your service endpoints in your private DNS associated with your internal network, and configure the DNS resolver to first look in your internal domain name.
If you use kubernetes, this is done automatically for you. The DNS search domain of the kubernetes cluster will resolve to the correct service endpoint in your cluster. It even supports <service>.<namespace> names to connect to endpoints in other namespaces.
- Store credentials in a secret store.
Now the application can just retrieve the credentials from the secret store. The secret name is the same in every environment, so you can remove the variable.
- Hard-code features toggles
Now the version of your application is linked with the feature toggle in the desired state. Your CI/CD pipeline will deploy it across your environments. This allows you to validate the behaviour of that setting in the different environments, in the same way as you would any other application change.
If a feature toggle is truly dynamic, it should be part of the application functionality.
By applying the suggestions in this blog, you will be able to reduce the number of variables in your desired state configuration code to just a handful. This will reduce the complexity and improve the reliability of your software delivery process.