Служба приложений Terraform не будет подключаться к учетной записи хранения

#azure #azure-devops #terraform #azure-web-app-service #terraform-provider-azure

Вопрос:

В 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

Тем не менее, мои ошибки, и я думаю, что это связано с ключом, я сначала попытался сделать это с помощью ключа, управляемого клиентом, затем источника данных, и теперь я просто очень запутался в том, как на самом деле заставить это работать.

И снова документы по терраформированию в лучшем случае ограничены.

Вот мой код:

Код приложения для веб-сайта:

 resource "azurerm_app_service" "website_app" {
  name                = var.website_name
  location            = azurerm_resource_group.Classroom_In_The_Cloud_Terraform.location
  resource_group_name = 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"

  }

  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.Classroom_In_The_Cloud_Terraform.name
  location                 = azurerm_resource_group.Classroom_In_The_Cloud_Terraform.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.Classroom_In_The_Cloud_Terraform.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.nscsecrets.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 Message:

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

UPDATE

I have been messing about with this all day,according to this website: https://github.com/kumarvna/terraform-azurerm-app-service

The Storage Name should be the identifier. Which I have changed and get a new error message that states the following:

 Error: updating Storage Accounts for App Service "nsclassroom-dgyn27h2dfoyojc": 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/3b92ad75-8bb4-44a3-92df-394bc15085ef/resourceGroups/Classroom_In_The_Cloud_Terraform/providers/Microsoft.Storage/storageAccounts/nscwebstoredinstallersac","MessageTemplate":"{0} is invalid.  {1}","Parameters":["AzureStoragePropertyDictionary","ID in AzureStoragePropertyDictionary contains invalid characters: /subscriptions/3b92ad75-8bb4-44a3-92df-394bc15085ef/resourceGroups/Classroom_In_The_Cloud_Terraform/providers/Microsoft.Storage/storageAccounts/nscwebstoredinstallersac"]}}] 

It sort of makes sense for the Storage Name to be the Identifier of the Storage account as why would you specify the name twice?

The storage account successfully writes its key that the web site config uses to the Key Vault so that does work. Its just the App Service just cant communicate with the storage account. Its driving me insane.

I have also done a complete destroy and reapply of the env changed my state file tried a whole new subscription. Error Still comes around.

Please see updated code bellow. Thank you.

Website Update Code:

 resource "azurerm_app_service_plan" "websiteappserviceplan" {
  name                = "appserviceplan-dgyn27h2dfoyojc"
  location            = azurerm_resource_group.Classroom_In_The_Cloud_Terraform.location
  resource_group_name = azurerm_resource_group.Classroom_In_The_Cloud_Terraform.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.Classroom_In_The_Cloud_Terraform.location
  resource_group_name = 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"

  }

  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.Guides_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"
  }
} 

Storage Account Update Code:

 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.Classroom_In_The_Cloud_Terraform.name
  location                 = azurerm_resource_group.Classroom_In_The_Cloud_Terraform.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.Classroom_In_The_Cloud_Terraform.name
  location                 = azurerm_resource_group.Classroom_In_The_Cloud_Terraform.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"
} 

As I am now passing the Access Key for the storage account Via Key Vault I have now included the Key Vault Code:

 // Users amp; Groups which I want to give permissions to be able to access the keyvault.
data "azuread_user" "user" {
  user_principal_name = "J.Content@netsupportsoftware.com"
}

data "azuread_group" "Classroom_In_The_Cloud_AZ_AD_Group" {
  display_name     = "NSL Development Dept"
  security_enabled = true
}

// This gets the Azure AD Tenant ID information to deploy for KeyVault. 
resource "azurerm_key_vault" "nscsecrets" {
  name                       = "${var.key_vault_name}-${random_string.myrandom.id}"
  resource_group_name        = azurerm_resource_group.Classroom_In_The_Cloud_Terraform.name
  location                   = 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
  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.nscsecrets.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
} 

Комментарии:

1. Пожалуйста, обновите свой вопрос сообщением об ошибке и другой соответствующей информацией.

2. Обновлено сообщение об ошибке было ли что-то еще, что вы хотели увидеть?

3. Здравствуйте @Jason, могу я узнать, присутствует ли контейнер «направляющие» в учетной записи хранения «nscwebstoredinstallersac»?

4. Как я вижу, контейнер, который вы добавили в код, имеет имя «${var.website_name}-installerscont».

5. да, это проблема? Он назвал его и создал контейнер, когда я его применил.

Ответ №1:

Если вы name = azurerm_storage_account.website_installers_account.id блокируете учетную запись хранения для своей учетной записи, это приведет к следующей ошибке . Таким образом , вы должны дать ему имя только то, которое вы хотите установить как WebsiteStorageConnectionString .

введите описание изображения здесь

И вторая ошибка, которую вы получите, как показано ниже, потому что мы не можем использовать Azure Blob-объектов на платформе Windows приложения сервис ,это ограничение от Microsoft конца, как указано в этой документации Майкрософт.Так, в качестве решения можно использовать kind = linux в службе приложений плана заблокировать или вы можете создать файл и используйте это приложение с сервисом, если вы не хотите, чтобы изменить вид.

введите описание изображения здесь


Решения:

  1. Создание общего файлового ресурса вместо контейнера и использование AzureFiles вместо больших двоичных объектов Azure.
 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 } 
 

Использование общего доступа к файлам в веб-приложении:

   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. Измените службу приложений с Windows на Linux, если вы хотите использовать AzureBlob.
 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"
  }
}