首页 > 解决方案 > Terraform 应用服务不会连接到存储帐户

问题描述

在 Terraform 中,我试图让我的应用服务连接到存储帐户,以便它可以读取主网站的文件。

我今天一直在关注 HashiCorp 的指南:https ://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service#access_key

在这里它提到能够做到这一点,它必须通过访问密钥进行连接,这就是令人困惑的地方。我在这里找到了一个工作示例: https ://github.com/hashicorp/terraform-provider-azurerm/issues/10435

然而我的错误,我认为它与密钥有关,我首先尝试通过客户管理的密钥然后是数据源来完成它,现在我对如何真正让它工作感到非常困惑。

再一次,Terraform Docs 充其量是有限的。

这是我的代码:

网站应用代码:

resource "azurerm_app_service" "website_app" {
  name                = var.website_name
  location            = azurerm_resource_group.Example.location
  resource_group_name = azurerm_resource_group.Example.name
  app_service_plan_id = azurerm_app_service_plan.websiteappserviceplan.id


  app_settings = {
    "KEY_VAULT_URL" = azurerm_key_vault.secrets.vault_uri

  }

  site_config {
    always_on                = true
    dotnet_framework_version = "v5.0"
    app_command_line         = "dotnet EventManagement.Web.dll"

  }

  storage_account {
    name         = "WebsiteStorageConnectionString"
    type         = "AzureBlob"
    account_name = azurerm_storage_account.website_installers_account.name
    access_key   = data.azurerm_storage_account.website_installers_account.primary_access_key
    share_name   = "guides"
    mount_path   = "/var/lib/guides"
  }

  logs {
    detailed_error_messages_enabled = true
    failed_request_tracing_enabled  = true
    application_logs {
      azure_blob_storage {
        level             = "Information"
        sas_url           = format("https://${azurerm_storage_account.website_log_storage.name}.blob.core.windows.net/${azurerm_storage_container.website_logs_container.name}%s", data.azurerm_storage_account_blob_container_sas.website_logs_container_sas.sas)
        retention_in_days = 365
      }
    }

    http_logs {
      azure_blob_storage {
        sas_url           = format("https://${azurerm_storage_account.website_log_storage.name}.blob.core.windows.net/${azurerm_storage_container.website_logs_container.name}%s", data.azurerm_storage_account_blob_container_sas.website_logs_container_sas.sas)
        retention_in_days = 365
      }
    }
  }

  connection_string {
    name  = "StorageAccount"
    type  = "Custom"
    value = azurerm_storage_account.website_log_storage.primary_connection_string
  }

  identity {
    type = "SystemAssigned"
  }
}

resource "azurerm_storage_account" "website_installers_account" {
  name                     = "nscwebstoredinstallersac"
  resource_group_name      = azurerm_resource_group.Example.name
  location                 = azurerm_resource_group.Example.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
  #primary_access_key       = azurerm_storage_account_customer_managed_key.guides_key.name 

  identity {
    type = "SystemAssigned"
  }
}

data "azurerm_storage_account" "website_installers_account" {
  name                = "nscwebstoredinstallersac"
  resource_group_name = azurerm_resource_group.example.name
}
resource "azurerm_storage_container" "website_installers_container" {
  name                  = "${var.website_name}-installerscont"
  storage_account_name  = azurerm_storage_account.website_installers_account.name
  container_access_type = "private"
}

data "azurerm_storage_account_blob_container_sas" "website_installers_container_sas" {
  connection_string = azurerm_storage_account.website_installers_account.primary_connection_string
  container_name    = azurerm_storage_container.website_installers_container.name


  start  = timestamp()
  expiry = time_rotating.main.rotation_rfc3339

  permissions {
    read   = true
    add    = true
    create = true
    write  = true
    delete = true
    list   = true
  }

  cache_control       = "max-age=5"
  content_disposition = "inline"
  content_encoding    = "deflate"
  content_language    = "en-US"
  content_type        = "application/json"
}

