Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

Infrastructure as Code (IaC) Explained

By Kokil Thapa | Last reviewed: September 2026

Manual server setup breaks under pressure. One missed firewall rule, one wrong PHP version, one forgotten cron path — and your Laravel app works locally but fails in production. Infrastructure as Code (IaC) Explained in plain terms means you describe servers, networks, DNS, and cloud resources in files that live in Git. You review them like application code, test them in CI, and apply them repeatedly. On projects I maintain with Linux system administration and Deployer 7, IaC is what turns "it worked on my laptop" into something a small Nepal team can reproduce without tribal knowledge.

What is Infrastructure as Code and why does it matter?

Infrastructure as Code treats infrastructure the same way you treat application source. Instead of logging into a panel and clicking through wizards, you write declarative or procedural definitions. A pull request shows exactly what will change before anything touches production.

The core idea is not new. Shell scripts and configuration management tools have automated servers for years. Modern IaC adds cloud APIs, state tracking, drift detection, and policy checks. That combination matters when you run multiple environments — staging, production, client sandboxes — on a budget.

For a law-firm portal or eCommerce store, IaC reduces downtime risk. DNS, SSL, load balancers, and database replicas become documented artifacts. When a developer leaves, the infrastructure does not leave with them. That is operational continuity, not buzzword bingo.

Infrastructure as Code (IaC) Explained — Core IdeaManual SetupConsole clicksUndocumented driftHard to reproduceIaC WorkflowFiles in GitReview and testRepeatable applyReplaceSame Result Every TimeServers, DNS, SSL, firewalls, databasesAuditable history in version control
Infrastructure as Code (IaC) explained: replace manual console work with version-controlled definitions and automated apply steps.

IaC sits alongside — not instead of — application deployment. On sister legal-tech sites I maintain, Deployer 7 handles Laravel releases. Terraform or cloud templates handle the EC2 instance, security groups, and elastic IP underneath. Both pipelines share Git as the source of truth. That split keeps concerns clean.

Declarative vs procedural IaC

Declarative tools describe the desired end state. You say "two Ubuntu 24.04 instances with port 443 open." The tool figures out how to get there. Terraform and AWS CloudFormation work this way.

Procedural tools run ordered steps. Ansible playbooks and shell scripts fit here. You control sequence explicitly. Many teams combine both: Terraform provisions, Ansible configures PHP-FPM pools.

Neither style is universally better. Declarative IaC excels at cloud resources with rich APIs. Procedural automation excels at bootstrapping software on a bare VPS from a domain and hosting provider where no cloud API exists.

How does Infrastructure as Code work in practice?

A typical IaC loop has five stages. You author files, commit to Git, run plan or dry-run in CI, apply to an environment, and monitor for drift. Each stage produces artifacts you can audit months later.

  1. Author — Write .tf, .yaml, or playbook files describing resources.
  2. Version — Store them in Git with branch protection and required reviews.
  3. Validate — Run terraform validate, linting, and security scans in CI.
  4. Plan — Show a diff of what will be created, changed, or destroyed.
  5. Apply — Execute against staging first, then production after approval.

This mirrors how you ship Laravel code. The difference is the artifact changes AWS or your VPS instead of PHP classes. Teams that already use GitLab CI for application deploys can extend the same pipeline for IaC with minimal new tooling.

IaC Pipeline FlowGit CommitPull requestCI ValidateLint and scanPlan / DiffHuman reviewApplyStaging then prodTarget EnvironmentEC2, VPC, RDS, DNS, SSL, UFW rulesState file tracks actual resourcesDrift detection on next plan
How Infrastructure as Code works: Git triggers validation, plan shows the diff, apply updates the live environment with tracked state.

A minimal Terraform example

Below is a simplified AWS example. It is not production-ready, but it shows the declarative pattern. Full walkthroughs live in our Terraform practical guide.

# main.tf — define one EC2 instance for a Laravel app
terraform {
  required_version = ">= 1.9"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-south-1"
}

resource "aws_instance" "app" {
  ami           = "ami-0dee22c13ea7a9a21"
  instance_type = "t3.small"

  tags = {
    Name        = "laravel-app-staging"
    Environment = "staging"
  }
}

