Terraform Module to Restrict App Service Plan SKUs: Inspired by AZAdvertizer

Terraform Module to Restrict App Service Plan SKUs: Inspired by AZAdvertizer

In Azure, maintaining compliance and minimizing risk is a constant challenge. This is particularly true when managing App Service Plans for a tenant(s), where unrestricted use of all SKUs can introduce risk.

This becomes crucial in environments where adherence to specific App Service Plans is a requirement. Alternatively, in a remediation scenario, if your organization lacks governance and has created numerous improperly specified App Service Plans, you can first remediate these, and then deploy and assign this policy definition.

To cater to this requirement, I’ve developed the terraform-azurerm-appservices_plan_sku module, drawing inspiration from a highly resourceful website, AZAdvertiser. I’ll get more into this connection shortly.

Understanding App Service Plans

Before we jump into the Terraform module, here is a section to help one understand App Service Plans and their SKUs.

App Service Plans in Azure are the driving force behind your App Service, determining its capacity, capabilities, and cost. They range from the Free tier, which offers shared infrastructure and limited resources, ideal for small projects or testing environments, to the Isolated tier, designed for large-scale, mission-critical enterprise applications, providing the highest level of performance and isolation.

However, it’s important to note that not all SKUs are compatible with App Service Environments (ASE), which can lead to potential compliance issues. For instance, an organization might choose to use an ASE and require all of their App Service Plans to be of the Isolated series and route their egress network traffic through the ASE. Conversely, a startup or smaller business might opt to restrict the use of Isolated series and other expensive SKUs to manage costs. It’s crucial to choose the right SKU for your organization’s needs to balance cost, performance, and compliance.

TierExample SKUDescriptionIdeal For
FreeF1Shared infrastructure, limited resources.Small projects, testing environments.
BasicB1Dedicated environment, more resources, scales up to 3 instances.Small applications, testing environments
StandardS1More resources, auto-scaling, traffic management features.Production workloads.
PremiumP1v2High resources, scales up to 30 instances.High-traffic applications.
IsolatedI1Highest performance and isolation, most expensive.Medium to Large-scale, mission-critical applications.
List of App Service SKUs with an example SKU, Description, and use case.

Introducing terraform-azurerm-appservices_plan_sku

This Terraform module deploys an Azure policy definition at the management group level that restricts the creation of App Service Plans to the allowed SKUs specified in the policy. To apply this policy, a policy assignment needs to be created and applied to either a management group or subscription.

Usage Example

To deploy the policy definition, you can use the following Terraform code snippet:

module "allowed_app_services_plan_skus" {
  source = "./terraform-azurerm-appservice-sku-policy"
  management_group_id = "/providers/Microsoft.Management/managementGroups/Your_Management_Group_ID_Here"
}

In this example, the module block is used to deploy the terraform-azurerm-appservice-sku-policy module. The source attribute points to the module’s location, and the management_group_id attribute is set to the ID of your management group.

The policy rule itself is defined in the main.tf file within the module. This rule checks for App Service Plans with SKUs that are not included in the allowed list and denies their creation. This ensures that only App Service Plans with approved SKUs can be created, helping to maintain compliance and control costs.

To enforce the policy definition created by the module, you need to create a policy assignment.

Here’s an example of how to do that:

resource "azurerm_subscription_policy_assignment" "allowed_app_service_skus" {
name                 = var.policy_assignment_name_app_service_skus
policy_definition_id = var.policy_definition_id_app_service_skus
subscription_id      = "/subscriptions/${var.appdev-subscription_id}"
parameters = jsonencode({
listOfAllowedSKUs = {
value = var.allowed_app_service_skus
}
})
}`

In this example, the azurerm_subscription_policy_assignment resource is used to create a policy assignment that only allows certain App Service Plan SKUs to be deployed. The policy_definition_id is set to the ID of the policy definition created by the module and can be found in the portal post deployment, see screenshot below. The parameters block specifies the list of allowed SKUs.

Post-Deployment Notes:

When the policy definition and policy assignment are both deployed, users can expect the below changes in the Azure portal:

  • Inability to delete App Service Plans that are not included in the allowed SKU variable

  • The creation of App Service Plans with SKUs not included in the allowed variable will be blocked

  • If a SKU is added to the policy definition and it conflicts with an existing App Service Plan’s SKU, most of its properties will become unmodifiable

These changes could potentially lead to issues, so it’s essential to identify and address any conflicts before implementing this policy definition and assignment(s).

Example of Policy Definition in Azure Portal - Post Deployment
Example of Policy Definition in Azure Portal – Post Deployment
Example of Policy Assignment in Azure Portal - Post Deployment
Example of Policy Assignment in Azure Portal – Post Deployment


Inspiration from AZAdvertiser

The idea for this module, along with several other custom Terraform modules I have created, was inspired by AZAdvertizer. Created by Microsoft Architect, Julian Hayward, AZAdvertiser is a fantastic resource that provides Azure Governance capabilities such as Azure Policy’s policy definitions, initiatives (set definitions), aliases, security & regulatory compliance controls and Azure RBAC’s role definitions and resource provider operations.

I specifically love the ability to display policy definitions aligned with specific industry standard security guidelines such as CIS, Azure Security Benchmark, or NIST. I have incorporated this tool into my personal Azure governance workflow enough to recommend it to others who are working on Azure governance.

The specific policy definition that influenced terraform-azurerm-appservices_plan_sku’s creation can be found here.

Conclusion

The terraform-azurerm-appservices_plan_sku module provides a repeatable solution for governing Azure App Service Plan SKUs. It surpasses manual configurations in the Azure portal with its ability to be version-controlled, shared, and easily restored if a policy is accidentally deleted. This ensures consistent SKU compliance and efficient resource management in your Azure environment.

As always, if you have any feedback or questions, you can send me an email or reach out to me on LinkedIn.

Thank you for reading and I hope you get value from this post.

-Rudy

Related Links:

RCFromCLE/appservices_plan_sku/azurerm | Terraform Registry
GitHub – RCFromCLE/terraform-azurerm-appservices_plan_sku
App Service Pricing | Microsoft Azure
AzAdvertizer
Allowed App Services Plan SKUs (azadvertizer.net)


Leave a Reply