Terraform (Azure) Coding — Naming Convention and Resource Creation Patterns

DevOpsWithYoge
4 min readJan 8, 2024

--

Hi Everyone ,
I am glad to share few upto date best practices while designing the infra for Azure using terraform . This blog gives you examples and a real time usages with problem statements to understand the scenarios and work better.

Note: This blog is for the targeted audience who has known the basics of terraform and usage of HCL syntax.

Topics Covered:

  1. Naming Conventions
  2. Resource creation patterns with HCL (collaborative [AzApi , ARM Template] and standalone)

Naming Conventions:

Naming conventions are pillars for the standard coding techniques.

1. Defining Resource Blocks

The resource blocks should have lowercase letters seperated with underscores (“_”)

resource "azurerm_resource_group" "resource_group" {
name = "test-resource-group"
location = "west-us"
tags = {"location" = "westus", "Environment"="Stage"}
}

2. Defining variables

Terraform has two types of variables : input and output

Rules:

1. The variables must have a meaning full name and if its long name it should follow lowercase letters with underscores.

variable location {
type = string
description = "(Required) The Azure location where the Resource group will be created. Changing this forces a new resource to be created."
}

2. variables should have a clear description with status of Required / Optional. so that it will be helpful in debugging in future.

3. if variables which are destined to hold secrets then its good to use sensitive flag. which will hide the values in the terraform plan/apply.

4. variables can have default values — when a structure of datatype is undefined or its so complex its to good to use default values.

5. we can use validation in the variables to avoid runtime errors / restrict the major issue in near future.

Variables must have defined datatypes

Datatypes in terraform :

The output variables are used for the following purpose.

the outputs can be cascaded between modules,
To print the id / specific attribute of the resource creation in the plan and apply.

Few examples;

output "id" {
value = azurerm_storage_account.storage_accounts.id
description = "id - The ID of the Storage Account."
}

variable with sensitive value:

output "primary_connection_string" {
value = azurerm_storage_account.storage_accounts.primary_connection_string
description = "The connection string associated with the primary location."
sensitive = true
}

3. Validation in variable level

Validation can be performed in the variable level. here is an example where the resource location is to be West/East/Central US . on passing any other locations it will throw a error message in the validation step. (terraform validate)

variable "location" {
type = string
description = "(Required)"
default = "WestUS"

validation {
condition = can(regex("^(WestUS|EastUS|CentralUS)$", var.location))
error_message = "Invalid location selected, only allowed locations are: WestUS|EastUS|CentralUS. Default 'WestUS'"
}
}

Resource Creation Patterns in Azure Terraform

1. Collaborative Coding Pattern

a) Using AzApi provider

On using the AzAPI provider the azure resources can be created in terraform. this is used occasionally . when a standard terraform — resource block is not available in the terraform/registry then one of the way to deploy azure resources is through AzApi provider.

Problem Statement:

Update the cosmos DB account with TLS version Tls12.

As of now through terraform the comosDB accounts can be created using Tls1.0 only. but Inorder to upgrade to Tls12 we can use azapi provider to update it.

Here is the example for upgrading the cosmos DB accounts TLS versions

#Update the minimum TLS configuration for cosmos database
resource "azapi_update_resource" "cosmos_tls" {
type = "Microsoft.DocumentDB/databaseAccounts@2023-03-01-preview"
resource_id = ([for cmsdb in module.cosmosdb_accounts : cmsdb.main if cmsdb.main.name == each.value.account_name])[0].id
body = jsonencode({
properties = {
minimalTlsVersion = each.value.tls_config.version
}
})

depends_on = [
module.cosmosdb_accounts
]
}

b) Deploy Azure Resource using ARM Templates

Azure Resources can also be deployed using `azurerm_resource_group_template_deployment` resource block

Problem Statement:

Create a managed API connection in azure for azure files and output the connection Runtime URL.

Consider the below ARM Template. and terraform resource block which uses incremental deployment mode to deploy the designated Api con resource

{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"connectionName": {
"type": "String",
"metadata": {
"description": "The name for the connection."
}
},
"connectionType": {
"type": "String",
"metadata": {
"description": "The type of the connection."
}
},
"parameterValues": {
"type": "Object"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Web/connections",
"apiVersion": "2018-07-01-preview",
"location": "[resourceGroup().location]",
"kind": "V2",
"name": "[parameters('connectionName')]",
"properties": {
"api": {
"id": "[subscriptionResourceId('Microsoft.Web/locations/managedApis', resourceGroup().location, parameters('connectionType'))]"
},
"displayName": "[parameters('connectionName')]",
"parameterValues": "[parameters('parameterValues')]"
}
}
],
"outputs": {
"connectionRuntime": {
"type": "String",
"value": "[reference(resourceId('Microsoft.Web/connections', parameters('connectionName')),'2016-06-01', 'full').properties.connectionRuntimeUrl]"
}
}
}
#resource block to create managed api connections
resource "azurerm_resource_group_template_deployment" "main" {
name = "api-con-template"
resource_group_name = "sample-resource-group"
template_content = file("../../Resources/ARM-Templates/apiconnection.json")
parameters_content = jsonencode({ "accountName" = "sample-storage-account", "accesskey" = "uk098234098lkjdlkjflkjdsflkj"})
deployment_mode = "Incremental"
}

2. StandAlone Coding Pattern

This coding pattern completely uses terraform HCL to deploy azure resources . the updates on resources are available in https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/*****<<azure resource name>>******

This is the majorly used pattern in terraform azure resource creation, its straight forward and easy to maintain with respect to terraform standards.

An Example -> https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine.html

Conclusion:

In the modern Software development world, creating infrastructure through code makes the life of developers at ease with deployments. For Azure Terraform there are few standards which I wished to share related to naming conventions and resource creations techinques which terraform offers.

Hope you liked the blog ! follow for more updates related to Azure !!!

--

--

DevOpsWithYoge

An enthusiastic DevOps professional ,I would like to help/share Azure Cloud aspirers and learners to know the aspect where Azure Cloud meets the realworld.