resource "azurerm_storage_account_customer_managed_key" "guides_key" {
  storage_account_id = azurerm_storage_account.website_installers_account.id
  key_vault_id       = azurerm_key_vault.secrets.id
  key_name           = azurerm_key_vault_key.website_guides_key.name

  depends_on = [
    azurerm_storage_account.website_installers_account,
    azurerm_key_vault_access_policy.client,
    azurerm_key_vault_access_policy.service_principal,
  ]
}

错误信息:

Error: updating Storage Accounts for App Service "websitename": web.AppsClient#UpdateAzureStorageAccounts: Failure sending request: StatusCode=409 -- Original Error: autorest/azure: Service returned an error. Status=<nil> <nil>

更新

根据这个网站,我整天都在搞砸这个:https ://github.com/kumarvna/terraform-azurerm-app-service

存储名称应该是标识符。我已更改并收到一条新的错误消息,其中指出以下内容:

Error: updating Storage Accounts for App Service "websitename": web.AppsClient#UpdateAzureStorageAccounts: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="BadRequest" Message="AzureStoragePropertyDictionary is invalid.  ID in AzureStoragePropertyDictionary contains invalid characters: /subscriptions/3b92ad75-8bb4-44a3-92df-394bc15085ef/resourceGroups/Classroom_In_The_Cloud_Terraform/providers/Microsoft.Storage/storageAccounts/nscwebstoredinstallersac" Details=[{"Message":"AzureStoragePropertyDictionary is invalid.  ID in AzureStoragePropertyDictionary contains invalid characters: /subscriptions/3b92ad75-8bb4-44a3-92df-394bc15085ef/resourceGroups/Classroom_In_The_Cloud_Terraform/providers/Microsoft.Storage/storageAccounts/nscwebstoredinstallersac"},{"Code":"BadRequest"},{"ErrorEntity":{"Code":"BadRequest","ExtendedCode":"51021","Message":"AzureStoragePropertyDictionary is invalid.  ID in AzureStoragePropertyDictionary contains invalid characters: /subscriptions/subid/resourceGroups/Terraform/providers/Microsoft.Storage/storageAccounts/nscwebstoredinstallersac","MessageTemplate":"{0} is invalid.  {1}","Parameters":["AzureStoragePropertyDictionary","ID in AzureStoragePropertyDictionary contains invalid characters: /subscriptions/subid/resourceGroups/Terraform/providers/Microsoft.Storage/storageAccounts/nscwebstoredinstallersac"]}}]

将存储名称作为存储帐户的标识符是有道理的,因为为什么要指定名​​称两次?

存储帐户成功地将网站配置使用的密钥写入 Key Vault,这样就可以正常工作。它只是应用服务无法与存储帐户通信。它让我发疯。

我还完成了完全销毁并重新应用 env 更改了我的状态文件尝试了全新的订阅。错误仍然出现。

请参阅下面的更新代码。谢谢你。

网站更新代码:

resource "azurerm_app_service_plan" "websiteappserviceplan" {
  name                = "website-plan"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  sku {
    tier = "Basic"
    size = "B1"
  }
}

