{"id":77505,"date":"2019-06-25T08:00:38","date_gmt":"2019-06-25T15:00:38","guid":{"rendered":""},"modified":"2025-06-27T05:37:43","modified_gmt":"2025-06-27T12:37:43","slug":"how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure","status":"publish","type":"post","link":"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/","title":{"rendered":"Migrating to HashiCorp Terraform 0.12 on Microsoft Azure"},"content":{"rendered":"\n<p>With the\u00a0<a href=\"https:\/\/www.hashicorp.com\/blog\/announcing-terraform-0-12\">release of Terraform 0.12<\/a>, we can improve the configuration of our infrastructure resources that are using the\u00a0<a href=\"https:\/\/azure.microsoft.com\/en-us\/blog\/introducing-the-azure-terraform-resource-provider\/\">Azure Terraform Resource Provider<\/a>. In this post, we will discuss how we can use Terraform 0.12 to organize, configure, and deploy resources to Azure.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-is-terraform-0-12\">What is Terraform 0.12?<\/h2>\n\n\n\n<p><a href=\"https:\/\/www.terraform.io\/\">Terraform<\/a>&nbsp;is an open source tool that uses declarative configuration files to create, change, and improve infrastructure. The Terraform 0.12 release, in particular, includes additional improvements and features to the declarative language, called HashiCorp Configuration Language version 2 (HCL2). We use HCL2 to describe infrastructure resources and configuration in configuration files.<\/p>\n\n\n\n<p>HCL2 simplifies the process of writing, inspecting, and applying the configuration to Azure resources. The first version of HCL in versions prior to Terraform 0.12 used string types while HCL2 in Terraform version 0.12 and higher leverages a generalized type system and stricter parsing of configuration. The new type system expands functionality and addresses long-standing community requests such as list comprehension, null or unset values, and expanded deserialization of JSON and other formats.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"upgrading-the-azure-terraform-resource-provider\">Upgrading the Azure Terraform Resource Provider<\/h2>\n\n\n\n<p>How does Terraform 0.12 affect the Azure Terraform Resource Provider? Stricter type enforcement may result in some errors but improved error messaging in Terraform 0.12 can help identify them. Furthermore, we proactively update the provider to support Terraform 0.12 syntax as we find errors. The Azure provider supports Terraform 0.12 syntax since version 1.27.<\/p>\n\n\n\n<p>Before running&nbsp;<code>terraform 0.12upgrade<\/code>, we advise that you review the detailed upgrade instructions on&nbsp;<a href=\"https:\/\/www.terraform.io\/upgrade-guides\/0-12.html\">upgrading to Terraform 0.12<\/a>. While the CLI upgrade command can facilitate an initial refactor for simple configurations, run&nbsp;<code>terraform 0.12checklist<\/code>&nbsp;and evaluate any pre-upgrade steps.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"benefits-of-terraform-0-12\">Benefits of Terraform 0.12<\/h2>\n\n\n\n<p>Improvements and features for Terraform 0.12 provide additional flexibility and minimize configuration when creating Azure resources. Using an example to deploy&nbsp;<a href=\"https:\/\/azure.microsoft.com\/en-us\/services\/app-service\/\">Azure App Service<\/a>&nbsp;instances and an [Azure Application Gateway](<a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/application-gateway\/overview\">https:\/\/docs.microsoft.com\/en-us\/azure\/application-gateway\/overview<\/a>), we will demonstrate the benefits of Terraform 0.12\u2019s first class expression syntax, richer type system, and dynamic nested blocks.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"upgrading-azure-app-service-configuration\">Upgrading Azure App Service Configuration<\/h2>\n\n\n\n<p>As part of our configuration, we need to create two App Service instances with Windows and Linux configurations. In order to support any arbitrary configuration of App Service instances, we could iterate over a list of maps describing each instance\u2019s kind, tier, and size. In Terraform 0.11, these&nbsp;<a href=\"https:\/\/www.terraform.io\/docs\/configuration\/types.html#collection-types\">maps<\/a>&nbsp;consisted of string labels and values that must be of the same type. For example, a map for an App Service must use a string label and string value.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n# Terraform 0.11 Configuration. Some sections omitted for clarity.\nlocals {\n app_services = [\n   {\n     kind     = \"Linux\"\n     sku_tier = \"Standard\"\n     sku_size = \"S1\"\n   },\n   {\n     kind     = \"Windows\"\n     sku_tier = \"Basic\"\n     sku_size = \"B1\"\n   },\n ]\n}\n<\/pre><\/div>\n\n\n<p>To iterate over our list of App Service instances, we use a series of functions and interpolated variables. Terraform versions prior to 0.12 use a string-based type system and could only interpret variables through string interpolation. As a result, accessing values in maps and lists requires the additional use of functions. We use the\u00a0<code>lookup<\/code>\u00a0function to access a value based on a key in a map. To access an element at an index in a list, we use the\u00a0<code>element<\/code>function.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n# Terraform 0.11 Configuration. Some sections omitted for clarity.\nresource \"azurerm_app_service\" \"example\" {\n count               = \"${length(local.app_services)}\"\n name                = \"${lower(lookup(local.app_services[count.index], \"kind\"))}-appservice\"\n location            = \"${azurerm_resource_group.example.location}\"\n resource_group_name = \"${azurerm_resource_group.example.name}\"\n app_service_plan_id = \"${element(azurerm_app_service_plan.example.*.id, count.index)}\"\n\n site_config {\n   # omitted for clarity\n }\n}\n<\/pre><\/div>\n\n\n<p>The generalized type system in Terraform 0.12 provides useful functionality to minimize configuration and better access values in richer types. Instead of using maps, we can leverage\u00a0<a href=\"https:\/\/www.terraform.io\/docs\/configuration\/types.html#structural-types\">structural types<\/a>\u00a0to group together multiple values of varying types. For example, we can rewrite our App Service instance configuration with a nested map for\u00a0<code>sku<\/code>. With this change, our App Service instance configuration becomes an object type with varying attributes.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n# Terraform 0.12 Configuration. Some sections omitted for clarity.\nlocals {\n app_services = [\n   {\n     kind = \"Linux\"\n     sku = {\n       tier = \"Standard\"\n       size = \"S1\"\n     }\n   },\n   {\n     kind = \"Windows\"\n     sku = {\n       tier = \"Basic\"\n       size = \"B1\"\n     }\n   }\n ]\n}\n<\/pre><\/div>\n\n\n<p>Furthermore, we can remove variable interpolation syntax, the\u00a0<code>lookup<\/code>\u00a0function, and the\u00a0<code>element<\/code>\u00a0function from our configuration. Maps, objects, and lists can be accessed using\u00a0<a href=\"https:\/\/www.terraform.io\/docs\/configuration\/expressions.html#indices-and-attributes\">indices and attributes<\/a>. For example, our\u00a0<code>local.appservices<\/code>\u00a0list can be accessed using an index syntax such as\u00a0<code>local.app_services[count.index]<\/code>. We can also retrieve the\u00a0<code>kind<\/code>\u00a0attribute in the App Service instance configuration with\u00a0<code>local.app_services[count.index].kind<\/code>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n# Terraform 0.12 Configuration. Some sections omitted for clarity.\nresource \"azurerm_app_service\" \"example\" {\n count               = length(local.app_services)\n name                = \"${lower(local.app_services[count.index].kind)}-appservice\"\n location            = azurerm_resource_group.example.location\n resource_group_name = azurerm_resource_group.example.name\n app_service_plan_id = azurerm_app_service_plan.example[count.index].id\n\n site_config {\n    # omitted for clarity\n }\n}\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"upgrading-azure-application-gateway-configuration\">Upgrading Azure Application Gateway Configuration<\/h2>\n\n\n\n<p>After upgrading the configuration for App Service instances, we can now tackle the Azure Application Gateway configuration. The&nbsp;<code>azurerm_application_gateway<\/code>&nbsp;resource requires nested blocks for certain attributes, such as the&nbsp;<code>backend_address_pool<\/code>. In Terraform 0.11, these attribute blocks contained other content and metadata necessary for the resource. If we need many of the same attributes, we would declare each nested block individually. This often leads to duplicated and hard-coded configuration for each block.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n# Terraform 0.11 Configuration. Some sections omitted for clarity.\nresource \"azurerm_application_gateway\" \"network\" {\n frontend_port {\n   name = \"${azurerm_app_service.example.0.name}\"\n   port = 8080\n }\n\n frontend_port {\n   name = \"${azurerm_app_service.example.1.name}\"\n   port = 8081\n }\n\n # omitted for clarity\n\n backend_address_pool {\n   name  = \"${local.backend_address_pool_name}\"\n   fqdns = [\"${azurerm_app_service.example.0.default_site_hostname}\"]\n }\n\n backend_address_pool {\n   name  = \"${local.backend_address_pool_name}\"\n   fqdns = [\"${azurerm_app_service.example.1.default_site_hostname}\"]\n }\n}\n<\/pre><\/div>\n\n\n<p>Upon upgrading to Terraform 0.12, we can rewrite the configuration to use&nbsp;<a href=\"https:\/\/www.terraform.io\/docs\/configuration\/expressions.html#dynamic-blocks\">dynamic blocks<\/a>. Instead of declaring each block with a different configuration, we iterate over a list and create a set of blocks dynamically. We achieve this by prefixing our nested block for an attribute with the&nbsp;<code>dynamic<\/code>&nbsp;keyword. The&nbsp;<code>for_each<\/code>&nbsp;iterator allows us to iterate over a list of objects, retrieve their values, and set variables in the nested block\u2019s&nbsp;<code>content<\/code>.<\/p>\n\n\n\n<p>To set variables for each attribute in the nested block, we need to access the element that the iterator references. Terraform 0.12 defaults the current element\u2019s variable name to the resource\u2019s attribute. For example, in the&nbsp;<code>dynamic \"frontend_port\"<\/code>&nbsp;block, we can retrieve each App Service object using the&nbsp;<code>frontend_port<\/code>&nbsp;variable. To get the value of a specific attribute, such as the name of the instance, we call&nbsp;<code>frontend_port.value.name<\/code>. We can also use&nbsp;<code>frontend_port.key<\/code>&nbsp;to retrieve the current iterator index and use it for the port.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n# Terraform 0.12 Configuration. Some sections omitted for clarity.\n\nresource \"azurerm_application_gateway\" \"network\" {\n\n dynamic \"frontend_port\" {\n   for_each = azurerm_app_service.example\n   content {\n     name = \"${frontend_port.value.name}-feport\"\n     port = \"808${frontend_port.key}\"\n   }\n }\n\n# omitted for clarity\n\n dynamic \"backend_address_pool\" {\n   for_each = azurerm_app_service.example\n   content {\n     name  = \"${backend_address_pool.value.name}-beap\"\n     fqdns = [backend_address_pool.value.default_site_hostname]\n   }\n }\n}\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"remote-state-storage-with-terraform-cloud\">Remote State Storage with Terraform Cloud<\/h2>\n\n\n\n<p>When deploying our App Service instances and Application Gateway, we use Terraform Cloud\u2019s remote state storage to manage their state. This reduces additional infrastructure configuration to store, version, and manage Terraform state files.<\/p>\n\n\n\n<p>First, we&nbsp;<a href=\"http:\/\/app.terraform.io\/signup?utm_source=partner_azure&amp;utm_campaign=intro_tf_cloud_remote\">sign up for Terraform Cloud<\/a>&nbsp;and create an organization.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/06\/create_org-1024x602.png\" alt=\"Snapshot of &quot;Creating an org&quot;\" \/><\/figure>\n\n\n\n<p>To leverage Terraform Cloud, we&nbsp;<a href=\"https:\/\/app.terraform.io\/app\/settings\/tokens\">create a user token<\/a>&nbsp;and insert it into the following&nbsp;<code>~\/.terraformrc<\/code>&nbsp;file. This will allow our CLI to call Terraform Cloud.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ncredentials \"app.terraform.io\" {\n token = \"\"\n}\n<\/pre><\/div>\n\n\n<p>Next, we add the\u00a0<code>backend \u201cremote\u201d<\/code>\u00a0directive to our Terraform declaration.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nterraform {\n required_version = \"~> 0.12\"\n backend \"remote\" {\n   organization = \"hashicorp-azurerm\"\n\n   workspaces {\n     name = \"prod\"\n   }\n }\n}\n<\/pre><\/div>\n\n\n<p>When we run&nbsp;<code>terraform init<\/code>, Terraform Cloud generates a workspace under our organization.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/06\/workspace-1024x246.png\" alt=\"snapshot of a workspace\" \/><\/figure>\n\n\n\n<p>After applying the configuration, Terraform Cloud reflects the state of our Azure resources and highlights the differences.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/06\/state-1024x712.png\" alt=\"snapshot of the new state\" \/><\/figure>\n\n\n\n<p>More detailed instructions for Terraform Cloud use can be found on the&nbsp;<a href=\"https:\/\/www.hashicorp.com\/blog\/using-terraform-cloud-remote-state-management\">HashiCorp blog<\/a>. By leveraging Terraform Cloud, we can maintain the state of our App Service instances and Application Gateway without setting up additional state management.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"conclusion\">Conclusion<\/h2>\n\n\n\n<p>In this post, we covered some of the new improvements to Terraform 0.12 and how to apply them to resources managed by the Azure Provider. In addition, we used Terraform Cloud to store the state of our Azure resources remotely as we upgrade our configuration.<\/p>\n\n\n\n<p>For more information about Terraform 0.12, refer to&nbsp;<a href=\"https:\/\/www.terraform.io\/docs\/configuration\/index.html\">HashiCorp\u2019s documentation<\/a>. Additional resource references for the Terraform Azure Provider can be found in our&nbsp;<a href=\"https:\/\/www.terraform.io\/docs\/providers\/azurerm\/index.html\">provider documentation<\/a>. To use remote state management, go to&nbsp;<a href=\"http:\/\/app.terraform.io\/signup?utm_source=partner_microsoft&amp;utm_campaign=intro_tf_cloud_remote\">Terraform Cloud<\/a>&nbsp;to create an organization.<\/p>\n\n\n\n<p>Other questions or feedback? Please let us know in the comments below.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>With the\u00a0release of Terraform 0.12, we can improve the configuration of our infrastructure resources that are using the\u00a0Azure Terraform Resource Provider. In this post, we will discuss how we can use Terraform 0.12 to organize, configure, and deploy resources to Azure. What is Terraform 0.<\/p>\n","protected":false},"author":5562,"featured_media":95475,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"msxcm_post_with_no_image":false,"ep_exclude_from_search":false,"_classifai_error":"","_classifai_text_to_speech_error":"","footnotes":""},"post_tag":[2271],"content-type":[340],"topic":[2241,2244,2245],"programming-languages":[],"coauthors":[639],"class_list":["post-77505","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","tag-community-partners","content-type-tutorials-and-demos","topic-cloud","topic-devops","topic-infrastructure","review-flag-1593580362-584","review-flag-1593580428-734","review-flag-1593580415-931","review-flag-1593580771-946","review-flag-1-1593580432-963","review-flag-2-1593580437-411","review-flag-lever-1593580265-989","review-flag-new-1593580248-669"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Migrating to HashiCorp Terraform 0.12 on Microsoft Azure | Microsoft Open Source Blog<\/title>\n<meta name=\"description\" content=\"In this post, HashiCorp&#039;s Rosemary Wang discusses how to use Terraform 0.12 to organize, configure, and deploy resources to Azure.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Migrating to HashiCorp Terraform 0.12 on Microsoft Azure | Microsoft Open Source Blog\" \/>\n<meta property=\"og:description\" content=\"In this post, HashiCorp&#039;s Rosemary Wang discusses how to use Terraform 0.12 to organize, configure, and deploy resources to Azure.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/\" \/>\n<meta property=\"og:site_name\" content=\"Microsoft Open Source Blog\" \/>\n<meta property=\"article:published_time\" content=\"2019-06-25T15:00:38+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-27T12:37:43+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO24-Azure-Retail-025.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1170\" \/>\n\t<meta property=\"og:image:height\" content=\"640\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Rosemary Wang\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@OpenAtMicrosoft\" \/>\n<meta name=\"twitter:site\" content=\"@OpenAtMicrosoft\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Rosemary Wang\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 min read\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/\"},\"author\":[{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/author\/rosemary-wang\/\",\"@type\":\"Person\",\"@name\":\"Rosemary Wang\"}],\"headline\":\"Migrating to HashiCorp Terraform 0.12 on Microsoft Azure\",\"datePublished\":\"2019-06-25T15:00:38+00:00\",\"dateModified\":\"2025-06-27T12:37:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/\"},\"wordCount\":1105,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO24-Azure-Retail-025.webp\",\"keywords\":[\"Community\/partners\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/\",\"name\":\"Migrating to HashiCorp Terraform 0.12 on Microsoft Azure | Microsoft Open Source Blog\",\"isPartOf\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO24-Azure-Retail-025.webp\",\"datePublished\":\"2019-06-25T15:00:38+00:00\",\"dateModified\":\"2025-06-27T12:37:43+00:00\",\"description\":\"In this post, HashiCorp's Rosemary Wang discusses how to use Terraform 0.12 to organize, configure, and deploy resources to Azure.\",\"breadcrumb\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/#primaryimage\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO24-Azure-Retail-025.webp\",\"contentUrl\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO24-Azure-Retail-025.webp\",\"width\":1170,\"height\":640},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/opensource.microsoft.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Migrating to HashiCorp Terraform 0.12 on Microsoft Azure\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#website\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/\",\"name\":\"Microsoft Open Source Blog\",\"description\":\"Open dialogue about openness at Microsoft \u2013 open source, standards, interoperability\",\"publisher\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/opensource.microsoft.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#organization\",\"name\":\"Microsoft Open Source Blog\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png\",\"contentUrl\":\"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png\",\"width\":259,\"height\":194,\"caption\":\"Microsoft Open Source Blog\"},\"image\":{\"@id\":\"https:\/\/opensource.microsoft.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/OpenAtMicrosoft\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Migrating to HashiCorp Terraform 0.12 on Microsoft Azure | Microsoft Open Source Blog","description":"In this post, HashiCorp's Rosemary Wang discusses how to use Terraform 0.12 to organize, configure, and deploy resources to Azure.","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:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/","og_locale":"en_US","og_type":"article","og_title":"Migrating to HashiCorp Terraform 0.12 on Microsoft Azure | Microsoft Open Source Blog","og_description":"In this post, HashiCorp's Rosemary Wang discusses how to use Terraform 0.12 to organize, configure, and deploy resources to Azure.","og_url":"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/","og_site_name":"Microsoft Open Source Blog","article_published_time":"2019-06-25T15:00:38+00:00","article_modified_time":"2025-06-27T12:37:43+00:00","og_image":[{"width":1170,"height":640,"url":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO24-Azure-Retail-025.png","type":"image\/png"}],"author":"Rosemary Wang","twitter_card":"summary_large_image","twitter_creator":"@OpenAtMicrosoft","twitter_site":"@OpenAtMicrosoft","twitter_misc":{"Written by":"Rosemary Wang","Est. reading time":"6 min read"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/#article","isPartOf":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/"},"author":[{"@id":"https:\/\/opensource.microsoft.com\/blog\/author\/rosemary-wang\/","@type":"Person","@name":"Rosemary Wang"}],"headline":"Migrating to HashiCorp Terraform 0.12 on Microsoft Azure","datePublished":"2019-06-25T15:00:38+00:00","dateModified":"2025-06-27T12:37:43+00:00","mainEntityOfPage":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/"},"wordCount":1105,"commentCount":2,"publisher":{"@id":"https:\/\/opensource.microsoft.com\/blog\/#organization"},"image":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/#primaryimage"},"thumbnailUrl":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO24-Azure-Retail-025.webp","keywords":["Community\/partners"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/","url":"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/","name":"Migrating to HashiCorp Terraform 0.12 on Microsoft Azure | Microsoft Open Source Blog","isPartOf":{"@id":"https:\/\/opensource.microsoft.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/#primaryimage"},"image":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/#primaryimage"},"thumbnailUrl":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO24-Azure-Retail-025.webp","datePublished":"2019-06-25T15:00:38+00:00","dateModified":"2025-06-27T12:37:43+00:00","description":"In this post, HashiCorp's Rosemary Wang discusses how to use Terraform 0.12 to organize, configure, and deploy resources to Azure.","breadcrumb":{"@id":"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/#primaryimage","url":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO24-Azure-Retail-025.webp","contentUrl":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2024\/06\/CLO24-Azure-Retail-025.webp","width":1170,"height":640},{"@type":"BreadcrumbList","@id":"https:\/\/opensource.microsoft.com\/blog\/2019\/06\/25\/how-to-migrate-to-hashicorp-terraform-0-12-microsoft-azure\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/opensource.microsoft.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Migrating to HashiCorp Terraform 0.12 on Microsoft Azure"}]},{"@type":"WebSite","@id":"https:\/\/opensource.microsoft.com\/blog\/#website","url":"https:\/\/opensource.microsoft.com\/blog\/","name":"Microsoft Open Source Blog","description":"Open dialogue about openness at Microsoft \u2013 open source, standards, interoperability","publisher":{"@id":"https:\/\/opensource.microsoft.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/opensource.microsoft.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/opensource.microsoft.com\/blog\/#organization","name":"Microsoft Open Source Blog","url":"https:\/\/opensource.microsoft.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/opensource.microsoft.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png","contentUrl":"https:\/\/opensource.microsoft.com\/blog\/wp-content\/uploads\/2019\/08\/Microsoft-Logo.png","width":259,"height":194,"caption":"Microsoft Open Source Blog"},"image":{"@id":"https:\/\/opensource.microsoft.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/OpenAtMicrosoft"]}]}},"msxcm_display_generated_audio":false,"msxcm_animated_featured_image":null,"distributor_meta":false,"distributor_terms":false,"distributor_media":false,"distributor_original_site_name":"Microsoft Open Source Blog","distributor_original_site_url":"https:\/\/opensource.microsoft.com\/blog","push-errors":false,"_links":{"self":[{"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/posts\/77505","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/users\/5562"}],"replies":[{"embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/comments?post=77505"}],"version-history":[{"count":1,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/posts\/77505\/revisions"}],"predecessor-version":[{"id":97741,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/posts\/77505\/revisions\/97741"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/media\/95475"}],"wp:attachment":[{"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/media?parent=77505"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/post_tag?post=77505"},{"taxonomy":"content-type","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/content-type?post=77505"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/topic?post=77505"},{"taxonomy":"programming-languages","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/programming-languages?post=77505"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/opensource.microsoft.com\/blog\/wp-json\/wp\/v2\/coauthors?post=77505"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}