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:
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.