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've 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,
it will 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 have not modernized just yet.
So, we'll bring on a VM
and now to actually connect up those dots
we'll need a VPC (Virtual Private Cloud).
So, there we go, we have a basic infrastructure in place.
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 development 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.
I decide, "OK, 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 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 of 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 step-by-step process.
But at the same time, this can come with complexity.
For example, if you wanted to tear down your VMs,
or your environments rather,
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
and what it basically allows you to do is to define the final state of your infrastructure
and then it lets the 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 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.
Let's take this simple example,
if you ran the imperative script multiple times
you would actually end up with a multiple environments
and, in addition, let's say one of the steps halfway through failed
then 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 infrastructure as code,
but, in general, I do prefer a declarative approach.
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 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 are 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 just due to the infrastructure that they're running on.
Now, that really holds them back.
Now, 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.
So, this includes things like versioning.
So, essentially, you want to make sure that any time infrastructure changes,
you're tracking that,
and is generally a best approach for automation.
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 development environment.
This 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 that 99% of the time that works fine,
but some of the times it fails,
and you're in a weird limbo state.
So, let's break that down.
So, we're going from version one to version two.
Now, 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 help debug those problem situations
you would have to wipe out the entire environment
and then redeploy version one and then run those scripts.
Now, that might seem OK the first couple of times you 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.
Thanks for joining me for this quick overview of infrastructure as code.
If you want to learn more about this, or DevOps check out the link below.
Remember you can always get started with a free account on IBM Cloud.
Thank you.