Blog Post

Azure Tools Blog
5 MIN READ

Announcing MSGraph Provider Public Preview and the Microsoft Terraform VSCode Extension

stevenjma's avatar
stevenjma
Icon for Microsoft rankMicrosoft
Aug 14, 2025

Microsoft Graph is now fully supported day 0 by Terraform and our VSCode Extension has been rebranded!

We are thrilled to announce two exciting developments in the Microsoft ecosystem for Terraform infrastructure-as-code (IaC) practitioners: the public preview of the Terraform Microsoft Graph (MSGraph) provider and the release of the Microsoft Terraform Visual Studio Code (VSCode) extension. These innovations are designed to streamline your workflow, empower your automation, and make managing Microsoft cloud resources easier than ever.

Public Preview: Terraform Microsoft Graph (MSGraph) Provider

The Terraform MSGraph provider empowers you to manage Entra APIs like privileged identity management as well as M365 Graph APIs like SharePoint sites from day 0 by leveraging the power and flexibility of HashiCorp Configuration Language (HCL) in Terraform.

resource "msgraph_resource" "application" {
   url = "applications"
   body = {
     displayName = "My Application"
   }
   response_export_values = {
     all    = "@"
     app_id = "appId"
   }
 }

 output "app_id" {
   value = msgraph_resource.application.output.app_id
 }

 output "all" {
   // it will output the whole response
   value = msgraph_resource.application.output.all
 }

Historically, Terraform users could utilize the `azuread` provider to manage Entra features like users, groups, service principals, and applications. The new `msgraph` provider also supports these features and extends functionality to all beta and v1 Microsoft Graph endpoints.

Querying role assignments for a service principal

The below example shows how to use the `msgraph` provider to grant app permissions to a service principal:

locals {
  MicrosoftGraphAppId = "00000003-0000-0000-c000-000000000000"

  # AppRoleAssignment
  userReadAllAppRoleId = one([for role in data.msgraph_resource.servicePrincipal_msgraph.output.all.value[0].appRoles : role.id if role.value == "User.Read.All"])
  userReadWriteRoleId  = one([for role in data.msgraph_resource.servicePrincipal_msgraph.output.all.value[0].oauth2PermissionScopes : role.id if role.value == "User.ReadWrite"])

  # ServicePrincipal
  MSGraphServicePrincipalId         = data.msgraph_resource.servicePrincipal_msgraph.output.all.value[0].id
  TestApplicationServicePrincipalId = msgraph_resource.servicePrincipal_application.output.all.id
}

data "msgraph_resource" "servicePrincipal_msgraph" {
  url = "servicePrincipals"
  query_parameters = {
    "$filter" = ["appId eq '${local.MicrosoftGraphAppId}'"]
  }
  response_export_values = {
    all = "@"
  }
}

resource "msgraph_resource" "application" {
  url = "applications"
  body = {
    displayName = "My Application"
    requiredResourceAccess = [
      {
        resourceAppId = local.MicrosoftGraphAppId
        resourceAccess = [
          {
            id   = local.userReadAllAppRoleId
            type = "Scope"
          },
          {
            id   = local.userReadWriteRoleId
            type = "Scope"
          }
        ]
      }
    ]
  }
  response_export_values = {
    appId = "appId"
  }
}

resource "msgraph_resource" "servicePrincipal_application" {
  url = "servicePrincipals"
  body = {
    appId = msgraph_resource.application.output.appId
  }
  response_export_values = {
    all = "@"
  }
}

resource "msgraph_resource" "appRoleAssignment" {
  url = "servicePrincipals/${local.MSGraphServicePrincipalId}/appRoleAssignments"
  body = {
    appRoleId   = local.userReadAllAppRoleId
    principalId = local.TestApplicationServicePrincipalId
    resourceId  = local.MSGraphServicePrincipalId
  }
}

SharePoint & Outlook Notifications

With your service principals properly configured, you can set up M365 endpoint workflows such an outlook notification template list as shown below. The actual service principal setup has been omitted from this code sample for the sake of brevity, but you will need Sites.Manage.All, Sites.ReadWrite.All, User.Read, and User.Read.All permissions for this example to work:

data "msgraph_resource" "sharepoint_site_by_path" {
  url = "sites/microsoft.sharepoint.com:/sites/msgraphtest:"
  response_export_values = {
    full_response = "@"
    site_id = "id || ''"
  }
}

