π 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!
Top comments (0)