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.
introduction
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.
-
Logical Resource Names
Names of resources that the application accesses: databases, database schemas, database users, queues, topics, subscriptions etc.
-
Credentials
API keys, username/passwords, and other proof of identity your application uses to authenticate itself with to the (internal) 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 credentials should be different per environment. The following table shows you for each categories what to do to remove the variables from your infrastructure code.
-
Network endpoints - 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.
-
Logical Resource Name - Keep the same in all environments
There is no need to change the logical resource names per environment, as the instances that serve these resources will be different per environment.
-
Internal Credentials - Generate and deploy per environment
Internal credentials are entirely managed by the system and can be generated per environment, and stored in a secret store.
-
Third Party Credentials - Use workload identity federation or encrypt and store credentials in a secret store
One you avoid hardcoded credentials and use workload identity federation to identity your application at the 3rd party. If this is not an option, encrypt third party credentials in IaC and store in a secret store. Now the application can retrieve them, without exposing them.
-
Feature toggles - Hard-code features toggles
This links the toggle state to the version of your application deployed using your CI/CD pipeline 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.
-
Global context - Add as configuration variables
The global context will be different per environment, so they need to be hard coded.
Conclusion
Of all of the configuration variables you will encounter in your infrastructure as code, you really only need the variables for global context and third party credentials. This will reduce the complexity and improve the reliability of your software delivery pipelines.
Image by Arek Socha from Pixabay
Written by

Mark van Holsteijn
Mark van Holsteijn is a senior software systems architect at Xebia Cloud-native solutions. He is passionate about removing waste in the software delivery process and keeping things clear and simple.
Contact



