티스토리 뷰
[azure] Application gateway와 private endpoint를 활용한 Open AI 연동
Hayley Shim 2025. 9. 28. 17:04안녕하세요, 최근 Azure의 Application gateway와 Private Endpoint를 활용해 Open AI 서비스를 연동한 내용을 간단히 설명합니다.
[요구사항]
외부 SaaS 서비스에서 도메인을 통해 Azure의 Open AI 서비스를 안정적으로 사용
[테스트 구성]
1. Network 구성
- Network Subscription과 서비스(DEV/STG/PRD)용 Subscription을 분리하여 Peering으로 연결 구성
- Open AI의 특정 모델의 경우 East US 2 리전에 출시되어 East US 리전에 vNet을 구성하여 Global Peering으로 구성
- Network Subscription과 서비스(DEV/STG/PRD)용 Subscription 간에는 Private Endpoint를 통해 연결하여 보안적으로 안정적인 통신이 가능하도록 구성
2. Application Gateway 구성
- Routing Rule의 Path based Rule을 적용하여 리전 별로 Open AI 서비스 호출 시 구분되도록 구성
- WAF 정책을 적용하여 특정 IP만 접속가능하도록 Whitelist 적용
3. 추가 고려사항
- 도메인 적용 시 SSL 적용을 위해 Host 단위로 서비스를 구분하려면 Wildcard 인증서를 적용할 필요가 있음
(단일 인증서를 적용하여 Path로 구분할 경우 rewrite rule 적용 등에서 이슈 발생 시 트러블슈팅 등 운영관리 어려움 발생될 수 있음)
Azure 유의사항
- 인증서 내 Key vault 적용 시 포탈에서 적용되지 않는 경우가 있어 Azure CLI, Powershell 등의 명령어를 통해 적용해야함
[테스트 결과]
- REST API 호출 : 배포된 리소스의 특정 엔드포인트 URL에 배포 이름을 경로 변수나 쿼리 매개변수로 포함하여 HTTP 요청
curl -vk "https://test.com/openai/deployments/gptTestkr/chat/completions?api-version=2025-01-01-preview" \
-H "Content-Type: application/json" \
-H "api-key: XXXXXXXXXXX" \
-d '{"messages":[{"role":"user","content":"Hello KRC"}]}'
* Host cns-hub.com:443 was resolved.
* IPv6: (none)
* IPv4: 4.230.64.34
* Trying 4.230.64.34:443...
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / x25519 / RSASSA-PSS
* ALPN: server accepted h2
* Server certificate:
* subject: CN=test.com
* start date: Sep 25 09:47:07 2025 GMT
* expire date: Sep 25 09:47:07 2026 GMT
* issuer: C=US; ST=Arizona; L=Scottsdale; O=GoDaddy.com, Inc.; OU=http://certs.godaddy.com/repository/; CN=Go Daddy Secure Certificate Authority - G2
* SSL certificate verify result: self-signed certificate in certificate chain (19), continuing anyway.
* Certificate level 0: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* Certificate level 1: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* Certificate level 2: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* Connected to test.com (4.230.64.34) port 443
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://test.com/openai/deployments/gptTestkr/chat/completions?api-version=2025-01-01-preview
* [HTTP/2] [1] [:method: POST]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: test.com]
* [HTTP/2] [1] [:path: /openai/deployments/gptTestkr/chat/completions?api-version=2025-01-01-preview]
* [HTTP/2] [1] [user-agent: curl/8.11.1]
* [HTTP/2] [1] [accept: */*]
* [HTTP/2] [1] [content-type: application/json]
* [HTTP/2] [1] [api-key: XXXXXXXXXXXXX]
* [HTTP/2] [1] [content-length: 52]
> POST /openai/deployments/gptTestkr/chat/completions?api-version=2025-01-01-preview HTTP/2
> Host: test.com
> User-Agent: curl/8.11.1
> Accept: */*
> Content-Type: application/json
> api-key: XXXXXXXXXXX
> Content-Length: 52
>
* upload completely sent off: 52 bytes
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/2 200
< date: Sun, 28 Sep 2025 07:46:00 GMT
< content-type: application/json
< content-length: 1246
< apim-request-id: aeb096fc-8d5f-4eb2-ab48-af49816b40d0
< strict-transport-security: max-age=31536000; includeSubDomains; preload
< x-content-type-options: nosniff
< x-ms-region: Korea Central
< x-ratelimit-remaining-requests: 249
< x-ratelimit-limit-requests: 250
< x-ratelimit-remaining-tokens: 249997
< x-ratelimit-limit-tokens: 250000
< azureml-model-session: d097-20250926132639
< x-ms-rai-invoked: true
< x-request-id: a2ccbd9a-75fb-41a3-b822-459987625eaa
< x-ms-deployment-name: gptTestkr
<
{"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"protected_material_code":{"filtered":false,"detected":false},"protected_material_text":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"finish_reason":"stop","index":0,"logprobs":null,"message":{"annotations":[],"content":"Hello! How can I assist you today?","refusal":null,"role":"assistant"}}],"created":1759045560,"id":"chatcmpl-CKgOWsFWaHE6IHV2AUFduAFgDb31g","model":"gpt-4.1-mini-2025-04-14","object":"chat.completion","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"system_fingerprint":"fp_c82f8028fa","usage":{"completion_tokens":10,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens":10,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":20}}
* Connection #0 to host test.com left intact
curl -vk "https://test.com/eastus2/openai/deployments/gpt-4o-mini/chat/completions?api-version=2025-01-01-preview" \
-H "Content-Type: application/json" \
-H "api-key: XXXXXXXXXXXXXXXXXXXXX" \
-d '{
"messages":[{"role":"user","content":"Hello via AGW"}],
"max_tokens":20
}'
* Host test.com:443 was resolved.
* IPv6: (none)
* IPv4: 4.230.64.34
* Trying 4.230.64.34:443...
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / x25519 / RSASSA-PSS
* ALPN: server accepted h2
* Server certificate:
* subject: CN=test.com
* start date: Sep 25 09:47:07 2025 GMT
* expire date: Sep 25 09:47:07 2026 GMT
* issuer: C=US; ST=Arizona; L=Scottsdale; O=GoDaddy.com, Inc.; OU=http://certs.godaddy.com/repository/; CN=Go Daddy Secure Certificate Authority - G2
* SSL certificate verify result: self-signed certificate in certificate chain (19), continuing anyway.
* Certificate level 0: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* Certificate level 1: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* Certificate level 2: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* Connected to test.com (4.230.64.34) port 443
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://test.com/eastus2/openai/deployments/gpt-4o-mini/chat/completions?api-version=2025-01-01-preview
* [HTTP/2] [1] [:method: POST]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: test.com]
* [HTTP/2] [1] [:path: /eastus2/openai/deployments/gpt-4o-mini/chat/completions?api-version=2025-01-01-preview]
* [HTTP/2] [1] [user-agent: curl/8.11.1]
* [HTTP/2] [1] [accept: */*]
* [HTTP/2] [1] [content-type: application/json]
* [HTTP/2] [1] [api-key: XXXXXXXXX]
* [HTTP/2] [1] [content-length: 85]
> POST /eastus2/openai/deployments/gpt-4o-mini/chat/completions?api-version=2025-01-01-preview HTTP/2
> Host: test.com
> User-Agent: curl/8.11.1
> Accept: */*
> Content-Type: application/json
> api-key: XXXXXXXXXXXXXXXX
> Content-Length: 85
>
* upload completely sent off: 85 bytes
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/2 200
< date: Sun, 28 Sep 2025 07:47:03 GMT
< content-type: application/json
< content-length: 1266
< apim-request-id: 42e1ee67-4f7c-44bc-9e9a-45d9c150b43c
< strict-transport-security: max-age=31536000; includeSubDomains; preload
< x-content-type-options: nosniff
< x-ms-region: East US 2
< x-ratelimit-remaining-requests: 2498
< x-ratelimit-limit-requests: 2500
< x-ratelimit-remaining-tokens: 249992
< x-ratelimit-limit-tokens: 250000
< azureml-model-session: d048-20250904053033
< x-ms-rai-invoked: true
< x-request-id: 9406edd7-6047-4549-b952-bfb487a49536
< x-ms-deployment-name: gpt-4o-mini
<
{"choices":[{"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"protected_material_text":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}},"finish_reason":"length","index":0,"logprobs":null,"message":{"annotations":[],"content":"Hello! It seems like you're referencing a form of communication possibly related to Amateur Radio or packet radio (","refusal":null,"role":"assistant"}}],"created":1759045622,"id":"chatcmpl-CKgPWpRkmDaWGHMkzoataclS0DkTP","model":"gpt-4o-mini-2024-07-18","object":"chat.completion","prompt_filter_results":[{"prompt_index":0,"content_filter_results":{"hate":{"filtered":false,"severity":"safe"},"jailbreak":{"filtered":false,"detected":false},"self_harm":{"filtered":false,"severity":"safe"},"sexual":{"filtered":false,"severity":"safe"},"violence":{"filtered":false,"severity":"safe"}}}],"system_fingerprint":"fp_efad92c60b","usage":{"completion_tokens":20,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens":11,"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0},"total_tokens":31}}
* Connection #0 to host cns-hub.com left intact
Response API 호출 : Response API는 Azure OpenAI Service에서 제공하는 새로운 개념으로, 최근에 도입되었거나 기능이 통합된 상태 저장(stateful) API
curl -k -X POST "https://test.com/eastus2/openai/responses?api-version=2025-04-01-preview" \
-H "Content-Type: application/json" \
-H "api-key: XXXXXXXXXXXX" \
-d '{
"model": "test",
"input": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello via Responses API"}
],
"max_output_tokens": 50
}'
{
"id": "resp_68d8e77b140881978dead2cb68731aa60369fb87e0e58628",
"object": "response",
"created_at": 1759045499,
"status": "completed",
"background": false,
"content_filters": null,
"error": null,
"incomplete_details": null,
"instructions": null,
"max_output_tokens": 50,
"max_tool_calls": null,
"model": "test",
"output": [
{
"id": "msg_68d8e77b6c2481979bc692b8d3cbfe410369fb87e0e58628",
"type": "message",
"status": "completed",
"content": [
{
"type": "output_text",
"annotations": [],
"text": "Hello! How can I assist you today? If you have any questions about using the Responses API or anything else, feel free to ask!"
}
],
"role": "assistant"
}
],
"parallel_tool_calls": true,
"previous_response_id": null,
"prompt_cache_key": null,
"reasoning": {
"effort": null,
"summary": null
},
"safety_identifier": null,
"service_tier": "default",
"store": true,
"temperature": 1.0,
"text": {
"format": {
"type": "text"
}
},
"tool_choice": "auto",
"tools": [],
"top_p": 1.0,
"truncation": "disabled",
"usage": {
"input_tokens": 21,
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens": 29,
"output_tokens_details": {
"reasoning_tokens": 0
},
"total_tokens": 50
},
"user": null,
"metadata": {}
[참고 문서]
https://learn.microsoft.com/ko-kr/azure/ai-foundry/openai/reference
Azure AI Foundry 모델 REST API 참조의 Azure OpenAI - Azure OpenAI
Azure OpenAI REST API를 사용하는 방법을 알아봅니다. 이 문서에서는 권한 부여 옵션, 요청을 구성하고 응답을 받는 방법에 대해 알아봅니다.
learn.microsoft.com
https://learn.microsoft.com/ko-kr/azure/ai-foundry/openai/how-to/create-resource?pivots=web-portal
방법: Azure AI Foundry Models 리소스에서 Azure OpenAI 만들기 및 배포 - Azure OpenAI
Azure OpenAI를 시작하고 첫 번째 리소스를 만들고 Azure CLI 또는 Azure Portal에서 첫 번째 모델을 배포하는 방법을 알아봅니다.
learn.microsoft.com
https://learn.microsoft.com/ko-kr/azure/ai-foundry/openai/how-to/responses?tabs=python-key
Azure OpenAI 응답 API - Azure OpenAI
Azure OpenAI의 새 상태 저장 응답 API를 사용하는 방법을 알아봅니다.
learn.microsoft.com
https://learn.microsoft.com/ko-kr/azure/app-service/troubleshoot-domain-ssl-certificates
도메인 및 TLS/SSL 인증서 문제 해결 - Azure App Service
Azure App Service에서 도메인 또는 TLS/SSL 인증서를 구성할 때 발생할 수 있는 일반적인 문제에 대한 해결책을 찾습니다.
learn.microsoft.com
'IT > Infra&Cloud' 카테고리의 다른 글
[aws] EKS Mode/Nodes (0) | 2025.03.23 |
---|---|
[aws] EKS Security (1) | 2025.03.16 |
[aws] EKS Autoscaling (0) | 2025.03.09 |
[aws] EKS Observability (0) | 2025.03.01 |
[aws] EKS Storage, Managed Node Groups (2) | 2025.02.23 |
- Total
- Today
- Yesterday
- security
- 파이썬
- AI
- gcp serverless
- cni
- VPN
- operator
- GKE
- NW
- PYTHON
- NFT
- S3
- autoscaling
- terraform
- 혼공파
- IaC
- cloud
- 혼공단
- k8s cni
- OS
- handson
- SDWAN
- controltower
- 도서
- GCP
- k8s
- 혼공챌린지
- EKS
- AWS
- k8s calico
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |