Azure Web App with Managed Identity to access Azure Open AI

如何使用 Web App 的 Managed Identity 存取 Azure Open AI 的服務?

Why?

因為用 Managed Identity 即可以不用使用 KEY 來存取 Azure Open AI, 不使用 KEY 也就不用煩惱要如何保護及定時更換 KEY.

How?

3 Stpes:

Step 1. 設定 Web App 使用 Managed Identity

Step 2. 設定 Web App 的 Managed Identity 可以存取 特定的 Azure Open AI 服務

Step 3. 程式碼中使用 Managed Identity 存取特定的 Azure Open AI 服務

詳細的說明:

Step 1. 設定 Web App 使用 Managed Identity

建議先使用 System assigned identity , 設定方式如下:
Web App -> Identity -> 啟用 System assigned identity

參考資訊: https://learn.microsoft.com/en-us/azure/app-service/overview-managed-identity?tabs=portal%2Cpython#add-a-system-assigned-identity

Step 2. 設定 Web App 的 Managed Identity 可以存取 特定的 Azure Open AI 服務

這裡特別注意是把 Web App 的 System assigned identity 加入 特定 Azure Open AI 服務的 Cognitive Services User 角色

參考資訊: https://learn.microsoft.com/en-us/azure/cognitive-services/openai/how-to/managed-identity#assign-yourself-to-the-cognitive-services-user-role

Step 3. 程式碼中使用 Managed Identity 存取特定的 Azure Open AI 服務

我的範例程式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
from azure.identity import DefaultAzureCredential
import openai
import os
import requests
import json
from datetime import datetime
from flask import Flask, render_template, request, redirect, url_for, send_from_directory
app = Flask(__name__)

@app.route('/')
def index():
print('Request for index page received')
return render_template('index.html')

@app.route('/favicon.ico')
def favicon():
return send_from_directory(os.path.join(app.root_path, 'static'),
'favicon.ico', mimetype='image/vnd.microsoft.icon')

@app.route('/hello', methods=['POST'])
def hello():
name = request.form.get('name')

if name:
# Request credential
default_credential = DefaultAzureCredential()
token = default_credential.get_token("https://cognitiveservices.azure.com/.default")

# Setup parameters
openai.api_type = "azure_ad"
openai.api_key = token.token
openai.api_base = "https://jackyopenai001.openai.azure.com/"
openai.api_version = "2022-12-01"
deployment_name='text-davinci-003' #This will correspond to the custom name you chose for your deployment when you deployed a model.

# Send a completion call to generate an answer
print('Sending a test completion job')
start_phrase = 'Write a tagline for an ice cream shop. '
response = openai.Completion.create(engine=deployment_name, prompt=start_phrase, max_tokens=10)
text = response['choices'][0]['text'].replace('\n', '').replace(' .', '.').strip()
print(start_phrase+text)

print('Request for hello page received with name=%s' % text)
return render_template('hello.html', name = text)
else:
print('Request for hello page received with no name or blank name -- redirecting')
return redirect(url_for('index'))


if __name__ == '__main__':
app.run()

參考資訊:
https://github.com/openai/openai-python#microsoft-azure-active-directory-authentication (特別感謝同事 Jimmy Liao 提供這個重要的資訊讓我可以快速完成.)

https://learn.microsoft.com/zh-tw/azure/app-service/quickstart-python?tabs=flask%2Cwindows%2Cazure-cli%2Clocal-git-deploy%2Cdeploy-instructions-azportal%2Cterminal-bash%2Cdeploy-instructions-zip-azcli#1---sample-application

範例程式執行後的結果將 Azure Open AI 回覆的資訊顯示在網頁上.

HTH. 20230305 By Jacky