Run terraform init, then terraform plan, then terraform apply. The plan output is your safety net. Never apply blind in production. Store state remotely — S3 plus DynamoDB locking on AWS, or Terraform Cloud — so two engineers do not corrupt the same state file.

State, modules, and environments

State is Terraform's memory of what it created. Without it, the next apply might try to recreate existing resources. Use separate state files per environment. Our guide on managing multiple environments in IaC covers directory layouts that scale past two servers.

Reusable modules encapsulate repeated patterns — a standard VPC, a Laravel-ready EC2 module with PHP 8.3 and Apache. Modules reduce copy-paste and enforce consistency across client projects.

Which Infrastructure as Code tools should you choose in 2026?

Tool choice depends on where your infrastructure lives and who maintains it. A solo developer on a single VPS needs different tooling than a team running Kubernetes on three clouds.

ToolStyleBest forLearning curve
TerraformDeclarative, multi-cloudAWS, GCP, Azure, Cloudflare DNSModerate
AWS CloudFormationDeclarative, AWS-onlyTeams fully on AWS with native integrationsModerate to steep
AnsibleProcedural, agentlessConfiguring PHP, Nginx, cron on existing serversGentle
PulumiReal programming languagesTeams who want TypeScript or Python for infraModerate
Cloud-init + bashProcedural, minimalOne or two VPS instances, tight budgetsLow

For most Laravel and WordPress projects I touch, the practical stack is Terraform or CloudFormation for cloud primitives plus Ansible or cloud-init for OS-level setup. Pulumi is worth a look if your team already writes TypeScript — see our Pulumi in real languages article.

Official references help when you evaluate trade-offs. HashiCorp maintains current Terraform docs at developer.hashicorp.com/terraform/docs. AWS documents CloudFormation at docs.aws.amazon.com/cloudformation. Ansible docs live at docs.ansible.com.

IaC Tool SelectionCloud provisioningTerraform, CloudFormation, PulumiServer configurationAnsible, cloud-init, bashMulti-cloud teamsPrefer Terraform or PulumiAWS-only teamsCloudFormation or CDKStart small: one VPS or one moduleExpand as environments multiply
Choosing IaC tools in 2026: separate cloud provisioning from OS configuration, then match scope to your cloud footprint.

GitOps and policy as code

GitOps for infrastructure means the Git repo is the only approved way to change production infra. Argo CD or Flux can reconcile Kubernetes clusters. Terraform Cloud or GitLab environments can gate applies behind merge approvals.

Policy as code adds guardrails. Tools like Open Policy Agent or Sentinel reject plans that open SSH to 0.0.0.0/0 or skip encryption. Pair that with IaC security scanning using tfsec, Checkov, or Trivy in CI. Treat failed scans like failing unit tests.

How do you implement Infrastructure as Code on a real project?

Start with one pain point, not a full cloud rewrite. Pick the resource that breaks most often — DNS records, firewall rules, or a staging server clone. Codify that first. Expand outward once the team trusts the workflow.

Step-by-step for a Laravel deployment stack

Imagine a typical stack: Ubuntu 24.04, Apache, PHP-FPM 8.3, MySQL 8.4, Redis 8.10, Let's Encrypt, and Deployer 7 releases. Here is a sensible adoption path.

  1. Inventory — Document current servers, ports, cron jobs, and env vars. Use a JSON formatter to clean up exported configs if needed.
  2. Pick scope — If on AWS, Terraform the EC2, security group, and elastic IP. If on a bare VPS, start with Ansible for packages and vhosts.
  3. Build staging first — Never experiment on production. Match PHP and MySQL versions to prod exactly.
  4. Wire CI — Add plan-on-PR and apply-on-merge, similar to CI quality gates for application code.
  5. Connect app deploy — Keep Deployer or GitLab CI for Laravel. IaC provisions the box; Deployer ships the code.
  6. Backup state and secrets — Remote state, encrypted secrets via SSM or Vault. Never commit .env files.

On the Notary Kathmandu sister-site pipeline, application deploy and server provisioning are separate concerns. That separation saved hours when PHP-FPM pool settings needed a change without touching DNS or SSL.

For booking platforms on Laravel and Livewire, staging parity matters. IaC makes spinning up a staging clone a terraform apply instead of a half-day manual rebuild.

