chore: import upstream snapshot with attribution
tools_continuous_delivery / Private PyPI non-main branch release (push) Has been skipped
tools_continuous_delivery / Private PyPI main branch release (push) Failing after 2m42s
Publish Promptflow Doc / Build (push) Has been cancelled
Publish Promptflow Doc / Deploy (push) Has been cancelled
Flake8 Lint / flake8 (push) Has been cancelled
Spell check CI / Spell_Check (push) Has been cancelled
tools_continuous_delivery / Private PyPI non-main branch release (push) Has been skipped
tools_continuous_delivery / Private PyPI main branch release (push) Failing after 2m42s
Publish Promptflow Doc / Build (push) Has been cancelled
Publish Promptflow Doc / Deploy (push) Has been cancelled
Flake8 Lint / flake8 (push) Has been cancelled
Spell check CI / Spell_Check (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
---
|
||||
resources: examples/connections/azure_openai.yml, examples/flows/standard/web-classification
|
||||
category: deployment
|
||||
weight: 60
|
||||
---
|
||||
|
||||
# Deploy flow using Azure App Service
|
||||
|
||||
This example demos how to deploy a flow using Azure App Service.
|
||||
|
||||
[Azure App Service](https://learn.microsoft.com/azure/app-service/) is an HTTP-based service for hosting web applications, REST APIs, and mobile back ends.
|
||||
The scripts (`deploy.sh` for bash and `deploy.ps1` for powershell) under this folder are here to help deploy the docker image to Azure App Service.
|
||||
|
||||
We will use [web-classification](../../../flows/standard/web-classification/README.md) as example in this tutorial.
|
||||
|
||||
## Build a flow as docker format app
|
||||
|
||||
Note that all dependent connections must be created before building as docker.
|
||||
```bash
|
||||
# create connection if not created before
|
||||
pf connection create --file ../../../connections/azure_openai.yml --set api_key=<your_api_key> api_base=<your_api_base> --name open_ai_connection
|
||||
```
|
||||
|
||||
Use the command below to build a flow as docker format app:
|
||||
|
||||
```bash
|
||||
pf flow build --source ../../../flows/standard/web-classification --output dist --format docker
|
||||
```
|
||||
|
||||
|
||||
## Deploy with Azure App Service
|
||||
The two scripts will do the following things:
|
||||
1. Create a resource group if not exists.
|
||||
2. Build and push the image to docker registry.
|
||||
3. Create an app service plan with the give sku.
|
||||
4. Create an app with specified name, set the deployment container image to the pushed docker image.
|
||||
5. Set up the environment variables for the app.
|
||||
|
||||
Example command to use bash script:
|
||||
```shell
|
||||
bash deploy.sh --path dist -i <image_tag> --name my-app-23d8m -r <docker registry> -g <resource_group>
|
||||
```
|
||||
|
||||
Example command to use powershell script:
|
||||
```powershell
|
||||
.\deploy.ps1 -Path dist -i <image_tag> -n my-app-23d8m -r <docker registry> -g <resource_group>
|
||||
```
|
||||
Note that the `name` will produce a unique FQDN as AppName.azurewebsites.net.
|
||||
|
||||
See the full parameters by `bash deploy.sh -h` or `.\deploy.ps1 -h`.
|
||||
|
||||
## View and test the web app
|
||||
The web app can be found via [azure portal](https://portal.azure.com/)
|
||||
|
||||

|
||||
|
||||
After the app created, you will need to go to https://portal.azure.com/ find the app and set up the environment variables
|
||||
at (Settings>Configuration) or (Settings>Environment variables), then restart the app.
|
||||
|
||||

|
||||
|
||||
Browse the app at Overview and see the test page:
|
||||
|
||||

|
||||
|
||||
You can also test the app by sending a POST request to the app like:
|
||||
```shell
|
||||
curl http://<Default-domain-of-app-service>/score --data '{"url":"https://play.google.com/store/apps/details?id=com.twitter.android"}' -X POST -H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
|
||||
Tips:
|
||||
- Reach deployment logs at (Deployment>Deployment Central) and app logs at (Monitoring>Log stream).
|
||||
- Reach advanced deployment tools at (Development Tools>Advanced Tools).
|
||||
- Reach more details about app service at [Azure App Service](https://learn.microsoft.com/azure/app-service/).
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 82 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
@@ -0,0 +1,171 @@
|
||||
<#
|
||||
.DESCRIPTION
|
||||
Script to deploy promptflow to Azure App Service.
|
||||
|
||||
.PARAMETER path
|
||||
The folder path to be deployed
|
||||
.PARAMETER image_tag
|
||||
The container image tag.
|
||||
.PARAMETER registry
|
||||
The container registry name, for example 'xx.azurecr.io'.
|
||||
.PARAMETER name
|
||||
The app name to produce a unique FQDN as AppName.azurewebsites.net.
|
||||
.PARAMETER location
|
||||
The app location, default to 'centralus'.
|
||||
.PARAMETER sku
|
||||
The app sku, default to 'F1'(free).
|
||||
.PARAMETER resource_group
|
||||
The app resource group.
|
||||
.PARAMETER subscription
|
||||
The app subscription, default using az account subscription.
|
||||
.PARAMETER verbose
|
||||
verbose mode.
|
||||
|
||||
.EXAMPLE
|
||||
PS> .\deploy.ps1 -Path <folder-path> -i <image_tag> -r <registry> -n <app_name> -g <resource_group>
|
||||
.EXAMPLE
|
||||
PS> .\deploy.ps1 -Path <folder-path> -i <image_tag> -r <registry> -n <app_name> -g <resource_group> -Subscription "xxxx-xxxx-xxxx-xxxx-xxxx" -Verbose
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$Path,
|
||||
[Alias("i", "image_tag")][string]$ImageTag,
|
||||
[Alias("r")][string]$Registry,
|
||||
[Alias("n")][string]$Name,
|
||||
[Alias("l")][string]$Location = "eastus",
|
||||
[string]$Sku = "F1",
|
||||
[Alias("g", "resource_group")][string]$ResourceGroup,
|
||||
[string]$Subscription
|
||||
)
|
||||
|
||||
####################### Validate args ############################
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# fail if image_tag not provided
|
||||
if (!$ImageTag) {
|
||||
Write-Host "***************************"
|
||||
Write-Host "* Error: image_tag is required.*"
|
||||
Write-Host "***************************"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# check if : in image_tag
|
||||
if (!$ImageTag.Contains(":")) {
|
||||
$version="v$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
$image_tag="${ImageTag}:${version}"
|
||||
}
|
||||
|
||||
Write-Host "image_tag: $ImageTag"
|
||||
|
||||
# fail if Registry not provided
|
||||
if (!$Registry) {
|
||||
Write-Host "***************************"
|
||||
Write-Host "* Error: registry is required.*"
|
||||
Write-Host "***************************"
|
||||
exit
|
||||
}
|
||||
|
||||
# fail if name not provided
|
||||
if (!$Name) {
|
||||
Write-Host "***************************"
|
||||
Write-Host "* Error: name is required.*"
|
||||
Write-Host "***************************"
|
||||
exit
|
||||
}
|
||||
|
||||
# fail if resource_group not provided
|
||||
if (!$ResourceGroup) {
|
||||
Write-Host "***************************"
|
||||
Write-Host "* Error: resource_group is required.*"
|
||||
Write-Host "***************************"
|
||||
exit
|
||||
}
|
||||
|
||||
# fail if image_tag not provided
|
||||
if (!$Path) {
|
||||
Write-Host "***************************"
|
||||
Write-Host "* Error: Path is required.*"
|
||||
Write-Host "***************************"
|
||||
exit 1
|
||||
}
|
||||
|
||||
####################### Build and push image ############################
|
||||
Write-Host "Change working directory to $Path"
|
||||
cd $Path
|
||||
docker build -t "$ImageTag" .
|
||||
|
||||
if ($Registry.Contains("azurecr.io")) {
|
||||
Write-Host "Trying to login to $Registry..."
|
||||
az acr login -n "$Registry"
|
||||
|
||||
$AcrImageTag = $Registry + "/" + $ImageTag
|
||||
Write-Host "ACR image tag: $AcrImageTag"
|
||||
docker tag "$ImageTag" "$AcrImageTag"
|
||||
$ImageTag = $AcrImageTag
|
||||
}
|
||||
else {
|
||||
Write-Host "***************************************************\n"
|
||||
Write-Host "* WARN: Make sure you have docker account login!!!*\n"
|
||||
Write-Host "***************************************************\n"
|
||||
|
||||
$DockerImageTag = $Registry + "/" + $ImageTag
|
||||
|
||||
Write-Host "Docker image tag: $DockerImageTag"
|
||||
docker tag "$ImageTag" "$DockerImageTag"
|
||||
$ImageTag = $DockerImageTag
|
||||
}
|
||||
|
||||
Write-Host "Start pushing image...$ImageTag"
|
||||
docker push "$ImageTag"
|
||||
|
||||
####################### Create and config app ############################
|
||||
|
||||
function Append-To-Command {
|
||||
param (
|
||||
[string] $Command
|
||||
)
|
||||
if ($Subscription) {
|
||||
$Command = "$Command --subscription $Subscription"
|
||||
}
|
||||
if ($VerbosePreference -eq "Continue") {
|
||||
$Command="$Command --debug"
|
||||
}
|
||||
Write-Host "$Command"
|
||||
return $Command
|
||||
}
|
||||
|
||||
function Invoke-Expression-And-Check{
|
||||
param (
|
||||
[string]$Command
|
||||
)
|
||||
$Command=$(Append-To-Command "$Command")
|
||||
Invoke-Expression $Command
|
||||
if ($LASTEXITCODE -gt 0) {
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
}
|
||||
# Check and create resource group if not exist
|
||||
$Result = (az group exists --name $ResourceGroup)
|
||||
if ($Result -eq "false") {
|
||||
Write-Host "Creating resource group...$ResourceGroup"
|
||||
$Command="az group create --name $ResourceGroup -l $Location"
|
||||
Invoke-Expression-And-Check "$Command"
|
||||
}
|
||||
# Create service plan
|
||||
$ServicePlanName = $Name + "_service_plan"
|
||||
Write-Host "Creating service plan...$ServicePlanName"
|
||||
$Command="az appservice plan create --name $ServicePlanName --sku $Sku --location $location --is-linux -g $ResourceGroup"
|
||||
Invoke-Expression-And-Check "$Command"
|
||||
# Create app
|
||||
Write-Host "Creating app...$Name"
|
||||
$Command="az webapp create --name $Name -p $ServicePlanName --deployment-container-image-name $ImageTag --startup-file 'bash start.sh' -g $ResourceGroup"
|
||||
Invoke-Expression-And-Check "$Command"
|
||||
# Config environment variable
|
||||
Write-Host "Config app...$Name"
|
||||
# Port default to 8080 corresponding to the DockerFile
|
||||
$Command="az webapp config appsettings set -g $ResourceGroup --name $Name --settings USER_AGENT=promptflow-appservice WEBSITES_PORT=8080 ('@settings.json')"
|
||||
Invoke-Expression-And-Check "$Command"
|
||||
Write-Host "Please go to https://portal.azure.com/ to config environment variables and restart the app: $Name at (Settings>Configuration) or (Settings>Environment variables)"
|
||||
Write-Host "Reach deployment logs at (Deployment>Deployment Central) and app logs at (Monitoring>Log stream)"
|
||||
Write-Host "Reach advanced deployment tools at https://$Name.scm.azurewebsites.net/"
|
||||
Write-Host "Reach more details about app service at https://learn.microsoft.com/en-us/azure/app-service/"
|
||||
@@ -0,0 +1,189 @@
|
||||
#! /bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
program_name=$0
|
||||
|
||||
function usage {
|
||||
echo "usage: $program_name [-i|-image_tag|--image_tag]"
|
||||
echo " -i|-image_tag|--image_tag specify container image tag"
|
||||
echo " -r|-registry|--registry specify container registry name, for example 'xx.azurecr.io'"
|
||||
echo " -n|-name|--name specify app name to produce a unique FQDN as AppName.azurewebsites.net."
|
||||
echo " -l|-location|--location specify app location, default to 'centralus'"
|
||||
echo " -sku|--sku specify app sku, default to 'F1'(free)"
|
||||
echo " -g|-resource_group|--resource_group specify app resource group"
|
||||
echo " -subscription|--subscription specify app subscription, default using az account subscription"
|
||||
echo " -v|-verbose|--verbose specify verbose mode"
|
||||
echo " -p|-path|--path specify folder path to be deployed"
|
||||
exit 1
|
||||
}
|
||||
if [ "$1" == "-help" ] || [ "$1" == "-h" ]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
location="eastus"
|
||||
sku="F1"
|
||||
verbose=false
|
||||
|
||||
####################### Parse and validate args ############################
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-i|-image_tag|--image_tag)
|
||||
image_tag="$2"
|
||||
;;
|
||||
-r|-registry|--registry)
|
||||
registry_name="$2"
|
||||
;;
|
||||
-n|-name|--name)
|
||||
name="$2"
|
||||
;;
|
||||
-l|-location|--location)
|
||||
location="$2"
|
||||
;;
|
||||
-sku|--sku)
|
||||
sku="$2"
|
||||
;;
|
||||
-g|-resource_group|--resource_group)
|
||||
resource_group="$2"
|
||||
;;
|
||||
-subscription|--subscription)
|
||||
subscription="$2"
|
||||
;;
|
||||
-v|-verbose|--verbose)
|
||||
verbose=true
|
||||
;;
|
||||
-p|-path|--path)
|
||||
path="$2"
|
||||
;;
|
||||
*)
|
||||
printf "***************************\n"
|
||||
printf "* Error: Invalid argument.*\n"
|
||||
printf "***************************\n"
|
||||
exit 1
|
||||
esac
|
||||
shift
|
||||
shift
|
||||
done
|
||||
|
||||
# fail if image_tag not provided
|
||||
if [ -z "$image_tag" ]; then
|
||||
printf "***************************\n"
|
||||
printf "* Error: image_tag is required.*\n"
|
||||
printf "***************************\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check if : in image_tag
|
||||
if [[ $image_tag == *":"* ]]; then
|
||||
echo "image_tag: $image_tag"
|
||||
else
|
||||
version="v$(date '+%Y%m%d-%H%M%S')"
|
||||
|
||||
image_tag="$image_tag:$version"
|
||||
echo "image_tag: $image_tag"
|
||||
fi
|
||||
|
||||
# fail if registry_name not provided
|
||||
if [ -z "$registry_name" ]; then
|
||||
printf "***************************\n"
|
||||
printf "* Error: registry is required.*\n"
|
||||
printf "***************************\n"
|
||||
fi
|
||||
|
||||
# fail if name not provided
|
||||
if [ -z "$name" ]; then
|
||||
printf "***************************\n"
|
||||
printf "* Error: name is required.*\n"
|
||||
printf "***************************\n"
|
||||
fi
|
||||
|
||||
# fail if resource_group not provided
|
||||
if [ -z "$resource_group" ]; then
|
||||
printf "***************************\n"
|
||||
printf "* Error: resource_group is required.*\n"
|
||||
printf "***************************\n"
|
||||
fi
|
||||
|
||||
# fail if path not provided
|
||||
if [ -z "$path" ]; then
|
||||
printf "***************************\n"
|
||||
printf "* Error: path is required.*\n"
|
||||
printf "***************************\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
####################### Build and push image ############################
|
||||
echo "Change working directory to $path"
|
||||
cd "$path"
|
||||
docker build -t "$image_tag" .
|
||||
|
||||
if [[ $registry_name == *"azurecr.io" ]]; then
|
||||
echo "Trying to login to $registry_name..."
|
||||
az acr login -n "$registry_name"
|
||||
|
||||
acr_image_tag=$registry_name/$image_tag
|
||||
echo "ACR image tag: $acr_image_tag"
|
||||
docker tag "$image_tag" "$acr_image_tag"
|
||||
image_tag=$acr_image_tag
|
||||
else
|
||||
echo "Make sure you have docker account login!!!"
|
||||
printf "***************************************************\n"
|
||||
printf "* WARN: Make sure you have docker account login!!!*\n"
|
||||
printf "***************************************************\n"
|
||||
|
||||
docker_image_tag=$registry_name/$image_tag
|
||||
|
||||
echo "Docker image tag: $docker_image_tag"
|
||||
docker tag "$image_tag" "$docker_image_tag"
|
||||
image_tag=$docker_image_tag
|
||||
fi
|
||||
|
||||
echo "Start pushing image...$image_tag"
|
||||
docker push "$image_tag"
|
||||
|
||||
####################### Create and config app ############################
|
||||
|
||||
function append_to_command {
|
||||
command=$1
|
||||
if [ -n "$subscription" ]; then
|
||||
command="$command --subscription $subscription"
|
||||
fi
|
||||
if $verbose; then
|
||||
command="$command --debug"
|
||||
fi
|
||||
echo "$command"
|
||||
}
|
||||
|
||||
# Check and create resource group if not exist
|
||||
result=$(az group exists --name "$resource_group")
|
||||
if [ "$result" = "false" ]; then
|
||||
echo "Creating resource group...$resource_group"
|
||||
command="az group create --name $resource_group -l $location"
|
||||
command=$(append_to_command "$command")
|
||||
eval "$command"
|
||||
fi
|
||||
# Create service plan
|
||||
service_plan_name=$name"_service_plan"
|
||||
echo "Creating service plan...$service_plan_name"
|
||||
command="az appservice plan create --name $service_plan_name --sku $sku --location $location --is-linux -g $resource_group"
|
||||
command=$(append_to_command "$command")
|
||||
echo "$command"
|
||||
eval "$command"
|
||||
# Create app
|
||||
echo "Creating app...$name"
|
||||
command="az webapp create --name $name -p $service_plan_name --deployment-container-image-name $image_tag --startup-file 'bash start.sh' -g $resource_group"
|
||||
command=$(append_to_command "$command")
|
||||
echo "$command"
|
||||
eval "$command"
|
||||
# Config environment variable
|
||||
echo "Config app...$name"
|
||||
# Port default to 8080 corresponding to the DockerFile
|
||||
command="az webapp config appsettings set -g $resource_group --name $name --settings USER_AGENT=promptflow-appservice WEBSITES_PORT=8080 @settings.json "
|
||||
command=$(append_to_command "$command")
|
||||
echo "$command"
|
||||
eval "$command"
|
||||
echo "Please go to https://portal.azure.com/ to config environment variables and restart the app: $name at (Settings>Configuration) or (Settings>Environment variables)"
|
||||
echo "Reach deployment logs at (Deployment>Deployment Central) and app logs at (Monitoring>Log stream)"
|
||||
echo "Reach advanced deployment tools at https://$name.scm.azurewebsites.net/"
|
||||
echo "Reach more details about app service at https://learn.microsoft.com/en-us/azure/app-service/"
|
||||
Reference in New Issue
Block a user