Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Intelligence View
⚡ tsecurity.de Intelligence

Deploying Infrastructure to Azure Using HCP Terraform and GitHub VCS

INTRODUCTION Every Cloud Engineer eventually reaches the same point. At first, running Terraform from your laptop feels exciting. You write your .tf files, run: terraform init terraform plan terraform apply and Azure resources appear…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!




INTRODUCTION



Every Cloud Engineer eventually reaches the same point.

At first, running Terraform from your laptop feels exciting. You write your .tf files, run:



terraform init

terraform plan

terraform apply


and Azure resources appear like magic.



But as projects grow, that approach becomes risky.

What happens when another engineer needs to review your changes?

What happens when the state file is sitting on someone’s laptop?

What happens when a junior engineer accidentally applies changes to production without approval?



That is where HCP Terraform and GitHub VCS integration come in.

In this project, I will walk you through how to deploy Azure infrastructure using Terraform code stored in GitHub, with HCP Terraform handling remote runs, state management, plan review, and controlled apply operations.



As a Cloud Engineer and technical instructor, this is the kind of workflow I encourage students and teams to learn early because it reflects how real infrastructure should be managed: version-controlled, reviewable, auditable, and repeatable.



HCP Terraform supports a VCS-driven workflow where it fetches Terraform configuration from a connected repository and automatically starts plan and apply operations when changes are pushed. This allows GitHub to act as the source of truth for infrastructure code.





Project Goal





We are going to deploy basic Azure infrastructure using:




  • Azure as the cloud provider

  • Terraform as the Infrastructure as Code tool

  • GitHub as the version control system

  • HCP Terraform as the remote execution and state management platform





The deployment will create:




  • Azure Resource Group

  • Virtual Network

  • Subnet

  • Network Security Group

  • Public IP

  • Network Interface

  • Linux Virtual Machine





Architecture Overview



Architectural Overview





In simple terms:




  1. We write Terraform code locally.

  2. We push the code to GitHub.

  3. HCP Terraform detects the change.

  4. HCP Terraform runs terraform plan.

  5. After approval, HCP Terraform runs terraform apply.

  6. Azure resources are deployed.



This is a professional DevOps workflow because no one is manually creating resources in the Azure portal, and no one is running production infrastructure from their laptop (Minimum DevOps requirements).





Prerequisites





Before starting, make sure you have:




  1. An Azure subscription

  2. A GitHub account

  3. An HCP Terraform account

  4. Terraform installed locally

  5. Azure CLI installed locally

  6. Basic knowledge of Git and Terraform



You also need permission to create resources in Azure and permission to create or use a service principal click here to know more.



Here We Go!





Step 1: Create a GitHub Repository




  • Create a new GitHub repository.

    azure-hcp-terraform-vcs


  • Clone the repository locally

    git clone https://github.com/YOUR_USERNAME/azure-hcp-terraform-vcs.git


  • Switch to the cloned repository

    cd azure-hcp-terraform-vcs





Create a repo
Creating a Repo in GitHub



For details on how to create a GitHub repository, click here




  • Create the Terraform project structure
    azure-hcp-terraform-vcs/



│
├── main.tf
├── variables.tf
├── outputs.tf
├── providers.tf
├── terraform.tfvars
└── README.md





Project Structure



The above structure is simple enough for beginners to understand, but also professional enough to build on later.





Step 2: Configure the Azure Provider




  • Create providers.tf.



terraform {
required_version = ">= 1.6.0"

required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.0"
}
}
}

provider "azurerm" {
features {}
}






This tells Terraform to use the AzureRM provider.

The features {} block is required by the AzureRM provider.





Step 3: Create Terraform Variables




  • Create variables.tf.



variable "resource_group_name" {
description = "Name of the Azure Resource Group"
type = string
}

variable "location" {
description = "Azure region where resources will be deployed"
type = string
}