resource "azurerm_app_service" "website_app" {
  depends_on = [
    azurerm_key_vault_access_policy.service_principal,
    azurerm_key_vault_access_policy.client,
    azurerm_key_vault_access_policy.website_installers_storage_accesspolicy,
    azurerm_storage_container.website_installers_container
  ]

  name                = var.website_name
  location            = azurerm_resource_group.Example.location
  resource_group_name = azurerm_resource_group.Example.name
  app_service_plan_id = azurerm_app_service_plan.websiteappserviceplan.id


  app_settings = {
    "KEY_VAULT_URL" = azurerm_key_vault.secrets.vault_uri

  }

  site_config {
    always_on                = true
    dotnet_framework_version = "v5.0"
    app_command_line         = "dotnet EventManagement.Web.dll"

  }

  storage_account {
    name         = azurerm_storage_account.website_installers_account.id 
    type         = "AzureBlob"
    account_name = azurerm_storage_account.website_installers_account.name
    access_key   = data.azurerm_key_vault_secret.AccessKey.id
    share_name   = azurerm_storage_container.website_installers_container.name
    mount_path   = "/var/lib/guides"
  }

  logs {
    detailed_error_messages_enabled = true
    failed_request_tracing_enabled  = true
    application_logs {
      azure_blob_storage {
        level             = "Information"
        sas_url           = format("https://${azurerm_storage_account.website_log_storage.name}.blob.core.windows.net/${azurerm_storage_container.website_logs_container.name}%s", data.azurerm_storage_account_blob_container_sas.website_logs_container_sas.sas)
        retention_in_days = 365
      }
    }

    http_logs {
      azure_blob_storage {
        sas_url           = format("https://${azurerm_storage_account.website_log_storage.name}.blob.core.windows.net/${azurerm_storage_container.website_logs_container.name}%s", data.azurerm_storage_account_blob_container_sas.website_logs_container_sas.sas)
        retention_in_days = 365
      }
    }

  }

  connection_string {
    name  = "StorageAccount"
    type  = "Custom"
    value = azurerm_storage_account.website_log_storage.primary_connection_string
  }

  identity {
    type = "SystemAssigned"
  }
}

存储帐户更新代码:

resource "time_rotating" "main" {
  rotation_rfc3339 = null
  rotation_years   = 2

  triggers = {
    end_date = null
    years    = 2
  }
}

resource "azurerm_storage_account" "website_log_storage" {
  name                     = "cicweblogsstorageacc"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "LRS"

  identity {
    type = "SystemAssigned"
  }
}


resource "azurerm_storage_container" "website_logs_container" {
  name                  = "${var.website_name}-logscont"
  storage_account_name  = azurerm_storage_account.website_log_storage.name
  container_access_type = "private"
}

data "azurerm_storage_account_blob_container_sas" "website_logs_container_sas" {
  connection_string = azurerm_storage_account.website_log_storage.primary_connection_string
  container_name    = azurerm_storage_container.website_logs_container.name


  start  = timestamp()
  expiry = time_rotating.main.rotation_rfc3339

  permissions {
    read   = true
    add    = true
    create = true
    write  = true
    delete = true
    list   = true
  }

  cache_control       = "max-age=5"
  content_disposition = "inline"
  content_encoding    = "deflate"
  content_language    = "en-US"
  content_type        = "application/json"
}

------ RELEVANT AREA FOR PROBLEM BELLOW ---------

resource "azurerm_storage_account" "website_installers_account" {
  name                     = "nscwebstoredinstallersac"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
  #primary_access_key       = azurerm_storage_account_customer_managed_key.guides_key.name 

  identity {
    type = "SystemAssigned"
  }
}

resource "azurerm_storage_container" "website_installers_container" {
  depends_on = [
    azurerm_storage_account.website_installers_account
  ]
  name                  = "${var.website_name}-installerscont"
  storage_account_name  = azurerm_storage_account.website_installers_account.name
  container_access_type = "private"
}

因为我现在通过 Key Vault 传递存储帐户的访问密钥,所以我现在包含了 Key Vault 代码:

// Users & Groups which I want to give permissions to be able to access the keyvault.
data "azuread_user" "user" {
  user_principal_name = "email"
}

data "azuread_group" "AZ_AD_Group" {
  display_name     = "email group"
  security_enabled = true
}

