Gunakan referensi Key Vault sebagai pengaturan aplikasi di Azure App Service dan Azure Functions

Artikel ini memperlihatkan kepada Anda cara menggunakan rahasia dari Azure Key Vault sebagai nilai pengaturan aplikasi atau string koneksi di aplikasi App Service atau Azure Functions Anda.

Azure Key Vault adalah layanan yang menyediakan manajemen rahasia terpusat, dengan kontrol penuh atas kebijakan akses dan riwayat audit. Saat pengaturan aplikasi atau string koneksi adalah referensi brankas kunci, kode aplikasi Anda dapat menggunakannya seperti pengaturan aplikasi atau string koneksi lainnya. Dengan cara ini, Anda dapat mempertahankan rahasia selain konfigurasi aplikasi Anda. Pengaturan aplikasi dienkripsi dengan aman saat tidak aktif, tetapi jika Anda memerlukan kemampuan manajemen rahasia, pengaturan tersebut harus masuk ke brankas kunci.

Memberikan akses aplikasi Anda ke brankas kunci

Untuk membaca rahasia dari brankas kunci, Anda harus membuat brankas dan memberi aplikasi Anda izin untuk mengaksesnya.

  1. Buat key vault dengan mengikuti mulai cepat Vault Kunci.

  2. Buat identitas terkelola untuk aplikasi Anda.

    Referensi brankas kunci menggunakan identitas yang ditetapkan sistem aplikasi secara default, tetapi Anda dapat menentukan identitas yang ditetapkan pengguna.

  3. Otorisasi akses baca ke rahasia brankas kunci Anda untuk identitas terkelola yang Anda buat sebelumnya. Cara Anda melakukannya tergantung pada model izin brankas kunci Anda:

Mengakses vault yang dibatasi jaringan

Jika vault Anda dikonfigurasi dengan pembatasan jaringan, pastikan bahwa aplikasi memiliki akses jaringan. Vault tidak boleh bergantung pada IP keluar publik aplikasi karena IP asal permintaan rahasia bisa berbeda. Sebagai gantinya, vault harus dikonfigurasi untuk menerima lalu lintas dari jaringan virtual yang digunakan oleh aplikasi.

  1. Pastikan aplikasi mengonfigurasi kemampuan jaringan keluar, seperti yang dijelaskan dalam fitur jaringan App Service dan opsi jaringan Azure Functions.

    Aplikasi Linux yang terhubung ke titik akhir privat harus dikonfigurasi secara eksplisit untuk merutekan semua lalu lintas melalui jaringan virtual. Persyaratan ini akan dihapus dalam pembaruan yang akan datang. Untuk mengonfigurasi pengaturan ini, jalankan perintah berikut:

    az webapp config set --subscription <sub> -g <group-name> -n <app-name> --generic-configurations '{"vnetRouteAllEnabled": true}'
    
  2. Pastikan konfigurasi vault memungkinkan jaringan atau subnet yang digunakan aplikasi Anda untuk mengaksesnya.

Mengakses brankas dengan identitas yang ditetapkan pengguna

Beberapa aplikasi perlu mereferensikan rahasia pada waktu pembuatan, saat identitas yang ditetapkan sistem belum tersedia. Dalam kasus ini, identitas yang ditetapkan pengguna dapat dibuat dan diberikan akses ke brankas terlebih dahulu.

Setelah Anda memberikan izin ke identitas yang ditetapkan oleh pengguna, ikuti langkah-langkah berikut:

  1. Tetapkan identitas ke aplikasi Anda, jika Anda belum melakukannya.

  2. Konfigurasikan aplikasi untuk menggunakan identitas ini untuk operasi referensi brankas kunci dengan mengatur keyVaultReferenceIdentity properti ke ID sumber daya identitas yang ditetapkan pengguna.

    identityResourceId=$(az identity show --resource-group <group-name> --name <identity-name> --query id -o tsv)
    az webapp update --resource-group <group-name> --name <app-name> --set keyVaultReferenceIdentity=${identityResourceId}
    

Pengaturan ini berlaku untuk semua referensi brankas kunci untuk aplikasi.

Rotasi

Jika versi rahasia tidak ditentukan dalam referensi, aplikasi menggunakan versi terbaru yang ada di brankas kunci. Saat versi yang lebih baru tersedia, seperti dengan peristiwa rotasi, aplikasi secara otomatis memperbarui dan mulai menggunakan versi terbaru dalam waktu 24 jam. Penundaan ini disebabkan karena App Service menyimpan nilai referensi brankas kunci dan mengambilnya kembali setiap 24 jam. Setiap perubahan konfigurasi pada aplikasi menyebabkan aplikasi dimulai ulang dan pengambilan ulang langsung dari semua rahasia yang direferensikan.

Pengaturan aplikasi sumber dari brankas kunci

Untuk menggunakan referensi brankas kunci, atur referensi sebagai nilai pengaturan. Aplikasi Anda dapat mereferensikan rahasia melalui kuncinya seperti biasa. Tidak ada perubahan kode yang diperlukan.

Tip

