Terraform App Service 无法连接到存储帐户
Terraform App Service wont connect to Storage account
在 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 文档再一次充其量是有限的。
这是我的代码:
网站应用代码:
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"]}}]
将存储名称作为存储帐户的标识符是有道理的,因为为什么要指定两次名称?
存储帐户成功地将网站配置使用的密钥写入密钥保管库,这样就可以正常工作了。它只是应用程序服务无法与存储帐户通信。它让我发疯。
我也完全销毁并重新应用了 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
}
如果您在存储帐户块中为您提供 name = azurerm_storage_account.website_installers_account.id
,则会出现以下错误。所以,你只需要给它一个你想设置的名字,比如 WebsiteStorageConnectionString
.
由于我们无法在 Windows 应用服务上使用 Azure Blob,因此您得到的第二个错误如下所示,这是 Microsoft Document 中提到的 Microsoft 端的限制。所以,作为解决方案,您可以在应用服务计划块中使用 kind = linux
,或者如果您不想更改类型,可以创建文件共享并将其与应用服务一起使用。
解决方案:
- 创建文件共享而不是容器并使用 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 }
Using the file Share in 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/
}
Outputs:
- 如果要使用 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"
}
}
And you can use the below:
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"
}
Outputs:
我用于测试的整体脚本:
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"
}
}
在 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 文档再一次充其量是有限的。
这是我的代码:
网站应用代码:
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"]}}]
将存储名称作为存储帐户的标识符是有道理的,因为为什么要指定两次名称?
存储帐户成功地将网站配置使用的密钥写入密钥保管库,这样就可以正常工作了。它只是应用程序服务无法与存储帐户通信。它让我发疯。
我也完全销毁并重新应用了 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
}
如果您在存储帐户块中为您提供 name = azurerm_storage_account.website_installers_account.id
,则会出现以下错误。所以,你只需要给它一个你想设置的名字,比如 WebsiteStorageConnectionString
.
由于我们无法在 Windows 应用服务上使用 Azure Blob,因此您得到的第二个错误如下所示,这是 Microsoft Document 中提到的 Microsoft 端的限制。所以,作为解决方案,您可以在应用服务计划块中使用 kind = linux
,或者如果您不想更改类型,可以创建文件共享并将其与应用服务一起使用。
解决方案:
- 创建文件共享而不是容器并使用 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 }
Using the file Share in 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/ }
Outputs:
- 如果要使用 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" } }
And you can use the below:
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" }
Outputs:
我用于测试的整体脚本:
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"
}
}