Going to AWS Summit London? 🇬🇧🇬🇧

Meet us there →

General

Infrastructure as Code : Best Practices, Benefits & Examples

What Is Infrastructure as Code? Examples, Best Practices & Tools

You will learn:

  1. What Is Infrastructure as Code (IaC)
  2. Benefits of Infrastructure as Code
  3. Challenges and Limitations with IaC
  4. Why Should I Store My Infrastructure as Code in a Version Control System (VCS)?
  5. Declarative vs. Imperative Approaches
  6. Infrastructure as Code Tooling
  7. Infrastructure as Code Examples

What Is Infrastructure as Code (IaC)

Benefits of Infrastructure as Code

  • New environments or infrastructure can be provisioned easily from your IaC configuration code. Infrastructure deployments with IaC are repeatable.
  • Manually configured environments are difficult to scale. With environments provisioned using IaC, they can be deployed and scaled rapidly.
  • If you want to make changes to the existing infrastructure that has been deployed with IaC, this can be done in code, and the changes will be tracked.
  • When IaC is used with a declarative tool (it describes the state you want your environment to look like), you can detect and correct environment drift. If a part of the infrastructure is modified manually outside of the code, it can be brought back in line with the desired state on the next run.
  • Changes can be applied multiple times without changing the result beyond the initial application. This is known as idempotence.
  • Avoid manual configuration of environments which can typically introduce mistakes due to human error. With IaC, these can be avoided.
  • IaC is a means to achieve consistency across environments and infrastructure. The code can be reused.
  • Infrastructure costs are lowered as the time to deploy and effort to manage, administer and maintain environments decrease.
  • IaC can be used in Continuous Integration / Continuous Deployment (or CI/CD) pipelines. The main benefit of doing this is to automate your Infrastructure deployments.
  • DevOps teams can test applications in production-like environments early in the development cycle.
  • With your Infrastructure configuration code held in your version control system alongside your application source code, commonly in the same repository. Now everything can be held together.
  • Productivity will increase due to a combination of all the benefits of using IaC.
  • As the code is held in your version control system, it gains all the benefits of the VCS. More on that in the next section.

Challenges and Limitations with IaC

Why Should I Store My Infrastructure as Code in a Version Control System (VCS)?

1. Efficiency

As configuration files are amended incrementally with changes, testing becomes easier as rollback to previous versions is possible. New features can be built up over time.

2. Tracking & Versioning

Declarative vs. Imperative Approaches

Infrastructure as Code Tooling

Terraform

Terraform logo

Learn more about how you can automate your infrastructure provisioning with Terraform.

OpenTofu

opentofu iac

OpenTofu is an open-source version of Terraform that will expand on Terraform’s existing concepts and offerings. It is a viable alternative to HashiCorp’s Terraform, being forked from Terraform version 1.5.6. OpenTofu retained all the features and functionalities that had made Terraform popular among developers, while also introducing improvements and enhancements. The project is part of the Linux Foundation, with the ultimate goal of joining the Cloud Native Computing Foundation (CNCF).

There are no differences between Terraform (versions prior to 1.5.6) and OpenTofu, but this will change as new versions emerge. Initially, it works exactly the same as Terraform, with OpenTofu being a drop-in replacement for it. OpenTofu is not going to have its own providers and modules, but it is going to use its own registry for them.

The community dictates the direction of OpenTofu, which will offer greater flexibility in the development of new features, considering what is important for the users. There are a couple of interesting feature requests already in the repository, and other features are planned, such as support for OCI provider registries and state encryption.

OpenTofu works with your existing Terraform state file so you won’t have any issues when you are migrating to it. 

Contributing to OpenTofu can be easily done by checking the Contribution Guide. The easiest way you can contribute is by opening an issue, and every major change will be done through an RFC.

OpenTofu is the future of the Terraform ecosystem and having a truly open-source project to support all your IaC needs is the main priority.

Pulumi

Pulumi logo

Read more about using Azure for Infrastructure as Code.

Microsoft Azure Bicep

Azure Bicep logo
az bicep decompile -f .\arm-example.json

See a more detailed list of the most useful IaC deployment tools.

Infrastructure as Code Examples

In this section we will compare the code required to create a Storage account in Azure, using Terraform, Pulumi, Bicep and ARM templates. All four examples will create the same result in Azure, a storage account with a container called ‘logs’.

resource "azurerm_storage_account" "storage_acount" {
  name                     = "storageAccountName"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

resource "azurerm_storage_container" "storage_account_container" {
  name                  = "logs"
  storage_account_name  = azurerm_storage_account.example.name
  container_access_type = "private"
}
import pulumi
import pulumi_azure as azure

storage_acount = azure.storage.Account("storageAcount",
    resource_group_name=azurerm_resource_group["example"]["name"],
    location=azurerm_resource_group["example"]["location"],
    account_tier="Standard",
    account_replication_type="LRS")
storage_account_container = azure.storage.Container("storageAccountContainer",
    storage_account_name=azurerm_storage_account["example"]["name"],
    container_access_type="private")

Existing Terraform can be converted to Pulumi files using tf2pulumi, a great resource that lets you view the code side-by-side and convert it to Typescript, Python, Go, or C#.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.4.1008.15138",
      "templateHash": "8636947863337745424"
    }
  },
  "parameters": {
    "storageAccountName": {
      "type": "string"
    },
    "containerName": {
      "type": "string",
      "defaultValue": "logs"
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    }
  },
  "functions": [],
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2019-06-01",
      "name": "[parameters('storageAccountName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "StorageV2",
      "properties": {
        "accessTier": "Hot"
      }
    },
    {
      "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
      "apiVersion": "2019-06-01",
      "name": "[format('{0}/default/{1}', parameters('storageAccountName'), parameters('containerName'))]",
      "dependsOn": [
        "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
      ]
    }
  ]
}
param storageAccountName string
param containerName string = 'logs'
param location string = resourceGroup().location

resource sa 'Microsoft.Storage/storageAccounts@2019-06-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    accessTier: 'Hot'
  }
}

resource container 'Microsoft.Storage/storageAccounts/blobServices/containers@2019-06-01' = {
  name: '${sa.name}/default/${containerName}'
}

The Bicep playground is a great resource that allows you to directly compare ARM templates and Bicep configuration files. Use the ‘Sample Template’ button to select a template to compare side-by-side. You will notice that Bicep files are always shorter, remove the ARM boilerplating, and as a result are easier to use.

Key Points

Continuous Integration and Deployment for your IaC

Spacelift allows you to automate, audit, secure, and continuously deliver your infrastructure. It helps overcome common state management issues and adds several must-have features for infrastructure management.

Start free trial