Embracing Infrastructure as Code: The Key to DevOps Excellence

Embracing Infrastructure as Code: The Key to DevOps Excellence

Over the years, I have given many versions of my talk on building applications with infrastructure as code (IaC). Building with IaC is a practice that I firmly believe every DevOps practitioner should embrace, and it's one that has led me to be a frequent speaker on the topic at developer events and conferences.

There’s so many reasons why I’m on #teamIaC. Let’s talk about some of them.

You can’t rely solely on a cloud provider’s UI

When I see tutorials that build from a cloud provider’s UI, they are often clear and easy to follow. There's something reassuring about following along with step-by-step instructions and clicking through the UI to achieve your desired outcome. It's like having a helpful guide holding your hand every step of the way. This is a great way for developers to learn.

However, there's a catch, and it's a big one: UIs are notorious for their propensity to change—frequently and sometimes drastically. With cloud providers constantly rolling out new features, enhancements, and interface redesigns, what once was a familiar landscape can quickly morph into uncharted territory. And if you rely solely on screenshots to illustrate the steps in a tutorial, well, you're playing a game of catch-up that you're bound to lose.

Think about it: a tutorial that showcases screenshots of a particular UI layout may be spot-on at the time of publication. But fast forward a few months, or even weeks, and those screenshots could be woefully outdated. Buttons might shift positions, menus might undergo a makeover, and new features might render old workflows obsolete. Suddenly, following the tutorial feels like trying to navigate with an outdated map—you're bound to get lost.

So, what's the solution? Infrastructure as code, of course.

One Source of Truth for Deployment

Before I was a developer advocate, I was a test engineer. I was in charge of QA, automation, and end-to-end testing for some pretty big companies. One of the things I had to do was open defect reports for things that weren’t working in the product, and then send them to our development team to fix. However, SO MANY times they would kick back the ticket to me and say, “it works on my machine.” This would cause a screenshot war between QA and dev, and would create an uncomfortable work environment.

If they had built their applications with infrastructure as code, they would have put all of their infrastructure (networks, compute instances, databases, storage, etc.) in a configuration file that can be deployed repeatedly. By using the same configuration files, they could have ensured consistency across environments and accounts. That’s why I’m so vocal about IaC. It gets rid of the “it works on my machine” phenomenon by ensuring that there is one source of truth - this configuration file.

One IaC tool that I've used and recommend is Terraform. When you build templates with Terraform modules, you can manage your infrastructure efficiently and effectively. With modules, you encapsulate your infrastructure configurations into reusable components. This means you can define common infrastructure patterns once and reuse them across multiple projects or environments. It saves time and effort by avoiding the need to rewrite similar configurations repeatedly.

Let’s go through an example. In the above configuration file, I am asking Terraform to create 2 resources: an AWS IAM role, and an AWS Lambda function. Configuration files are declarative, meaning that they describe the end state of your infrastructure. You do not need to write step-by-step instructions to create resources because Terraform handles the underlying logic. You can see here in a format that’s simple and human readable, you describe the overall topology. When you deploy the configuration file, these resources will be created or updated depending on If they exist or not. In this example configuration file, we are saying hello Terraform, please create this IAM role with these configurations, and please create this Lambda function with these configurations. Thank you, have a nice day. Thats it! I don’t need to spell out how to create these resources. Your cloud provider (in this case AWS) will handle the logic to create or update the resources in your config file.

Unlike imperative languages that dictate the step-by-step execution of tasks, declarative languages allow users to specify the desired state of their infrastructure without getting bogged down in implementation details. This declarative approach not only simplifies the process of defining infrastructure configurations but also promotes consistency and repeatability across environments.

Empowering Developers to Self-Service their Infrastructure

Another reason IaC is important is because it empowers developers to take control of their infrastructure and service their own cloud resources. When you use IaC, you have one place with all the steps and configuration for your application that you can reuse whenever you need. This allows you to treat your infrastructure as code. And what do you do with code? You version it, you put it in some kind of repo – in GitHub, or CodeCommit, or something like that. So you can deploy a version, then work on it, then merge a new version, and you can rollback if you need to.

When you move to infrastructure as code, you can do the same thing with your infrastructure as you do with your code. If something breaks and your infrastructure isn’t working, you have the ability to roll back that change, or try a new version, or move it to another environment. With IaC, you can treat infrastructure as you do application code—versioned, tested, and deployed using familiar development tools and workflows.

It’s important to me that developers understand how IaC can enable them in this way to build faster, scalable solutions because this process facilitates collaboration, scalability, and reproducibility of infrastructure changes over time. You can track all of the changes to your infrastructure, roll back to previous versions if needed, and review the history of infrastructure modifications.