Immutable infrastructure vs mutable servers

Immutable infrastructure replaces servers instead of patching them in place. Packer builds a golden AMI or image. Terraform launches new instances. Deployer swaps the release. Old instances terminate after health checks pass.

Mutable servers — SSH in, apt upgrade, tweak config — are fine for small budgets. Many Nepal SMB sites run this way successfully. Move toward immutability when patch drift causes repeated production surprises.

Laravel Stack with IaCGitLab CITwo pipelinesTerraformEC2, SG, DNSDeployer 7Laravel releaseProdUbuntu 24.04 + Apache + PHP 8.3MySQL 8.4, Redis 8.10, Certbot SSLIdempotent apply, zero-downtime deployRollback via dep rollback or terraform
Real-world Infrastructure as Code (IaC) explained for Laravel: Terraform provisions the server layer, Deployer ships application releases.

Idempotent applies mean running the same IaC twice does not double your resources. Terraform tracks state. Ansible skips tasks already satisfied. That property is essential for safe reruns after partial failures.

Zero-downtime updates require lifecycle rules — create-before-destroy on load balancers, blue-green instance groups, or rolling ASG refreshes. Plan these before your first production apply, not during an outage.

What are common Infrastructure as Code mistakes to avoid?

IaC fails when teams treat it like a one-time script dump. The files rot, state diverges from reality, and someone SSHs in to "fix it quickly." That path destroys the value you invested in automation.

  • Secrets in Git — Use environment variables, SSM Parameter Store, or GitLab masked variables. Scan repos with Trivy or gitleaks.
  • Local state files — A laptop crash should not lose your infrastructure memory. Remote state with locking is non-negotiable for teams.
  • No plan review — A destroy of the wrong resource shows up in plan output. Skipping review is how production databases disappear.
  • Manual hotfixes — Emergency SSH edits create drift. Fix the IaC file, then apply. Document the incident.
  • Over-engineering day one — Twelve modules for one VPS helps nobody. Start flat, refactor when pain appears.
  • Ignoring costterraform apply can launch expensive instances. Use tags, budgets, and policy checks.

Security scanning belongs in CI, not as an optional step. Our write-up on Trivy for containers and IaC shows how to catch misconfigured S3 buckets before merge.

Drift detection matters on long-lived servers. Schedule weekly terraform plan runs against production. Non-empty plans signal someone changed infrastructure outside Git. Reconcile or revert promptly.

For AWS-specific patterns, compare native tooling in our CloudFormation on AWS guide. CloudFormation integrates deeply with IAM and StackSets. Terraform offers broader provider coverage. Many teams use both for different layers.

If you run ongoing support and maintenance, IaC lowers handover friction. A new engineer reads the repo instead of shadowing for two weeks. That is worth the upfront authoring time on any project expected to live more than twelve months.

Key Takeaways

  • Infrastructure as Code (IaC) replaces manual console work with version-controlled, reviewable infrastructure definitions.
  • Use declarative tools like Terraform for cloud resources and Ansible or cloud-init for OS-level configuration on VPS hosts.
  • Always run plan before apply, store remote state with locking, and never commit secrets to Git.
  • Keep application deploy (Deployer, GitLab CI) separate from infrastructure provisioning — both can share Git as source of truth.
  • Start with one high-pain resource, add CI validation and security scans, then expand modules as environments multiply.
  • Schedule drift detection and treat manual SSH hotfixes as debt to reconcile back into IaC files.

People Also Ask

Is Infrastructure as Code only for large cloud teams?

No. A single developer managing two VPS instances still benefits from codified firewall rules, DNS records, and package lists. IaC scales down as easily as it scales up. The ROI appears the first time you rebuild staging in minutes instead of hours.

What is the difference between IaC and DevOps?

DevOps is a practice culture — collaboration, automation, measurement. IaC is a specific technique within DevOps. You can do DevOps without full IaC, but IaC without CI integration misses most of its safety benefits.

Can Infrastructure as Code work with shared hosting?

Limited shared hosting offers no API, so full IaC rarely applies. You can still codify DNS at Cloudflare, document deployment steps, and use Ansible where SSH access exists. For serious Laravel or eCommerce workloads, VPS or cloud instances with API access make IaC practical.

