Terraform + GitHub Actions for automation



This content originally appeared on DEV Community and was authored by Achref Rhouma

🚀 Building a Secure DevOps Pipeline on Azure with Terraform & GitHub Actions

📖 Why This Guide?

Every DevOps engineer dreams of fully automated, secure infrastructure. This article shows how to build a production-ready Azure pipeline using Terraform and GitHub Actions, with built-in security checks and deployment automation.

1⃣ Step 1 — Provision Azure Infrastructure with Terraform

We’ll create a Resource Group, VNet, and an NSG for secure app deployment.

# main.tf
provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "rg" {
  name     = "rg-devsec-demo"
  location = "westeurope"
}

resource "azurerm_virtual_network" "vnet" {
  name                = "vnet-devsec"
  address_space       = ["10.10.0.0/16"]
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
}

resource "azurerm_subnet" "app_subnet" {
  name                 = "app-subnet"
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.10.1.0/24"]
}

resource "azurerm_network_security_group" "nsg" {
  name                = "nsg-app"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name

  security_rule {
    name                       = "Allow-HTTPS-Internet"
    priority                   = 100
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_address_prefix      = "Internet"
    destination_port_range     = "443"
  }
}

resource "azurerm_subnet_network_security_group_association" "assoc" {
  subnet_id                 = azurerm_subnet.app_subnet.id
  network_security_group_id = azurerm_network_security_group.nsg.id
}

2⃣ Step 2 — GitHub Actions Workflow

Automate Terraform plan & apply, plus run a security linting check.

# .github/workflows/terraform.yml
name: Terraform CI/CD

on:
  push:
    branches:
      - main

jobs:
  terraform:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: 1.5.0

      - name: Terraform Init
        run: terraform init

      - name: Terraform Validate
        run: terraform validate

      - name: Terraform Plan
        run: terraform plan -out=tfplan

      - name: Terraform Apply
        if: github.ref == 'refs/heads/main'
        run: terraform apply -auto-approve tfplan

💡 Tip: Add tflint or checkov in the workflow for automated security scanning.

3⃣ Step 3 — Integrate Azure Key Vault for Secrets

resource "azurerm_key_vault" "kv" {
  name                        = "kv-devsec-${random_integer.suffix.result}"
  resource_group_name         = azurerm_resource_group.rg.name
  location                    = azurerm_resource_group.rg.location
  sku_name                    = "standard"
  tenant_id                   = data.azurerm_client_config.current.tenant_id
  purge_protection_enabled    = true
  soft_delete_enabled         = true
}

resource "azurerm_key_vault_access_policy" "admin_policy" {
  key_vault_id = azurerm_key_vault.kv.id
  tenant_id    = data.azurerm_client_config.current.tenant_id
  object_id    = "YOUR_AAD_GROUP_OBJECT_ID"

  key_permissions = [
    "get",
    "list",
    "create",
    "delete"
  ]
}

4⃣ Step 4 — Continuous Security Checks

Add Azure Policy compliance checks to enforce:

  • NSG inbound rules restrictions
  • Private endpoints for Key Vault
  • Tagging policies for all resources
# Assign built-in Azure Policy
az policy assignment create \
  --name "nsg-inbound-check" \
  --scope "/subscriptions/<SUBSCRIPTION_ID>" \
  --policy "/providers/Microsoft.Authorization/policyDefinitions/NSGInboundRule"

📌 Key Takeaways

  • Terraform + GitHub Actions = fully automated, secure deployment.
  • Always scan and lint your IaC code before deployment.
  • Use RBAC + Key Vault to protect secrets and keys.
  • Continuous compliance ensures long-term security.

💬 Challenge:

Add a private endpoint to Key Vault and modify the workflow to only deploy when the endpoint is private. Share your code snippets in the comments!


This content originally appeared on DEV Community and was authored by Achref Rhouma