Leveraging IaC to Collaborate Across Teams

One of the things I love most about IaC is its ability to foster collaboration between development and operations teams. Gone are the days of siloed workflows and finger-pointing—thanks to IaC, we can work together more effectively, sharing ownership of infrastructure and breaking down traditional barriers. IaC is all about shared ownership of infrastructure. By treating infrastructure as code—something that developers and operations folks can both understand and manipulate—we're leveling the playing field and delegating everyone to contribute to the infrastructure's evolution.

So, when I talk about the benefits of IaC, it's not just about the technical advantages—it's also about the impact it has on the way teams work together. By fostering collaboration, breaking down barriers, and promoting a culture of shared ownership, IaC is not just revolutionizing infrastructure management—it's revolutionizing the way we work. And that's something worth celebrating!

IaC is cloud-agnostic

You can use IaC with any cloud provider. However, there are some things to consider. Many cloud providers have their own IaC tool, but you can only use resources from that specific cloud provider. For example, if your entire stack is on AWS, you should use one of the AWS tools (CloudFormation for non-serverless resources or SAM for serverless resources). If your entire stack is on GCP, then you should use GCP Deployment manager. If you want to build something using more than one cloud provider, then you should use Terraform because it supports multicloud deployments.

Terraform configuration files are written in HCL - HashiCorp Configuration Language. But don’t worry - you don’t need to learn a new language to implement infrastructure as code. Terraform has a registry that you can use to copy and paste resources, and many of them are from the cloud providers themselves. In the Terraform Registry, you have access to thousands of resources you can add to your applications. You just search for the resources, and copy and paste the code into your configuration file.

TL;DR - I don’t care which IaC tool you use, I just care that you’re utilizing a process that is easily repeatable and can be automated in a way that works for you.

Multicloud Deployments

Companies often leverage multiple cloud providers to meet their diverse requirements, and managing infrastructure can quickly become a complex task. However, with Terraform and HCL, you can navigate multi-cloud environments with ease. By abstracting away the nuances of each cloud provider's API behind a unified interface, Terraform enables you to define infrastructure configurations once and deploy them seamlessly across different clouds. Whether provisioning virtual machines in AWS, spinning up Kubernetes clusters in Google Cloud Platform, or configuring databases in Microsoft Azure, DevOps engineers can leverage the power of infrastructure as code to orchestrate their entire infrastructure stack.

IaC Integrations

With infrastructure as code, you have a holistic view of your application. You can add your observability tools, your CI/CD tools, and basically anything with an API to Terraform. This will give you a holistic view of what’s going on in your application and you’ll have a deeper understanding of your ecosystem.

You can seamlessly incorporate observability tools such as Prometheus, Grafana, Datadog, or New Relic into your infrastructure configurations. For example, you can add a Datadog monitor to your Terraform configuration file that will alert you when certain thresholds are met. By defining monitoring dashboards, alerting rules, and data collection mechanisms within Terraform, you can establish a robust observability framework that spans the entire stack. This integration ensures that every aspect of the application, from resource utilization to error rates, is meticulously monitored and analyzed in real-time, facilitating proactive troubleshooting and performance optimization.

You can also integrate CI/CD tools like Jenkins, GitLab CI, or CircleCI into Terraform configurations, which enables you to codify your entire deployment pipeline. By defining pipeline stages, triggers, and dependencies within Terraform modules, you can establish a unified CI/CD orchestration mechanism that streamlines the software delivery process. This approach ensures consistency and repeatability across environments while empowering teams to automate tedious tasks, such as environment provisioning, testing, and deployment, with ease.

By integrating observability tools, CI/CD pipelines, and other services into Terraform configurations, you’ll gain a holistic view of your application's behavior and performance. This comprehensive insight extends beyond individual components to encompass the entire application ecosystem, from infrastructure provisioning to code deployment to runtime monitoring. Armed with this holistic perspective, you can identify bottlenecks, optimize resource utilization, and mitigate risks more effectively, ultimately enhancing the reliability, scalability, and resilience of their applications.

So, why should I keep talking about infrastructure as code?

My journey as a developer advocate is fueled by a deep-seated belief in the power of teaching best practices in the cloud, and developing and deploying applications with infrastructure as code is one of those practices. Infrastructure as code, to me, expedites and simplifies the way we build and deploy software. By continuing to speak about IaC at events, I hope to inspire you to embrace this approach and unlock new possibilities.

Thanks for reading! For all things cloud, follow me by clicking the follow button at the top of this page, subscribe to my newsletter below, and follow me on Twitter!