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 Infrashttps://cdn.filestackcontent.com/EiHhb7IdQ5GdqsuOnDJRtructure 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).
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!
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:
- A declarative specification of what to instantiate. (React apps use a DOM.)
- A declarative syntax when possible. (React uses JSX.)
- Specification of state-based infrastructure updates like blue-green deploy or fail-over. (React was built to make this easy.)
- Components that can encapsulate these state-based updates. (React hooks let components do exactly this.)
- Components that are easy to write, easy to use, and easy to compose. (The whole point of React components.)
- A robust module system for distributing and reusing components.
- A single specification that can work from development through production. (Adapt has some new technology for this one.)
- How do you define a module?
- How do you version the module?
- How do you distribute the module?
component. Same for
component could be very simple, like this:
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.
State and Rebuilding
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 . 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:The
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
In a more complex application, you could even style in a custom version of Adapt’s
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.