Infrastructure as Code : Best Practices, Benefits & Examples

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

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 logo


Pulumi logo

Microsoft Azure Bicep

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

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      =
  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  =
  container_access_type = "private"
import pulumi
import pulumi_azure as azure

storage_acount ="storageAcount",
storage_account_container ="storageAccountContainer",

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": "",
  "contentVersion": "",
  "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: '${}/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

Automation and Collaboration Layer for Infrastructure as Code

Spacelift is a flexible orchestration solution for IaC development. It delivers enhanced collaboration, automation and controls to simplify and accelerate the provisioning of cloud based infrastructures.

Start free trial