
Explore the fundamentals of Terraform and automating cloud infrastructure with a hands-on, Azure-focused approach. Learn practical Terraform usage and the theory to build robust Azure solutions.
Master how Terraform implements infrastructure as code to automate provisioning and configuration of cloud resources, delivering repeatable, production-like environments for developers and operations teams.
Explore what Terraform is and why it became the de facto infrastructure as code tool, offering a cloud-agnostic, declarative language (HCL) for multi-cloud provisioning and iterative infrastructure evolution.
Explore common Terraform terminology and key concepts through a glossary-style section, with an invitation to suggest terms and help improve this Azure edition course.
Understand idempotence in infrastructure as code and how Terraform apply, using the plan, converges to a single desired environment state, unlike non-idempotent actions like bank deposits.
Understand immutability and distinguish it from mutability in infrastructure, and learn how artifacts and snapshots from Terraform, Packer, and version control enable last known good states and drift recovery.
Explore encapsulation in Terraform by grouping infrastructure into modules with inputs and outputs, defining the logical module boundary and its physical folder, and exposing preconditions and byproducts for reusable components.
Explore cohesion as a design principle in software and infrastructure as code, showing how organizing modules and components by task improves maintainability, readability, and extensibility.
Explore declarative versus imperative approaches in infrastructure as code with Terraform. Learn how declarative describes the desired state and how Terraform plans and executes resources as an infrastructure orchestrator.
Discover why the dry principle doesn't always fit infrastructure as code, especially in Terraform. Learn to favor clarity, plain language, and testing that reveals intent over abstract reuse.
Install Visual Studio Code on Windows, selecting the appropriate arm64 or x64 build, enable 'open with code' in the context menu, and choose a dark modern color scheme.
install chocolaty, a package manager for Windows, to install and manage software, especially command line tools. verify installation by typing the choco command in the terminal.
Learn to install Terraform on Windows using Chocolatey for a streamlined setup, verify version, and understand that Terraform is an infrastructure as code tool that works across cloud platforms.
Install the hashicorp terraform extension in VSCode to enable intellisense, syntax validation, highlighting, and automatic formatting for Terraform configurations; enable format on save.
Install the Azure CLI on Windows using Chocolatey or an MSI, verify the version, and run commands to provision resources or query existing resources from the command line.
install git for Windows and use git bash as a lightweight bash environment for cross-platform scripting, with VS Code terminal integration and PowerShell versus Bash workflows.
Set up a dedicated source code folder on Windows, create and organize source and repos directories under your user home, and pin it to quick access for fast lab access.
Dive into Terraform hands-on basics without cloud connections. Learn to use Terraform as a command line tool, write in HCL, and make environment changes, with cloud-agnostic concepts.
Create your first Terraform resource by building a simple lab in Terraform 101, using a random_string resource named suffix with length 6 in a Main.tf file.
Learn to use the Terraform core workflow: initialize with terraform init, preview changes with terraform plan, apply updates, manage state, and safely destroy resources.
Learn the Terraform core workflow by tracking code, state, and environment as a random string is provisioned, planned, applied, and eventually destroyed, updating the state file accordingly (init included).
Learn how input variables in Terraform pass parameters to configurations, enabling reusable modules and environment-specific settings via application name and environment name.
Explore local variables in Terraform by declaring a shared locals block to create environment prefixes and reusable constants, and see how locals differ from input variables in plan outcomes.
Define and use outputs to extract values from Terraform for use in automation pipelines, including Ansible or Kubernetes. Create outputs in outputs.tf and access them via Terraform output after apply.
Stitch inputs, outputs, and locals with string interpolation in Terraform to create dynamic strings from application name and environment name.
Define and lock providers in a versions.tf file with a required_providers block, specifying the source and version (e.g., random 3.6.3). Apply exact, ~>, or >= constraints via terraform init.
Learn how to reference resource outputs in Terraform by accessing a random string resource's result, using outputs in another resource, and applying string interpolation to build an environment prefix.
Explore the official Terraform provider registry to access provider documentation, discover resource inputs and outputs, and use filtering to locate resources like random string and understand read-only outputs.
Explore how to supply Terraform input variables with tfvars files, including terraform.tfvars and default.auto.tfvars, to avoid prompting and organize values across environments.
Learn to manage Terraform input variables with a default auto tfrs file for shared app settings and a dev.tfrs file for environment names, using -var-file during apply.
Organize environment configuration by using input variable value files for dev, test, and prod with prefixed tfr files or an env folder, then apply Terraform using a relative path.
Mark input variables and outputs as sensitive in Terraform to prevent leaking secrets in console output, and secure state at rest on trusted machines with least privilege.
Learn to securely pass secret values to Terraform by exporting environment variables in PowerShell using the TF_VAR_<input_var> naming convention, avoiding tfvars files and interactive prompts during terraform apply.
Set and access terraform input variables with environment variables in bash across Linux, Mac, and Windows, and manage separate terminals in VS Code to keep variables secure.
Follow Terraform’s order of operations for input variables: environment, then default tfr files, then var options, then manual input. Set each variable only once to avoid misconfig.
Explore Terraform input variable value precedence through hands-on experiments, revealing how terraform.tf, auto.tfvars, var, var files, and environment variables shape final values. Follow a mutually exclusive strategy to avoid confusion.
Explore Terraform input variable types, including string, number, and bool, plus collection types (list, map, set) and complex objects, with examples and dot notation for accessing attributes.
Master input variable validation in Terraform with nested validation blocks, boolean conditions, and built-in functions to enforce string length, instance count constraints, and quorum requirements.
Explore how to comment your Terraform code in HCL, using single-line styles (// or #) and multi-line blocks (/* ... */), tailored to your programming background.
Explore Terraform workspaces to manage separate state files for dev, test, and prod, switch between them with workspace commands, and understand local vs remote back end.
Iterate across a list in Terraform using the count meta argument to create multiple resources, generating a random string per region and indexing with list length.
Iterate over a map of region keys with foreach, where maps are dictionaries of unique keys like West US and East US, to create deployment blocks in Terraform.
Explore how to use boolean conditions and the count meta argument in Terraform to toggle resource provisioning with a ternary operator, enabling or destroying blocks based on input.
Explore Terraform modules, including reusable modules, and learn to use the Terraform module registry to find, reference, and instantiate modules with inputs and outputs.
Create your first Terraform module using a local, relative-path in a modules folder, then reference it from the root module. Add input variables and outputs to enable reuse.
Encapsulate environments with a regional stamp module and replicate across regions. Configure region, name, and min/max node counts, then run Terraform init and apply.
Leverage Terraform's count with a regional stamps collection to iterate across regions, using count.index to pull each object's region, name, and min/max node counts for two deployments.
Refactor a list into a map and iterate with foreach across regional stamps. Use each key and each value to access region attributes such as min and max node count.
Discover how the Terraform console provides an interactive command line to interrogate resources, view attributes, and extract values for inputs and outputs across the current workspace.
Sign up for an Azure subscription to access more features, compare free trial limitations with the pay-as-you-go option, and keep costs low while noting potential charges.
Log into the Azure portal, explore the free tier options, including Cosmos DB and storage, and pace your usage to fit the monthly allowances over 12 months.
Navigate the Azure portal to explore resource groups, subscriptions, and the Entra ID tenant. See how deployments live in groups, how subscriptions organize work, and how authentication uses the tenant.
Log in with the Azure CLI using az login, verify installation with az version, and complete interactive sign-in. Manage the default subscription and capture the subscription ID for Terraform automation.
Provision Azure resources with Terraform using the Azure RM provider, set up a storage account as a backend for state files, and learn foundational Azure Monitor and Key Vault concepts.
Configure the Azure provider for Terraform by creating the standard project structure and declaring the Azure RM provider. Run terraform init and set the subscription id explicitly.
Provision an Azure resource group using the Terraform provider; declare the Azure RM resource group, set name and location, then run init and apply.
Define a simple, consistent Azure resource group naming convention in Terraform by concatenating application name and environment name, using a primary region and environment-specific configs to prevent renaming.
Provision an Azure storage account for Terraform state using the Azure provider docs and example code, applying simple naming conventions with a random string for uniqueness, then run Terraform init.
Set up dev and prod Terraform state in same Azure subscription using workspaces, init, and apply with a dev environment file to provision a new storage account and resource group.
Set up blob storage containers for Terraform state in both dev and prod environments, enabling private access and secure remote state storage in Azure storage accounts.
Learn the standard Azure resource naming prefixes and abbreviations, apply hyphenated, readable names, and follow a consistent scheme for grouping resources in the Azure portal.
Configure the Azure RM backend to store Terraform state in Azure Blob Storage with a unique key based on application and environment.
Configure an Azure Terraform state backend using a storage account and blob container, with unique backend keys per environment to store separate dev and prod state files.
Set up an Azure Log Analytics workspace to capture and query logs across Azure services within the observability stack, using Terraform to create it in the main resource group.
Examine how to compartmentalize observability services like logs and metrics into dedicated resource groups alongside Terraform state. Discuss enterprise-wide versus workload-specific observability and the value of a timeline across components.
Set up a local runner to dynamically configure Terraform back end state and context for multiple environments, using a shell script with environment variables and back end config.
Create a dev Terraform project to provision an Azure key vault and configure backend state, a resource group, and Log Analytics with a random suffix for uniqueness.
Use the Azure client config data source to read the current subscription and tenant id from your authenticated context, avoiding hard coded values and improving key vault provisioning.
Create a role assignment in Azure to grant access to a provisioned resource using a principal ID, role definition, and scope, demonstrating Terraform-managed Key Vault permissions with least privilege.
Enable rbac authorization on the key vault to replace the legacy access policies, by setting enable_rbac_authorization to true and applying the Terraform plan.
Utilize a local lab script to provision dev and prod environments for the shared DevOps infrastructure. Configure environment and application names in the script to drive backend and Terraform state.
Explore how Terraform provisions a key vault and grants data plane access via role assignment. Contrast data plane with the Azure ARM control plane and connect state, observability, and secrets.
Configure an Azure Monitor diagnostic setting to connect a Key Vault to a Log Analytics workspace via Terraform, using data sources and portal mappings for accurate resource references.
Use the Azure portal to configure Azure Monitor diagnostic settings with Terraform, exploring logs, metrics, and category group options. Verify category values with jsonview.
Create a virtual network and VM as you learn Azure networking and compute with Terraform, using a storage backend, log analytics workspace for Azure Monitor, and Key Vault for secrets.
Learn to provision an Azure virtual network with Terraform, choosing a pragmatic /22 address space in a development resource group, while noting standalone subnets and drift challenges from Network Watcher.
Provision a virtual network with a /22 address space and create four /24 subnets (Alpha, Bravo, Charlie, Delta) using Terraform, while optimizing subnet sizing and accounting for Azure's reserved addresses.
Learn to extract the base address space and use the cidr subnet function in Terraform to generate four /24 subnets from a /22 base.
Master switchbacking in infrastructure as code with Terraform, zigzagging through safe intermediate steps to update a virtual network and subnets from 10.39 to 10.40.
Explore how to pivot infrastructure with Terraform by destroying and recreating a virtual network and subnets when implicit dependencies force a base address change, using drop create.
Set up a network security group in Azure with Terraform, enable inbound SSH on port 22, and associate the NSG with a subnet to control traffic.
Secure your azure subnet by restricting ssh access with the source address prefix. Use an HTTP data source to fetch the IP and update the NSG via Terraform.
Provision a public IP address for an Azure virtual machine using Terraform, linking it to a resource group and virtual machine with static allocation in West US 3.
Create and attach an azure network interface card to the linux virtual machine, linking the private alpha subnet and the public ip address to enable internet access and traffic routing.
Create an SSH key with the TLS private key resource in Terraform, generate RSA keys, and provision a Linux VM using the public key while safeguarding the private key.
Provision your first Azure Linux virtual machine with Terraform, using Ubuntu 20.04 LTS, SSH key, and a network interface on a subnet; then apply and connect via public IP.
Move the generated ssh key from Terraform to your local machine via a local file resource, save the private key with secure permissions, then ssh to VM using admin user.
Compare direct ssh or rdp with Azure Bastion for secure indirect access over https, avoiding port 22 or 3389, and reconfigure networks and VMs to adopt Azure Bastion.
Reorganize subnets to replace direct SSH with Azure Bastion by moving the VM's NIC from Alpha to Bravo, freeing apex subnet for the Azure Bastion, and applying changes with Terraform.
Remove the alpha subnet to free space and create a /26 azure bastion subnet at 10.40.0.0/26, updating the Terraform plan to use the Azure Bastion Subnet name.
Configure an Azure Bastion host with Terraform, create the bastion subnet and public IP, provision the service, and remove the old NSG to force SSH via the Bastion.
Move the SSH key from local storage to a key vault secret and configure Terraform data sources to enable bastion-based access to the virtual machine, replacing direct SSH.
Connect to the Linux virtual machine via Azure Bastion using an SSH key from Key Vault over secure HTTPS, avoiding port 22 exposure and VPN.
Enable Microsoft Entra ID authentication for Linux VMs using a VM extension, configure managed identities, assign VM user or administrator roles, and automate with Terraform.
Enable entry ID authentication on an Azure Linux virtual machine by adding a system assigned identity with Terraform, validating with Terraform apply, and verifying the identity in the Azure portal.
Build and apply an Azure virtual machine extension with Terraform, adapting the registry resource and converting JSON settings into a Terraform block; enable Entra ID authentication via bastion.
Leverage the Entra ID Terraform provider to replace per-user access with group-based RBAC, create Entra ID groups, assign members, and define permissions for VM access and service principals.
Set up the Entra ID Terraform provider azuread, upgrade to version 3.2.0, and configure the tenant context to enable provisioning of groups and their role assignments.
Create an Entra ID group with the Azure AD client config, set the current user as owner, and update the role assignment to use the new group's object ID.
Assign a user to an Entra ID group with the Azure AD group member resource in Terraform, wiring group and member object IDs, applying changes to restore remote access.
Replace the Azure AD client config current user with an Entra ID data source to reference an existing Azure AD user and stabilize access across Terraform runs.
Refactor to assign multiple remote access users to an Entra ID group using a list of emails, moving from count-based iteration to for each to improve maintainability.
Learn to safely destroy Azure resources with Terraform destroy, including key vault purge and soft delete, across resource groups and Entra ID, and handle drift.
Assess the Azure API provider for Terraform alongside the Azure RM provider. Learn how a single body resource delivers day zero support and uses the official ARM schema.
Compare the Azure ARM provider with the AZ API provider in the Terraform registry, highlighting the AZ API provider’s single resource and type attribute approach.
Discover how to locate Azure API provider resource schemas using the Azure Resources reference, inspect the body structure, and adapt from Bicep, ARM, or Terraform templates.
Set up a new lab and start with the AZ API provider by configuring a main.tf, using a pessimistic version constraint for 2.3.0, then run terraform init.
Set up a Terraform root module with the AZ API provider, define variables for application name, environment, and west us three, and ensure a unique backend state key for dev.
Create a resource group using the AZ API provider, obtaining the current subscription ID via a data source and constructing the resource ID for a subscription-scoped deployment.
Create a public ip address resource for a virtual machine using the az api provider, configuring the public ip allocation method as static or dynamic.
Create a network interface with the AZ API provider by referencing a subnet via the AZ API data source, then attach a public IP and configure dynamic private IP allocation.
Create Key Vault secrets with A-Z API provider by generating a TLS key pair and storing the SSH private and public keys as secrets, while configuring ignore changes for location.
Provision a virtual machine with the azure api provider in terraform, detailing image reference, os disk, ssh keys, network interfaces, and vm size. Compare day-zero support with azure rm provider.
Compare the Azure API provider and Azure ARM provider side by side while provisioning a virtual machine, a resource group, and network components, highlighting readability, complexity, and cross-subscription tradeoffs.
Refactor by merging the azure provider with the azure api provider for day zero support, replacing the resource group, and simplifying subnet and key vault handling.
Explore how to get started with Azure Terraform using Terraform 101 Azure edition, and discover resources via the Terraform registry with the Azure provider.
This course offers a beginner-friendly introduction to Terraform, covering the basics of the Terraform CLI and HashiCorp Configuration Language (HCL) in a cloud-agnostic way. You’ll learn how to set up Azure using the “azurerm” provider, starting with configuring a storage account for remote state management. Next, you’ll build a local runner (or script) that makes it easier to manage multiple environments directly from your own workstation. Then, you’ll set up key DevOps infrastructure, including Azure KeyVault for secret management and Azure Monitor for observability, capturing logs and metrics to ensure your deployments run smoothly.
Leading you through these topics is Mark Tinderholt, currently a Principal Architect at Microsoft Azure. Mark brings a highly practical perspective drawn from over 25 years of real-world experience in software development, technology consulting, and leading teams. He has worked on everything from data center migrations to microservices architecture and multi-tenant SaaS solutions, all while driving DevOps culture at organizations both large and small. Because he’s not a typical “professional trainer,” but rather a veteran industry practitioner, his instruction is hands-on and focused on real-world scenarios. This approach makes learning both intuitive and immediately applicable to modern infrastructure challenges, ensuring that you gain the skills to succeed in today’s fast-paced Cloud and DevOps landscape.
As you progress, you’ll create an Azure Virtual Network and deploy a Linux Virtual Machine, exploring various connectivity options such as SSH and Azure Bastion. We'll also enable Entra ID Authentication and explore how to automate Entra ID using the "azuread" Terraform Provider. Finally, we'll look at the "other" Azure Terraform provider--the "azapi" Terraform Provider which unlocks Day Zero Support for new Azure services and features.
Throughout the course, you’ll pick up best practices for structuring your Terraform code, handling multiple environments, and maintaining a reliable infrastructure as code workflow. By the end, you’ll have a strong grasp of Terraform fundamentals and Azure essentials—perfect if you’re just starting out with either technology or if you’re looking to solidify your cloud infrastructure skills. With Mark’s guidance, you’ll gain the confidence to design and deploy repeatable, scalable infrastructure on Azure using Terraform.