variable "vnet_name" {
description = "Name of the Virtual Network"
type = string
}

variable "vnet_address_space" {
description = "Address space for the Virtual Network"
type = list(string)
}

variable "subnet_name" {
description = "Name of the subnet"
type = string
}

variable "subnet_address_prefixes" {
description = "Address prefixes for the subnet"
type = list(string)
}

variable "vm_name" {
description = "Name of the Linux Virtual Machine"
type = string
}

variable "admin_username" {
description = "Admin username for the virtual machine"
type = string
}

variable "public_key" {
description = "SSH public key content for the virtual machine"
type = string
}









Important Note



In HCP Terraform, avoid using local file paths like this:

file("C:/Users/USER/.ssh/azure_rsa.pub")

That path exists on your laptop, not inside the HCP Terraform remote execution environment.

Instead, paste the actual public key content into an HCP Terraform variable and check the sensitive atribute box.





Step 4: Create the Azure Infrastructure Code




  • Create main.tf.



resource "azurerm_resource_group" "rg" {
name = var.resource_group_name
location = var.location
}

resource "azurerm_virtual_network" "vnet" {
name = var.vnet_name
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
address_space = var.vnet_address_space
}

resource "azurerm_subnet" "subnet" {
name = var.subnet_name
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = var.subnet_address_prefixes
}

resource "azurerm_network_security_group" "nsg" {
name = "${var.vm_name}-nsg"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name

security_rule {
name = "Allow-SSH"
priority = 1001
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}

resource "azurerm_public_ip" "public_ip" {
name = "${var.vm_name}-public-ip"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
allocation_method = "Static"
sku = "Standard"
}

resource "azurerm_network_interface" "nic" {
name = "${var.vm_name}-nic"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name

ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.public_ip.id
}
}

resource "azurerm_network_interface_security_group_association" "nsg_association" {
network_interface_id = azurerm_network_interface.nic.id
network_security_group_id = azurerm_network_security_group.nsg.id
}

resource "azurerm_linux_virtual_machine" "vm" {
name = var.vm_name
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
size = "Standard_D2s_v3"
admin_username = var.admin_username

network_interface_ids = [
azurerm_network_interface.nic.id
]

admin_ssh_key {
username = var.admin_username
public_key = var.public_key
}

os_disk {
name = "${var.vm_name}-osdisk"
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}

source_image_reference {
publisher = "Canonical"
offer = "ubuntu-24_04-lts"
sku = "server"
version = "latest"
}
}





This code builds a simple Azure VM environment with networking, security, and SSH access.

This is a good starter project because it touches the core Azure infrastructure components: compute, networking, identity, and security.





Step 5: Create Outputs




  • Create outputs.tf.



output "resource_group_name" {
description = "The name of the created resource group"
value = azurerm_resource_group.rg.name
}

output "public_ip_address" {
description = "The public IP address of the virtual machine"
value = azurerm_public_ip.public_ip.ip_address
}

output "vm_name" {
description = "The name of the virtual machine"
value = azurerm_linux_virtual_machine.vm.name
}





Outputs are useful because after deployment, HCP Terraform will show important values such as the public IP address of the VM.





Step 6: Create an Example tfvars File




  • Create terraform.tfvars



resource_group_name      = "rg-hcp-terraform-demo"
location = "westeurope"
vnet_name = "vnet-hcp-demo"
vnet_address_space = ["10.0.0.0/16"]
subnet_name = "subnet-hcp-demo"
subnet_address_prefixes = ["10.0.1.0/24"]
vm_name = "vm-hcp-demo"
admin_username = "azureuser"
public_key = "ssh-rsa AAAA..."





Do not commit real secrets or sensitive values into GitHub.

For public_key, use the content of your .pub file.

For example:

cat ~/.ssh/azure_rsa.pub

On Windows PowerShell:

Get-Content C:\Users\USER\.ssh\azure_rsa.pub

Copy the full public key content.