// This gets the Azure AD Tenant ID information to deploy for KeyVault. 
resource "azurerm_key_vault" "secrets" {
  name                       = "${var.key_vault_name}-${random_string.myrandom.id}"
  resource_group_name        = azurerm_resource_group.example.name
  location                   = azurerm_resource_group.example.location
  sku_name                   = "standard"
  tenant_id                  = data.azurerm_client_config.current.tenant_id
  soft_delete_retention_days = 7
  purge_protection_enabled   = false

  #access_policy {
  #  tenant_id = data.azurerm_client_config.current.tenant_id
  #object_id = data.azurerm_client_config.current.object_id

  #  key_permissions         = ["Backup", "Create", "Decrypt", "Delete", "Encrypt", "Get", "Import", "List", "Purge", "Recover", "Restore", "Sign", "UnwrapKey", "Update", "Verify", "WrapKey", ]
  # secret_permissions      = ["Backup", "Delete", "Get", "List", "Purge", "Recover", "Restore", "Set", ]
  #  certificate_permissions = ["create", "delete", "deleteissuers", "get", "getissuers", "import", "list", "listissuers", "managecontacts", "manageissuers", "setissuers", "update", ]
  #}
}

resource "azurerm_key_vault_secret" "Website_Logs_Storage_URI" {
  name         = "WebsiteLogsStorageURI"
  value        = format("https://${azurerm_storage_account.website_log_storage.name}.blob.core.windows.net/${azurerm_storage_container.website_logs_container.name}%s", data.azurerm_storage_account_blob_container_sas.website_logs_container_sas.sas)
  key_vault_id = azurerm_key_vault.nscsecrets.id

  depends_on = [
    azurerm_key_vault_access_policy.client,
    azurerm_key_vault_access_policy.service_principal,
  ]

}

resource "azurerm_key_vault_secret" "Website_Guides_Access_key" {
  name         = "WebsiteGuidesAccessKey"
  value        = azurerm_storage_account.website_installers_account.primary_access_key
  key_vault_id = azurerm_key_vault.nscsecrets.id

  depends_on = [
    azurerm_key_vault_access_policy.client,
    azurerm_key_vault_access_policy.service_principal,
  ]

}

data "azurerm_key_vault_secret" "Guides_AccessKey" {
  depends_on = [
    azurerm_storage_container.website_installers_container
  ]
  name         = azurerm_key_vault_secret.Website_Guides_Access_key.name
  key_vault_id = azurerm_key_vault.nscsecrets.id
}

resource "azurerm_key_vault_key" "website_logs_key" {
  name         = "${var.website_name}-logskey"
  key_vault_id = azurerm_key_vault.nscsecrets.id
  key_type     = "RSA"
  key_size     = 2048
  key_opts     = ["decrypt", "encrypt", "sign", "unwrapKey", "verify", "wrapKey"]

  depends_on = [
    azurerm_key_vault_access_policy.client,
    azurerm_key_vault_access_policy.service_principal,
  ]
}

resource "azurerm_key_vault_key" "website_guides_key" {
  name         = "${var.website_name}-guideskey"
  key_vault_id = azurerm_key_vault.nscsecrets.id
  key_type     = "RSA"
  key_size     = 2048
  key_opts     = ["decrypt", "encrypt", "sign", "unwrapKey", "verify", "wrapKey"]

  depends_on = [
    azurerm_key_vault_access_policy.client,
    azurerm_key_vault_access_policy.service_principal,
  ]
}



resource "azurerm_key_vault_access_policy" "client" { // This is for AD Users Logged into Azure to give them the right access when creating resources. 
  key_vault_id            = azurerm_key_vault.nscsecrets.id
  tenant_id               = data.azurerm_client_config.current.tenant_id
  object_id               = data.azuread_group.Classroom_In_The_Cloud_AZ_AD_Group.object_id
  secret_permissions      = ["Backup", "Delete", "Get", "List", "Purge", "Recover", "Restore", "Set", ]
  key_permissions         = ["Backup", "Create", "Decrypt", "Delete", "Encrypt", "Get", "Import", "List", "Purge", "Recover", "Restore", "Sign", "UnwrapKey", "Update", "Verify", "WrapKey", ]
  storage_permissions     = ["Backup", "Delete", "DeleteSAS", "Get", "GetSAS", "List", "ListSAS", "Purge", "Recover", "RegenerateKey", "Restore", "Set", "SetSAS", "Update", ]
  certificate_permissions = ["create", "delete", "deleteissuers", "get", "getissuers", "import", "list", "listissuers", "managecontacts", "manageissuers", "setissuers", "update", ]
}