resource "msgraph_resource" "notification_templates_list" {
  url = "sites/${msgraph_resource.sharepoint_site_by_path.output.site_id}/lists"
  body = {
    displayName = "DevOps Notification Templates"
    description = "Centrally managed email templates for DevOps automation"
    template = "genericList"
    columns = [
      {
        name = "TemplateName"
        text = {
          allowMultipleLines = false
          appendChangesToExistingText = false
          linesForEditing = 1
          maxLength = 255
        }
      },
      {
        name = "Subject"
        text = {
          allowMultipleLines = false
          appendChangesToExistingText = false
          linesForEditing = 1
          maxLength = 500
        }
      },
      {
        name = "HtmlBody"
        text = {
          allowMultipleLines = true
          appendChangesToExistingText = false
          linesForEditing = 10
          maxLength = 10000
        }
      },
      {
        name = "Recipients"
        text = {
          allowMultipleLines = true
          appendChangesToExistingText = false
          linesForEditing = 3
          maxLength = 1000
        }
      },
      {
        name = "TriggerConditions"
        text = {
          allowMultipleLines = true
          appendChangesToExistingText = false
          linesForEditing = 5
          maxLength = 2000
        }
      }
    ]
  }
  response_export_values = {
    list_id = "id"
    list_name = "displayName"
    web_url = "webUrl"
  }
}

The MSGraph provider is to AzureAD as the AzAPI provider is to AzureRM. Since support for resource types is automatic, you can access the latest features and functionality as soon as they're released via the provider. AzureAD will continue to serve as the convenience layer implementation of a subset of Entra APIs.

We invite you to try the new provider today:

-          Deploy your first msgraph resources

-          Check out the registry page

-          Visit the provider GitHub

Introducing the Microsoft Terraform VSCode Extension

The new official Microsoft Terraform extension for Visual Studio Code consolidates AzureRM, AzAPI, and MSGraph VSCode support into a single powerful extension. The extension supports exporting Azure resources as Terraform code, as well as IntelliSense, syntax highlighting, and code sample generation. It replaces the Azure Terraform and AzAPI VSCode extensions and adds some new features.

Installation & Migration

New users can install the extension by searching “Microsoft Terraform” within Visual Studio Marketplace or their “Extensions” tab. Users can also click this link to the Visual Studio marketplace.

Users of the “Azure Terraform” extension can navigate to “Extensions” tab and selecting the old extension. Select the “Migrate” button to move to the new extension.

Users of the “Terraform AzAPI Provider” extension will be directed to the new extension:

 

 

New Features

Export Azure Resources As Terraform

This feature allows you to export existing Azure resources as Terraform configuration blocks using Azure Export for Terraform. This helps you migrate existing Azure resources to Terraform-managed infrastructure.

  1. Open the Command Palette (Command+Shift+P on macOS and Ctrl+Shift+P on Windows/Linux).
  2. Search for and select the command Microsoft Terraform: Export Azure Resource as Terraform.
  3. Follow the prompts to select the Azure subscription and resource group containing the resources you want to export.

 

  1. Select the azurerm provider or the azapi provider to export the resources.
  2. The extension will generate the Terraform configuration blocks for the selected resources and display them in a new editor tab. 

 

Support for MSGraph

The new extension comes fully equipped with intellisense, code completion, and code samples just like the AzAPI provider. See the next section for recorded examples of these features within the AzureRM & AzAPI providers.

Preexisting Features

Intelligent Code Completion:

Benefit from context-aware suggestions, like property names or resource types.

Code Samples:

Quickly insert code samples for your resources:

Paste as AzAPI:

Copy your existing resource JSON or ARM Templates into VSCode with the Microsoft Terraform extension, and it will automatically convert your code into AzAPI. The below example takes a resource JSON from the Azure Portal and pastes it into VSCode as AzAPI:

Migrate AzureRM to AzAPI:

Move existing AzureRM code to the AzAPI provider whenever you wish to. Read more in the Guide to migrate AzureRM resources to AzAPI

 

Feedback

We value your feedback! You can share your experience with the Microsoft Terraform extension by running the command Microsoft Terraform: Show Survey from the Command Palette. Your input helps us improve the extension and better serve your needs.

Conclusion

Whether you are managing traditional Azure resources, modern Microsoft Graph environments, or a combination of both, the new MSGraph provider and Microsoft Terraform VS Code extension are designed to help you deliver robust, reliable infrastructure—faster and with greater confidence.

Stay tuned for further updates, workshops, and community events as we continue to evolve these offerings. Your feedback and participation are invaluable as we build the next generation of infrastructure automation together.

Updated Aug 14, 2025
Version 1.0