Step 7: Create an Azure Service Principal



HCP Terraform needs permission to deploy resources into Azure.

The common approach is to create a service principal and store its values as environment variables in HCP Terraform. Microsoft recommends using service principals for automated tools such as Terraform instead of using a fully privileged personal user account.




  • Login to Azure:

    az login


  • Confirm your subscription:

    az account show


  • Set the subscription:

    az account set --subscription "<SUBSCRIPTION_ID>"


  • Create a service principal:




az ad sp create-for-rbac \
--name "sp-hcp-terraform-azure" \
--role "Contributor" \
--scopes "/subscriptions/<SUBSCRIPTION_ID>"





The output will look similar to this:




{
"appId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"displayName": "sp-hcp-terraform-azure",
"password": "xxxxxxxxxxxxxxxxxxxx",
"tenant": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}






Save these values securely.

You will need them in HCP Terraform.





Step 8: Push Your Code to GitHub




  • In your working director, run:



git status
git add .
git commit -m "Initial Azure infrastructure with Terraform"
git push origin main





At this point, GitHub becomes the source of truth for your infrastructure code.

This is a major shift from manual cloud administration to real Infrastructure as Code practice.



Push to GitHub




  • The files in the repository in GitHub
    Terraform Config Files in GitHub





Step 9: Create an HCP Terraform Organization




  • Go to HCP Terraform and create an organization. Click here


  • Click on Create Organization

    Select Personal

    A good organization naming pattern could be:

    peabsmart-cloud-labs




HCP Organization




  • On the left pane inside the organization click on Projects,
    then click on New project and enter the project detail and Click on Create.
    For this project, we will use Azure-Training-Projects



Create a Project



Projects in HCP Terraform help organize related workspaces, especially when you are managing multiple environments or cloud providers. HashiCorp’s HCP Terraform learning path includes project and variable set organization as part of the recommended collaboration workflow.





Step 10: Connect HCP Terraform to GitHub and Create a HCP Terraform Workspace




  • In the project you created, Click on Create a workspace HCP Terraform:



Create a workspace




  • Select Version Control Workflow


  • Choose GitHub.




Connect GitHub




  • Authorize HCP Terraform to access your GitHub account or organization.


  • Select the repository: azure-hcp-terraform-vcs



  • Click on Create





    Terraform working directory: /



    Use / if your .tf files are in the root of the repository.

    If your files are inside a folder liketerraform/, then set the working directory to: terraform





This is a common mistake. If the working directory is wrong, HCP Terraform will not find your Terraform configuration.



Complete Workspace




  • The Terraform variable page will popup


  • Enter the required variable values from terraform.tfvars file we created earlier and click Save variables.




Variables





Step 11: Add Azure Credentials to HCP Terraform




  • Go to the workspace:

    Workspace > Variables


  • Add the following as Environment Variables:

    ARM_CLIENT_ID

    ARM_CLIENT_SECRET

    ARM_SUBSCRIPTION_ID

    ARM_TENANT_ID




Use these values:




ARM_CLIENT_ID        = appId from the service principal output
ARM_CLIENT_SECRET = password from the service principal output
ARM_SUBSCRIPTION_ID = your Azure subscription ID
ARM_TENANT_ID = tenant from the service principal output
Mark ARM_CLIENT_SECRET as Sensitive.






Env Variables



Microsoft documents these Azure Terraform authentication variables as the standard service-principal environment variables for Terraform automation.






Step 12: Queue the First Terraform Plan



Once the workspace is connected to GitHub and variables are added, HCP Terraform will usually trigger a run automatically.



You can also manually queue a run:

Workspace > Runs > Queue plan

HCP Terraform will run:

terraform init

terraform plan

remotely.

This is where the value becomes clear.

The plan is no longer hidden on one person’s machine. It is visible, reviewable, and part of the deployment workflow.



runs





Step 13: Review the Plan