resource "azurerm_key_vault_access_policy" "service_principal" { // This is for the Service Principal in the pipeline to be able to make changes to Key Vault. 
  key_vault_id            = azurerm_key_vault.nscsecrets.id
  tenant_id               = data.azurerm_client_config.current.tenant_id
  object_id               = data.azurerm_client_config.current.object_id
  secret_permissions      = ["Backup", "Delete", "Get", "List", "Purge", "Recover", "Restore", "Set", ]
  key_permissions         = ["Backup", "Create", "Decrypt", "Delete", "Encrypt", "Get", "Import", "List", "Purge", "Recover", "Restore", "Sign", "UnwrapKey", "Update", "Verify", "WrapKey", ]
  storage_permissions     = ["Backup", "Delete", "DeleteSAS", "Get", "GetSAS", "List", "ListSAS", "Purge", "Recover", "RegenerateKey", "Restore", "Set", "SetSAS", "Update", ]
  certificate_permissions = ["create", "delete", "deleteissuers", "get", "getissuers", "import", "list", "listissuers", "managecontacts", "manageissuers", "setissuers", "update", ]
}

resource "azurerm_key_vault_access_policy" "website_logs_storage_accesspolicy" { // This is for the Storage Account for Website Logs. 
  key_vault_id            = azurerm_key_vault.nscsecrets.id
  tenant_id               = data.azurerm_client_config.current.tenant_id
  object_id               = azurerm_storage_account.website_log_storage.identity[0].principal_id
  key_permissions         = ["get", "create", "delete", "list", "restore", "recover", "unwrapkey", "wrapkey", "purge", "encrypt", "decrypt", "sign", "verify", ]
  secret_permissions      = ["Backup", "Delete", "Get", "List", "Purge", "Recover", "Restore", "Set", ]
  certificate_permissions = ["create", "delete", "deleteissuers", "get", "getissuers", "import", "list", "listissuers", "managecontacts", "manageissuers", "setissuers", "update", ]
}

resource "azurerm_key_vault_access_policy" "website_installers_storage_accesspolicy" { // This is for the Storage Account for Website Logs. 
  depends_on = [
    azurerm_storage_container.website_installers_container
  ]
  key_vault_id            = azurerm_key_vault.secrets.id
  tenant_id               = data.azurerm_client_config.current.tenant_id
  object_id               = azurerm_storage_account.website_installers_account.identity[0].principal_id
  key_permissions         = ["get", "create", "delete", "list", "restore", "recover", "unwrapkey", "wrapkey", "purge", "encrypt", "decrypt", "sign", "verify", ]
  secret_permissions      = ["Backup", "Delete", "Get", "List", "Purge", "Recover", "Restore", "Set", ]
  certificate_permissions = ["create", "delete", "deleteissuers", "get", "getissuers", "import", "list", "listissuers", "managecontacts", "manageissuers", "setissuers", "update", ]
}

使用的提供者:

# Terraform Block
terraform {
  required_version = ">= 1.0"
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">= 2.0"
    }
    random = {
      source  = "hashicorp/random"
      version = ">= 3.0"
    }
  }
  #Terraform State Storage Account
  backend "azurerm" {}
}

# Providers Block
provider "azurerm" {
  features {}
}
provider "azuread" {
  tenant_id     = "VALUE"
  client_id     = "VALUE"
  client_secret = "VALUE"
}

provider "random" {}
provider "time" {}

# Random String Resource

