Skip to content

Expert · Infrastructure as code · topic 35 of 50 · 25 min

Why infrastructure as code

Explanation

Infrastructure as code (IaC) means you describe your servers, networks, buckets and databases in text files and let a tool create them. The files live in Git, so every change is reviewed, repeatable and easy to undo. Most IaC tools are declarative: you say what you want, and the tool works out the steps, again and again, with the same result.

The problem with clicking

In the early modules you created resources by clicking in the AWS, Azure or Google Cloud console. That is fine for learning. In a real company it causes trouble. Nobody remembers exactly which 40 boxes were ticked. The test environment slowly becomes different from production. When someone leaves, their knowledge leaves too. And if a region has a bad day, rebuilding everything by hand can take days.

Infrastructure as code (IaC) solves this. You write a text file that describes the infrastructure: "one S3 bucket with versioning on, one VPC with two subnets, one database of this size". A tool reads the file and calls the cloud APIs (the web interfaces that the console itself uses) to make reality match the file.

Think of it like this: Clicking in the console is like a cook who makes biryani from memory: tasty, but different every time, and nobody else can repeat it. IaC is the written recipe card with exact quantities. Any cook in any branch can follow it and get the same biryani, and when you improve the recipe, you change the card, not every cook.

What IaC gives you

  • Repeatable: run the same files and get the same infrastructure, today or in two years.
  • Reviewable in Git: every change is a commit with an author, a reason and a pull request that a teammate checks before it goes live.
  • Fewer click mistakes: no forgotten checkbox, no typo in a security group rule made at 2 am.
  • Disaster recovery: if a region or account is lost, you can rebuild the whole setup from the files (your data still needs separate backups).
  • Matching environments: dev, test and production come from the same files with different settings, so "it worked in test" means something.
  • Living documentation: the files show exactly what exists, which is more reliable than an old diagram.

Declarative versus imperative

An imperative approach lists the steps: "create a bucket, then turn on versioning, then add a tag". A declarative approach describes the end state: "there should be a bucket with versioning on and this tag". The declarative tool compares that wish with what already exists and does only what is missing.

bash
# Imperative: a script of steps. Running it twice fails or makes duplicates.
aws s3api create-bucket --bucket results-dev-demo --region ap-south-1 \
  --create-bucket-configuration LocationConstraint=ap-south-1
aws s3api put-bucket-versioning --bucket results-dev-demo \
  --versioning-configuration Status=Enabled
Imperative: you say HOW, step by step.
yaml
# Declarative: the end state. Running it twice changes nothing the second time.
Resources:
  ResultsBucket:
    Type: AWS::S3::Bucket
    Properties:
      VersioningConfiguration:
        Status: Enabled
Declarative (a CloudFormation snippet): you say WHAT, and the tool decides the steps.

Idempotency

Idempotent means "doing it again gives the same result". Pressing a lift button five times still calls one lift. A good IaC apply is idempotent: the first run creates the bucket, the second run sees the bucket is already correct and does nothing. This is why you can safely run the same pipeline on every commit.

To be idempotent, the tool computes a plan: it compares the desired state (your files) with the current state (what exists) and lists the actions. A resource that is wanted but missing is created. A resource that exists but differs is updated. A resource that exists but is no longer in the files is deleted. A resource that already matches is left alone.

Drift

Drift is the difference between what your files say and what really exists, usually caused by someone changing a setting by hand in the console. If a developer opens port 22 to the whole internet "just for a minute" and forgets, the real security group has drifted from the code. CloudFormation has drift detection, and Terraform shows drift when it plans. The fix is to change the code (or undo the manual change) so the two match again.

Mutable versus immutable infrastructure

Mutable infrastructure is changed in place: you log in to a running server and upgrade packages. Over months each server becomes slightly different (people call these "snowflake" servers). Immutable infrastructure is never changed in place: you build a new machine image or container image with the change, start new servers from it, and throw the old ones away. Immutable setups are easier to reason about and roll back, and they fit well with IaC and auto scaling.

The tool landscape

ToolMade byYou writeWorks with
AWS CloudFormationAWSYAML or JSON templatesAWS
AWS CDKAWSTypeScript, Python, Java, C# or Go; it synthesises CloudFormationAWS
Bicep and ARM templatesMicrosoftBicep, which compiles to ARM JSON templatesAzure
TerraformHashiCorp (now part of IBM)HCL (HashiCorp Configuration Language)AWS, Azure, Google Cloud and many more through providers
OpenTofuLinux Foundation communityHCL, almost the same as TerraformSame providers as Terraform
PulumiPulumiTypeScript, Python, Go, C# and othersMany clouds

Licences matter for some companies. In August 2023 HashiCorp moved Terraform from an open-source licence to the Business Source License (BSL 1.1). It is still free for most teams to use, but it limits building competing products. OpenTofu was forked from the last open-source version and is run under the Linux Foundation. On Google Cloud, most teams use Terraform or OpenTofu; check the current Google Cloud documentation for its managed IaC options.

