Map application dependencies to prepare for cloud migration
The practices a development team puts in place to manage dependencies before a move to the cloud will determine how smoothly apps run long after they get there.
Developers build enterprise apps from a series of interconnected components, and those components have explicit dependencies on OSes and middleware. This means, if an application becomes unstable, it can take weeks to resolve, and these challenges are only amplified in the cloud.
Nearly every development team has experienced issues when an update to one part of an app breaks the workflow exchange among other application components. The same problem exists with OS and middleware versions, but on a larger scale.
Almost every commercial and open source software project has a series of releases. In many cases, these releases are meant to accommodate new features available in the platform APIs that OS and middleware expose to developers. Every one of these releases defines a cascade of application dependencies, and without proper synchronization, failures can occur.
Dependencies in the cloud are even more complex, as the application might maintain some of its on-premises dependencies and add new ones as well.
Application dependencies in cloud
Public cloud services have their own platform APIs, and every tool the cloud provider offers -- both for operations and development teams -- has its own specific dependencies. These vary among providers, and they are in addition to any built-in dependencies that are part of the machine images set to deploy in the cloud. It's difficult enough to resolve these machine image dependencies with those of the public cloud provider, but if the images have unresolved problems, it's impossible.
The key is to harmonize your machine image platform versions across all applications and standardize the OS and middleware for everything you plan to deploy to the cloud. This new standard set of platform tools should become the basis for your application lifecycle management tasks, from development to deployment. Don't build, test or run with a hodgepodge of OS and middleware combinations, except when special features demand it.
Follow the dependency chain
It's helpful to visualize an application as a hierarchy -- a chain of dependent tools and APIs that start with the application's own interfaces and work downward through the platform tools. The goal of dependency management is to identify combinations of versions that work together and then ensure that, if something changes, your development team recognizes the new application dependencies.
To start this dependency chain process, version your own application components. If you have a software component that you plan to deploy independently, assign it a version number for each revision, and track the underlying dependency chain for that version. That way, you'll know what specific platform tool versions are associated with every application version. If you have to roll back for some reason, you'll know what other components to roll back to maintain version compatibility.
This approach requires you to change some platform components, including middleware, so you'll need to synchronize each application's platform versions. To do this, always start at the top of the dependency chain. Developers design applications to use specific OS and middleware features and, usually, to expect "version X or later" of the tools they use. For each tool that has a specified version, developers need to validate it against its own dependencies, as well as validate each of those dependencies, until they reach the bottom of the chain.
Not all application dependencies are obvious and explicit. Many developers run into problems because they expect to run a guest OS in a VM whose own hypervisor platform comes from a different source. Many also encounter problems when a given release of a cloud stack, such as OpenStack, requires a specific version of a scripting language. Test each dependency chain against your standard OS and middleware combination, and ensure that everything that's dependent is recognized.
Move to cloud
When you're ready to migrate to the cloud, supplement your dependency tree for each application to include all references to your cloud provider's features and APIs. Make sure you understand how your cloud provider will notify you of changes to APIs and tools, and prepare to validate any new dependencies that these changes might create.
If you plan to have a hybrid or multi-cloud deployment, compare these cloud dependency trees for all applications and components that will migrate across cloud platform boundaries. If you have different dependency trees for two different providers, expect problems if you scale or fail over between those providers' platforms. To avoid this, synchronize components upfront.
Finally, rebuild your dependency trees every time you change any software platform component. Your lifecycle management processes have to ensure that all the work you've done to resolve dependency problems isn't undone by the introduction of an incompatible element. One simple update can undo everything, and unlike application version changes, changes to a small piece of middleware are easy to overlook.