Back to Blog
Lesson 49 of the CI/CD: Continuous Integration from Scratch course
DevOpsAugust 24, 20264 min read

Infrastructure as Code Basics: Automating Cloud Setup in CI

Stop manual server configuration. Learn the fundamentals of IaC, write your first Terraform script, and automate infrastructure provisioning in your CI pipeline.

DevOpsTerraformInfrastructure as CodeCI/CDAutomationGitHub Actions
Close-up view of a developer typing code on a keyboard with a computer screen showing scripts.

Previously in this course, we explored Canary Releases: Implement a Basic Traffic Split for Safer Deploys. Now that you can reliably deploy application code, this lesson introduces the concept of Infrastructure as Code (IaC)—the practice of managing your cloud resources through version-controlled files rather than clicking through a web console.

What is Infrastructure as Code?

Infrastructure as Code (IaC) is the transition from "manual server configuration" to "automated environment definition." Instead of logging into a cloud provider's dashboard to create a database or a server, you write a text file that declares the desired state of your infrastructure.

When you use tools like Terraform or AWS CloudFormation, the software reads your file, compares it to what currently exists in your cloud account, and calculates the necessary changes (the "diff") to reach your target state.

The Core Principles of IaC

  1. Declarative: You define the what (e.g., "I need one server with 2GB of RAM"), not the how (the step-by-step API calls to build it).
  2. Idempotency: Running the same script multiple times should result in the same outcome without creating duplicate or conflicting resources.
  3. Version Control: Your infrastructure lives in Git, allowing you to audit, revert, and collaborate on environment changes just like source code.

Worked Example: Your First Terraform Script

We will use Terraform for this example because it is provider-agnostic and widely used in industry. We'll define a basic resource: an AWS S3 bucket.

Create a file named main.tf in your project root:

HCL
# Define the provider
provider "aws" {
  region = "us-east-1"
}

# Declare the resource
resource "aws_s3_bucket" "my_app_bucket" {
  bucket = "my-unique-ci-cd-demo-bucket-2024"

  tags = {
    Environment = "Dev"
    ManagedBy   = "Terraform"
  }
}

To "apply" this, you would normally run terraform init and terraform apply. But in a DevOps environment, we want this to happen automatically in our CI pipeline.

Incorporating IaC into your CI Pipeline

To automate this, add a new job to your existing GitHub Actions workflow. This job will check your code for errors, plan the changes, and apply them.

YAML
jobs:
  infrastructure:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v2
      - name: Terraform Init
        run: terraform init
      - name: Terraform Plan
        run: terraform plan
      - name: Terraform Apply
        if: github.ref == 'refs/heads/main'
        run: terraform apply -auto-approve
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

Hands-on Exercise

  1. Install the Tooling: Install Terraform on your local machine.
  2. Define Infrastructure: Create a main.tf file as shown above, using a unique bucket name.
  3. Pipeline Integration: Add the job snippet above to your existing .github/workflows/main.yml.
  4. Secrets: Ensure you have added AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to your repository's Managing Secrets: Securing Your CI/CD Pipelines settings.
  5. Commit and Push: Push your changes to trigger the pipeline and verify the bucket creation in your AWS console.

Common Pitfalls

  • Hardcoding Credentials: Never put your AWS keys directly in main.tf. Always use environment variables or secret managers (as shown in our CI example).
  • Drift: If someone modifies the infrastructure manually via the web console, the state file will no longer match the reality. Always use your IaC tool as the "Source of Truth."
  • State Management: Terraform keeps track of your infrastructure in a terraform.tfstate file. If you work in a team, you must store this file in a shared, remote location (like an S3 bucket with locking enabled) to prevent conflicting changes.

FAQ

Q: Can I use IaC for things other than AWS? A: Yes. Terraform supports hundreds of providers, including Azure, Google Cloud, Cloudflare, and even GitHub (you can manage repository settings as code!).

Q: Is IaC strictly for production? A: No. It is even more useful in development and staging, where you want to spin up and tear down ephemeral environments frequently.

Q: What is the difference between IaC and Configuration Management? A: IaC (Terraform) focuses on provisioning the infrastructure (the virtual machine itself). Configuration management (Ansible/Chef) focuses on installing software inside that machine.

Recap

Infrastructure as Code turns your environment into a repeatable, versioned asset. By moving from manual configuration to declarative scripts, you reduce human error and gain visibility into your system's history. We've successfully integrated a basic Terraform plan/apply cycle into our GitHub Actions workflow, taking us one step closer to full-stack automation.

Up next: Pipeline as Code Auditing.

Similar Posts