Founder at Unbounded Systems. TypeScript Enthusiast. Taking some pain out of dev with adaptjs.org
What is "Infrastructure as Code"? If someone checks a bunch of YAML files into a Git repository, do they suddenly become code? That seems more like "Infrastructure as Files" to me. I suppose that's better than infrastructure as a gaggle of shell scripts and some commands run by hand in the middle of the night in a coffee-fueled haze, but it is a far cry from code. How about a system to define infrastructure that really is like code?
How about a system to define infrastructure that really is like code?
Real code -- well-written code -- uses concepts that are largely absent from today's Infrastructure as Code technologies. These concepts are abstraction, modularity, composability, and reusability. In code, you can import a library (reusability) and use its functionality to build your own library (composability). Moreover, you don't need to know the implementation of the library to use it (abstraction). You can even divide up the coding effort among different teams by agreeing on an interface (modularity).
If we really had Infrastructure as Code, we wouldn't see every
deployment system rolling its own complex deployment implementations. But today, everyone rolls their own. Using AWS Fargate? Great! It has a blue-green deployment mechanism built in. Want to use the same logic to blue-green something that isn't using Fargate? Too bad!
With proper Infrastructure as Code, you should have an abstract, reusable, component that knows how to blue-green deploy anything that meets a certain interface. And you should then be able to instantiate that blue-green component, and specify what you want to blue-green (Kubernetes Pods, AWS EC2 Instances, etc.). Just like you do in real code.
We set out to address this problem head on by creating a open source
system that lets you specify your entire application architecture with
reusable library components, while still making it easy to stitch
together custom components when you need them. You know, just like you do with actual code.
We wanted these libraries to be modular, composable and reusable.
We wanted everyone to be able to contribute components so that you can
stitch the best ones together with your own to create your own unique
architecture. And we wanted it to be easy to get started and easy to use, but still powerful enough for mission critical applications.
Why use a web front-end technology? Because the requirements for a good Infrastructure as Code system look a lot like those for a good front-end framework:
Let's take a quick look at how all these things work in Adapt (or you can just get started, no React experience required).
Just like in React, the function App is a component. Its return value is a collection of elements that represent your infrastructure, which, in this example, is at a fairly high level of abstraction. Here, all the details of how the Node.js service is built and deployed are hidden in the
component. Same for
This abstraction allows fairly simple, but powerful, specification of infrastructure and operational behavior. For example, the
component could be very simple, like this:
This component will locally build the Node.js application from source code into a local Docker image (via the
component) and run that image in a local container. Here,
is a primitive element whose behavior is defined by a plugin. This is just like how the behavior of primitive elements
are determined by the browser. Because all primitive component behaviors are defined by plugins, Adapt can be extended to work with any infrastructure or application services that your code needs.
Because all primitive component behaviors are defined by plugins, Adapt can be extended to work with any infrastructure or application services that your code needs.
Fortunately, there is no need to actually write a
component since the Adapt cloud library provides one, but as you can see, it isn't too difficult to build a custom version if you need to.
If you're familiar with React, you know there is a lot more to React than just some clever HTML-like syntax to assemble a web page. In fact, the most powerful part of React is its state model and how it handles re-rendering a web page when state changes. Adapt has the same capability, allowing it to alter infrastructure in response to state changes, triggered by changes in the external environment, such as increased server load, a zone outage, or a push to a GitHub repository.
For example, in the simple
component above, we really want to wait for the
component to be ready before deploying the <docker.Container>. To do this, we use some state to keep track of when the
is ready, and only after it is ready, render the
element. Just like with React, we can use the
hook like this:
Of course, this is such a common operation, Adapt already provides a
component to do this:
component even deals with the tricky case where we want the
to keep running the old container until the new one is ready, along with a few other optimizations. The important thing here is how we can abstract away complex sequencing and roll out behavior using a component. Moreover,
can deal with roll out and updates to any components that meet some basic interface requirements. This means that all the logic around sequenced deploys and updates are reusable.
As Adapt evolves, you will be able to update state based on long running observations. For example, you might be able to dynamically enable a backup availability zone if the main one has failed.
You would also be able to build out components that encapsulate complex functionality, like blue-green deployment, by periodically updating the state that controls how much blue you have vs. green:
You could even monitor data from other applications. For example, the
component could wait for a manual approval from a code review application before continuing to roll out more than 5% of systems with new code.
Of course, all this functionality and complexity would be available in a
component from a library, much like Sequence in the example above, so you wouldn't have to implement complex features yourself.
We think that combining simple, composable, declarative specifications, along with the ability for deployments to dynamically react to their environment is already enough to make Adapt exciting and substantially different than other solutions. But there are other deployment challenges that Adapt addresses too.
Adapt allows you to create a single application architecture specification, then use style sheets to deploy that architecture using different underlying components for each of your environments. For example, in your dev style sheet, you can replace
in the above example with a
component that starts a Docker container and preloads some test data. Your prod style sheet replaces it with a
component that points to a production database that is managed outside Adapt. In a more complex application, you could even style in a custom version of Adapt's
component, which normally just deploys to a docker container, with one that builds the React application, pushes it to S3 and uses AWS cloud front as a CDN.
In a more complex application, you could even style in a custom version of Adapt's <ReactApp> component that normally just deploys to a docker container, with one that builds the React application, pushes it to S3 and uses AWS cloud front as a CDN.
Of course, Adapt also deals with all the typical issues you'd expect a deployment system to handle, like keeping track of each deployment's history and state, deployment logs, and as time goes on much more.
Our goal is to take all the difficult, repetitive, and mundane parts of deployment and make them easy...maybe even fun. That way, you can focus on delivering your application, not managing infrastructure.
If you want to try Adapt, head over to adaptjs.org. Don't worry, you don't need to know React to get started. There are examples and a getting started guide that will have you up and running with your first application in under 5 minutes.
Create your free account to unlock your custom reading experience.