Sebagian besar pengaturan aplikasi yang menggunakan referensi brankas kunci harus ditandai sebagai pengaturan slot, karena Anda harus memiliki vault terpisah untuk setiap lingkungan.

Referensi brankas kunci adalah formulir @Microsoft.KeyVault({referenceString}), di mana {referenceString} berada dalam salah satu format berikut:

String referensi Deskripsi
SecretUri=secretUri SecretUri harus menjadi URI bidang data lengkap dari rahasia di brankas, secara opsional termasuk versi, misalnya, https://myvault.vault.azure.net/secrets/mysecret/ atauhttps://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931
VaultName=vaultName;SecretName=secretName;SecretVersion=secretVersion VaultName diperlukan dan merupakan nama vault. SecretName diperlukan dan merupakan nama rahasia. SecretVersion bersifat opsional, tetapi jika ada menunjukkan versi rahasia yang akan digunakan.

Misalnya, referensi lengkap akan terlihat seperti string berikut:

@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/)

Atau:

@Microsoft.KeyVault(VaultName=myvault;SecretName=mysecret)

Pertimbangan untuk pemasangan Azure Files

Aplikasi dapat menggunakan WEBSITE_CONTENTAZUREFILECONNECTIONSTRING pengaturan aplikasi untuk memasang Azure Files sebagai sistem file. Pengaturan ini memiliki pemeriksaan validasi untuk memastikan bahwa aplikasi dapat dimulai dengan benar. Platform ini mengandalkan berbagi konten dalam Azure Files, dan menerima nama default kecuali satu yang ditentukan melalui pengaturan WEBSITE_CONTENTSHARE. Untuk setiap permintaan yang mengubah pengaturan ini, platform memvalidasi apakah berbagi konten ini ada, dan mencoba membuatnya jika tidak. Jika tidak dapat menemukan atau membuat berbagi konten, itu memblokir permintaan.

Saat Anda menggunakan referensi brankas kunci dalam pengaturan ini, pemeriksaan validasi gagal secara default, karena rahasia itu sendiri tidak dapat diselesaikan saat memproses permintaan masuk. Untuk menghindari masalah ini, Anda dapat melompati validasi dengan mengatur WEBSITE_SKIP_CONTENTSHARE_VALIDATION ke "1". Pengaturan ini memberi tahu App Service untuk melewati semua pemeriksaan, dan tidak membuat berbagi konten untuk Anda. Anda harus memastikan bahwa itu dibuat terlebih dahulu.

Perhatian

Jika Anda melompati validasi dan string koneksi atau berbagi konten tidak valid, aplikasi tidak akan dapat memulai dengan benar dan hanya akan menampilkan kesalahan HTTP 500.

Sebagai bagian dari pembuatan aplikasi, upaya pemasangan berbagi konten dapat gagal karena izin identitas terkelola tidak disebarluaskan atau integrasi jaringan virtual tidak disiapkan. Anda dapat menunda pengaturan Azure Files hingga nanti di templat penyebaran untuk mengakomodasi ini. Lihat Penyebaran Azure Resource Manager untuk mempelajari selengkapnya. Dalam hal ini, App Service menggunakan sistem file default hingga Azure Files disiapkan, dan file tidak disalin. Anda harus memastikan bahwa tidak ada upaya penyebaran yang terjadi selama periode sementara sebelum Azure Files dipasang.

Pertimbangan untuk instrumentasi Application Insights

Aplikasi dapat menggunakan APPINSIGHTS_INSTRUMENTATIONKEY pengaturan aplikasi atau APPLICATIONINSIGHTS_CONNECTION_STRING untuk diintegrasikan dengan Application Insights. Pengalaman portal untuk App Service dan Azure Functions juga menggunakan pengaturan ini untuk menampilkan data telemetri dari sumber daya. Jika nilai-nilai ini dirujuk dari Key Vault, pengalaman ini tidak tersedia, dan Anda perlu bekerja langsung dengan sumber daya Application Insights untuk melihat telemetri. Namun, nilai-nilai ini tidak dianggap sebagai rahasia, jadi Anda mungkin mempertimbangkan untuk mengonfigurasinya secara langsung alih-alih menggunakan referensi brankas kunci.

Penyebaran Azure Resource Manager

Saat mengotomatiskan penyebaran sumber daya melalui templat Azure Resource Manager, Anda mungkin perlu mengurutkan dependensi Anda dalam urutan tertentu agar fitur ini berfungsi. Pastikan untuk menentukan pengaturan aplikasi Anda sebagai sumber dayanya sendiri, daripada menggunakan siteConfig properti dalam definisi aplikasi. Ini karena aplikasi perlu didefinisikan terlebih dahulu sehingga identitas yang ditetapkan sistem dibuat dengannya dan dapat digunakan dalam kebijakan akses.

Pseudo-template berikut adalah contoh seperti apa aplikasi fungsi:

