At this point, most IT leaders understand the benefits of Infrastructure-as-code. But many still expect that migrating to the cloud will rid them of scalability issues, IT debt and convoluted system logic – forever.
Unfortunately, few IT leaders and enterprises take the next step: maintaining cloud infrastructure like a piece of software.
When a cloud is maintained the same way as traditional hardware (which many enterprises fall back into), engineers are tasked with manual, “custom” work with no central documentation. If every server instance and network configuration is seen as a snowflake, it should come as no surprise that within 18 months your cloud has the same problems as your on-premises data centers: it takes a long time to update anything, there is little visibility into who owns what, or why changing X broke Y.
When your infrastructure is code, you need to maintain it by following good software development practices:
- Expect requirements to change — and welcome those changes
- Deliver updates frequently (daily/weekly, rather than quarterly)
- Spend time coding, not firefighting or on documentation
- Test everything often & automatically
- Simplify (“the art of maximizing the work not done”)
These are principles that you are no doubt very familiar with from Agile/DevOps philosophy. Developers have long seen these standards as best practices, but systems engineering still lags behind — mostly because with the advent of cloud computing in the enterprise, the specific tactics for implementing these principles are changing rapidly.
In this two-part series, we dive into six tactics to ensure your business is getting the most out of its cloud.
Build modular systems. As your development team becomes more agile, the frequency of large infrastructure changes or additions increases. Rather than building a “perfect” environment manually for today’s applications, invest time upfront in building high quality system components that can be reproduced and rearranged modularly. This time may seem like a waste upfront when requirements are straightforward, but it will streamline future changes.
Separate the functionality of your cloud into independent modules, capable of failing independently as well as re-assembled in varying structures. This means building your cloud’s foundational architectural components as templates: one that creates NAT instance, another that builds public subnets, etc. Substack templates are pulled into a master template per environment.
Modularity has two main advantages in the cloud. First, when you need to create a new cloud stack to support a new application, it is simply a matter of reassembling and customizing those templates rather than starting from scratch. Cloud teams can deliver fully-architected environments to support a new application in a matter of days or even hours. Secondly, it means that updates to your cloud environment can be deployed to a narrow set of templates, limiting the blast radius of errors that travel down your stack.
Separate configuration and code. Separate your infrastructure from your configuration via a configuration tool like Puppet or Ansible. Rather than spinning up “Golden” AMIs and modifying those AMIs, you spin up “Vanilla” templates with CloudFormation and bootstrap those instances with the most recent version of packages, operating systems, etc.
Configuration management improves flexibility of your cloud; meaning your configuration can potentially apply to other systems. It reduces manual work by eliminating the need to replicate configuration work across your environment. Rather than modifying instances and rerolling AMIs, you modify configuration modules once. The declarative nature of the modules ensures the configuration is maintained. Configuration management also improves transparency and locality: configuration is stored in a limited number of places, so it is easier to manage and monitor change.
Code as documentation. The cloud makes it possible to have your cloud templates and configuration management scripts themselves act as a central documentation for both the current state and history of your cloud environment. This documentation is by its very nature continually updated, versioned and specific.
Often it is significantly faster to modify a cloud environment using the CLI or console than modifying central configuration management modules. But if you train your team to push changes to a central configuration management engine, you get central documentation of changes, can impose some governance on what gets pushed when and can roll back changes if problems occur. Your cloud configuration becomes a versioned, frequently updated piece of code. You always have a point-in-time snapshot of your environment by looking at your configuration management module. This becomes more valuable over time; as your environment becomes more complex, centralization and transparency prevent technical debt and over-engineering.
When you maintain your cloud following good software development practices, you create a cloud that is versioned, modular and frequently changed. This should not only be your design principle on Day 1, but your engineers’ mindset on Day 800. Because on Day 800, you do not want your cloud to be an outdated, inscrutable monolith.
Stay tuned for our second half of the series, which will cover how to enable continuous integration and delivery using cloud resources.
About the Author
Jason McKay is the senior vice president and chief technology officer at Logicworks.