Infrastructure as Code Pitfalls and How to Avoid Them - Part 2
April 06, 2021

Tim Davis
env0

As I mentioned before, Infrastructure as Code (IaC) comes with not only the pitfalls of infrastructure but also the pitfalls of code.

Start with: Infrastructure as Code Pitfalls and How to Avoid Them - Part 1

Code Pitfalls

One of the biggest code pitfalls is a very common issue with code in general. Redundant coding. This essentially means that you're creating entire duplicate sets of your code for each individual environment, and hard coding the customization values into each set of files.

he concept of DRY is usually pretty well known in the software development community. Don't repeat yourself (DRY, or sometimes do not repeat yourself) is a principle of software development aimed at reducing repetition of software patterns (Foote, Steven [2014]. Learning to Program. Addison-Wesley Professional. p. 336. ISBN 9780133795226), replacing it with abstractions or using data normalization to avoid redundancy.

So how do we make sure we're following this methodology while creating IaC files?

There are a few ways of doing this. Using variable values during the deployment process can help enable you to create a more "generic" set of IaC configurations that you can then use in a repeatable manner, customizing each deployment using the needed values.

Another way is using an IaC framework that natively enables this type of configuration creation. For example, Terragrunt is a "wrapper" for Terraform that enables the DRY methodology in the creation of IaC configuration files. It accomplishes this by restructuring the way Terraform files are organized and executed. You create 1 set of "DRY" configurations, then you use customization files to define each deployment. This allows you to write only one set of configuration files to be used for development and production deployments, but each has its own respective customization files in place so that it creates each one with the needed parameters.

Speaking of values, this is a significant topic when you're writing your infrastructure as code files. Specifically, what the default values are for each object you're going to be creating. If you do not specify a value for a specific object, there may be a default value associated with it. For example, if you write in your configuration to create a firewall, but don't specify values for a security policy, it may create the firewall with a default-permit-all policy. This is very bad.

How do we mitigate this pitfall?

From a code perspective, we make sure that we have the needed values and parameters for all of the objects we are creating in our code files.

We also talked about misconfiguration a bit earlier in the Infrastructure Pitfalls section. Using some kind of Policy as Code framework or security tool during the actual deployment phase can help you stop the deployment of misconfigured resources before it happens. It's better to have your deployment process fail and have to fix the code and try and redeploy again than have to fix an application that has been compromised due to being deployed with that misconfiguration.

Designing your IaC configuration files can also introduce a pitfall of performance issues. This performance hit comes during deployment, re-deployment, destroy, and other maintenance tasks when you have a large state file.

When you use Infrastructure as Code, the framework you choose needs to document the active "state" of what was actually deployed. This file is used to make future deploy or destroy operations more efficient so that it doesn't duplicate work it's already done.

For example, in Terraform, let's say you want to scale a cluster from 2 nodes to 3 nodes in the configuration file. When you subsequently run the Apply command again, it will check the state of the active deployment and see that it has already created 2 nodes, so it will only add 1 node to make 3 nodes in the cluster. Much more efficient than tearing down the 2 existing nodes and deploying the 3 new nodes you asked for from scratch. If you have a fast development cycle, and all of your infrastructure deployments are jammed into 1 giant state file, every little update or redeployment can take a significant amount of time to execute.

So how do we avoid this pitfall?

Modular programming is a software design technique that emphasizes separating the functionality of a program into independent, interchangeable modules, such that each contains everything necessary to execute only one aspect of the desired functionality. You can design your Infrastructure as Code files and the deployment process in such a way that you can split the full infrastructure into modular pieces. The network, the storage, and the compute, all in their own bite-sized modules. You can then chain these modules into a Workflow, or just re-deploy them individually when you need to. This makes it a much more "cloud-native" or "micro-service" friendly design.

Now, if you need to update just one piece of the infrastructure, you don't have to run the update or re-deploy operation against the entire infrastructures' state. Just that small piece that you're updating. This will make it so that you have more state files, but in the long run, that is a much easier situation to manage.

Wrap-Up

As you can see, there are a lot of decisions and pitfalls that go into using Infrastructure as Code. From choosing a framework, to who helps create and manage the files, and how you can manage the deployment process to try and help curb some of the pitfalls that come along with IaC configuration issues. And these aren't even close to all of the other types of pitfalls you may encounter along the way.

But, hopefully, this was helpful to get your head wrapped around some of the things you may need to be thinking about. And helps you to start off on the right foot, or even to help you go back and make some changes to your existing IaC configurations or procedures.

Tim Davis is a DevOps Advocate at env0
Share this

Industry News

December 06, 2022

The Cloud Native Computing Foundation® (CNCF®), which builds sustainable ecosystems for cloud native software, announced the graduation of Argo, which will join other graduated projects such as Kubernetes, Prometheus, and Envoy.

December 06, 2022

Wib announced API PenTesting-as-a-Service (PTaaS) designed to help organizations proactively cover the latest PCI-DSS 4.0 mandates for testing application security, APIs, and vulnerabilities in Business Logic.

December 05, 2022

Harness announced Harness Cluster Orchestrator to allow customers to optimize their Kubernetes cloud workload costs and realize up to 90% cloud cost savings with Amazon Elastic Compute Cloud (Amazon EC2) Spot instances from Amazon Web Services (AWS).

December 01, 2022

Salesforce introduced a new Automation Everywhere Bundle to accelerate end-to-end workflow orchestration, automate across any system, and embed data and AI-driven workflows anywhere.

December 01, 2022

Weaveworks announced that Flux, the original GitOps project, has graduated in the Cloud Native Computing Foundation (CNCF®).

December 01, 2022

Tigera announced enhancements to its cluster mesh capabilities for managing multi-cluster environments with Calico.

December 01, 2022

CloudBees achieved the Amazon Web Service (AWS) Service Ready Program for Amazon Elastic Compute Cloud (Amazon EC2) Spot Instances.

November 30, 2022

GitLab announced the limited availability of GitLab Dedicated, a new way to use GitLab - as a single-tenant software as a service (SaaS) solution.

November 30, 2022

Red Hat announced an expansion of its open solutions publicly available in AWS Marketplace.

November 30, 2022

Sisense announced the availability of the Sisense CI/CD Git integration module.

November 29, 2022

Codenotary announced TrueSBOM for Serverless, a self-updating Software Bill of Materials (SBOM) for applications running on AWS Lamda, Google Cloud Functions and Microsoft Azure Functions that is made possible by simply adding one line to the application source code.

November 29, 2022

Code Intelligence announced its open-source Command-Line Interface (CLI) tool, CI Fuzz CLI, now allows Java developers to easily incorporate fuzz testing into their existing JUnit setup in order to find functional bugs and security vulnerabilities at scale.

November 29, 2022

Parasoft announced the 2022.2 release of Parasoft C/C++test with support for MISRA C:2012 Amendment 3 and a draft version of MISRA C++ 202x.

November 28, 2022

Kasm Technologies announced the release of Kasm Workspaces v1.12, providing major enhancements to its portfolio of digital workspaces delivering Desktop as a Service (DaaS), Virtualized Desktop Infrastructure (VDI), Remote Browser Isolation (RBI), Open-Source Intelligence Collection (OSINT), Training/Sandboxes, and Containerized Application Streaming (CAS).

November 28, 2022

Cloud4C has achieved Amazon Web Services (AWS) DevOps Competency status.