{
    //...
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[variables('storageAccountName')]",
            //...
        },
        {
            "type": "Microsoft.Insights/components",
            "name": "[variables('appInsightsName')]",
            //...
        },
        {
            "type": "Microsoft.Web/sites",
            "name": "[variables('functionAppName')]",
            "identity": {
                "type": "SystemAssigned"
            },
            //...
            "resources": [
                {
                    "type": "config",
                    "name": "appsettings",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
                        "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                        "[resourceId('Microsoft.KeyVault/vaults/secrets', variables('keyVaultName'), variables('storageConnectionStringName'))]",
                        "[resourceId('Microsoft.KeyVault/vaults/secrets', variables('keyVaultName'), variables('appInsightsKeyName'))]"
                    ],
                    "properties": {
                        "AzureWebJobsStorage": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('storageConnectionStringName')).secretUriWithVersion, ')')]",
                        "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('storageConnectionStringName')).secretUriWithVersion, ')')]",
                        "APPINSIGHTS_INSTRUMENTATIONKEY": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('appInsightsKeyName')).secretUriWithVersion, ')')]",
                        "WEBSITE_ENABLE_SYNC_UPDATE_SITE": "true"
                        //...
                    }
                },
                {
                    "type": "sourcecontrols",
                    "name": "web",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
                        "[resourceId('Microsoft.Web/sites/config', variables('functionAppName'), 'appsettings')]"
                    ],
                }
            ]
        },
        {
            "type": "Microsoft.KeyVault/vaults",
            "name": "[variables('keyVaultName')]",
            //...
            "dependsOn": [
                "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]"
            ],
            "properties": {
                //...
                "accessPolicies": [
                    {
                        "tenantId": "[reference(resourceId('Microsoft.Web/sites/', variables('functionAppName')), '2020-12-01', 'Full').identity.tenantId]",
                        "objectId": "[reference(resourceId('Microsoft.Web/sites/', variables('functionAppName')), '2020-12-01', 'Full').identity.principalId]",
                        "permissions": {
                            "secrets": [ "get" ]
                        }
                    }
                ]
            },
            "resources": [
                {
                    "type": "secrets",
                    "name": "[variables('storageConnectionStringName')]",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                        "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
                    ],
                    "properties": {
                        "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountResourceId'),'2019-09-01').key1)]"
                    }
                },
                {
                    "type": "secrets",
                    "name": "[variables('appInsightsKeyName')]",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                        "[resourceId('Microsoft.Insights/components', variables('appInsightsName'))]"
                    ],
                    "properties": {
                        "value": "[reference(resourceId('microsoft.insights/components/', variables('appInsightsName')), '2019-09-01').InstrumentationKey]"
                    }
                }
            ]
        }
    ]
}

Catatan

Dalam contoh ini, penyebaran kontrol sumber bergantung pada pengaturan aplikasi. Perilaku ini biasanya tidak aman, karena pembaruan pengaturan aplikasi berperilaku asinkron. Namun, karena kita sudah menyertakan pengaturan aplikasi WEBSITE_ENABLE_SYNC_UPDATE_SITE, pembaruannya sinkron. Artinya penyebaran kontrol sumber hanya akan dimulai setelah pengaturan aplikasi sudah diperbarui sepenuhnya. Untuk pengaturan aplikasi lainnya, lihat Variabel lingkungan dan pengaturan aplikasi di Azure App Service.

Pemecahan masalah referensi brankas kunci

Jika referensi tidak diselesaikan dengan benar, string referensi digunakan sebagai gantinya (misalnya, @Microsoft.KeyVault(...)). Ini dapat menyebabkan aplikasi melemparkan kesalahan, karena mengharapkan rahasia nilai yang berbeda.

Kegagalan untuk mengatasi umumnya disebabkan oleh kesalahan konfigurasi kebijakan akses Key Vault. Namun, ini juga bisa disebabkan oleh rahasia yang tidak lagi tersedia atau kesalahan sintaks dalam referensi itu sendiri.

Jika sintaks benar, Anda dapat melihat penyebab kesalahan lainnya dengan memeriksa status resolusi saat ini di portal. Buka Pengaturan Aplikasi dan pilih "Edit" untuk referensi yang dimaksud. Dialog edit memperlihatkan informasi status, termasuk kesalahan apa pun. Jika Anda tidak melihat pesan status, itu berarti sintaksnya tidak valid dan tidak dikenali sebagai referensi brankas kunci.

Anda juga dapat menggunakan salah satu detektor bawaan untuk mendapatkan informasi tambahan.

Menggunakan detektor untuk App Service

  1. Di portal, navigasi ke aplikasi Anda.
  2. Pilih Diagnosis dan selesaikan masalah.
  3. Pilih Ketersediaan dan Performa dan pilih Aplikasi web tidak berfungsi.
  4. Dalam kotak pencarian, cari dan pilih Key Vault Diagnostik Pengaturan Aplikasi.

Menggunakan detektor untuk Azure Functions

  1. Di portal, navigasi ke aplikasi Anda.
  2. Navigasi ke fitur Platform.
  3. Pilih Diagnosis dan selesaikan masalah.
  4. Pilih Ketersediaan dan Performa dan pilih Aplikasi fungsi tidak berfungsi atau melaporkan kesalahan.
  5. Pilih Key Vault Diagnostik Pengaturan Aplikasi.