Today at my work I had to help secure our function apps. We have a few of them, and we use terraform to manage all our infrastructures.

This is the example provided by terraform:

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "West Europe"
}

resource "azurerm_storage_account" "example" {
  name                     = "linuxfunctionappsa"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

resource "azurerm_service_plan" "example" {
  name                = "example-app-service-plan"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  os_type             = "Linux"
  sku_name            = "Y1"
}

resource "azurerm_linux_function_app" "example" {
  name                = "example-linux-function-app"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location

  storage_account_name = azurerm_storage_account.example.name
  service_plan_id      = azurerm_service_plan.example.id

  site_config {}
}

By default, function apps are reached through http and https protocols, ftp and ftps. And we needed to fix that.

When you read that terraform documentation, you see that you can fix that by adding these 2 fields:

Setting Https only to true

To me that means https_only needs to be added under site_config. The same goes with FTP:

ftps_state – (Optional) State of FTP / FTPS service for this function app. Possible values include: AllAllowed, FtpsOnly and Disabled. Defaults to Disabled

So what did I do? I went to each function app, add Site_config, put both variables there and done.

This is the final code:

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "West Europe"
}

resource "azurerm_storage_account" "example" {
  name                     = "linuxfunctionappsa"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

resource "azurerm_service_plan" "example" {
  name                = "example-app-service-plan"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  os_type             = "Linux"
  sku_name            = "Y1"
}

resource "azurerm_linux_function_app" "example" {
  name                = "example-linux-function-app"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location

  storage_account_name = azurerm_storage_account.example.name
  service_plan_id      = azurerm_service_plan.example.id

  site_config {
    ftps_state      = "FtpsOnly"
    https_only      = true
  }
}

and gave it a shot. That did not do what I expected. if you go to azure, function app and check settings, those settings are not there. (Actually I believe terraform plan failed to begin with, and had to move “https_only” block outside.

After a few looking around, I found out that the documentation is not up to date, and that is not how to set function apps to be https_only or ftps only. ftps_state needs to remain under site_config, but https_only needs to move outside like this below:

resource "azurerm_linux_function_app" "example" {
  name                = "example-linux-function-app"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location

  storage_account_name = azurerm_storage_account.example.name
  service_plan_id      = azurerm_service_plan.example.id
  https_only           = true

  site_config {
    ftps_state      = "FtpsOnly"
  }

The take away of all of this is that, sometimes documentation remain so out of date, that it gives you nightmare what you need to do to get a task complete. I had to rely on other sources on internet, instead of relying the official documentation of terraform.

It can be annoying, but it’s part of learning I guess.