resource "random_string" "myrandom" {
  length  = 6
  number  = false
  upper   = false
  special = false
}

标签: azureazure-devopsterraformazure-web-app-serviceterraform-provider-azure

解决方案


如果您要为您提供name = azurerm_storage_account.website_installers_account.id存储帐户块,则会出现以下错误。所以,你必须给它一个你想设置的名字WebsiteStorageConnectionString

在此处输入图像描述

对于您得到的第二个错误,因为我们无法在 Windows 应用服务上使用 Azure Blob,这是 Microsoft 端的限制,如本Microsoft 文档中所述。因此,作为一种解决方案,您可以kind = linux在应用服务计划块中使用或者,如果您不想更改类型,您可以创建文件共享并将其与应用服务一起使用。

在此处输入图像描述


解决方案:

  1. 创建文件共享而不是容器并使用 AzureFiles 而不是 Azure blob。
resource "azurerm_storage_account" "website_installers_account" { 
name                     = "nscwebstoredinstallersac"  
resource_group_name      =
data.azurerm_resource_group.Classroom_In_The_Cloud_Terraform.name  
location                 =
data.azurerm_resource_group.Classroom_In_The_Cloud_Terraform.location 
account_tier             = "Standard"   account_replication_type =
"LRS"   identity {
    type = "SystemAssigned"   } }

resource "azurerm_storage_share" "website_installers_share" {   name  
= "${var.website_name}-installersfileshare"   storage_account_name = azurerm_storage_account.website_installers_account.name   quota       
= 50 } 

在 Web App 中使用文件共享:

  storage_account {
    name         = "WebsiteStorageConnectionString"
    type         = "AzureFiles"
    account_name = azurerm_storage_account.website_installers_account.name
    access_key   = azurerm_storage_account.website_installers_account.primary_access_key
    share_name   = azurerm_storage_share.website_installers_share.name
    mount_path   = "/mounts/guides"#requires to be /mounts/
  }

输出:

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

  1. 如果要使用 AzureBlob,请将应用服务从 Windows 更改为 Linux。
resource "azurerm_app_service_plan" "websiteappserviceplan" {  
name = "appserviceplan-dgyn27h2dfoyojc"     
location =
data.azurerm_resource_group.Classroom_In_The_Cloud_Terraform.location 
resource_group_name =
data.azurerm_resource_group.Classroom_In_The_Cloud_Terraform.name   
kind = "Linux" # only necessary when you want to set linux otherwise
# it bydefault take windows    
reserved = true    
sku {
    tier = "Standard"
    size = "B1"    
}  
}   

您可以使用以下内容:

    storage_account {
    name         = "WebsiteStorageConnectionString"
    type         = "AzureBlob"
    account_name = azurerm_storage_account.website_installers_account.name
    access_key   = azurerm_storage_account.website_installers_account.primary_access_key
    share_name   = azurerm_storage_container.website_installers_container.name
    mount_path   = "/var/lib/guides"
  }

输出:

在此处输入图像描述

在此处输入图像描述


我用于测试的整体脚本:

provider "azurerm" {
  features {}
}
provider "random"{}
provider "time" {}
resource "random_string" "myrandom" {
  length  = 6
  number  = false
  upper   = false
  special = false
}
data "azurerm_client_config" "current"{}
data "azurerm_resource_group" "Classroom_In_The_Cloud_Terraform"{
    name="ansumantest"
}
variable "website_name" {
  default = "ansuman-app"
}

// This gets the Azure AD Tenant ID information to deploy for KeyVault. 
resource "azurerm_key_vault" "nscsecrets" {
  name                       = "${var.website_name}-${random_string.myrandom.id}"
  resource_group_name        = data.azurerm_resource_group.Classroom_In_The_Cloud_Terraform.name
  location                   = data.azurerm_resource_group.Classroom_In_The_Cloud_Terraform.location
  sku_name                   = "standard"
  tenant_id                  = data.azurerm_client_config.current.tenant_id
  soft_delete_retention_days = 7

}

