Managing infrastructure with code is a critical practice for delivering infrastructure with less drama. You can use code to deliver infrastructure quickly, consistently, and safely.

Improving infrastructure delivery can help you improve on the four key aspects of Software Delivery Performance which drive business outcomes (Accelerate: State of DevOps 2018, Accelerate (book)):

  1. Deployment frequency
  2. Lead time for changes
  3. Change failure rate
  4. Time to restore service

When you adopt “Infrastructure as Code” (IaC), you manage infrastructure by defining the desired state of your infrastructure in source files and use a tool to realize those infrastructure resources.

The source files consist of code, configuration, policy definitions, templates, and other assets used to create and manage compute resources using services that offer them as an API. There are many resources that are now provided by API and accessible via IaC systems including:

  • Cloud services like AWS/Azure/GCP that offer an immense variety of infrastructure, platform, and application options
  • infrastructure platforms like VMWare
  • Docker, Kubernetes
  • Content Delivery Networks, Domain Name System, Monitoring, Logging
Toy Building‘, Johnny Vino

Some IaC systems enable you to create a reusable libraries or modules that can be defined, tested, and released independently of any given deployment. These modules can serve as building blocks for larger, more sophisticated deployments.

For example, the following Terraform code instantiates a module (source code) that creates and manages an AWS Virtual Private Cloud network:

module "vpc" {
  source = "git@github.com:qualimente/tf_vpc.git?ref=0.1.0"
  name               = "sandbox"
  env                = "sandbox"
  region             = "us-west-2"
  cidr_block         = "10.1.0.0/16"
  dmz_subnet_cidrs   = ["10.1.0.0/22", "10.1.4.0/22", "10.1.8.0/22"]
  app_subnet_cidrs   = ["10.1.32.0/19", "10.1.64.0/19", "10.1.96.0/19"]
  data_subnet_cidrs  = ["10.1.128.0/22", "10.1.132.0/22", "10.1.136.0/22"]
  mgmt_subnet_cidrs  = ["10.1.160.0/24", "10.1.161.0/24", "10.1.162.0/24"]
  availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
  owner              = "platform"
}

Inside that module, there’s a bunch of direct configuration of resource definitions like this one for an AWS VPC resource:

resource "aws_vpc" "main" {
  cidr_block                       = "${var.cidr_block}"
  enable_dns_support               = "${var.enable_dns_support}"
  enable_dns_hostnames             = "${var.enable_dns_hostnames}"
  assign_generated_ipv6_cidr_block = "false"
  instance_tenancy                 = "${var.instance_tenancy}"
  tags {
    Name        = "${var.name}"
    Environment = "${var.env}"
    ManagedBy   = "Terraform"
    Owner       = "${var.owner}"
  }
}

Existing building blocks are also composed by instantiating other modules, e.g. for subnets, within the vpc module. Once the infra is defined, we can realize it.

Calvin & Hobbes’ Transmogrifier

The infrastructure as code tool, e.g. Terraform, is like Calvin and Hobbes’ magical transmogrifier because it turns the desired state of infrastructure into the actual state. The IaC tool is responsible for:

  1. constructing a model of the desired state of the infrastructure as defined by code
  2. comparing the desired state to the current, actual state
  3. plan a change by generating a ‘diff’ and set of API calls to converge the actual state to the desired state
  4. applying that change, if you choose to

If you apply that code using Terraform, it will create a network that looks like:

VPC with multiple security zones supporting high availability app deployment

Using the QualiMente tf_vpc module to create that VPC is reusable and tested, which makes it a simpler and more reliable way of creating a VPC of that design than doing it manually.

This network might serve as one of the foundational layers in the castle depicted above 🙂

Principles of IaC

CI & CD for Application and Its Infrastructure

It still feels a bit ‘early’ in the industry’s adoption of infrastructure as code because quality practices around inspection and testing are still maturing, but it’s definitely better than having no constructs for composing and testing infrastructure.

The main principles for managing infrastructure with code have become clear:

  • Specify desired state in version control
  • Converge current infrastructure state to desired state using tool to apply code
  • Apply software development practices like encapsulation, testing, refactoring
  • Use Continuous Integration for infrastructure code modules
  • Manage infrastructure resources with automated delivery pipelines

These principles apply across the specific tooling you might use to adopt IaC such as Terraform, CloudFormation, Packer, or Docker. I will share more on these principles and specifics of delivery soon.

The most important principle to work towards is management of infrastructure resources with an automated delivery pipeline that matches the change lifecycle of the things the infrastructure supports.

The ‘CI & CD for App and its Infra’ figure above depicts a delivery pipeline for an application and its app-specific infrastructure. Changes of the application’s software often need supporting changes in its infrastructure. Infrastructure as code enables you to develop, test, and deliver these changes together.

Key Benefits of IaC

On the whole, Infrastructure as Code can provide the following benefits:

  • Collaborate on changes using a versioned, reviewable medium!
  • Infrastructure can be developed as a product
  • Teams can create modules that solve particular problems and can be tested and reused
  • Versioning, testing, review, and automated delivery of small batches reduces the risk of changes
  • The time to restore service is shorter and more predictable when a problem does occur because you can rollback (or forward) to the previous implementation (this gets trickier with stateful resources, but we can manage that, too)
  • Since changes all run through code, there is an audit history that provides a timeline of changes and (hopefully) intent

I’d love to hear from you if you are thinking about managing infrastructure with code, especially Terraform. I’ll try to answer questions or concerns you may have about what you can expect in this process. If you are already using IaC and have experiences or problems you’d like to share, I’d love to hear that too.

#NoDrama