Tag: abstraction

  • Infrastructure Abstraction Will Be Key to Managing Multi-Cloud

    Infrastructure Abstraction Will Be Key to Managing Multi-Cloud

    There’s no doubt we’re now living in a hybrid multi-cloud age. Companies are using major cloud providers like AWS, Azure and GCP with niche cloud computing providers emerging within the market. Simultaneously, many organizations still retain workloads in on-premises data centers or embrace colocation. Regardless of deployment pattern, DevOps teams desire the same elasticity as the cloud, but it’s becoming increasingly difficult to consistently manage the nuances of each service provider.

    To support today’s distributed polyglot architectures, a common layer could ease issues when deploying applications and provisioning various servers. By decoupling the infrastructure control plane from specific cloud providers, a unified management console could bring visibility into cost and performance, empowering CloudOps with knowledge before they commit. But engineering such an outcome would rely on plugins for each environment and a robust set of APIs to enable programmatic control.

    I recently met with Jake Warner, Cycle.io, to explore how increased infrastructure abstraction can solve the above problems. According to Warner, a standard layer for computing management is needed to enable consistent control over multi-cloud and bespoke on-premise environments. Below, we’ll define this concept and consider the benefits infrastructure abstraction could bring to modern enterprise software development.

    The Problems Facing Infrastructure Management

    We like to think that the cloud is pervasive and that everyone’s on board with a similar computing style. However, this is far from the truth. Multi-cloud is rising, and 95% of businesses are making multi-cloud a strategic priority in 2022, a Valtix study found. Yet only about half of respondents felt they had the appropriate tools and skills required to execute a multi-cloud strategy.

    “There’s a lot of value in multi-cloud, including reducing risk, ensuring better uptime and the flexibility to select the best hardware for the use case,” said Warner. “But multi-cloud is extremely complex.” Using multiple clouds means supporting increasingly variable operational processes for each environment. Whether it’s AWS, GCP, Azure, Equinix or Vultr, operators also require a deep level of visibility into telemetry data. This becomes complicated to track as software is increasingly modular and distributed across multiple computing regions.

    Furthermore, on-premises data centers are far from dead—surprisingly, a Spiceworks study found that 98% of enterprises still used on-premises servers. Traditional servers are often preferred due to corporate restrictions or to meet security compliance mandates. It could also be a cultural case of “if it works, don’t fix it.” The dilemma is that you can’t easily obtain common cloud features like auto-scaling and load balancing while on your own infrastructure.

    Another issue Warner described is that traditional platform-as-a-service (PaaS) companies present inherent limitations if you aim to build substantive applications and services. “Many of these PaaS offerings make it really easy to get started but, more often than not, developers are quickly forced to make compromises with their approach. These compromises can create long-term technical issues, especially when it’s time to scale,” he said. “Need a server with a specific hardware configuration in a targeted region? Good luck. For most PaaS companies, their exit ramp is just as defined as their on-ramp.”

    Movements Toward Infrastructure Abstraction

    We’re already seeing movement within the market to manage the operational burdens of multi-cloud. One example is the Infrastructure Abstraction Layer (IAL), open sourced by Cycle.io, which Warner explained can act as a standardized system for deployments. With the specification, an infrastructure provider can generate an API endpoint to enable the provisioning of infrastructure without requiring a deep integration between both services. With this endpoint live, an application development platform or orchestrator gains the ability to send standardized JSON payloads to provision servers, allocate IPs, configure regions and a number of other requests. The response, another JSON payload, confirms that the desired request has been completed and includes a unique ID.

    With more programmatic control over infrastructure, an engineer could interface with a standardized list of all the servers, across a number of providers, to deploy to and act upon this information in one unified console. This layer is an opportune location to help compare costs and server configurations for different regions too. It’s also an advantageous spot to filter by proximity to showcase the closest available servers to optimize delivery.

    Benefits of Unifying Multi-Cloud Deployment

    Decoupling the infrastructure management layer from service providers can bring potential benefits to DevOps, said Warner. For one, it enables operators to extend infrastructure automation into their private data centers, helping them achieve the same programmability they would have in the cloud. A degree of standardization can remove many of the cons of multi-cloud, too—”Developers can move from one provider to another provider without any major changes along the way,” he said.

    Of course, IT doesn’t want an added burden. This is why an API-based solution is required to enable programmability, said Warner. By taking a RESTful API approach to managing a hybrid infrastructure, operators could create custom flows based on fine-grained environmental characteristics that change over time, like latency, expense or location. “One of the neat things is it allows infrastructure providers to constantly make tweaks and improvements without having to resubmit their integration with an underlying platform,” said Warner.

    The Flexibility of LowOps

    Today’s software deployment is increasingly wide and varied—a recent HashiCorp report found that 76% of organizations are already multi-cloud. Multi-cloud brings many advantages, yet it also multiplies the number of operational tasks required. At the same time, organizations want to leverage investments into on-premises data centers for as long as they are economically viable. Automating DevOps for such a varied infrastructure can be difficult without a unified layer decoupled from each niche computing area.

    According to Warner, companies require a LowOps platform and the flexibility to abstract this automation on their own infrastructure when appropriate, which can vary widely. For example, operators may be working with a fleet of tens of thousands of IoT devices. Furthermore, as we’ve covered previously, a LowOps method can be beneficial to small-to-medium-sized companies that may lack the resources to support complex infrastructure like Kubernetes.

    Could something like IAL ever become an open standard? Well, at the time of writing, the IAL specification has only been implemented by Cycle.io and a few of its infrastructure partners, but there’s no reason it couldn’t be extrapolated into a common specification down the line, said Warner. He even foresees a community marketplace or shared registry for infrastructure abstractions, enabling platforms to support hundreds of cloud providers.

    In conclusion, the need for LowOps, combined with the rise of multi-cloud and the staying power of on-premises data centers, is fueling a requirement for a decoupled management center. Infrastructure abstraction could enable the convenience of a PaaS while empowering operators with custom infrastructure choices.

  • DevOps and Automation Abstraction?

    DevOps and Automation Abstraction?

    Similarity breeds consistency, giving way to predictability and, thereby, dropping costs of operations and quality from a lower number of incidents and a shorter duration to resolve them. But at the heart of this chain of events is the recognition that we tend to do certain tasks the same way, over and over again, for a given type of technology. Variability then becomes our enemy.  Consistency becomes our ally.  So the question: How do we as DevOps service providers instill a level of consistency in what we do that is not engineer-specific (i.e. only one guy knows how it is supposed to work) and will still scale at the enterprise level?

    From a people perspective, we use teams, whether co-located in person or virtually using the same backbone of tooling over wide geographical separation. From a process perspective, we use governance and education to ensure the same processes and approaches are taken at a fundamental level across different types of technologies. And finally, from a tooling perspective, we use templates or frameworks (or pick your synonym) that allows us to construct a shell that guides the automation construction to be consistent from parent to child. The combination of these three fundamental elements leads to consistency that scales. But is that all?

    What Are We Missing?

    Could there be another fundamental element we have overlooked—namely, abstraction? Case in point: Consider the effect of a drag-and-drop interface versus a typed one to accomplish a given task. Both look to accomplish the same outcome. One could argue the typed text approach offers more flexibility and customization to get the task done. But the drag-and-drop method offers a consistent, simplistic way of doing a similar task, the same way, over and over again. Examining both methods objectively, the drag-and-drop method offers a level of consistency the typed method never could. For the typed one, you would always have to check to ensure punctuation and lack of changes (additions or deletions) to “know” it was the same script as last time. The drag-and-drop method on the other hand, is “canned” or largely unalterable; it may limit customization (by design), but it excels at consistency.

    The drag-and-drop method achieves this consistency by effectively abstracting the typed or scripted code within it from the user who employs it. The user only makes the choice to use it, when desired (or needed); the rest of the mechanics are abstracted from the user. The reason drag-and-drop methods exist is beyond just consistency, however; it is for simplicity. Apple computers would appear to be founded on this idea. For those of you old enough to remember DOS on PC computers, the parallel here immediately becomes clear. DOS was a typed-based command-line operating system (OS) fully capable of operating a PC many years ago. But Apple’s graphical interface made the same functions “intuitive” and forced the PC industry into Windows to stay competitive. Nobody chooses a command line OS like DOS when something as elegant as iOS exists, or Windows (or pick your graphical poison here).

    A graphical OS abstracts core functions from the user, and makes every attempt to make an elegant intuitive packaging of the same functions. Users “get” an iPhone, which accounts for its sales. You don’t need formal education classes or an eidetic memory to use an iPhone. Users effectively have been abstracted from all the typed code it takes to create an OS like this, millions of lines of such code packaged up into swipes, beeps and elegant graphical displays. Keep in mind, at its core this OS abstracts users from variability that might exist if hundreds of companies created their own versions of iOS. The simplicity is paired with consistency, and the quality of Apple is a result (for better or worse). But whatever the quality of Apple is, it is far better than if a wide degree of variability were permitted in the vendors of iOS or the construction of it.

    Extending Abstraction in DevOps

    Now enter DevOps. Containers are a level of abstraction widely popular in our discipline for keeping hardware particulars away from what are typically software engineers. The value of this abstraction is well-understood. My challenge is simply to extend this thinking into the next tier of DevOps tooling. What if the ability to include database DevOps automation was simply a product of drag-and-drop methods that every build tool understood perfectly? Granted, you may have to limit the expression of this idea to say Oracle or SQL Server at first to capture the nuances and particular capabilities of products and technologies in this space. But if someone built a “container” for Oracle, I would wager the choice to use Oracle would rise substantially over its competitors, at least until those containers or abstraction layers were just as effective with other database products.

    The abstraction phenomenon need not be limited to hardware, or as I have proposed to database platforms. It also could apply to .NET or Java development efforts at the top of the stack. The steps needed to take an idea, code it and put it through the build process are going to be largely similar when working in a .NET shop or a java shop (or pick your particular development tool of choice here). Even the top of the stack—that is to say, the development of applications itself—could be a viable candidate for abstraction from the mundane details as it relates to a build construction or a deployment to a given class of environment.

    Creating effective containers for the application layer in effect limits variability, and increases predictability. I realize it has to be technology-type sensitive. The .NET shops have their own container. The java shops have theirs, and so on. The only question is whether we are able to include enough of the common core steps we take to produce a build with a given technology type to form an abstraction construct of value. Over time, this would include every type of technology widely in use today.

    The effort to simplify through abstractions ultimately would result in our ability to include technologies such as WebSphere at our pleasure. It would also allow us to switch out WebSphere for a new competitor using the same abstraction constructs, universally, just by rebuilding all our apps one time. This kind of power is alluring to development teams. It drives application developers and operations engineers to begin to work together to look for the most cost effective technology that can perform a given spec. Being the best at something is no longer a cage from which there is no escape later.

    Technology components would be selected based on performance and cost of ownership (i.e. operations) later. Switching is ultrasimplistic if all we ever used to include it in our build routine was a drag-and-drop style method with universal, well-defined parameters. A customer’s ability to switch products to the best of breed through easy or simplistic means keeps pressure on vendors to actually be the best of breed. If the performance suffers or a new release is full of bugs, developers just switch it out through abstraction (not long, complicated scripts where everything has to go right, including a full moon on the third Tuesday of the month with a Gregorian chant in the background).

    Impacts to the Bottom Line

    The selection of DevOps tooling often is a cantankerous one in large organizations. Debates ensue about flexibility, extensibility and whether a given tool can be customized to accommodate the unique little snowflake of my development teams. Perhaps these debates are headed in the wrong direction. Perhaps instead of prizing and valuing the extensibility or customization a given tool affords, we should be looking closer at how that extensibility is achieved.

    For an enterprise to make an unwitting choice to get into the script business, is effectively stating: “I will be maintaining the scripts I use to construct a build with as much rigor as I maintain the code these scripts are designed to create builds out of.” So, we just doubled our programming staff without realizing it—one half working on the application code and the other half working on the scripting code that “automates” the delivery of a build during construction. While overall speed may be increased, it comes at the cost of doubling already expensive headcount.

    As an alternative, what if enterprise customers were asking tooling vendors how simplistic their tools are to use, and how standardized are their approaches. While we may not enjoy losing a degree of flexibility as we may be unable to customize a drag-and-drop method construct, the payoffs to the business are simplicity of use and scale at an enterprise level. Not only do I refrain from doubling headcount, I can actually free resources to focus on the disciplines and areas they enjoy most instead of performing script maintenance. Abstraction as a construct: From the hardware layer up through the application layer, it may be a driving fundamental that keeps DevOps scaling and lowering the cost of innovation for many years to come—but only if you begin to ask for it.

    To continue the conversation, feel free to contact me.

  • 5 Key Aspects of High Fidelity DevOps

    5 Key Aspects of High Fidelity DevOps

    As much as we talk about how we should have shared goals spanning Dev and Ops, it’s not nearly as easy as it sounds. To fuel a DevOps culture, we have to build robust tooling, also. That means investing up front in five key areas: abstraction, composability, automation, orchestration, and idempotency. Together, these concepts allow sharing work at every level of the pipeline. Unfortunately, it’s tempting to optimize work at one level and miss the true system bottlenecks.

    Creating production-like fidelity for developers is essential: We need it for scale, security and upgrades. It’s not just about sharing effort; it’s about empathy and collaboration.

    But even with growing acceptance of DevOps as a cultural movement, I believe deployment disparities are a big unsolved problem. When developers have vastly different working environments from operators, it creates a “fidelity gap” that makes it difficult for the teams to collaborate.

    Before we talk about the costs and solutions, let me first share a story from back when I was a bright-eyed OpenStack enthusiast:

    I was at the fourth OpenStack Summit in Boston. My team at Dell had created open deployment automation, Crowbar, that could turn raw servers and install a fully working OpenStack cluster in about 30 minutes. I don’t want to oversell it; there were plenty of rough edges and preconditions. However, the automation worked and OpenStack came up like a kudzu seedling. In fact, we’d actually brought a half-rack of servers to the summit for live production demos.

    On my way back up to the demo rack, I was riding an elevator with one of the founding developers of the project. He was positively glowing over a new project that he’d created called “Devstack” and wanted to show off the cool logo they’d designed. He gushed, “It’s awesome! It runs all of OpenStack in a single python environment on my laptop! You don’t even need Vagrant anymore—it’s a super fast and easy for developers to get OpenStack running because all the configuration is in Python.” I watched as he typed a command, text scrolled and welcomed me to the OpenStack API. “See, now I’m running OpenStack!”

    At the time, it seemed like a harmless toy, since a single-node cloud deployment is useless to users, testers and operators. I pointed out that we’d gotten our multinode automation working in virtual machines (VMs) now so it would be easy to use even without dedicated hardware. He asked what we’d written it in. “Mainly Chef with some Rails UI,” I responded, thinking we’d made some solid 2011 DevOps choices. He was less enthusiastic, because we were not using the developer-preferred Python. Even so, I encouraged him to come by the rack for a demo, but without any anticipation.

    We left the elevator on a friendly wave of OpenStack synergy. He sprinted into the developer lounge and I trudged back to the user and vendor showcase. Even without words to describe it, I saw that the project had started diverging between developers and operators. Developer collaboration drove a need for something fast to set up that ran on a single laptop. More importantly, Devstack stripped away all that messy multinode networking and DevOps tooling that made it hard to configure and run OpenStack. In what turned out to be a one-way journey, there was now a universal developer environment.

    Unfortunately, that developer environment configuration did not translate into production.

    In fact, OpenStack deployments are notoriously challenging and there is an overabundance of divergent approaches. Even with so many efforts, few have managed basic operational milestones such as upgrades and high-availability configurations. I believe a wide fidelity gap is a key, if sad, part of this story.

    We don’t have to live with fidelity gaps!

    In fact, DevOps exists to close those gaps by bringing developers and operators to a shared space. You are already well-versed in the need to treat development as a pipeline with automation to keep it repeatable.

    If we know the challenge, why do we allow these gaps? It’s because fidelity can have too high a cost in terms of complexity, system overhead and time. These costs multiply the faster we try to iterate. That creates a conflict between the organizational benefits of agility and fidelity; sadly, few teams have been willing to burden developers with fidelity or operators with change frequency.

    How Can We Make Fidelity Cost-Effective in Initial and Ongoing Costs?

    There are five components to consider: abstraction, composability, automation, orchestration and idempotency/repeatability.

    Platform abstraction

    Platform abstraction hides the differences between environments and tools that make developer and production environments different. For true fidelity, we use “platform” in a very broad way. A cloud API or server is a platform, but so is an operating system or container system. In practice, there are many possible and acceptable abstraction layers.

    Teams need to invest in ways that allow the same automation to work on multiple platforms in the same way. That requires modifying the automation to be resilient in different environments and accept configurations instead of making assumptions. These changes are good hygiene, anyway, and make your automation more robust and portable.

    The simplest way to add abstraction is externalize environmental configuration. Since it’s difficult for operational systems to detect the broader system configuration, we need to inject that information into your deployments. Unfortunately, that leads to the “massive pre-deploy inventory file” antipattern and our next component.

    Composability

    Composability goes beyond making automation modular. It means that we can flow information, à la functional programming, through the discrete parts of the install.

    In a good composable design, each unit has defined inputs, outputs, preconditions and behaviors. That allows us to chain them together to accomplish work. Our systems should be able to connect outputs from earlier modules to inputs from later ones. This eliminates the “pre-configuration file of doom” because we can build up system knowledge as the work is done. Since the functions are well-known, we can determine if we’ve completed all the needed setup.

    Substitution is even more important than having a chained configuration flow. Since modules are isolated actions and known parameters, we can create alternate modules based on user- or infrastructure-driven requirements. For example, choosing CentOS vs. Ubuntu changes package management; however, downstream applications only care that their packages are installed. We need to make it acceptable to detect and adjust modules based on situational awareness without breaking up our downstream components.

    This type of change tolerance is essential to fidelity.

    Automation

    You may assume this is obvious; however, we all have a tendency to overlook manual steps or setup in our daily work. Common statements such as, “It takes a day to build my dev environment,” or, “We always run this pre-config script the systems are up,” indicate that we are not as automated as we want to admit.

    Fidelity gaps open when teams have different processes.

    We don’t expect developers to use hundreds of physical servers; however, we can expect them to isolate components in ways that are similar to operations. That adds overhead to their work that requires automation. We don’t expect operators to reset and redeploy systems 10 times a day; however, we can expect them to use repeatable configurations that do not require manual intervention.

    Remember: It does not have to be the same automation in all cases! Composability allows us to have equivalent but different paths to the same state.

    Sequence/Orchestration

    There is a downside to composability. If you’ve replaced your fragile monolithic automation with robust composable modules, then you’re going to have to add some complexity to chain them together. It an unavoidable tradeoff because the composite system needs glue to hold together. That glue is orchestration.

    Truthfully, adding orchestration is not a downside. It is a necessity for scale. Any multisystem configuration process requires orchestration to be sustained. The nature of scale applications is that we have to coordinate activities horizontally across the system during deployment, scaling and upgrade. That allows us to create trust relationships between nodes, set up networks before trying to use them and coordinate servers and clients while we upgrade APIs. Wait loops and iterative convergence are difficult to troubleshoot and more difficult to predict.

    There is a concrete benefit when you combine composition and orchestration: Small work units create a system that is very transparent and parallelization in operation. Those are key values in scale ops.

    Idempotency / Repeatability

    The last component is one of the most elusive: idempotency. The objective is to allow multiple runs of modules in our automation system to leave the system in a consistent state. That allows us to repeat execution of a component without harming or undoing work that we’ve already done.

    The concept is not simply skipping work we think we completed! If we rerun an action, then the action should exit in the requested state every time. If the state is already good, then do nothing. If the state is not configured, then create it. If the state is not good, then fix it. Basically, we want to be confident that we can achieve our end goal every time but never make unneeded changes.

    This is not a simple task! The nature of configuration is to change systems, and we usually assume that we are going from unconfigured or misconfigured to correctly configured. For idempotent scripts, we have to guard against going from correctly configured to broken.

    This may seem like a lot of work for developers who usually start from clean systems, but it’s life-saving for operators when a timing error causes a unit to fail.

    Hey, You’re Adding a Lot of Work to my Deployments!

    Following these five principles does add some overhead; however, all of the changes are good hygiene anyway. They make your automation more robust and portable. More importantly, they reduce friction between your development, test and ops processes.

    Deployment fidelity is a real benefit that helps drive success. Hopefully, these five principles have made it a more concrete and obtainable goal.