Azure Alert Creation Via terraform fails with error code 400 - azure

While creating metric alert on storage account via terraform I am getting Error 400
I've gone through the documentation and corss-verified that the name I am using for alert creation is correct
resource "azurerm_metric_alertrule" "test" {
name = "alerttestacc"
resource_group_name = "${azurerm_resource_group.main.name}"
location = "${azurerm_resource_group.main.location}"
description = "An alert rule to watch the metric Used capacity"
enabled = true
resource_id = "${azurerm_storage_account.to_monitor.id}"
metric_name = "UsedCapacity"
operator = "GreaterThan"
threshold = 20
aggregation = "Total"
period = "PT5M"
email_action {
send_to_service_owners = false
custom_emails = [
"xyz#gmail.com",
]
}
webhook_action {
service_uri = "https://example.com/some-url"
properties = {
severity = "incredible"
acceptance_test = "true"
}
}
Expected: Alert should be created
Actual:
azurerm_metric_alertrule.test:
insights.AlertRulesClient#CreateOrUpdate: Failure responding to
request: StatusCode=400 -- Original Error: autorest/azure: Service
returned an error. Status=400 Code="UnsupportedMetric" Message="The
metric with namespace '' and name 'UsedCapacity' is not supported for
this resource id

You could use azurerm_monitor_metric_alert instead of azurerm_metric_alertrule to create a UsedCapacity metric alert for the storage account. It is possible due to the different experiences between classic alerts and new alerts in Azure monitoring. Read alerts overview.
This example works on my side.
resource "azurerm_resource_group" "main" {
name = "example-resources"
location = "West US"
}
resource "azurerm_storage_account" "to_monitor" {
name = "examplestorageaccount123"
resource_group_name = "${azurerm_resource_group.main.name}"
location = "${azurerm_resource_group.main.location}"
account_tier = "Standard"
account_replication_type = "LRS"
}
resource "azurerm_monitor_action_group" "main" {
name = "example-actiongroup"
resource_group_name = "${azurerm_resource_group.main.name}"
short_name = "exampleact"
webhook_receiver {
name = "callmyapi"
service_uri = "http://example.com/alert"
}
}
resource "azurerm_monitor_metric_alert" "test" {
name = "example-metricalert"
resource_group_name = "${azurerm_resource_group.main.name}"
scopes = ["${azurerm_storage_account.to_monitor.id}"]
description = "Action will be triggered when the Used capacity is Greater than 777 bytes."
criteria {
metric_namespace = "Microsoft.Storage/storageAccounts"
metric_name = "UsedCapacity"
aggregation = "Total"
operator = "GreaterThan"
threshold = 777
}
action {
action_group_id = "${azurerm_monitor_action_group.main.id}"
}
}

Related

Error creating azurerm_monitor_metric_alert for IPsec Site-to-Site on Azure with Terraform

So I am trying to create monitoring alerts for IPsec VPN Connections on a Azure Virtual Network Gateway. We have automated the creation of the actual deployment of the connections. However when I try to deploy the monitoring portion of the bundle I'm getting an error. The plan looks good but fails when actually deploying the Alerts.
resource "azurerm_monitor_action_rule_action_group" "vpn-alerts" {
name = "vpn-alerts"
resource_group_name = azurerm_resource_group.rg-canadacentral-prod-region.name
action_group_id = azurerm_monitor_action_group.azure-vpn-monitor.id
scope {
type = "ResourceGroup"
resource_ids = [azurerm_resource_group.rg-canadacentral-prod-region.id]
}
}
resource "azurerm_monitor_action_group" "main" {
name = "vgw-${var.azure_region}-${var.vdc_env}-monitor"
resource_group_name = azurerm_resource_group.rg-canadacentral-prod-region.name
short_name = "ipsec-alerts"
# webhook_receiver {
# name = "callmyapi"
# service_uri = "http://example.com/alert"
# }
}
resource "azurerm_monitor_metric_alert" "ipsec_tunnel" {
for_each = {for cn in var.vpn: cn.name => cn}
name = "lgw-${var.azure_region}-${var.vdc_env}-region-${each.value.name}-connectivity"
resource_group_name = azurerm_resource_group.rg-canadacentral-prod-region.name
scopes = [azurerm_local_network_gateway.region_to_site[each.value.name].id]
description = "IPSec tunnel did not receive any traffic for over 5 minutes"
criteria {
metric_namespace = "Microsoft.Insights/metricAlerts"
metric_name = "BitsInPerSecond"
aggregation = "Average"
operator = "LessThanOrEqual"
threshold = 0
dimension {
name = "ApiName"
operator = "Include"
values = ["*"]
}
}
action {
action_group_id = azurerm_monitor_action_group.main.id
}
}
Inital Failure
So I tried changing the metric namespace to both
Microsoft.Network/connections
Microsoft.Network/localNetworkGateways
And recieved this error
This is code used to deploy the alerting, Could it be an issue with the actual alert namespace not being found? Any help appreciated.
I tried to reproduce the same in my environment , for vpn gateways:
Received similar error:
creating or updating Monitor Metric Alert: (Name "example-metricalert" / Resource Group "xxx "): insights.MetricAlertsClient#CreateOrUpdate: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="ResourceNotFound" Message="{\"code\":\"BadRequest\",\"message\":\"Detect invalid value: Microsoft.Insights/metricAlerts for query parameter: 'metricnamespace', the value must be: Microsoft.Network/vpnGateways if the query parameter is provided, you can also skip this optional query parameter
Code:
resource "azurerm_virtual_network" "example" {
name = "example-network"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
address_space = ["10.0.0.0/16"]
}
resource "azurerm_virtual_wan" "example" {
name = "example-vwan"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
}
resource "azurerm_virtual_hub" "example" {
name = "example-hub"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
virtual_wan_id = azurerm_virtual_wan.example.id
address_prefix = "10.0.1.0/24"
}
resource "azurerm_vpn_gateway" "example" {
name = "example-vpng"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
virtual_hub_id = azurerm_virtual_hub.example.id
}
resource "azurerm_monitor_action_group" "ag" {
name = "myactiongroup"
resource_group_name = data.azurerm_resource_group.example.name
short_name = "ipsec-alerts"
}
resource "azurerm_monitor_metric_alert" "alert" {
name = "example-metricalert"
resource_group_name = data.azurerm_resource_group.example.name
scopes = ["/subscriptions/xxx/resourceGroups/xxxxx/providers/Microsoft.Network/vpnGateways"]
description = "IPSec tunnel did not receive any traffic for over 5 minutes"
target_resource_type = "Microsofts.Network/vpnGateways"
#Microsoft.Network/vpnGateways
criteria {
metric_namespace = "Microsoft.Insights/metricAlerts"
metric_name = "Percentage CPU"
aggregation = "Total"
operator = "GreaterThan"
threshold = 80
}
action {
action_group_id = azurerm_monitor_action_group.ag.id
}
}
So here metric namespace is correct but it doesnot contain metrics CPU percentage and all.
I checked the issue is due to non support of the tried namespaces for the newtwork related metrics:
Only below are supported for the metrics as they require
metrics-supported
Try with namespace Microsoft.Network/virtualNetworkGateways as localNetworkGateways is not the supported one.
And if you check Virtual network gateway , Local network gateway is involved in VPN connections .see Configure IPsec/IKE policy for site-to-site VPN connections
In my case, as i am setting monitor alerts for VPN gateway,
i used "Microsoft.Network/vpnGateways" in metric_namespace and "AverageBandwidth" as metric , which only supports average as aggregation and it executed succssully.
According to below table from above metrics-supported :
similarly check for vnetgateway:
resource "azurerm_monitor_metric_alert" "alert" {
name = "example-metricalert"
resource_group_name = data.azurerm_resource_group.example.name
scopes = ["/subscriptions/xx/resourceGroups/xxx/providers/Microsoft.Network/vpnGateways/kavexample-vpng"]
description = "IPSec tunnel did not receive any traffic for over 5 minutes"
// target_resource_type = "Microsofts.Network/vpnGateways"
#Microsoft.Network/vpnGateways
criteria {
metric_namespace="Microsoft.Network/vpnGateways"
metric_name = "AverageBandwidth"
aggregation = "Average"
operator = "GreaterThan"
threshold = 80
}
action {
action_group_id = azurerm_monitor_action_group.ag.id
}
}
we can then monitor in insights:

Receiving error from Azure API when attempting to use additional_unattend_content argument

Hoping someone might be able to assist. Using Terraform on Azure and looking for a method to deploy windows VMs and auto-login + configure winrm. I’ve found that some use the azurerm_windows_virtual_machine.<name_of_vm>.additional_unattend_content to set this up normally.
Example found in provider github repo: https://github.com/hashicorp/terraform-provider-azurerm/blob/b0c897055329438be6a3a[…]ned-to-active-directory/modules/active-directory-domain/main.tf
I’m getting some errors from the azure backend and was hoping maybe someone more knowledgeable than me would have experience with this. Getting pushback from Azure support when I requested their help. Appreciate any info anyone can provide!
Happy to provide logs or anything else thats needed!!!
resource "azurerm_windows_virtual_machine" "wks_win10" {
count = var.number_of_win10_wks
depends_on = [azurerm_network_interface.wks_nic_win10]
name = "wks-win10-${count.index}"
location = var.location
resource_group_name = var.rg_name
size = var.vm_size
provision_vm_agent = true
computer_name = "wks-win10-${count.index}"
admin_username = var.windows_username
admin_password = var.windows_password
network_interface_ids = ["${element(azurerm_network_interface.wks_nic_win10.*.id, count.index)}"]
os_disk {
caching = "ReadWrite"
name = "wks-win10-osdisk-${count.index}"
disk_size_gb = "250"
storage_account_type = "StandardSSD_LRS"
}
source_image_reference {
publisher = "MicrosoftWindowsDesktop"
offer = "Windows-10"
sku = "win10-21h2-ent"
version = "latest"
}
additional_unattend_content {
setting = "AutoLogon"
content = local.auto_logon_data
# content = "<AutoLogon><Password><Value>${var.windows_password}</Value></Password><Enabled>true</Enabled><LogonCount>3</LogonCount><Username>${var.windows_username}</Username></AutoLogon>"
}
winrm_listener {
protocol = "Http"
}
tags = merge(var.tags,
{
"kind"="workstation"
"os"="windows"
})
}
resource "azurerm_virtual_machine_extension" "wks_win10_vm_extension_network_watcher" {
count = var.number_of_win10_wks
depends_on = [azurerm_windows_virtual_machine.wks_win10]
name = "win10netwatch${count.index}"
virtual_machine_id = "${element(azurerm_windows_virtual_machine.wks_win10.*.id, count.index )}"
publisher = "Microsoft.Azure.NetworkWatcher"
type = "NetworkWatcherAgentWindows"
type_handler_version = "1.4"
auto_upgrade_minor_version = true
}
Errors:
module.compute.azurerm_network_interface.wks_nic_win10[0]: Creation complete after 1s [id=/subscriptions/<subscription-id>/resourceGroups/test-rg/providers/Microsoft.Network/networkInterfaces/wks-win10-nic-0]
module.compute.azurerm_windows_virtual_machine.wks_win10[0]: Creating...
2022-11-23T16:09:12.176-0500 [ERROR] provider.terraform-provider-azurerm_v3.30.0_x5: Response contains error diagnostic: #module=sdk.proto diagnostic_detail= diagnostic_severity=ERROR diagnostic_summary="creating Windows Virtual Machine: (Name "wks-win10-0" / Resource Group "test-rg"): compute.VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="InvalidParameter" Message="The value of parameter windowsConfiguration.additionalUnattendContent.content is invalid." Target="windowsConfiguration.additionalUnattendContent.content"" #caller=github.com/hashicorp/terraform-plugin-go#v0.10.0/tfprotov5/internal/diag/diagnostics.go:56 tf_provider_addr=provider tf_req_id=6a628786-49b2-388d-85f9-07e4eeb8a618 tf_resource_type=azurerm_windows_virtual_machine tf_rpc=ApplyResourceChange tf_proto_version=5.2 timestamp=2022-11-23T16:09:12.176-0500
2022-11-23T16:09:12.181-0500 [ERROR] vertex "module.compute.azurerm_windows_virtual_machine.wks_win10[0]" error: creating Windows Virtual Machine: (Name "wks-win10-0" / Resource Group "test-rg"): compute.VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="InvalidParameter" Message="The value of parameter windowsConfiguration.additionalUnattendContent.content is invalid." Target="windowsConfiguration.additionalUnattendContent.content"
I tried to reproduce the scenario in my environment:
Terraform code:
resource "azurerm_windows_virtual_machine" "example" {
name = "kaacctvm"
location = data.azurerm_resource_group.example.location
resource_group_name = data.azurerm_resource_group.example.name
network_interface_ids = [azurerm_network_interface.example.id]
size = "Standard_F2"
admin_username = "txxxin"
admin_password = "Pasxxx4!"
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
os_profile {
computer_name = "hostname"
admin_username = "txxxmin"
admin_password = "gfgxx4!"
}
source_image_reference {
publisher = "MicrosoftWindowsDesktop"
offer = "Windows-10"
sku = "win10-21h2-ent"
version = "latest"
}
additional_unattend_content {
setting = "AutoLogon"
content = "<AutoLogon><Password><Value>${var.windows_password}</Value></Password><Enabled>true</Enabled><LogonCount>3</LogonCount><Username>${var.windows_username}</Username></AutoLogon>"
}
winrm_listener {
protocol = "Http"
}
tags = {
environment = "staging"
}
}
resource "azurerm_virtual_machine_extension" "example" {
name = "kavyahostname"
virtual_machine_id = azurerm_windows_virtual_machine.example.id
publisher ="Microsoft.Azure.NetworkWatcher"
type = "NetworkWatcherAgentWindows"
type_handler_version = "1.4"
auto_upgrade_minor_version = true
settings = <<SETTINGS
{
"commandToExecute": "hostname && uptime"
}
SETTINGS
tags = {
environment = "Production"
}
}
Received similar error:
VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="InvalidParameter" Message="The value of parameter “” is invalid."
Make sure the contents in the username and password are of correct format here while calling autologon data .
content = "<AutoLogon><Password><Value>${var.windows_password}</Value></Password><Enabled>true</Enabled><LogonCount>3</LogonCount><Username>${var.windows_username}</Username></AutoLogon>"
Please check azure-quickstart-templates| issues | github
It can be array which can not be base64 encoded
Check with the colon mistakes or spelling mistakes
I have variables:
variable "windows_username" {
type = string
default = "xxx"
}
variable "windows_password" {
type = string
default = "xxx"
}
Then vm extension created sucessfully:
Also check this Microsoft.Compute/virtualMachines - Bicep, ARM template & Terraform AzAPI reference | Microsoft Learn

Terraform Azure App Service Plan Error - The parameter SKU.Name has an invalid value

Module declaration
resource "azurerm_app_service_plan" "appserviceplan" {
name = var.name
location = var.location
resource_group_name = var.resource_group_name
kind = var.kind
reserved = var.reserved
is_xenon = var.is_xenon
sku {
# name = var.sku_name
tier = var.sku_tier
size = var.sku_tier
}
}
Calling the above module like so (in main.tf) ...
module "appserviceplan1" {
source = "../modules/app_service_plan"
name = "${var.project_name}-${var.environment}-appserviceplan"
location = var.location
resource_group_name = var.resource_group_name
kind = var.asp_kind
reserved = var.asp_reserved
is_xenon = var.asp_is_xenon
# sku_name = var.asp_sku_name
sku_tier = var.asp_sku_tier
sku_size = var.asp_sku_tier
}
Input variable assignment (in main.auto.tfvars):
# Variable assignment for App Service Plan
asp_kind = "xenon"
# Recommended value is false
# Ref: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service_plan
asp_reserved = false
asp_is_xenon = true
# asp_sku_name = "P3"
asp_sku_tier = "PremiumV3"
asp_sku_size = "P3v3"
Getting the following error with terraform apply:
Error: Error creating/updating App Service Plan "xyz-sandbox-appserviceplan" (Resource Group "abc-sandbox-xyz-cc-rg"): web.AppServicePlansClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="BadRequest" Message="The parameter SKU.Name has an invalid value." Details=[{"Message":"The parameter SKU.Name has an invalid value."},{"Code":"BadRequest"},{"ErrorEntity":{"Code":"BadRequest","Message":"The parameter SKU.Name has an invalid value.","MessageTemplate":"The parameter {0} has an invalid value.","Parameters":["SKU.Name"]}}]
I have been spinning on this for hours now. Any help would be greatly appreciated!
Solution: I was using incorrect tier and size.
Using the following solved it ..
asp_sku_tier = "P3v3"
asp_sku_size = "P3v3"
Thanks #KalC, the below works.
resource "azurerm_app_service_plan" "af-sp" {
name = "af-sp"
location = var.azure_functions_location
resource_group_name = var.azure_functions_rg_name
kind = "Linux"
reserved = true
sku {
tier = "P1v2"
size = "P1v2"
}
}

Terraform 403 error when creating function app and storage account with private endpoint

I am getting a 403 forbidden when creating a function app that connects to its storage account via private endpoint inside a vnet. Storage account has firewall default action of 'Deny', and of course if I set it to 'Allow' it will work. I want this as 'Deny', however. Following this microsoft link if the function app and storage account are created in the same region with vnet, subnets, and private endpoints then it's supposed to work so I must be doing something wrong. I also tried changing the region for the storage account and it still resulted in a 403.
Error:
Error: web.AppsClient#CreateOrUpdate: Failure sending request: StatusCode=0 -- Original Error: Code="BadRequest" Message="There was a conflict. The remote server returned an error: (403) Forbidden." Details=[{"Message":"There was a conflict. The remote server returned an error: (403) Forbidden."},{"Code":"BadRequest"},{"ErrorEntity":{"Code":"BadRequest","ExtendedCode":"01020","Message":"There was a conflict. The remote server returned an error: (403) Forbidden.","MessageTemplate":"There was a conflict. {0}","Parameters":["The remote server returned an error: (403) Forbidden."]}}]
Here is my terraform code
resource "azurerm_function_app" "func" {
name = "${var.func_basics.name}-func"
location = var.func_basics.location
resource_group_name = var.func_basics.resource_group_name
app_service_plan_id = azurerm_app_service_plan.svc_plan.id
storage_account_name = azurerm_storage_account.func_sa.name
storage_account_access_key = azurerm_storage_account.func_sa.primary_access_key
version = var.runtime_version
https_only = true
depends_on = [
azurerm_storage_account.func_sa,
azurerm_app_service_plan.svc_plan,
azurerm_application_insights.func_ai,
azurerm_virtual_network.func_vnet
]
app_settings = merge(var.app_settings, local.additional_app_settings)
}
resource "azurerm_app_service_plan" "svc_plan" {
name = "${var.func_basics.name}-func-plan"
location = var.func_basics.location
resource_group_name = var.func_basics.resource_group_name
kind = "elastic"
sku {
tier = "ElasticPremium"
size = "EP1"
}
}
resource "azurerm_application_insights" "func_ai" {
name = "${var.func_basics.name}-func-appi"
location = var.func_basics.location
resource_group_name = var.func_basics.resource_group_name
application_type = var.ai_app_type
}
resource "azurerm_storage_account" "func_sa" {
name = "st${lower(replace(var.func_basics.name, "/[-_]*/", ""))}"
resource_group_name = var.func_basics.resource_group_name
location = var.func_basics.location
account_tier = var.sa_settings.tier
account_replication_type = var.sa_settings.replication_type
account_kind = "StorageV2"
enable_https_traffic_only = true
min_tls_version = "TLS1_2"
depends_on = [
azurerm_virtual_network.func_vnet
]
network_rules {
default_action = "Deny"
virtual_network_subnet_ids = [azurerm_subnet.func_endpoint_subnet.id]
bypass = [
"Metrics",
"Logging",
"AzureServices"
]
}
}
resource "azurerm_virtual_network" "func_vnet" {
name = "${var.func_basics.name}-func-vnet"
resource_group_name = var.func_basics.resource_group_name
location = var.func_basics.location
address_space = ["10.0.0.0/16"]
}
resource "azurerm_subnet" "func_service_subnet" {
name = "${var.func_basics.name}-func-svc-snet"
resource_group_name = var.func_basics.resource_group_name
virtual_network_name = azurerm_virtual_network.func_vnet.name
address_prefixes = ["10.0.1.0/24"]
enforce_private_link_service_network_policies = true
service_endpoints = ["Microsoft.Storage"]
delegation {
name = "${var.func_basics.name}-func-del"
service_delegation {
name = "Microsoft.Web/serverFarms"
actions = ["Microsoft.Network/virtualNetworks/subnets/action"]
}
}
}
resource "azurerm_subnet" "func_endpoint_subnet" {
name = "${var.func_basics.name}-func-end-snet"
resource_group_name = var.func_basics.resource_group_name
virtual_network_name = azurerm_virtual_network.func_vnet.name
address_prefixes = ["10.0.2.0/24"]
enforce_private_link_endpoint_network_policies = true
}
resource "azurerm_private_endpoint" "func_req_sa_blob_endpoint" {
name = "${var.func_basics.name}-func-req-sa-blob-end"
resource_group_name = var.func_basics.resource_group_name
location = var.func_basics.location
subnet_id = azurerm_subnet.func_endpoint_subnet.id
private_service_connection {
name = "${var.func_basics.name}-func-req-sa-blob-pscon"
private_connection_resource_id = azurerm_storage_account.func_sa.id
is_manual_connection = false
subresource_names = ["blob"]
}
}
resource "azurerm_private_endpoint" "func_req_sa_file_endpoint" {
name = "${var.func_basics.name}-func-req-sa-file-end"
resource_group_name = var.func_basics.resource_group_name
location = var.func_basics.location
subnet_id = azurerm_subnet.func_endpoint_subnet.id
private_service_connection {
name = "${var.func_basics.name}-func-req-sa-file-pscon"
private_connection_resource_id = azurerm_storage_account.func_sa.id
is_manual_connection = false
subresource_names = ["file"]
}
}
resource "azurerm_app_service_virtual_network_swift_connection" "func_vnet_swift" {
app_service_id = azurerm_function_app.func.id
subnet_id = azurerm_subnet.func_service_subnet.id
}
locals {
additional_app_settings = {
"APPINSIGHTS_INSTRUMENTATIONKEY" = azurerm_application_insights.func_ai.instrumentation_key
"WEBSITE_CONTENTAZUREFILECONNECTIONSTRING" = azurerm_storage_account.func_sa.primary_connection_string
"AzureWebJobsStorage" = azurerm_storage_account.func_sa.primary_connection_string
"WEBSITE_VNET_ROUTE_ALL" = "1"
"WEBSITE_CONTENTOVERVNET" = "1"
"WEBSITE_DNS_SERVER" = "168.63.129.16"
}
}
It seems that it's a common error message when you create an Azure function where the storage account of the function is added to the Virtual Network, read here for more details.
To resolve it, you can use the local-exec Provisioner to invoke the az CLI command to deny the traffic after all of the provisions are finished.
az storage account update --name storage_account_name --resource-group reource_group_name --default-action 'Deny' --bypass 'AzureServices', 'Logging', 'Metrics'
Alternatively, you can separately configure the storage account network rules. You may need to allow your client's IP to access the storage account.
resource "azurerm_storage_account_network_rules" "test" {
resource_group_name = var.resourceGroupName
storage_account_name = azurerm_storage_account.func_sa.name
default_action = "Deny"
bypass = [
"Metrics",
"Logging",
"AzureServices"
]
ip_rules = ["x.x.x.x"]
depends_on = [
azurerm_storage_account.func_sa,
azurerm_app_service_plan.svc_plan,
azurerm_application_insights.func_ai,
azurerm_virtual_network.func_vnet,
azurerm_function_app.func
]
}
In addition, there is a possible solution for this similar case on Github.
I've had this issue in the past and found that it can be resolved as follows. I've tested this on v3.3.0 of the provider using the azurerm_windows_function_app resource. I think currently this is an Azure problem, in that it if you don't supply a share it will try and create one but will be denied. You'd expect this to work if Allow Azure services on the trusted services list to access this storage account is enabled, but webapps aren't trusted.
Create your storage account with IP rules and deny
Create a share within this for your function app content
within the function set the following configuration settings
WEBSITE_CONTENTAZUREFILECONNECTIONSTRING = <storage_account.primary_connection_string>
WEBSITE_CONTENTSHARE = <your share>
WEBSITE_CONTENTOVERVNET = 1
In the functions site configuration set the attribute vnet_route_all_enabled = true

Terraform can not create a storage account in Azure

I have a Terraform script that used to be able to create a storage account in Azure ok, but today started to return the error message:
azurerm_storage_account.testsa: 1 error(s) occurred:
* azurerm_storage_account.testsa: Error waiting for Azure Storage Account "terraformtesthubb" to be created: Future#WaitForCompletion: the number of retries has been exceeded: StatusCode=400 -- Original Error: Code="AadClientCredentialsGrantFailure" Message="Failure in AAD Client Credentials Grant Flow."
The trace logs don't show anything useful, and the term AadClientCredentialsGrantFailure literally returns nothing in Google. What is the cause?
Answering this one for myself because Google totally failed me.
This turned out to be an issue with Azure. Despite there being no errors listed in any of the status pages, the script would work in US West, but fail in US West 2.
After a few days this issue went away, so it was an intermittent Azure issue.
Edit
For reference, this was the script. Markers like #{Principal.TenantId} are being replaced during the template deployment.
provider "azurerm" {
client_id = "#{Principal.Client}"
client_secret = "#{Principal.Password}"
subscription_id = "#{Principal.SubscriptionNumber}"
tenant_id = "#{Principal.TenantId}"
}
resource "azurerm_resource_group" "testrg" {
name = "terraformtesthub#{Octopus.Environment.Name | ToLower}"
location = "#{Octopus.Environment.Name | ToLower}"
}
resource "azurerm_virtual_network" "test" {
name = "terraformtesthub#{Octopus.Environment.Name | ToLower}"
address_space = ["10.0.0.0/16"]
location = "${azurerm_resource_group.testrg.location}"
resource_group_name = "${azurerm_resource_group.testrg.name}"
}
resource "azurerm_subnet" "test" {
name = "terraformtesthub#{Octopus.Environment.Name | ToLower}"
resource_group_name = "${azurerm_resource_group.testrg.name}"
virtual_network_name = "${azurerm_virtual_network.test.name}"
address_prefix = "10.0.2.0/24"
service_endpoints = ["Microsoft.Sql", "Microsoft.Storage"]
}
resource "azurerm_storage_account" "testsa" {
name = "terraformtesthub#{Octopus.Environment.Name | ToLower}"
resource_group_name = "${azurerm_resource_group.testrg.name}"
location = "#{Octopus.Environment.Name | ToLower}"
account_tier = "Standard"
account_kind = "StorageV2"
account_replication_type = "RAGRS"
lifecycle {
prevent_destroy = true
}
network_rules {
ip_rules = ["100.0.0.1"]
virtual_network_subnet_ids = ["${azurerm_subnet.test.id}"]
}
}

Resources