resource "azurerm_key_vault_access_policy" "client" { // This is for AD Users Logged into Azure to give them the right access when creating resources. 
  key_vault_id        = azurerm_key_vault.nscsecrets.id
  tenant_id           = data.azurerm_client_config.current.tenant_id
  object_id           = data.azurerm_client_config.current.object_id
  secret_permissions  = ["Backup", "Delete", "Get", "List", "Purge", "Recover", "Restore", "Set", ]
  key_permissions     = ["Backup", "Create", "Decrypt", "Delete", "Encrypt", "Get", "Import", "List", "Purge", "Recover", "Restore", "Sign", "UnwrapKey", "Update", "Verify", "WrapKey", ]
  storage_permissions = ["Backup", "Delete", "DeleteSAS", "Get", "GetSAS", "List", "ListSAS", "Purge", "Recover", "RegenerateKey", "Restore", "Set", "SetSAS", "Update", ]
}


resource "azurerm_key_vault_access_policy" "website_accesspolicy" {
  key_vault_id       = azurerm_key_vault.nscsecrets.id
  tenant_id          = azurerm_app_service.website_app.identity[0].tenant_id
  object_id          = azurerm_app_service.website_app.identity[0].principal_id
  secret_permissions = ["get"]
}

resource "azurerm_key_vault_access_policy" "website_logs_storage_accesspolicy" { // This is for the Storage Account for Website Logs. 
  key_vault_id       = azurerm_key_vault.nscsecrets.id
  tenant_id          = data.azurerm_client_config.current.tenant_id
  object_id          = azurerm_storage_account.website_log_storage.identity[0].principal_id
  key_permissions    = ["get", "create", "delete", "list", "restore", "recover", "unwrapkey", "wrapkey", "purge", "encrypt", "decrypt", "sign", "verify", ]
  secret_permissions = ["Backup", "Delete", "Get", "List", "Purge", "Recover", "Restore", "Set", ]
}

resource "azurerm_key_vault_key" "website_logs_key" {
  name         = "website-logs-key"
  key_vault_id = azurerm_key_vault.nscsecrets.id

  key_type = "RSA"
  key_size = 2048
  key_opts = ["decrypt", "encrypt", "sign", "unwrapKey", "verify", "wrapKey", ]

  depends_on = [
    azurerm_key_vault_access_policy.client,
    azurerm_key_vault_access_policy.website_logs_storage_accesspolicy
  ]

}

resource "azurerm_storage_account" "website_log_storage" {
  name                     = "ansumanstorageacc12345"
  resource_group_name      = data.azurerm_resource_group.Classroom_In_The_Cloud_Terraform.name
  location                 = data.azurerm_resource_group.Classroom_In_The_Cloud_Terraform.location
  account_tier             = "Standard"
  account_replication_type = "GRS"

  identity {
    type = "SystemAssigned"
  }
}

resource "azurerm_storage_container" "website_logs_container" {
  name                  = "${var.website_name}-cont"
  storage_account_name  = azurerm_storage_account.website_log_storage.name
}
resource "time_rotating" "main" {
  rotation_rfc3339 = null
  rotation_years   = 2

  triggers = {
    end_date = null
    years    = 2
  }
}

data "azurerm_storage_account_blob_container_sas" "website_logs_container_sas" {
  connection_string = azurerm_storage_account.website_log_storage.primary_connection_string
  container_name    = azurerm_storage_container.website_logs_container.name


  start  = timestamp()
  expiry = time_rotating.main.rotation_rfc3339

  permissions {
    read   = true
    add    = true
    create = true
    write  = true
    delete = true
    list   = true
  }

  cache_control       = "max-age=5"
  content_disposition = "inline"
  content_encoding    = "deflate"
  content_language    = "en-US"
  content_type        = "application/json"
}
resource "azurerm_storage_account" "website_installers_account" {
  name                     = "nscwebstoredinstallersac"
  resource_group_name      = data.azurerm_resource_group.Classroom_In_The_Cloud_Terraform.name
  location                 = data.azurerm_resource_group.Classroom_In_The_Cloud_Terraform.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
  identity {
    type = "SystemAssigned"
  }
}


