These days, it's increasingly crucial to automate your infrastructure—an Infrastructure as Code (IaC) approach can help.
In my most recent lightboarding video, I define Infrastructure as Code (IaC), talk about the difference between an imperative and declarative approach, look at the difference between mutable vs. immutable infrastructure, and explain how each approach impacts your dev environment.
- IBM DevOps
- Try IBM UrbanCode Velocity free for 60 days
- Introduction to DevOps
- Free eBook: DevOps for Dummies
What is Infrastructure as Code (IaC)?
Hi everyone, my name is Sai Vennam, and I'm with the IBM Cloud team. Today, let's talk about Infrastructure as Code.
These days, it's increasingly crucial to automate your infrastructure as applications can be deployed into production up to hundreds of times per day. In addition, infrastructure is fleeting and can be provisioned or deprovisioned in response to load.
Let's start with an example
Let's say you're building out an application, and you've chosen a public cloud. Now, the first thing you decided to do is build your application on Kubernetes. So, we'll have a Kubernetes application stack.
Now, we don't actually have to dive deeper into Kubernetes because it isolates the hardware from the application layer. So, we don't actually have to go in deeper, and it’ll manage that for us.
Next, let's say that, after a week of development, we’ve decided to bring in a VM that holds a legacy application that we haven’t modernized just yet. So, we'll bring in a VM.
And now to actually connect up those dots, we’ll need a VPC.
So, there we go, we have a basic infrastructure in place.
Moving into the test phase and problems that can arise
Now, let's say that I've developed this, it's great, all the infrastructure details are documented—now I'm ready to move it into a test phase.
Now, I know that for best practice, what I should do is create a whole new environment that mimics my dev environment.
To do so I'll go back to my documentation and start following the steps to spin up that infrastructure.
But, let's say that maybe I forgot to document one of the config switches that I've changed, or maybe the platform is different in how it handles provisioning infrastructure. Regardless, the application and test don't work the same way in the new environment.
The approaches to IaC
I decide: Okay, we need to fix this problem and to never have this problem in the future again—we need to take advantage of infrastructure as code.
Let's talk about the first approach to infrastructure automation—it's going to be Imperative.
Now, this is kind of intuitive for most people because an imperative approach allows you to define, step-by-step, how to get your infrastructure into a certain state. So, in general, an imperative approach would use something like a CLI along with maybe a bash script.
So, for example, in this in this case, we could do something like
cli create k8s, and then we would define some additional commands to customize that Kubernetes deployment.
We'll do the same thing for the VM, as well as the VPC.
So, an imperative approach has an advantage. It allows you to really define, step-by-step, how your infrastructure is provisioned. And that generally comes with more power, as well, because you're using the cloud tools and doing it in a kind of step-by-step process.
But, at the same time, this can come with complexity. For example, if you wanted to tear down your environments, or let's say you wanted to scale it up or down, you'd have to write custom scripts.
It's not handled for you in an imperative approach, so this generally doesn't scale well.
Another approach to infrastructure automation is going to be Declarative, and this is actually my favorite approach.
Now, a declarative approach would be something like Terraform. What this basically allows you to do is to define the final state of your infrastructure and then it lets a provider handle the rest. So, instead of defining every step, you just define the final state.
So, in this example, maybe you would do something like define a Kubernetes resource and a VM resource, as well as a VPN or VPC resource.
Another great thing about this is, it's generally managed through just simple config maps. So, if you wanted to do something like define a host, you could do that, maybe a domain, or maybe even the subnets.
So, in general, a declarative approach allows you to more easily manage the configuration and is my preferred approach for automating infrastructure.
Comparing imperative and declarative approaches
Let's take this simple example, if you ran the imperative script multiple times you would actually end up with multiple environments. And, in addition, let’s say one of the steps halfway through failed—you would have to add error handling to tear down the steps that did succeed.
Now, with the declarative approach, no matter how many times you run the script, you end up with the exact same infrastructure. So, you could do it the first time, provision your environment, and then maybe run it again later on to ensure that your environment hasn't changed.
So, I'd say this is very important to can understand the different approaches to Infrastructure as Code but, in general, I do prefer a declarative approach.
DevOps and IaC
Next, let's talk about DevOps.
Now, we all understand how important about DevOps is. When developing an application, you’ll first write some code, you'll want to test that it actually works, and then you want to push it into production. And then, you want to make sure that all of that is always working and you can repeat those processes.
Now, I know there's teams out there that have a perfect agile DevOps flow, but because they're working with legacy infrastructure they have to open a ticket every time they want to get a new VM, and that's kind of just due to the infrastructure that they're running on. Now, that really holds them back.
With Infrastructure as Code, when it’s supported, it allows you to treat your infrastructure with the same level of quality that you treat your code.
This includes things like versioning—so, essentially, you want to make sure that any time infrastructure changes, you’re tracking that—it’s generally a best approach for automation.
Immutable vs. mutable infrastructure
The last thing I want to talk about is immutable vs. mutable infrastructure.
Now, breaking that down, an immutable infrastructure is one that can't be changed—it can't be mutated. Now, at first impression, that might sound like a bad thing; but let's break this down by seeing an example with a mutable approach to infrastructure architecture.
So, we have our example here, and let's say that we're building out the app and we decide we need a database. So, to do so, we'll run a script in our dev environment that brings up that database within our VPC.
Now all of this is working great, so we say, “Hey let's just run that script across all of the environments that we have.”
Now, let's say 99% of the time that works fine, but some of the times it fails—you're in a weird limbo state, so let's break that down.
So, we're going from version one to version two.
We have infrastructure code in place to bring up version one, but now we ran this custom script to move it from version one to version two.
What we essentially have right now is something called configuration drift, or environment drift. Our existing environment is no longer matching what we have in our automation.
Now the problem is, to kind of help debug those problem situations, you would have to wipe out the entire environment and then redeploy version one and then run those scripts. That might seem okay the first couple times to do it, but when moving to scale, it becomes incredibly hard to maintain.
So with an immutable approach to infrastructure and infrastructure automation, every time you want to make a change to the infrastructure, you bring up a brand new environment alongside the old one. And then, once you verify that they're both working, you can bring down the older version.
Now, it's a little expensive because you can imagine that you're running both environments at the same time, but, in general, it's the best practice to ensure that your infrastructure can move to scale.