{"id":36604,"date":"2025-01-16T14:43:38","date_gmt":"2025-01-16T13:43:38","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/?p=36604"},"modified":"2025-02-18T16:01:23","modified_gmt":"2025-02-18T15:01:23","slug":"automate-your-deployments-in-azure-with-terraform","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/","title":{"rendered":"Automate your Deployments in Azure with Terraform!"},"content":{"rendered":"\n<p>Terraform is a strong open-source declarative and platform agnostic infrastructure as code (IaC) tool developed by HashiCorp. It facilitates the deployment and whole management of infrastructure. In this hands on blog I will show you how you can use Terraform to automate your cloud deployments in Azure.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-initial-setup\">Initial Setup:<\/h2>\n\n\n<p>For this blog I\u2019m using a ubuntu server as a automation server where I\u2019m running Terraform. You can install Terraform on different operating systems. For instructions how to install Terraform check out this <a href=\"https:\/\/developer.hashicorp.com\/terraform\/tutorials\/aws-get-started\/install-cli\">link<\/a> from HashiCorp.<\/p>\n<p>Starting with the hands on part I\u2019m creating a new dedicated directory for my new Terraform project:<\/p>\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"721\" height=\"83\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-20.png\" alt=\"\" class=\"wp-image-36605\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-20.png 721w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-20-300x35.png 300w\" sizes=\"auto, (max-width: 721px) 100vw, 721px\" \/><\/figure>\n\n\n\n<p>Within this new directory I\u2019m creating the following files which will hold my configuration code:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>main.tf<\/li>\n\n\n\n<li>providers.tf<\/li>\n\n\n\n<li>variables.tf<\/li>\n\n\n\n<li>outputs.tf<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"909\" height=\"221\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-21.png\" alt=\"\" class=\"wp-image-36606\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-21.png 909w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-21-300x73.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-21-768x187.png 768w\" sizes=\"auto, (max-width: 909px) 100vw, 909px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-installing-the-azure-cli\">Installing the Azure CLI:<\/h2>\n\n\n\n<p>For the authentication with Azure I\u2019m using the Azure CLI command line tool. You can Install the Azure CLI on Ubuntu with one command which curls a script, provided by Microsoft, from the internet and executes it on your system:<\/p>\n\n\n\n<p><strong><em>curl -sL https:\/\/aka.ms\/InstallAzureCLIDeb | sudo bash<\/em><\/strong><\/p>\n\n\n\n<p>To get more information\u2019s about how to install the Azure CLI on your system, checkout this <a href=\"https:\/\/learn.microsoft.com\/en-us\/cli\/azure\/install-azure-cli\">link<\/a> from Microsoft.<\/p>\n\n\n\n<p>As far as the installation is successfully done, you can verify it with the following command:<\/p>\n\n\n\n<p><strong><em>az &#8211;version<\/em><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"691\" height=\"414\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-22.png\" alt=\"\" class=\"wp-image-36607\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-22.png 691w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-22-300x180.png 300w\" sizes=\"auto, (max-width: 691px) 100vw, 691px\" \/><\/figure>\n\n\n\n<p>Then use the following command for connecting to Azure:<\/p>\n\n\n\n<p><strong><em>az login<\/em><\/strong><\/p>\n\n\n\n<p>This command will open a browser window where you can sign in to Azure:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"95\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-23.png\" alt=\"\" class=\"wp-image-36608\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-23.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-23-300x30.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-23-768x78.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>After you successfully authenticated yourself to Azure, you can check your available subscriptions with the following command:<\/p>\n\n\n\n<p><strong><em>az account list<\/em><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"679\" height=\"422\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-24.png\" alt=\"\" class=\"wp-image-36609\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-24.png 679w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-24-300x186.png 300w\" sizes=\"auto, (max-width: 679px) 100vw, 679px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-initialize-terraform\">Initialize Terraform:<\/h2>\n\n\n\n<p>As the Azure CLI is now installed on the system and we are successfully authenticated to Azure, we can now start with the configuration of Terraform and the required provider for interacting with the Azure cloud platform.<\/p>\n\n\n\n<p>Therefore I add the code block below into the providers.tf file which will tell terraform to install and initialize the azurerm provider with the specific version 4.10.0, which is the latest at the moment:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"584\" height=\"340\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-25.png\" alt=\"\" class=\"wp-image-36610\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-25.png 584w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-25-300x175.png 300w\" sizes=\"auto, (max-width: 584px) 100vw, 584px\" \/><\/figure>\n\n\n\n<p>To configure the azurerm provider, I add the provider code block below additionally into the providers.tf file.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"816\" height=\"234\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-26.png\" alt=\"\" class=\"wp-image-36611\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-26.png 816w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-26-300x86.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-26-768x220.png 768w\" sizes=\"auto, (max-width: 816px) 100vw, 816px\" \/><\/figure>\n\n\n\n<p>You can find your subscription ID in the output from the \u201caz account list\u201d command above.<\/p>\n\n\n\n<p>After inserting those code blocks into the providers.tf file, we can install the defined azurerm provider and initialize Terraform by running the below command in our project directory:<\/p>\n\n\n\n<p><strong><em>terraform init<\/em><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"595\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-27.png\" alt=\"\" class=\"wp-image-36612\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-27.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-27-300x190.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-27-768x486.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-terraform-workspaces\">Terraform Workspaces:<\/h2>\n\n\n\n<p>As Terraform is now successfully initialized and the required provider is installed, we can start with the development of our infrastructure code.<\/p>\n\n\n\n<p>But before doing so I would like to target the concept of workspaces in Terraform. Workspaces enables you to use the same configuration code for multiple environments through separate state files. You can imagine workspaces as a separated deployment environment and you terraform code as a independent plan or image of your infrastructure. As an example, imagine you added a new virtual machine to your terraform code and deployed it in production. If you now want to have the same virtual machine for test purposes, you just have to switch into your test workspace and run the terraform code again. You will have the exact same virtual machine within a few minutes!<\/p>\n\n\n\n<p>To check the workspaces you have in your Terraform project, use the following command:<\/p>\n\n\n\n<p><strong><em>terraform workspace list<\/em><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"78\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-28.png\" alt=\"\" class=\"wp-image-36613\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-28.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-28-300x25.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-28-768x64.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>As you can see we just have the default workspace in our new Terraform project. I want to deploy my infrastructure in this hands on blog post for multiple environments, therefore I will create some new workspaces. Lets assume we have a development, test and production stage for our infrastructure. I will create therefore the workspaces accordingly with the commands below:<\/p>\n\n\n\n<p><strong><em>terraform workspace new development<\/em><\/strong><\/p>\n\n\n\n<p><strong><em>terraform workspace new test<\/em><\/strong><\/p>\n\n\n\n<p><strong><em>terraform workspace new production<\/em><\/strong><\/p>\n\n\n\n<p>After executing these commands, we can now check again our available workspaces in our terraform project:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"140\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-29.png\" alt=\"\" class=\"wp-image-36614\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-29.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-29-300x45.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-29-768x114.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>Note that terraform will let you know your current workspace through the \u201c*\u201d symbol behind the particular workspace. We want to deploy our infrastructure for development first. So I will switch back into the development workspace with the following command:<\/p>\n\n\n\n<p><strong><em>terraform workspace select development<\/em><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"58\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-30.png\" alt=\"\" class=\"wp-image-36615\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-30.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-30-300x19.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-30-768x47.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-create-an-azure-resource-group\">Create an Azure Resource Group:<\/h2>\n\n\n\n<p>As the workspaces are now successfully created, we can start with our configuration code.<\/p>\n\n\n\n<p>First of all I go into the variables.tf file and add the variable code block below to that file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"721\" height=\"565\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-31.png\" alt=\"\" class=\"wp-image-36616\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-31.png 721w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-31-300x235.png 300w\" sizes=\"auto, (max-width: 721px) 100vw, 721px\" \/><\/figure>\n\n\n\n<p>I will use this \u201cenv\u201d variable for the suffix or prefix of resource names, which I will deploy, to simple recognize to which environment these resources belong.<\/p>\n\n\n\n<p>Next I will create a resource group in Azure. Therefore I add the code block below to the main.tf file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"731\" height=\"320\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-32.png\" alt=\"\" class=\"wp-image-36617\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-32.png 731w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-32-300x131.png 300w\" sizes=\"auto, (max-width: 731px) 100vw, 731px\" \/><\/figure>\n\n\n\n<p>As you can see I set the name of the resource group dynamically with the prefix \u201cRG_\u201d and the value for the current workspace in the variable \u201cenv\u201d, which I\u2019ve defined before in the variables.tf file. The variable \u201cterraform.workspace\u201d is a default variable which refers to the current workspace.<\/p>\n\n\n\n<p>To check which resource terraform would create in case we would apply the current configuration code, we can run the following command:<\/p>\n\n\n\n<p><strong><em>terraform plan<\/em><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"259\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-33.png\" alt=\"\" class=\"wp-image-36619\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-33.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-33-300x83.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-33-768x212.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>We can see that terraform would create a new resource group with the name \u201cRG_DEV\u201d.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-create-a-virtual-network-and-subnets\">Create a Virtual Network and Subnets:<\/h2>\n\n\n\n<p>Next I will create a virtual network. Therefore I add the variable code block below to the variables.tf file. This variable defines for each environment stage a own address space:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"903\" height=\"421\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-34.png\" alt=\"\" class=\"wp-image-36620\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-34.png 903w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-34-300x140.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-34-768x358.png 768w\" sizes=\"auto, (max-width: 903px) 100vw, 903px\" \/><\/figure>\n\n\n\n<p>I add now the code block below to the main.tf file to create a virtual network:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"896\" height=\"275\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-35.png\" alt=\"\" class=\"wp-image-36621\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-35.png 896w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-35-300x92.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-35-768x236.png 768w\" sizes=\"auto, (max-width: 896px) 100vw, 896px\" \/><\/figure>\n\n\n\n<p>As you can see I\u2019m referencing here as well to the \u201cenv\u201d variable for dynamically setting the suffix of the network name and as well to the new \u201ccidr\u201d variable to set the address space of the virtual network.<\/p>\n\n\n\n<p>Next I will create some subnets within the virtual network. I want to create 4 subnets in total:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A front tier subnet<\/li>\n\n\n\n<li>A middle tier subnet<\/li>\n\n\n\n<li>A backend tier subnet<\/li>\n\n\n\n<li>A bastion subnet for the administration<\/li>\n<\/ul>\n\n\n\n<p>Therefore I add the variable below to my variables.tf file, which defines for each environment stage and subnet an address space:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"876\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-36.png\" alt=\"\" class=\"wp-image-36623\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-36.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-36-300x280.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-36-768x716.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>Next I will add for each subnet a new resource block to the main.tf file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"204\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-37.png\" alt=\"\" class=\"wp-image-36624\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-37.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-37-300x65.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-37-768x167.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"242\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-38.png\" alt=\"\" class=\"wp-image-36625\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-38.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-38-300x77.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-38-768x198.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"262\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-39.png\" alt=\"\" class=\"wp-image-36626\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-39.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-39-300x84.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-39-768x214.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"226\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-40.png\" alt=\"\" class=\"wp-image-36627\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-40.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-40-300x72.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-40-768x185.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>Note that I enabled in the backend tier subnet the option \u201cprivate_endpoint_network_policies\u201d. This is a option which enforces the network security groups to take effect on the private endpoints in the particular subnet. Checkout this <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/private-link\/disable-private-endpoint-network-policy?tabs=network-policy-portal\">link<\/a> from Microsoft for more information\u2019s about this option.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-create-an-azure-sql-database\">Create an Azure SQL Database:<\/h2>\n\n\n\n<p>Next I will create an Azure SQL Server. Therefore I add the variable below to my variables.tf file. This variable is supposed to hold the admin password of the Azure SQL Server. I set the sensitivity option for this variable which will prevent the password to be exposed in the terminal output or in the Terraform logs:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"746\" height=\"190\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-41.png\" alt=\"\" class=\"wp-image-36629\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-41.png 746w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-41-300x76.png 300w\" sizes=\"auto, (max-width: 746px) 100vw, 746px\" \/><\/figure>\n\n\n\n<p>I did also not set any value in the configuration files, instead I will set the variable value as a environment variable before applying the configuration.<\/p>\n\n\n\n<p>Next I add the code block below to my main.tf file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"312\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-42.png\" alt=\"\" class=\"wp-image-36630\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-42.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-42-300x100.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-42-768x255.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>As you can see I referenced the \u201csqlserver_password\u201d variable to set the password for the \u201csqladmin\u201d user. I also disabled the public network access to prevent database access over the public endpoint of the server. I will create instead a private endpoint later on.<\/p>\n\n\n\n<p>Next I will create the Azure SQL Database. Therefore I add the variable below to my variables.tf file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"821\" height=\"806\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-43.png\" alt=\"\" class=\"wp-image-36631\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-43.png 821w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-43-300x295.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-43-768x754.png 768w\" sizes=\"auto, (max-width: 821px) 100vw, 821px\" \/><\/figure>\n\n\n\n<p>The thought behind this variable is, that we have different requirements for the different stages. The general purpose SKU is sufficient for the non-productive databases but for the productive one we want the business critical service tier. As well as we want to have 30 days of point in time recovery for our productive data while 7 days is sufficient for non-productive and we want to store our productive database backups on geo-zone redundant storage while zone redundant storage is sufficient for the non-productive databases.<\/p>\n\n\n\n<p>Then I add the resource block below into my main.tf file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"286\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-44.png\" alt=\"\" class=\"wp-image-36632\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-44.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-44-300x91.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-44-768x234.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>As you can see I\u2019m referencing to my \u201cdatabase_settings\u201d variable to set the configuration options dynamically.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-create-a-dns-zone-and-a-private-endpoint\">Create a DNS Zone and a Private Endpoint:<\/h2>\n\n\n\n<p>For name resolution I will next create a private DNS zone. For that I add the resource block below to my main.tf file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"870\" height=\"219\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-45.png\" alt=\"\" class=\"wp-image-36633\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-45.png 870w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-45-300x76.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-45-768x193.png 768w\" sizes=\"auto, (max-width: 870px) 100vw, 870px\" \/><\/figure>\n\n\n\n<p>To associate this private DNS zone now with my virtual network, I will next create a virtual network link. Therefore I add the resource block below to my main.tf file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"201\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-46.png\" alt=\"\" class=\"wp-image-36634\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-46.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-46-300x64.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-46-768x164.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>To be able to securely connect to my azure sql database I will now create a private endpoint in my backend subnet. Therefore I add the resource block below to my main.tf file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"405\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-47.png\" alt=\"\" class=\"wp-image-36635\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-47.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-47-300x129.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-47-768x331.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>With this configuration code, I create a private endpoint with the name of the Azure SQL Server and the suffix \u201c-endpoint\u201d. Through the option \u201csubnet_id\u201d I place this endpoint in the backend subnet with a private service connection to the Azure SQL Server. I also associate the endpoint to the private DNS zone, which I\u2019ve created just before, for name resolution.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-create-an-azure-bastion\">Create an Azure Bastion:<\/h2>\n\n\n\n<p>Lets now continue and create an azure bastion host for the administration of our environment. Therefore I first create a public IP address through adding the resource block below to my main.tf file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"938\" height=\"313\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-48.png\" alt=\"\" class=\"wp-image-36636\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-48.png 938w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-48-300x100.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-48-768x256.png 768w\" sizes=\"auto, (max-width: 938px) 100vw, 938px\" \/><\/figure>\n\n\n\n<p>Next I create the bastion host itself. For that I add the code block below to my main.tf file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"383\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-49.png\" alt=\"\" class=\"wp-image-36637\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-49.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-49-300x122.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-49-768x313.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-create-a-virtual-machine\">Create a Virtual Machine:<\/h2>\n\n\n\n<p>Now I will add a virtual machine to my middle tier subnet. Therefore I need to create first a network interface for that virtual machine. The resource block below will create the needed network interface:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"285\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-50.png\" alt=\"\" class=\"wp-image-36638\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-50.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-50-300x91.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-50-768x233.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>As the virtual machine, which I intend to create, needs an admin password like the azure sql server, I will create an additional password variable. Therefore I add the code block below to my variables.tf file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"626\" height=\"190\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-51.png\" alt=\"\" class=\"wp-image-36639\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-51.png 626w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-51-300x91.png 300w\" sizes=\"auto, (max-width: 626px) 100vw, 626px\" \/><\/figure>\n\n\n\n<p>To create the virtual machine itself, I add the resource block below to my main.tf file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"765\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-52.png\" alt=\"\" class=\"wp-image-36640\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-52.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-52-300x244.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-52-768x625.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-create-network-security-groups-and-rules\">Create Network Security Groups and Rules:<\/h2>\n\n\n\n<p>Next I want to secure my subnets. Therefore I create for my front tier, middle tier and backend tier subnet a network security group by adding the resource blocks below to my main.tf file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"302\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-53.png\" alt=\"\" class=\"wp-image-36641\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-53.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-53-300x96.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-53-768x247.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"263\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-54.png\" alt=\"\" class=\"wp-image-36642\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-54.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-54-300x84.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-54-768x215.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"262\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-55.png\" alt=\"\" class=\"wp-image-36643\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-55.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-55-300x84.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-55-768x214.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>Next I create for each network security group particular rules.<\/p>\n\n\n\n<p>Starting with the front tier subnet I want to block all Inbound traffic except traffic over https. Therefore I add the two resource blocks below to my main.tf file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"690\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-56.png\" alt=\"\" class=\"wp-image-36644\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-56.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-56-300x220.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-56-768x564.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>Continuing with the middle tier subnet I want to block all inbound traffic but allow http traffic only from the front tier subnet and allow rdp traffic only from the bastion subnet. Therefore I add the three resource blocks below to my main.tf file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"667\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-57.png\" alt=\"\" class=\"wp-image-36645\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-57.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-57-300x213.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-57-768x545.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"354\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-58.png\" alt=\"\" class=\"wp-image-36646\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-58.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-58-300x113.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-58-768x289.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>Last but not least I want to block all Inbound traffic to my backend tier subnet except traffic to the sql-server port from the middle tier subnet. In addition I want to block explicitly the internet access from this subnet.<\/p>\n\n\n\n<p>You are questioning why I\u2019m explicitly block internet access from this subnet while I haven\u2019t any public IP address or NAT gateway for this subnet? That\u2019s because Microsoft provides access to the internet through a default outbound IP address in case no explicit way is defined. That\u2019s a feature which will be deprecated on the 30<sup>th<\/sup> September 2025. To get more information\u2019s about this feature check out this <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/virtual-network\/ip-services\/default-outbound-access\">link<\/a> from Microsoft.<\/p>\n\n\n\n<p>To create the rules for the backend tier subnet I add the three resource blocks below to my main.tf file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"662\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-59.png\" alt=\"\" class=\"wp-image-36647\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-59.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-59-300x211.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-59-768x541.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"341\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-60.png\" alt=\"\" class=\"wp-image-36648\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-60.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-60-300x109.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-60-768x279.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-define-output-variables\">Define Output Variables:<\/h2>\n\n\n\n<p>I will stop with the creation of resources for this blog post and will show you finally how you can define outputs. For example let\u2019s assume we want to have the name of the Azure SQL Server and the IP address of the virtual machine extracted after the deployment. Therefore I add the two output variables below to the outputs.tf file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"364\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-61.png\" alt=\"\" class=\"wp-image-36649\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-61.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-61-300x116.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-61-768x297.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>Outputs are especially useful when you need to pass up information\u2019s from the deployment to a higher context. For example when you are working with modules in terraform and you want to pass information\u2019s from a child module to a parent module. In our case the outputs will just be printed out to the command line after the deployment.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-apply-the-configuration-code\">Apply the Configuration Code:<\/h2>\n\n\n\n<p>As I am now done with the definition of the configuration code for this blog post, I will plan and apply my configuration for each stage. Before doing so, I need to first set a value for my password variables. On Ubuntu this can be done with this command:<\/p>\n\n\n\n<p><strong><em>export TF_VAR_sqlserver_password=&#8221;your password&#8221;<\/em><\/strong><\/p>\n\n\n\n<p><strong><em>export TF_VAR_vm_password=&#8221;your password&#8221;<\/em><\/strong><\/p>\n\n\n\n<p>After I\u2019ve set the variables, I run the terraform plan command and we can see that terraform would create 29 resources:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"809\" height=\"184\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-62.png\" alt=\"\" class=\"wp-image-36650\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-62.png 809w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-62-300x68.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-62-768x175.png 768w\" sizes=\"auto, (max-width: 809px) 100vw, 809px\" \/><\/figure>\n\n\n\n<p>This seems to be good for my so I run the terraform apply command to deploy my infrastructure:<\/p>\n\n\n\n<p><strong><em>terraform apply<\/em><\/strong><\/p>\n\n\n\n<p>After some minutes of patience terraform applied the configuration code successfully:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"696\" height=\"203\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-63.png\" alt=\"\" class=\"wp-image-36651\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-63.png 696w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-63-300x88.png 300w\" sizes=\"auto, (max-width: 696px) 100vw, 696px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-check-the-infrastructure-in-the-azure-portal\">Check the Infrastructure in the Azure Portal:<\/h2>\n\n\n\n<p>When I\u2019m signing in to the Azure portal I can see my development resource group with all the resources inside:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"429\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-64.png\" alt=\"\" class=\"wp-image-36653\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-64.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-64-300x137.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-64-768x351.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>I want to have my test and production resources as well so I switch the terraform workspace to test and production and run in both workspaces again the terraform apply command.<\/p>\n\n\n\n<p>After some additional minutes of patience we can see in the Azure portal that we have now all resources for each environment stage:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"939\" height=\"230\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-65.png\" alt=\"\" class=\"wp-image-36654\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-65.png 939w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-65-300x73.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-65-768x188.png 768w\" sizes=\"auto, (max-width: 939px) 100vw, 939px\" \/><\/figure>\n\n\n\n<p>Lets now compare the settings from the productive database with the development database and we can see that the SKU for the productive one is business critical while the SKU for the non-productive one is general purpose:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"257\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-66.png\" alt=\"\" class=\"wp-image-36655\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-66.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-66-300x82.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-66-768x210.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"243\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-67.png\" alt=\"\" class=\"wp-image-36656\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-67.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-67-300x78.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-67-768x199.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>The Backup storage has also been set according to the \u201cdatabase_settings\u201d variable:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"453\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-68.png\" alt=\"\" class=\"wp-image-36657\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-68.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-68-300x145.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-68-768x370.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"474\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-71.png\" alt=\"\" class=\"wp-image-36660\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-71.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-71-300x151.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-71-768x387.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We can see the same for the point in time recovery option:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"939\" height=\"350\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-72.png\" alt=\"\" class=\"wp-image-36663\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-72.png 939w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-72-300x112.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-72-768x286.png 768w\" sizes=\"auto, (max-width: 939px) 100vw, 939px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"939\" height=\"334\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-73.png\" alt=\"\" class=\"wp-image-36664\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-73.png 939w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-73-300x107.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-73-768x273.png 768w\" sizes=\"auto, (max-width: 939px) 100vw, 939px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We can see that our subnets are also all in place with the corresponding address space and network security group associated:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"191\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-74.png\" alt=\"\" class=\"wp-image-36665\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-74.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-74-300x61.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-74-768x156.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"939\" height=\"189\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-75.png\" alt=\"\" class=\"wp-image-36666\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-75.png 939w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-75-300x60.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-75-768x155.png 768w\" sizes=\"auto, (max-width: 939px) 100vw, 939px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"939\" height=\"197\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-76.png\" alt=\"\" class=\"wp-image-36667\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-76.png 939w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-76-300x63.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-76-768x161.png 768w\" sizes=\"auto, (max-width: 939px) 100vw, 939px\" \/><\/figure>\n\n\n\n<p>Lets check the private endpoint of the Azure SQL Server. We can see that we have a private IP address within our backend subnet which is linked to the Azure SQL Server:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"102\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-77.png\" alt=\"\" class=\"wp-image-36668\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-77.png 940w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-77-300x33.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-77-768x83.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>Lets connect to the virtual machine and try a name resolution. You can see that we were able to successfully resolve the FQDN:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"879\" height=\"269\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-78.png\" alt=\"\" class=\"wp-image-36669\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-78.png 879w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-78-300x92.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-78-768x235.png 768w\" sizes=\"auto, (max-width: 879px) 100vw, 879px\" \/><\/figure>\n\n\n\n<p>After installing SQL-Server management studio on the virtual machine, we can also connect to the Azure SQL Server through the FQDN of the private endpoint:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"766\" height=\"310\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-79.png\" alt=\"\" class=\"wp-image-36672\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-79.png 766w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-79-300x121.png 300w\" sizes=\"auto, (max-width: 766px) 100vw, 766px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-delete-the-deployed-resources\">Delete the Deployed Resources:<\/h2>\n\n\n\n<p>For now preventing getting a high bill for something I didn\u2019t use, I will now delete all resources which I\u2019ve created with Terraform. This is very simple, and can be done through running the terraform destroy command in each workspace:<\/p>\n\n\n\n<p><strong><em>terraform destroy<\/em><\/strong><\/p>\n\n\n\n<p>I hope you got some interesting examples and ideas about Terraform and Azure! Feel free to share your questions and feelings about Terraform and Azure with me in the comment section below.<\/p>\n\n\n\n<p><strong>PS:<\/strong> I\u2019ve uploaded the configuration code used in this blog post to a GitHub repository to make it easier for you to reproduce the steps and examples. You can find it <a href=\"https:\/\/github.com\/HocineMechara\/TerraformBlog01\">here<\/a>.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Terraform is a strong open-source declarative and platform agnostic infrastructure as code (IaC) tool developed by HashiCorp. It facilitates the deployment and whole management of infrastructure. In this hands on blog I will show you how you can use Terraform to automate your cloud deployments in Azure. Initial Setup: For this blog I\u2019m using a [&hellip;]<\/p>\n","protected":false},"author":145,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[3271,955,99],"tags":[1338,135,51,1340],"type_dbi":[],"class_list":["post-36604","post","type-post","status-publish","format-standard","hentry","category-azure","category-cloud","category-sql-server","tag-azure","tag-cloud","tag-sql-server","tag-terraform"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Automate your Deployments in Azure with Terraform! - dbi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Automate your Deployments in Azure with Terraform!\" \/>\n<meta property=\"og:description\" content=\"Terraform is a strong open-source declarative and platform agnostic infrastructure as code (IaC) tool developed by HashiCorp. It facilitates the deployment and whole management of infrastructure. In this hands on blog I will show you how you can use Terraform to automate your cloud deployments in Azure. Initial Setup: For this blog I\u2019m using a [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2025-01-16T13:43:38+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-02-18T15:01:23+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-20.png\" \/>\n\t<meta property=\"og:image:width\" content=\"721\" \/>\n\t<meta property=\"og:image:height\" content=\"83\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Hocine Mechara\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Hocine Mechara\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"23 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/automate-your-deployments-in-azure-with-terraform\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/automate-your-deployments-in-azure-with-terraform\\\/\"},\"author\":{\"name\":\"Hocine Mechara\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/29415d02bc1b50884796a01cf649951f\"},\"headline\":\"Automate your Deployments in Azure with Terraform!\",\"datePublished\":\"2025-01-16T13:43:38+00:00\",\"dateModified\":\"2025-02-18T15:01:23+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/automate-your-deployments-in-azure-with-terraform\\\/\"},\"wordCount\":2544,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/automate-your-deployments-in-azure-with-terraform\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2025\\\/01\\\/image-20.png\",\"keywords\":[\"Azure\",\"Cloud\",\"SQL Server\",\"Terraform\"],\"articleSection\":[\"Azure\",\"Cloud\",\"SQL Server\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/automate-your-deployments-in-azure-with-terraform\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/automate-your-deployments-in-azure-with-terraform\\\/\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/automate-your-deployments-in-azure-with-terraform\\\/\",\"name\":\"Automate your Deployments in Azure with Terraform! - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/automate-your-deployments-in-azure-with-terraform\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/automate-your-deployments-in-azure-with-terraform\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2025\\\/01\\\/image-20.png\",\"datePublished\":\"2025-01-16T13:43:38+00:00\",\"dateModified\":\"2025-02-18T15:01:23+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/29415d02bc1b50884796a01cf649951f\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/automate-your-deployments-in-azure-with-terraform\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/automate-your-deployments-in-azure-with-terraform\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/automate-your-deployments-in-azure-with-terraform\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2025\\\/01\\\/image-20.png\",\"contentUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2025\\\/01\\\/image-20.png\",\"width\":721,\"height\":83},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/automate-your-deployments-in-azure-with-terraform\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Automate your Deployments in Azure with Terraform!\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/29415d02bc1b50884796a01cf649951f\",\"name\":\"Hocine Mechara\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f771f838feed0619485da1e42ae05d771dcb446e1f4785244582280315fa73c3?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f771f838feed0619485da1e42ae05d771dcb446e1f4785244582280315fa73c3?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f771f838feed0619485da1e42ae05d771dcb446e1f4785244582280315fa73c3?s=96&d=mm&r=g\",\"caption\":\"Hocine Mechara\"},\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/author\\\/hocinemechara\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Automate your Deployments in Azure with Terraform! - dbi Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/","og_locale":"en_US","og_type":"article","og_title":"Automate your Deployments in Azure with Terraform!","og_description":"Terraform is a strong open-source declarative and platform agnostic infrastructure as code (IaC) tool developed by HashiCorp. It facilitates the deployment and whole management of infrastructure. In this hands on blog I will show you how you can use Terraform to automate your cloud deployments in Azure. Initial Setup: For this blog I\u2019m using a [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/","og_site_name":"dbi Blog","article_published_time":"2025-01-16T13:43:38+00:00","article_modified_time":"2025-02-18T15:01:23+00:00","og_image":[{"width":721,"height":83,"url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-20.png","type":"image\/png"}],"author":"Hocine Mechara","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Hocine Mechara","Est. reading time":"23 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/"},"author":{"name":"Hocine Mechara","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/29415d02bc1b50884796a01cf649951f"},"headline":"Automate your Deployments in Azure with Terraform!","datePublished":"2025-01-16T13:43:38+00:00","dateModified":"2025-02-18T15:01:23+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/"},"wordCount":2544,"commentCount":0,"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-20.png","keywords":["Azure","Cloud","SQL Server","Terraform"],"articleSection":["Azure","Cloud","SQL Server"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/","url":"https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/","name":"Automate your Deployments in Azure with Terraform! - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/#primaryimage"},"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-20.png","datePublished":"2025-01-16T13:43:38+00:00","dateModified":"2025-02-18T15:01:23+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/29415d02bc1b50884796a01cf649951f"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/#primaryimage","url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-20.png","contentUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2025\/01\/image-20.png","width":721,"height":83},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/automate-your-deployments-in-azure-with-terraform\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Automate your Deployments in Azure with Terraform!"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/29415d02bc1b50884796a01cf649951f","name":"Hocine Mechara","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f771f838feed0619485da1e42ae05d771dcb446e1f4785244582280315fa73c3?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f771f838feed0619485da1e42ae05d771dcb446e1f4785244582280315fa73c3?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f771f838feed0619485da1e42ae05d771dcb446e1f4785244582280315fa73c3?s=96&d=mm&r=g","caption":"Hocine Mechara"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/hocinemechara\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/36604","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/145"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=36604"}],"version-history":[{"count":27,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/36604\/revisions"}],"predecessor-version":[{"id":37349,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/36604\/revisions\/37349"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=36604"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=36604"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=36604"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=36604"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}