A good Cloud Engineer does not blindly apply infrastructure changes.

Review the plan carefully.

Look for:




  • Resources to be created

  • Resources to be modified

  • Resources to be destroyed

  • Unexpected region changes

  • Unexpected VM sizes

  • Public exposure

  • Security group rules

  • Naming mistakes



For example, if the plan says:

Plan: 8 to add, 0 to change, 0 to destroy.

that means Terraform intends to create 8 resources.

A depicted in the image below





Step 14: Apply the Infrastructure



If the plan looks correct, click: Confirm & Apply



Apply



HCP Terraform will run the apply operation remotely.

After a successful apply, you should see your outputs:




resource_group_name = rg-hcp-terraform-demo
vm_name = vm-hcp-demo
public_ip_address = x.x.x.x
You can now test SSH access:
ssh azureuser@<PUBLIC_IP_ADDRESS>







  • Apply completed



Apply completed




  • Prove of authorization after review (Reviewer's Comment)



Reviewers






Step 15: Verify Resources in Azure




  • Go to the Azure portal and check:

    Resource Groups > rg-hcp-terraform-demo

    You should see:


  • Virtual Machine


  • Virtual Network


  • Subnet


  • Network Security Group


  • Public IP


  • Network Interface


  • OS Disk




As Depicted below



Azure Portal



You can also verify using Azure CLI:




az resource list \
--resource-group rg-hcp-terraform-demo \
--output table









Step 16: Make a Change Through GitHub



Imagine your team wants to change the VM size.




  • Update this line in main.tf:

    size = "Standard_D2s_v3"

    Change it to:

    size = "Standard_B1s"


  • Commit and push:





git add .
git commit -m "Update VM size"
git push origin main






HCP Terraform detects the GitHub change and starts a new run.

This is the power of VCS-driven infrastructure.

You are no longer clicking around in Azure. You are managing infrastructure through code, Git history, and controlled deployment runs.






Step 17: Destroy the Infrastructure Safely



When you are done with the demo, destroy the resources to avoid unnecessary Azure cost.




  • In HCP Terraform:
    Workspace > Settings > Destruction and Deletion > Queue destroy plan



Queue destroy plan




  • Confirm by typing delete

    delete


  • Review the destroy plan, then confirm.




Confirm destroy




  • Deletion Completed
    Deletion completed



HCP Terraform supports destroy operations from the workspace, and HashiCorp warns that deleting a workspace does not automatically destroy the infrastructure it manages. You must queue a destroy plan if you want the actual cloud resources removed.






Common Errors and How to Fix Them






Error 1: Unsupported Operator for public_key_path



Example error:

invalid HCL for variable "public_key_path" at 1,1: Unsupported operator

Cause:

You are probably passing a Windows path like this directly into HCP Terraform:

C:/Users/USER/.ssh/azure_rsa.pub

HCP Terraform runs remotely and cannot access files on your local machine.

Fix:

Use the actual public key content instead:

public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ..."






Error 2: List of String Required, But Have String



Bad value:

vnet_address_space = "[\"10.0.0.0/16\"]"

Correct value:

vnet_address_space = ["10.0.0.0/16"]

Cause:

The first example is a string. The second example is a real HCL list.






Error 3: Azure Authentication Failed



Check that these environment variables exist in HCP Terraform:

ARM_CLIENT_ID

ARM_CLIENT_SECRET

ARM_SUBSCRIPTION_ID

ARM_TENANT_ID


Also confirm that the service principal has enough permissions on the subscription or resource group.






Error 4: Terraform Cannot Find Configuration



Cause:

Your HCP Terraform workspace working directory is wrong.

If your files are here:

repo/main.tf

use:

/

If your files are here:

repo/terraform/main.tf

use:

terraform






Best Practices I Teach My Students






1. Do Not Store Secrets in GitHub



Never commit:




  • client secrets

  • passwords

  • private keys

  • .tfstate files
    Use HCP Terraform sensitive variables for secrets.






2. Use Git Branches and Pull Requests



For production teams, avoid pushing directly to main.

Use:

feature branch > pull request > review > merge > HCP Terraform run

This improves collaboration and prevents careless infrastructure changes.






3. Keep State Remote



One of the strongest benefits of HCP Terraform is remote state management.

Your state is not scattered across laptops.

It is centrally managed, protected, and connected to the workspace.






4. Separate Environments



For serious projects, create separate workspaces:




  • azure-dev

  • azure-staging

  • azure-prod
    Each workspace should have its own variables and approval controls.






5. Use Clear Naming Standards



Bad names:




  • test-rg

  • vm1

  • network-demo



Better names:




  • rg-dev-hcp-demo-weu

  • vnet-dev-hcp-demo-weu

  • vm-dev-hcp-demo-01
    Good naming helps with operations, cost tracking, troubleshooting, and governance.






Final Reflection



This project is more than just deploying a virtual machine to Azure.

It demonstrates a professional Infrastructure as Code workflow.

As a Cloud Engineer, I see Terraform as more than a provisioning tool. It is a discipline. It teaches structure, repeatability, version control, collaboration, and accountability.



As a technical instructor, I also see this workflow as one of the best ways to help students understand how modern cloud teams work. They learn that cloud engineering is not about clicking buttons in the portal. It is about building systems that are predictable, secure, reviewable, and easy to reproduce.

1. Sofort-Triage & Abwehrmaßnahmen

SOC Incident Playbook: Remote Code Execution (RCE) Defense
Syntax validiert (0 Fehler)
title: Detect Exploitation - Deploying Infrastructure to Azure Using HCP Terraform and GitHub VCS
id: 35d7c0bc-3290-4613-9f44-718a8a7c2119
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-27
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
  - attack.t1059
Syntax validiert (0 Fehler)
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-27"
        description = "YARA Signature for "
    strings:
        $str = "Deploying Infrastructure to Az" ascii wide
    condition:
        any of them
}
Syntax validiert (0 Fehler)
index=security sourcetype IN ("cisco:asa", "pan:traffic", "zeek_conn", "suricata", "WinEventLog:Security")
("Deploying Infrastructure to Azure Using ")
| stats count earliest(_time) as first_seen latest(_time) as last_seen by src_ip, dest_ip, dest_host, signature
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| sort - count
Syntax validiert (0 Fehler)
message: "*Deploying Infrastructure to Azure Using *"
Syntax validiert (0 Fehler)
CommonSecurityLog
| where Message has "Deploying Infrastructure to Azure Using "
| summarize EventCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, DestinationIP, DestinationPort, Activity
| extend DetectionRule = "iShareStuff-CTI-Compiled"
| sort by EventCount desc

2. Cyber Threat Intelligence & Forensik

CTI Threat Relationship Graph5 Knoten / 4 Relationen
CVE / Incident Software MITRE ATT&CK CWE Weakness IoC
🎯
MITRE ATT&CK Matrix Navigator 14 Taktiken
Identifiziert: T1059Command and Scripting Interpreter
Reconnaissance
-
Resource Development
-
Initial Access
Execution
Persistence
-
Privilege Escalation
Defense Evasion
Credential Access
-
Discovery
-
Lateral Movement
-
Collection
-
Command and Control
Exfiltration
-
Impact
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Analyse für identifizierte Bedrohung auf Basis von Live-CTI (ENISA EUVD): CVSS 0.0 · EPSS 0.0% · CISA KEV: nein. Handlungsableitung aus den verlinkten Hersteller-Quellen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

⚡ Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Deploying Infrastructure to Azure Using HCP Terraform and GitHub VCS

Thematisch verwandte Begriffe: Deploying, Infrastructure, Azure, Using · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-100620 | Capgo CLI (npm package @capgo/cli) through 7.98.2 is affected by an ove…
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag