17-June-25

Infrasturtucre testing in ci/cd makesure to running smoothly provisioning using terraform work realy well as expected

17-June-25
Photo by nbtrisna Within this quiet space, unseen travelers leave only a lingering hush.

Daily Quest #13: Infrastructure Testing

Infrasturtucre testing in ci/cd makesure to running smoothly provisioning using terraform work realy well as expected. Reference :

  • https://terratest.gruntwork.io/
  • https://github.com/hashicorp/setup-terraform

With terratest or kitchen-terraform you can write automate test with :

  • terraform init & apply in temporarry workspace
  • Verify resource exsist and right configuration
  • Cleanup destroy after test complated
Realworld Usecase : You have terraform module to create bucket in s3 storage. Terratest will apply that module, check that bucket created, and destroy resources.

Skenario : Integrate terratest to github actions for validate live infrasturcture post-apply and pre-merge

makesure installing go first
  1. Create directory test/ and install go module ond test/
mdkir test && cd test
go mod init ci_cd_demo_test
got get github.com/gruntwork-io/terratest/modules/terraform

Create text/terraform_hello_test.go

package test

import (
	"testing"

	"github.com/gruntwork-io/terratest/modules/terraform"
	"github.com/stretchr/testify/assert"
	"io/ioutil"
)

func TestHelloFile(t *testing.T) {
	// retryable errors in terraform testing.
	terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
		TerraformDir: "../",
	})

	defer terraform.Destroy(t, terraformOptions)

	terraform.InitAndApply(t, terraformOptions)
	
	content, err := ioutil.ReadFile("hello.txt")
	assert.NoError(t, err)
	assert.Contains(t, string(content), "Hello, OpenTofu!")
}	

Create main.tf

terraform {
  required_providers {
    local = {
      source  = "hashicorp/local"
      version = "~> 2.0"
    }
  }

  required_version = ">= 1.0"
}

provider "local" {
  # No configuration needed for local provider
  
}

resource "local_file" "hello_world" {
  content  = "Hello, OpenTofu!"
  filename = "${path.module}/test/hello.txt"
  
}

Create workflow files .github/workflows/infra-test.yml

name: Infrastructure as Code (IaC) testing
on:
  push:
jobs:
  test-iac:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Setup terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: 1.7.3
      
      - name: Setup terratest
        uses: actions/setup-go@v5
        with:
          go-version: '1.24'
      
      - name: Run terratest
        working-directory: test
        run: |
          go test -v
  1. Push & test passed
Pasted image 20250617111609

Answer :

  1. Instead using teraform plan/validate using terratest we can makes it easier to write automated tests for your infrastructure code. It provides a variety of helper functions and patterns for common infrastructure testing tasks
  2. Kitchen terraform using ruby language. (jelaskan)

Refleksi Jawaban

  1. Mengapa Terratest vs terraform plan/validate?
    • plan/validate hanya melakukan static pemeriksaan konfigurasi Terraform, tanpa menjalankan resource.
    • Terratest melakukan live init & apply, lalu menjalankan pemeriksaan di runtime (misal membaca file, mengecek resource eksis), dan akhirnya destroy. Ini menangkap bug yang hanya muncul saat provisioning nyata—misal kesalahan permission, path, atau ketergantungan environment.
  2. Kenapa/Bagaimana Kitchen-Terraform menggunakan Ruby?
    • Kitchen-Terraform adalah plugin untuk Test Kitchen, framework testing infrastruktur berbasis Ruby.
    • Kamu mendefinisikan platforms, provisioner, dan verifier (biasanya InSpec) di file .kitchen.yml.
    • Saat dijalankan, Test Kitchen (kitchen converge) akan apply Terraform, lalu InSpec (kitchen verify) menjalankan tes compliance/functional yang ditulis dalam Ruby DSL.
    • Ini cocok jika kamu tim yang sudah familier dengan ekosistem Ruby/Test Kitchen atau butuh InSpec untuk security/compliance testing.

Daily Quest #14: Cleanup & Maintenance

Makesure environment clean, build, and resource runner eficient Reference :

  • https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#scheduled-events
  • https://docs.docker.com/reference/cli/docker/system/prune/
  • https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/storing-and-sharing-data-from-a-workflow#setting-retention-period
Real world case : Devops team running self-hosted runner only have 50GB disk, so in end-of-day, need to run prune image.

Skenario : Create workflows action to clean docker resource, volume and set artifact retention

  1. Create cleanup-workflow.yml
name: Cleanup & maintenance
on:
  push:
    branches:
    - main
  schedule:
    - cron: '0 0 * * *' # Every Sunday at midnight
jobs:
  maintenance:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Cleanup old branches
        run: |
          docker system prune -a -f
          docker volume prune -f 
      - name: Cleanuup old terraform state files
        run: |
          find ${{ github.workspace }}/test -name "*.tfstate" -mtime +7 -delete
      - name: cleanup temporary workspace
        run: |
          rm -rf ${{ github.workspace }}/tmp/* || true
      - name: Generate report
        run: |
          echo "Cleanup completed successfully on $(date)" > ${{ github.workspace }}/cleanup_report.txt
          cat ${{ github.workspace }}/cleanup_report.txt
      - name: Upload report
        uses: actions/upload-artifact@v4
        with:
          name: cleanup-report
          path: ${{ github.workspace }}/cleanup_report.txt


Workflow run every push to branch main & scheduled using cron every sunday midnight.
  1. Push & Result
Pasted image 20250617122501

Answer :

  1. Scheduling cleanup after off-peak hours is important to makesure not inffected production environment.
  2. Retention-days make efficient storage and audit because deleted unused old resources.

🧠 Refleksi Jawaban

  1. Mengapa schedule di off-peak hours penting?
    Menjalankan cleanup saat traffic rendah (off-peak) mengurangi risiko mengganggu job produksi dan menghindari bottleneck I/O di runner.
  2. Bagaimana retention-days bantu storage & audit?
    Dengan membatasi umur artefak, kita mencegah penumpukan file usang—menghemat storage dan memudahkan audit karena hanya artefak relevan yang tersimpan.