Careful: Common mistakes: (1) Using IaC for most things but still making "small" console changes, which causes drift and surprises at the next apply. Fix: make every change in code. (2) Writing shell scripts that only work on the first run. Fix: use a declarative tool, or make scripts check before they create. (3) Thinking IaC backs up your data. It rebuilds the bucket, not the files inside it. Fix: back up data separately (module 10).

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Why infrastructure as code · 1/7

Infrastructure as code

In this lesson you will learn why teams describe their cloud infrastructure in code instead of clicking in the console.

Prefer a video by a teacher? Find free videos on “infrastructure as code explained declarative idempotent terraform cloudformation” on YouTube ↗

In real life: A coaching institute in Kota rebuilds its test environment in 20 minutes

An online coaching platform ran its test environment, built by hand two years earlier, in a separate AWS account. Before the JEE season, test and production had drifted: different database versions and missing alarms. The team wrote the whole setup in Terraform, reviewed it in pull requests and used the same files for test and production with different variable files. Now a fresh test environment comes up in about 20 minutes, and when an engineer asks "what is our production database size?", the answer is in Git, with the history of who changed it and why.

Practice (0/3 done)

Task 1 · Code · Python

Drift check. desired and actual are dicts of settings for ONE resource, for example {"versioning": "Enabled", "public": False}. Write drifted(desired, actual) that returns a sorted list of setting names whose actual value is different from the desired value, or that are missing from actual.

Task 2 · Code · Python

An idempotent apply starts with a plan. desired and current are dicts that map a resource name to its settings (a dict). Write plan(desired, current) that returns a list of (action, name) tuples, sorted by name: "create" if the name is only in desired, "update" if it is in both but the settings differ, "delete" if it is only in current. Resources that already match get no action, so plan(x, x) must return [].

Task 3 · Question

Your team writes AWS infrastructure in TypeScript, and the tool turns it into a CloudFormation template before deploying. Which tool is this?

Quick quiz

Question 1

1.What does "declarative" mean for an IaC tool?

Question 2

2.You run the same IaC apply twice in a row with no changes to the files. What should happen the second time?

Question 3

3.A developer opened a firewall port by hand in the console. The code still says it is closed. What is this called?

Question 4

4.Which statement about Terraform and OpenTofu is correct?

Question 5

5.In an immutable infrastructure approach, how do you apply an OS security patch?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What does "declarative" mean for an IaC tool?

Answer: You describe the end state and the tool works out the steps

Declarative tools take the desired end state and compute the actions needed to reach it.

You run the same IaC apply twice in a row with no changes to the files. What should happen the second time?

Answer: Nothing changes, because the apply is idempotent

Idempotent means running it again gives the same result, so the second run finds nothing to do.

A developer opened a firewall port by hand in the console. The code still says it is closed. What is this called?

Answer: Drift

Drift is the gap between the code and what really exists, usually caused by manual changes.

Which statement about Terraform and OpenTofu is correct?

Answer: Terraform moved to the Business Source License in 2023, and OpenTofu is an open-source fork under the Linux Foundation

HashiCorp changed Terraform to BSL 1.1 in August 2023. OpenTofu forked the last open-source version.

In an immutable infrastructure approach, how do you apply an OS security patch?

Answer: Build a new image with the patch, start new servers from it and remove the old ones

Immutable servers are never changed in place; you replace them with new ones built from an updated image.

In immutable infrastructure, how do you apply an OS patch?Related

Answer: Build a new image with the patch and replace the servers

Immutable servers are never changed in place; you replace them with servers from a new image.

From Why infrastructure as code

Why should terraform.tfstate not be committed to Git?Related

Answer: It can contain secrets in plain text and it must be shared with locking, which Git cannot do

State can hold passwords and keys, and it needs locking to stop two applies at once. Use an encrypted remote backend.

From Terraform for the cloud

In a good IaC workflow, when does the change get applied to production?Related

Answer: After the PR is reviewed and merged, by the pipeline, usually with an approval step

The pipeline applies reviewed, merged code, with a manual approval for production.

From IaC in a team: reviews, pipelines and policy

A bucket was created by hand last year. How do you bring it under Terraform without recreating it?Related

Answer: Use an import block (or terraform import), then plan and apply

Import adopts an existing object into state. A plain resource block would try to create a new one.

From Terraform state, backends and drift

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 3 more topics in “Infrastructure as code” before its exam: AWS CloudFormation, Terraform for the cloud, IaC in a team: reviews, pipelines and policy.
  2. Module 9 exam: Infrastructure as code · 12 questions · 20 min, without help. 4 topics of this module still to finish first.
  3. Then the next module, High availability, scaling and disaster recovery. 50 topics left in the course before the final exam.

← Previous: Choosing where to run a container