Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create webapp from arm template automatically #285

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .pipelines/diabetes_regression-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ resources:
variables:
- template: diabetes_regression-variables-template.yml
- group: devopsforai-aml-vg
- name: "ACR_NAME"
value: "$(BASE_NAME)amlcr"

stages:
- stage: 'Deploy_ACI'
Expand Down Expand Up @@ -142,6 +144,34 @@ stages:
condaFilePath: '$(Build.SourcesDirectory)/$(SOURCES_DIR_TRAIN)/conda_dependencies.yml'
- script: echo $(IMAGE_LOCATION) >image_location.txt
displayName: "Write image location file"

- task: AzureCLI@2
displayName: 'Get ACR username and password'
continueOnError: false
inputs:
azureSubscription: '$(AZURE_RM_SVC_CONNECTION)'
scriptLocation: inlineScript
scriptType: 'bash'
inlineScript: |
export acr_password=`az acr credential show -n $(ACR_NAME) --query passwords[0].value -g $(RESOURCE_GROUP)`
export acr_username=`az acr credential show -n $(ACR_NAME) --query username -g $(RESOURCE_GROUP)`
echo "Got username: "
echo $acr_username
echo "##vso[task.setvariable variable=acr_password]$acr_password"
echo "##vso[task.setvariable variable=acr_username]$acr_username"

- task: AzureResourceGroupDeployment@2
inputs:
azureSubscription: '$(AZURE_RM_SVC_CONNECTION)'
action: 'Create Or Update Resource Group'
resourceGroupName: '$(RESOURCE_GROUP)'
location: $(LOCATION)
templateLocation: 'Linked artifact'
csmFile: '$(Build.SourcesDirectory)/environment_setup/arm-templates/webapp-env.json'
overrideParameters: '-baseName $(BASE_NAME) -location $(LOCATION) -imagelocation $(IMAGE_TAGGED) -acr $(ACR_NAME) -acr_password $(acr_password) -acr_username $(acr_username)'
deploymentMode: 'Incremental'
displayName: 'Create webapp'

- task: AzureWebAppContainer@1
name: WebAppDeploy
displayName: 'Azure Web App on Container Deploy'
Expand Down
3 changes: 3 additions & 0 deletions .pipelines/diabetes_regression-package-model-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,6 @@ steps:
# Set environment variable using the last line of logs that has the package location
IMAGE_LOCATION=$(tail -n 1 image_logs.txt)
echo "##vso[task.setvariable variable=IMAGE_LOCATION]$IMAGE_LOCATION"
echo $IMAGE_LOCATION > image_location.txt
IMAGE_TAGGED="$(sed 's/@sha256.*/:latest/g' image_location.txt)"
echo "##vso[task.setvariable variable=IMAGE_TAGGED]$IMAGE_TAGGED"
Copy link
Contributor

@j-so j-so Sep 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the need for this additional environment variable? Can we reuse the image location variable?

4 changes: 1 addition & 3 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,7 @@ Delete the **ACI_DEPLOYMENT_NAME** variable.

The pipeline uses the [Azure ML CLI](../.pipelines/diabetes_regression-package-model-template.yml) to create a scoring image. The image will be registered under an Azure Container Registry instance that belongs to the Azure Machine Learning Service. Any dependencies that the scoring file depends on can also be packaged with the container with an image config. Learn more about how to create a container using the Azure ML SDK with the [Image class](https://docs.microsoft.com/en-us/python/api/azureml-core/azureml.core.image.image.image?view=azure-ml-py#create-workspace--name--models--image-config-) API documentation.

Make sure your webapp has the credentials to pull the image from the Azure Container Registry created by the Infrastructure as Code pipeline. Instructions can be found on the [Configure registry credentials in web app](https://docs.microsoft.com/en-us/azure/devops/pipelines/targets/webapp-on-container-linux?view=azure-devops&tabs=dotnet-core%2Cyaml#configure-registry-credentials-in-web-app) page. You'll need to run the pipeline once (including the Deploy to Webapp stage up to the `Create scoring image` step) so an image is present in the registry. After that, you can connect the Webapp to the Azure Container Registry in the Azure Portal.

![build](./images/multi-stage-webapp.png)
The pipeline should create the webapp automatically the first time it is run with **WEBAPP_DEPLOYMENT_NAME** set.

### Example pipelines using R

Expand Down
104 changes: 104 additions & 0 deletions environment_setup/arm-templates/webapp-env.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"imagelocation": {
"type": "string"
},
"acr_username": {
"type": "string"
},
"acr_password": {
"type": "secureString"
},
"baseName": {
"type": "string",
"maxLength": 10,
"minLength": 3,
"metadata": {
"description": "The base name to use as prefix to create all the resources."
}
},
"location": {
"type": "string",
"metadata": {
"description": "Specifies the location for all resources."
}
},
"acr": {
"type": "string",
"defaultValue": "[concat(toLower(parameters('baseName')),'amlcr')]"
},
"webAppName": {
"type": "string",
"defaultValue": "[concat(toLower(parameters('baseName')),'webapp')]",
"metadata": {
"description": "Base name of the web app name and app service plan"
},
"minLength": 2
},
"sku": {
"type": "string",
"metadata": {
"description": "SKU for the app service plan"
},
"defaultValue": "S1"
}
},
"variables": {
"webAppPortalName": "[concat(parameters('webAppName'), '-webapp')]",
"appServicePlanName": "[concat(parameters('webAppName'),'AppServicePlan')]"

},
"resources": [
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2018-02-01",
"name": "[variables('appServicePlanName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('sku')]"
},
"kind": "linux",
"properties": {
"reserved": true,
"maximumElasticWorkerCount": 5
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2018-11-01",
"name": "[variables('webAppPortalName')]",
"location": "[parameters('location')]",
"kind": "app,linux,container",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]"
],
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]",
"httpsOnly": true,
"siteConfig": {
"linuxFxVersion": "[concat('DOCKER|', parameters('imagelocation'))]",
"appSettings": [
{
"name": "WEBSITES_ENABLE_APP_SERVICE_STORAGE",
"value": "false"
},
{
"name": "DOCKER_REGISTRY_SERVER_URL",
"value": "[concat('https://', parameters('acr'), '.azurecr.io')]"
},
{
"name": "DOCKER_REGISTRY_SERVER_USERNAME",
"value": "[parameters('acr_username')]"
},
{
"name": "DOCKER_REGISTRY_SERVER_PASSWORD",
"value": "[parameters('acr_password')]"
}
]
}
}
}
]
}