How does IaC relate to containers and Kubernetes?

Containers package applications. Kubernetes orchestrates them. IaC provisions the cluster itself — node pools, networks, IAM roles — often via Terraform or Crossplane. Application manifests then deploy via GitOps. The layers stack; they do not replace each other.

Put Infrastructure as Code to work on your next deployment

Infrastructure as Code (IaC) Explained in one sentence: describe what you need, store it in Git, validate in CI, apply with care, and never let manual drift become normal. Whether you run a legal-tech portal, a WooCommerce store, or a custom Laravel booking system, repeatable infrastructure saves money and sleep. If you want help designing an IaC pipeline alongside your application stack, contact us or explore enterprise application development and about my production workflow. Read more on the blog, browse the portfolio, or review web development services for your next project.

Frequently Asked Questions

Infrastructure as Code means defining servers, networks, DNS, and cloud resources in version-controlled files, then using tools like Terraform or Ansible to create and update them automatically instead of manual console clicks.

Manual server setup fails under pressure — one missed firewall rule, wrong PHP version, or forgotten cron path can break a Laravel app in production. IaC turns tribal knowledge into reviewable Git artifacts. Pull requests show exactly what will change before anything touches live systems. For law-firm portals, eCommerce stores, or booking platforms, DNS, SSL, load balancers, and database replicas become documented. When a developer leaves, the infrastructure definition stays in the repo. That operational continuity reduces downtime risk and makes staging rebuilds repeatable instead of half-day manual work.

Declarative tools describe the desired end state — you specify two Ubuntu 24.04 instances with port 443 open, and the tool figures out how to get there. Terraform and AWS CloudFormation work this way. Procedural tools run ordered steps explicitly, like Ansible playbooks or shell scripts. Neither style is universally better. Declarative IaC excels at cloud resources with rich APIs. Procedural automation excels at bootstrapping software on a bare VPS where no cloud API exists. Most Laravel and WordPress stacks combine both: Terraform provisions cloud primitives, Ansible configures PHP-FPM pools and vhosts.

A typical IaC loop has five stages that mirror how you ship Laravel code. Author — write .tf, .yaml, or playbook files describing resources. Version — store them in Git with branch protection and required reviews. Validate — run terraform validate, linting, and security scans in CI. Plan — show a diff of what will be created, changed, or destroyed before any apply. Apply — execute against staging first, then production after approval. Each stage produces auditable artifacts. Teams already using GitLab CI for application deploys can extend the same pipeline for IaC with minimal new tooling.

Tool choice depends on where your infrastructure lives and who maintains it. Terraform is declarative and multi-cloud — best for AWS, GCP, Azure, and Cloudflare DNS with a moderate learning curve. AWS CloudFormation suits teams fully on AWS wanting native IAM integrations. Ansible is procedural and agentless — ideal for configuring PHP, Nginx, and cron on existing servers with a gentle learning curve. Pulumi lets teams write infrastructure in TypeScript or Python. Cloud-init plus bash fits one or two VPS instances on tight budgets. For most Laravel and WordPress projects, the practical stack is Terraform or CloudFormation for cloud primitives plus Ansible or cloud-init for OS-level setup.

Start with one pain point — DNS records, firewall rules, or a staging server clone — not a full cloud rewrite. Inventory current servers, ports, cron jobs, and env vars. If on AWS, Terraform the EC2 instance, security group, and elastic IP. On a bare VPS, start with Ansible for packages and vhosts. Build staging first with Ubuntu 24.04, Apache, PHP-FPM 8.3, MySQL 8.4, and Redis 8.10 matching production exactly. Wire CI with plan-on-PR and apply-on-merge. Keep Deployer 7 for Laravel releases separate from IaC provisioning. Store remote state and secrets via SSM or Vault — never commit .env files to Git.

No. A single developer managing two VPS instances still benefits from codified firewall rules, DNS records, and package lists. IaC scales down as easily as it scales up.

DevOps is a practice culture covering collaboration, automation, and measurement across development and operations. Infrastructure as Code is a specific technique within DevOps — you define infrastructure in version-controlled files and apply changes through automated pipelines. You can practice DevOps without full IaC, but IaC without CI integration misses most of its safety benefits. Plan review, security scanning, and drift detection only deliver value when IaC files trigger validation on every pull request, similar to how you gate Laravel application deploys through GitLab CI quality checks.

