Terraform: Resources, Variables, Outputs and Locals

Somebody who likes to code
Search for a command to run...

Somebody who likes to code
No comments yet. Be the first to comment.
Google processes tens of thousands of code changes every day across a codebase of hundreds of millions of lines. The secret isn't magic tooling — it's a documented, principled approach to code review

Amazon Simple Notification Service (SNS) looks straightforward on the surface — publish a message, deliver it to subscribers — but the gap between a topic that "works in dev" and one that is productio

Amazon Simple Queue Service (SQS) is deceptively simple to get started with, but surprisingly easy to misconfigure in ways that cause silent message loss, runaway costs, duplicate processing storms, o

HTTP API is the right default choice for the majority of .NET serverless workloads. At 70% less cost than REST API, lower latency, and native JWT authorization, it covers most production requirements

AWS Lambda has become a cornerstone of modern serverless architectures, but writing a function that "just works" is very different from writing one that is performant, cost-effective, secure, and read

HashiCorp Terraform is an infrastructure as code tool that lets you define both cloud and on-prem resources in human-readable configuration files that you can version, reuse, and share. You can then use a consistent workflow to provision and manage all of your infrastructure throughout its lifecycle.
In this post, we are going to learn about resources, variables, outputs, and local while we create a web app in Azure. Please follow the links to go to the official documentation.
Create an azure folder with a main.tf file and add the Terraform Provider for Azure:
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.5.0"
}
}
}
provider "azurerm" {
features {}
}
Resources are the most important element in the Terraform language. Each resource block describes one or more infrastructure objects, such as virtual networks, compute instances, or higher-level components such as DNS records.
Let's start creating our first resource, the Resource Group:
resource "azurerm_resource_group" "resource_group" {
name = "myFirstResourceGroupWithTerraform"
location = "eastus"
}
The next step is to create the App Service Plan:
resource "azurerm_service_plan" "app_service_plan" {
name = "myFirstAppServicePlanWithTerraform"
resource_group_name = azurerm_resource_group.resource_group.name
location = azurerm_resource_group.resource_group.location
os_type = "Linux"
sku_name = "B1"
}
And finally, the Web App:
resource "azurerm_linux_web_app" "web_app" {
name = "myFirstWebApp-1958666"
resource_group_name = azurerm_resource_group.resource_group.name
location = azurerm_service_plan.app_service_plan.location
service_plan_id = azurerm_service_plan.app_service_plan.id
site_config {}
}
The first step is to run the init command to initiate terraform:
terraform init
Before continuing with the following command, we need to log in against Azure:
az login
Time to provision the infrastructure, run the plan command to create the execution plan:
terraform plan -out app.tfplan
As the last step, we are going to apply the actions proposed in the plan:
terraform apply 'app.tfplan'
We can check the deployment on the Azure Portal:

Input Variables serve as parameters for a Terraform module, so users can customize behavior without editing the source.
Let's introduce some variables to parametrize the name of the resources:
variable "resource_group_name" {
description = "Name of the resource group"
type = string
}
variable "app_service_plan_name" {
description = "Name of the app service plan"
type = string
}
variable "web_app_name" {
description = "Name of the web app"
type = string
}
Then change the resources to use the variables:
resource "azurerm_resource_group" "resource_group" {
name = var.resource_group_name
location = "eastus"
}
resource "azurerm_service_plan" "app_service_plan" {
name = var.app_service_plan_name
resource_group_name = azurerm_resource_group.resource_group.name
location = azurerm_resource_group.resource_group.location
os_type = "Linux"
sku_name = "B1"
}
resource "azurerm_linux_web_app" "web_app" {
name = var.web_app_name
resource_group_name = azurerm_resource_group.resource_group.name
location = azurerm_service_plan.app_service_plan.location
service_plan_id = azurerm_service_plan.app_service_plan.id
site_config {}
}
Now during the execution of the plan, we can specify the value for the variables:
terraform plan -out app.tfplan -var="resource_group_name=myRGwithTerraform" -var="app_service_plan_name=mySPWithTerraform" -var="web_app_name=myWAWithTerraform-4589"
Output Values are like return values for a Terraform module.
Let's introduce an output to see the Web App Id:
output "web_app_id" {
value = azurerm_linux_web_app.web_app.id
}
Local Values are a convenience feature for assigning a short name to an expression.
We are going to create a new variable to ask for the owner of the resource group and then concatenate it with the name of the Resource Group:
variable "owner" {
description = "Owner of the resource group"
type = string
}
locals {
resource_group_name = "${var.owner}-${var.resource_group_name}"
}
resource "azurerm_resource_group" "resource_group" {
name = local.resource_group_name
location = "eastus"
}
Run the terraform plan and terraform apply commands to update the infrastructure in Azure. Notice that the Web App Id is visible at the end of the execution.
Run the plan command but with the destroy attribute:
terraform plan -destroy -out app.tfplan
And apply the plan:
terraform apply -destroy 'app.tfplan'
Now you can check the portal, and all the resources should not be there anymore. You can see the final main.tf file here.