With respect to immutability, the first exposure many folks in technology experience with with arrays. An array is a contiguous space of memory for elements of the same time to be groups together. We can quickly read the element because they’re accessed sequentially. However, this adjacency limits our ability to expand because any new elements would require additional memory which could already be allocated to something else. In order to address this, we have to create a new array of the desired size and then copy the values of the original elements into the new array. This is immutability… we can not change some aspect of the original.
Containers provide us another perspective on immutability leading into the ideas of immutable infrastructure. Instead of treating our systems as precious pets we can treat them like cattle. We’re prioritizing the execution and capability of these systems not the intimate details of maintaining the systems. We should be able to quickly build a replacement if a system has some issues and destroy the older instance. This also gives us more flexibility with respect to scale because we can expand out with additional instances when demand increases and contract those systems when they’re no longer needed.
While this approach can be an extensive endeavor, we can at least embrace some aspects of this philosophy.
I have been working with a customer that is migrating virtual machines to a cloud provider. They have certainly grown attached to these systems because they work and they don’t have a lot of comfort with replacing them. It has driven the migration approach and isn’t one that I would recommend to any customer. It took a lot of effort to convince this customer that certain workloads should not be migrated at, rather they should be replaced with new systems that conform to the best practices for the cloud provider’s platform with respect to those systems.
The ideal would be to use Infrastructure as Code tooling that build images (Hashicorp Packer and Ansible) through a series of layers: a Golden Image that implements security concerns and common tooling, a Platform Image that is built from the Golden Image and loads the bits and configuration for services and frameworks, and finally an Application Image that is built from the Platform Image with the latest code for the application. The Application Image can be deployed with Terraform and any load balancing could be updated with some tooling like Consul-Terraform-Sync.
Not everyone is ready to adopt this, however. At a bare minimum, a customer could document that necessary steps for building the system and be prepared to do so. There are many systems that are common across many organizations that should not require significant involvement. For instance, Active Directory Domain Services or Azure Active Directory Connect should be relatively straight forward to replace. When a system like this is on the outs, it should be like losing a friend, but rather just getting another package of paper towels from the store.
This situation has limited the agility of the customer to move into the cloud platform and should be rather concerning. While implementing a full stack of Infrastructure as Code practices may not be the current priority, incorporating some of the ideas can create some progress in that direction. DevOps and Automation start with understanding the processing, how to automate them, and sometimes replacing them with something that is easier to automate. Consider the overall effort to own a system and reduce the burden.