Full IaC rarely applies to shared hosting because most providers offer no API for provisioning or configuration. You cannot declaratively manage cPanel resources the way you manage AWS EC2 instances. You can still codify DNS at Cloudflare, document deployment steps in Git, and use Ansible where SSH access exists on VPS or dedicated servers. For serious Laravel or eCommerce workloads with custom PHP-FPM pools, Redis, and Deployer 7 releases, VPS or cloud instances with API access make IaC practical. Shared hosting suits brochure sites; operational workflows need infrastructure you can define and reproduce in files.

Containers package applications; Kubernetes orchestrates them at runtime. IaC provisions the cluster layer itself — node pools, networks, IAM roles — often via Terraform or Crossplane. Application manifests then deploy via GitOps tools like Argo CD or Flux. The layers stack; they do not replace each other. On a typical Laravel project, Terraform might provision EC2 and security groups, Deployer 7 ships PHP releases, and Kubernetes would only enter the picture if you containerised the application. For most PHP workloads I maintain, bare VPS or EC2 with Ansible configuration remains simpler and cheaper than adding a cluster.

IaC fails when teams treat it like a one-time script dump that rots while someone SSHs in to fix things quickly. Never commit secrets — use SSM Parameter Store or GitLab masked variables and scan repos with Trivy or gitleaks. Local state files are dangerous; remote state with locking via S3 plus DynamoDB or Terraform Cloud is non-negotiable for teams. Skipping plan review is how production databases disappear — destroy operations show up in plan output. Manual hotfixes create drift; fix the IaC file then apply. Over-engineering twelve modules for one VPS helps nobody. Ignoring cost means terraform apply can launch expensive instances without tags or budget alerts.

State is Terraform's memory of what it created. Without it, the next apply might try to recreate existing resources or miss dependencies. Use separate state files per environment so staging changes never touch production resources. Store state remotely — S3 plus DynamoDB locking on AWS, or Terraform Cloud — so two engineers do not corrupt the same state file and a laptop crash does not lose your infrastructure memory. Reusable modules encapsulate repeated patterns like a standard VPC or a Laravel-ready EC2 module with PHP 8.3 and Apache, reducing copy-paste across client projects while keeping each environment's state isolated.

IaC sits alongside application deployment, not instead of it. On sister legal-tech sites I maintain, Deployer 7 handles Laravel releases while Terraform or cloud templates handle the EC2 instance, security groups, and elastic IP underneath. Both pipelines share Git as the source of truth, but concerns stay separated. That split saved hours when PHP-FPM pool settings needed a change without touching DNS or SSL configuration. IaC provisions and configures the box; Deployer or GitLab CI ships the PHP code. Treat them as two pipelines with the same review culture — plan before apply for infrastructure, quality gates before merge for application code.

Immutable infrastructure replaces servers instead of patching them in place. Packer builds a golden AMI or image, Terraform launches new instances, Deployer swaps the release, and old instances terminate after health checks pass. Mutable servers — SSH in, apt upgrade, tweak config — are fine for small budgets, and many Nepal SMB sites run this way successfully. Move toward immutability when patch drift causes repeated production surprises. Zero-downtime updates require lifecycle rules like create-before-destroy on load balancers, blue-green instance groups, or rolling ASG refreshes. Plan these before your first production apply, not during an outage.

GitOps for infrastructure means the Git repo is the only approved way to change production infra. Argo CD or Flux reconcile Kubernetes clusters against committed manifests. Terraform Cloud or GitLab environments can gate applies behind merge approvals. Policy as code adds guardrails — Open Policy Agent or Sentinel reject plans that open SSH to 0.0.0.0/0 or skip encryption. Pair that with IaC security scanning using tfsec, Checkov, or Trivy in CI and treat failed scans like failing unit tests. Schedule weekly terraform plan runs against production for drift detection; non-empty plans signal someone changed infrastructure outside Git and need prompt reconciliation back into IaC files.

Share this article

0 Comments

Leave a comment

Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

Quick Contact Options
Choose how you want to connect me: