Terraform VSTSRM Issue

This is an issue that had been plaguging me (and the team) for some weeks and quite frankly had been driving us all a little mad.

Every time we wanted to change a resource in Azure it'd often result in an error stating 400 VSTSRM.

What is VSTSRM

VSTSRM stands for Visual Studio Team Services Release Management

Visual Studio Team Services is "old school" for what is now Azure DevOps (at least that's my under standing) and it's sort of related to the issue.

Essentially it's the old way of saying, my code is hosted in Azure DevOps.

Deployment centre

What is the Deployment centre? Is a good quesiton, and honestly I'm not entirely sure of the intricate in's and out's.

Deployment center in Azure

It's a feature in azure that is attached to resources that run code, i.e web apps or functions, and it serves as a place to allow CI/CD pipelines for you web app.

Deployment center in Azure

From what I can gather if you're using Azure DevOps this section gets auto-populated when you release function code into a given resource.

For more information watch this video

The Issue

The issue is really a bug in Terraform that when Terraform is ran against a resource it can't correctly set the source control type for a resource, as described in that link the issue is transient.

When a web resource is initally created via, if the source control type not specified the default behaviour is to set this value to "None" which is fine.

You deploy the resource to Azure and then once satisfied it's created your next step is to push the code from the local dev machine up to the repo, have it built and via a pipeline in Azure DevOps which, in turn, automatically links the resource to the repository it originated from (this may also be true of Github Actions or other CI/CD tools and repos, but I can't say).

Now the "state" of the application has changed from Terraforms perspective, this is where the problem lies.

Say that you've got the function deployed, the tests are passing and it's getting some use great, imagine then that an external dependency that's pulled in via the app config has changed and you use Terraform to handle that change.

You modify the terraform file for the resoruce and run it against Azure, "Error RepoURL 400 VSTSRM":

Error: failed to create App Service Source Control for "beerbuddies-blog-func" (Resource Group "beer-buddies-site"): web.AppsClient#CreateOrUpdateSourceControl: Failure sending request: StatusCode=400 -- Original Error: Code="BadRequest" Message="Operation not supported: RepoUrl VSTSRM is not supported." Details=[{"Message":"Operation not supported: RepoUrl VSTSRM is not supported."},{"Code":"BadRequest"},{"ErrorEntity":{"Code":"BadRequest","ExtendedCode":"51024","Message":"Operation not supported: RepoUrl VSTSRM is not supported.","MessageTemplate":"Operation not supported: {0}","Parameters":["RepoUrl VSTSRM is not supported."]}}]

  on Function.tf line 21, in resource "azurerm_function_app" "blog_function":
  21: resource "azurerm_function_app" "blog_function" {

This operation fails because Terraform attempts to set the scm_type to "None", but because code has been deployed it attempts to "undo" the link and errors, if you rerun this step then it will apply correctly, because the first run actually succeeds in "delinking" the CI/CD stuff created by the code release.

Deployment center default

The Fix

Well this was the fix that solved it for me and it's found in the Github issue above.

Firstly you need to specify the type of scm (since Azure DevOps is goingto link them via code releases/deployments you might as well specify the type)

resource "azurerm_function_app" "blog_function" {

--- REMOVED FOR BREVITY ---

  site_config {
    scm_type = "VSTSRM"
  }
  lifecycle{
    ignore_changes = [
      site_config["scm_type"]
    ]
  }

}

So this does two things. Firstly it tells Terraform that we want the VSTSRM type to be set on our funcitons source control, then lastly we tell it to basically ignore any changes going forward, i.e when we deploy the code to the resource and Azure "automagically" links the code to the repo.

And that's it.

Hope that this post was somewhat informative, or alternatively if you felt it was a waste of 5 minutes of your life, then either way reach out and let me know.