hashicorp / terraform-provider-azurerm

Terraform provider for Azure Resource Manager
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs
Mozilla Public License 2.0
4.59k stars 4.63k forks source link

Support for Deployment Stacks #23457

Open moredhel opened 1 year ago

moredhel commented 1 year ago

Is there an existing issue for this?

Community Note

Description

We are depending on a blend of Terraform, Bicep and ARM in our project & wish to have better oversight of all the different resources.

As such, we are looking to integrate the new Deployment Stacks which incorporates lifecycle tracking natively into the Azure ecosystem.

New or Affected Resource(s)/Data Source(s)

azurerm_resource_group_template_deployment_stack

Potential Terraform Configuration

resource "azurerm_resource_group_template_deployment" "example" {
  name                = "example-deploy"
  resource_group_name = "example-group"
  deployment_mode     = "Incremental"
  parameters_content = jsonencode({
    "vnetName" = {
      value = local.vnet_name
    }
  })
  template = "{}"
  resource_groups_on_delete = "Detach"
  resources_on_delete = "Destroy"
}

References

rcskosir commented 1 year ago

@moredhel Thank you for taking the time to open this feature request!

D-Bissell commented 9 months ago

I'd really like to see this (or some way of deploying an ARM/Bicep deployment stack) added to terrafrom. I'm hoping this will give me the best of the worlds of Terraform, Bicep and deployment stacks.

Currently trying to use 'azurerm_resource_group_template_deployment' to deploy a transpiled bicep template, which contains a deployment stack resource, which in turn contains transpiled Bicep template with the defined Azure resources. This kind of works - a deployment stack is created along with the azure resources in the deployment stack, and the resources are even in the state file. However when removing the 'azurerm_resource_group_template_deployment' resource from the terraform code and re-deploying, neither the deployment stack or any of its contained resources are removed. I note that the deployment stack resource does not actually get created in the state file, unlike the azure resources themselves.

I have not yet tried the az_api provider to try deploy a deployment stack resource.

dxlusby commented 8 months ago

@D-Bissell, @moredhel - a few months ago I worked with a colleague of mine to do something very similar and provide an 'acceptable' workaround for supporting deploymentStacks in Terraform. It still requires authoring of the bicep file, but uses a null_resource local-exec provisioner to execute az bicep build, triggered on a data.local_file reference to the bicep file. It has the advantage of showing the relevant changes in the transpiled template and deployment stack and does, indeed, delete the deploymentStack when terraform destroyed.

data "local_file" "bicep-template" {
  filename = "C:\\path\\to\\template.bicep"
}

resource "null_resource" "transpile_template" {
    provisioner "local-exec" {
        command =  "az bicep build -f ${data.local_file.bicep-template.filename} --outfile template.json"
        on_failure = fail
    }

    triggers = {
        template = data.local_file.bicep-template.content
    }
}

data "local_file" "compiled-template" {
  filename = "template.json"

  depends_on = [ null_resource.transpile_template ]
}

resource "azapi_resource" "deploymentStack" {
  type      = "Microsoft.Resources/deploymentStacks@2022-08-01-preview"
  name      = "myMGDeploymentStack"
  parent_id = "/providers/Microsoft.Management/managementGroups/myManagementGroup"

  body = jsonencode({
      location = "eastus"
      tags = {}
      properties = {
          template = jsondecode(data.local_file.compiled-template.content)
          parameters = {
              location = {value = "eastus"}
              param1 = {value = "value1"}
              param2 = {value = "value2"}
          }
          actionOnUnmanage = {
              resources = "detach"
              resourceGroups = "detach"
          }
          deploymentScope = "/providers/Microsoft.Management/managementGroups/MG2"
          denySettings = {
              mode = "denyWriteAndDelete"
              applyToChildScopes = false
          }
      }
  })

  depends_on = [ data.local_file.compiled-template ]
}
D-Bissell commented 8 months ago

@dxlusby Thanks very much for posting that! It has worked for us. We are now just trying to see if we can modify it to also load in the parameters file as well to see if we can make it a generic template for any system.