resource "azurerm_storage_container" "website_installers_container" {#for linux app
  depends_on = [
    azurerm_storage_account.website_installers_account
  ]
  name                  = "${var.website_name}-installerscont"
  storage_account_name  = azurerm_storage_account.website_installers_account.name
  container_access_type = "private"
}

/*
## This Should be used for Windows App Service instead of container
resource "azurerm_storage_share" "website_installers_share" {
  name                 = "${var.website_name}-installersfileshare"
  storage_account_name = azurerm_storage_account.website_installers_account.name
  quota                = 50
}
*/
resource "azurerm_app_service_plan" "websiteappserviceplan" {
  name                = "appserviceplan-dgyn27h2dfoyojc"
  location            = data.azurerm_resource_group.Classroom_In_The_Cloud_Terraform.location
  resource_group_name = data.azurerm_resource_group.Classroom_In_The_Cloud_Terraform.name
  kind = "Linux" # only necessary when you want to set linux otherwise it bydefault take windows
reserved = true

  sku {
    tier = "Standard"
    size = "B1"
  }
}

resource "azurerm_app_service" "website_app" {
  name                = var.website_name
  location            = data.azurerm_resource_group.Classroom_In_The_Cloud_Terraform.location
  resource_group_name = data.azurerm_resource_group.Classroom_In_The_Cloud_Terraform.name
  app_service_plan_id = azurerm_app_service_plan.websiteappserviceplan.id

  app_settings = {
    "KEY_VAULT_URL"                        = azurerm_key_vault.nscsecrets.vault_uri
  }

  site_config {
  always_on = true
  dotnet_framework_version = "v5.0"
  app_command_line         = "dotnet EventManagement.Web.dll"
  
  }
  # this is for linux app
    storage_account {
    name         = "WebsiteStorageConnectionString"
    type         = "AzureBlob"
    account_name = azurerm_storage_account.website_installers_account.name
    access_key   = azurerm_storage_account.website_installers_account.primary_access_key
    share_name   = azurerm_storage_container.website_installers_container.name
    mount_path   = "/var/lib/guides" 
  }
  /*
  # this is for Wnidows App
  storage_account {
    name         = "WebsiteStorageConnectionString"
    type         = "AzureFiles"
    account_name = azurerm_storage_account.website_installers_account.name
    access_key   = azurerm_storage_account.website_installers_account.primary_access_key
    share_name   = azurerm_storage_share.website_installers_share.name
    mount_path   = "/mounts/guides" #requires to be /mounts/
  }
  */
  logs{
    detailed_error_messages_enabled = true
    failed_request_tracing_enabled = true
    application_logs {
      azure_blob_storage {
        level="Information"
        sas_url = format("https://${azurerm_storage_account.website_log_storage.name}.blob.core.windows.net/${azurerm_storage_container.website_logs_container.name}%s", data.azurerm_storage_account_blob_container_sas.website_logs_container_sas.sas)
        retention_in_days = 365
      }
    }
    http_logs {
      azure_blob_storage{
        sas_url=format("https://${azurerm_storage_account.website_log_storage.name}.blob.core.windows.net/${azurerm_storage_container.website_logs_container.name}%s", data.azurerm_storage_account_blob_container_sas.website_logs_container_sas.sas)
        retention_in_days = 365
      }
    }
  }

  connection_string {
    name  = "StorageAccount"
    type  = "Custom"
    value = azurerm_storage_account.website_log_storage.primary_connection_string
  }

  identity {
    type = "SystemAssigned"
  }
}

推荐阅读