Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
62357ea
new split pipelines
May 13, 2020
70468e7
specify channel
May 14, 2020
413b4ff
fix pip jq install
May 14, 2020
0b4d411
fixes and cleanup
May 21, 2020
ec7b7e9
Merge branch 'master' into jenns/splitpipeline
May 21, 2020
1d30998
add new lines
May 21, 2020
c28b886
add docs and clean up naming
May 26, 2020
9c07bd3
use shared image
May 26, 2020
a7c7fa5
rename
May 28, 2020
a175ad9
Merge branch 'master' into jenns/splitpipeline
Jun 3, 2020
a138306
strip quotes from location
Jun 3, 2020
11ee8f6
fix env var
Jun 3, 2020
0a914b6
remove succeeded condition
Jun 3, 2020
d1f7f03
remove extra deploy yml
Jun 3, 2020
eb62b5c
no pr trigger
Jun 4, 2020
b9cd127
remove unused template
Jun 9, 2020
b865800
remove unused pipeline
Jun 9, 2020
1128194
add more docs and add to bootstrap
Jun 10, 2020
7a69c0e
linting
Jun 10, 2020
bae4b61
fix model package to show logs
Jun 11, 2020
dbe8b33
Squashed commit of the following:
Jun 12, 2020
9bc9f8b
Squashed commit of the following:
Jun 16, 2020
82ab9ec
Merge branch 'master' into jenns/splitpipeline
Jun 16, 2020
cd450ec
remove need for model build id
Jun 16, 2020
f58e0df
Merge branch 'master' into jenns/splitpipeline
Jun 18, 2020
bb61306
Merge branch 'master' into jenns/splitpipeline
Jun 22, 2020
c6167eb
fix batch scoring
Jun 22, 2020
4bfa69b
use model version for batch scoring
Jun 22, 2020
c9fc6ed
linting
Jun 22, 2020
a95183b
Squashed commit of the following:
Jun 22, 2020
16063ca
improve the docs
Jun 24, 2020
e07e93e
fix secret access
Jun 25, 2020
bcbeb98
pass to cli task and impove naming
Jun 25, 2020
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
157 changes: 157 additions & 0 deletions .pipelines/diabetes_regression-cd-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# Continuous Integration (CI) pipeline that orchestrates the deployment of the diabetes_regression model.

# Runtime parameters to select artifacts
parameters:
- name : artifactBuildId
displayName: Model Train CI Build ID. Default is 'latest'.
type: string
default: latest

pr: none

# Trigger this pipeline on model-train pipeline completion
trigger: none
resources:
containers:
- container: mlops
image: mcr.microsoft.com/mlops/python:latest
pipelines:
- pipeline: model-train-ci
source: Model-Train-Register-CI # Name of the triggering pipeline
trigger:
branches:
include:
- master

variables:
- template: diabetes_regression-variables-template.yml
- group: devopsforai-aml-vg

stages:
- stage: 'Deploy_ACI'
displayName: 'Deploy to ACI'
condition: variables['ACI_DEPLOYMENT_NAME']
jobs:
- job: "Deploy_ACI"
displayName: "Deploy to ACI"
container: mlops
timeoutInMinutes: 0
steps:
- download: none
- template: diabetes_regression-get-model-id-artifact-template.yml
parameters:
projectId: '$(resources.pipeline.model-train-ci.projectID)'
pipelineId: '$(resources.pipeline.model-train-ci.pipelineID)'
artifactBuildId: ${{ parameters.artifactBuildId }}
- task: AzureCLI@1
displayName: 'Install AzureML CLI'
inputs:
azureSubscription: '$(WORKSPACE_SVC_CONNECTION)'
scriptLocation: inlineScript
workingDirectory: $(Build.SourcesDirectory)
inlineScript: 'az extension add -n azure-cli-ml'
- task: AzureCLI@1
displayName: "Deploy to ACI (CLI)"
inputs:
azureSubscription: '$(WORKSPACE_SVC_CONNECTION)'
scriptLocation: inlineScript
workingDirectory: $(Build.SourcesDirectory)/$(SOURCES_DIR_TRAIN)/scoring
inlineScript: |
az ml model deploy --name $(ACI_DEPLOYMENT_NAME) --model '$(MODEL_NAME):$(MODEL_VERSION)' \
--ic inference_config.yml \
--dc deployment_config_aci.yml \
-g $(RESOURCE_GROUP) --workspace-name $(WORKSPACE_NAME) \
--overwrite -v
- task: AzureCLI@1
displayName: 'Smoke test'
inputs:
azureSubscription: '$(WORKSPACE_SVC_CONNECTION)'
scriptLocation: inlineScript
inlineScript: |
set -e # fail on error
export SUBSCRIPTION_ID=$(az account show --query id -o tsv)
python -m ml_service.util.smoke_test_scoring_service --type ACI --service "$(ACI_DEPLOYMENT_NAME)"

- stage: 'Deploy_AKS'
displayName: 'Deploy to AKS'
dependsOn: Deploy_ACI
condition: and(succeeded(), variables['AKS_DEPLOYMENT_NAME'])
jobs:
- job: "Deploy_AKS"
displayName: "Deploy to AKS"
container: mlops
timeoutInMinutes: 0
steps:
- template: diabetes_regression-get-model-id-artifact-template.yml
parameters:
projectId: '$(resources.pipeline.model-train-ci.projectID)'
pipelineId: '$(resources.pipeline.model-train-ci.pipelineID)'
artifactBuildId: ${{ parameters.artifactBuildId }}
- task: AzureCLI@1
displayName: 'Install AzureML CLI'
inputs:
azureSubscription: '$(WORKSPACE_SVC_CONNECTION)'
scriptLocation: inlineScript
workingDirectory: $(Build.SourcesDirectory)
inlineScript: 'az extension add -n azure-cli-ml'
- task: AzureCLI@1
displayName: "Deploy to AKS (CLI)"
inputs:
azureSubscription: '$(WORKSPACE_SVC_CONNECTION)'
scriptLocation: inlineScript
workingDirectory: $(Build.SourcesDirectory)/$(SOURCES_DIR_TRAIN)/scoring
inlineScript: |
az ml model deploy --name $(AKS_DEPLOYMENT_NAME) --model '$(MODEL_NAME):$(MODEL_VERSION)' \
--compute-target $(AKS_COMPUTE_NAME) \
--ic inference_config.yml \
--dc deployment_config_aks.yml \
-g $(RESOURCE_GROUP) --workspace-name $(WORKSPACE_NAME) \
--overwrite -v
- task: AzureCLI@1
displayName: 'Smoke test'
inputs:
azureSubscription: '$(WORKSPACE_SVC_CONNECTION)'
scriptLocation: inlineScript
inlineScript: |
set -e # fail on error
export SUBSCRIPTION_ID=$(az account show --query id -o tsv)
python -m ml_service.util.smoke_test_scoring_service --type AKS --service "$(AKS_DEPLOYMENT_NAME)"

- stage: 'Deploy_Webapp'
displayName: 'Deploy to Webapp'
condition: variables['WEBAPP_DEPLOYMENT_NAME']
jobs:
- job: "Deploy_Webapp"
displayName: "Package and deploy model"
container: mlops
timeoutInMinutes: 0
steps:
- template: diabetes_regression-get-model-id-artifact-template.yml
parameters:
projectId: '$(resources.pipeline.model-train-ci.projectID)'
pipelineId: '$(resources.pipeline.model-train-ci.pipelineID)'
artifactBuildId: ${{ parameters.artifactBuildId }}
- template: diabetes_regression-package-model-template.yml
parameters:
modelId: $(MODEL_NAME):$(MODEL_VERSION)
scoringScriptPath: '$(Build.SourcesDirectory)/$(SOURCES_DIR_TRAIN)/scoring/score.py'
condaFilePath: '$(Build.SourcesDirectory)/$(SOURCES_DIR_TRAIN)/conda_dependencies.yml'
- script: echo $(IMAGE_LOCATION) >image_location.txt
displayName: "Write image location file"
- task: AzureWebAppContainer@1
name: WebAppDeploy
displayName: 'Azure Web App on Container Deploy'
inputs:
azureSubscription: '$(AZURE_RM_SVC_CONNECTION)'
appName: '$(WEBAPP_DEPLOYMENT_NAME)'
resourceGroupName: '$(RESOURCE_GROUP)'
imageName: '$(IMAGE_LOCATION)'
- task: AzureCLI@1
displayName: 'Smoke test'
inputs:
azureSubscription: '$(WORKSPACE_SVC_CONNECTION)'
scriptLocation: inlineScript
inlineScript: |
set -e # fail on error
export SUBSCRIPTION_ID=$(az account show --query id -o tsv)
python -m ml_service.util.smoke_test_scoring_service --type Webapp --service "$(WebAppDeploy.AppServiceApplicationUrl)/score"
97 changes: 97 additions & 0 deletions .pipelines/diabetes_regression-ci-train-register.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Continuous Integration (CI) pipeline that orchestrates the training, evaluation, and registration of the diabetes_regression model.

resources:
containers:
- container: mlops
image: mcr.microsoft.com/mlops/python:latest

pr: none
trigger:
branches:
include:
- master
paths:
include:
- diabetes_regression/
- ml_service/pipelines/diabetes_regression_build_train_pipeline.py
- ml_service/pipelines/diabetes_regression_build_train_pipeline_with_r.py
- ml_service/pipelines/diabetes_regression_build_train_pipeline_with_r_on_dbricks.py

variables:
- template: diabetes_regression-variables-template.yml
- group: devopsforai-aml-vg

pool:
vmImage: ubuntu-latest

stages:
- stage: 'Model_CI'
displayName: 'Model CI'
jobs:
- job: "Model_CI_Pipeline"
displayName: "Model CI Pipeline"
container: mlops
timeoutInMinutes: 0
steps:
- template: code-quality-template.yml
- task: AzureCLI@1
inputs:
azureSubscription: '$(WORKSPACE_SVC_CONNECTION)'
scriptLocation: inlineScript
workingDirectory: $(Build.SourcesDirectory)
inlineScript: |
set -e # fail on error
export SUBSCRIPTION_ID=$(az account show --query id -o tsv)
# Invoke the Python building and publishing a training pipeline
python -m ml_service.pipelines.diabetes_regression_build_train_pipeline
displayName: 'Publish Azure Machine Learning Pipeline'

- stage: 'Trigger_AML_Pipeline'
displayName: 'Train and evaluate model'
condition: succeeded()
variables:
BUILD_URI: '$(SYSTEM.COLLECTIONURI)$(SYSTEM.TEAMPROJECT)/_build/results?buildId=$(BUILD.BUILDID)'
jobs:
- job: "Get_Pipeline_ID"
condition: and(succeeded(), eq(coalesce(variables['auto-trigger-training'], 'true'), 'true'))
displayName: "Get Pipeline ID for execution"
container: mlops
timeoutInMinutes: 0
steps:
- task: AzureCLI@1
inputs:
azureSubscription: '$(WORKSPACE_SVC_CONNECTION)'
scriptLocation: inlineScript
workingDirectory: $(Build.SourcesDirectory)
inlineScript: |
set -e # fail on error
export SUBSCRIPTION_ID=$(az account show --query id -o tsv)
python -m ml_service.pipelines.run_train_pipeline --output_pipeline_id_file "pipeline_id.txt" --skip_train_execution
# Set AMLPIPELINEID variable for next AML Pipeline task in next job
AMLPIPELINEID="$(cat pipeline_id.txt)"
echo "##vso[task.setvariable variable=AMLPIPELINEID;isOutput=true]$AMLPIPELINEID"
name: 'getpipelineid'
displayName: 'Get Pipeline ID'
- job: "Run_ML_Pipeline"
dependsOn: "Get_Pipeline_ID"
displayName: "Trigger ML Training Pipeline"
timeoutInMinutes: 0
pool: server
variables:
AMLPIPELINE_ID: $[ dependencies.Get_Pipeline_ID.outputs['getpipelineid.AMLPIPELINEID'] ]
steps:
- task: ms-air-aiagility.vss-services-azureml.azureml-restApi-task.MLPublishedPipelineRestAPITask@0
displayName: 'Invoke ML pipeline'
inputs:
azureSubscription: '$(WORKSPACE_SVC_CONNECTION)'
PipelineId: '$(AMLPIPELINE_ID)'
ExperimentName: '$(EXPERIMENT_NAME)'
PipelineParameters: '"ParameterAssignments": {"model_name": "$(MODEL_NAME)"}, "tags": {"BuildId": "$(Build.BuildId)", "BuildUri": "$(BUILD_URI)"}, "StepTags": {"BuildId": "$(Build.BuildId)", "BuildUri": "$(BUILD_URI)"}'
- job: "Training_Run_Report"
dependsOn: "Run_ML_Pipeline"
condition: always()
displayName: "Publish artifact if new model was registered"
container: mlops
timeoutInMinutes: 0
steps:
- template: diabetes_regression-publish-model-artifact-template.yml
45 changes: 45 additions & 0 deletions .pipelines/diabetes_regression-get-model-id-artifact-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
parameters:
- name: projectId
type: string
default: ''
- name: pipelineId
type: string
default: ''
- name: artifactBuildId
type: string
default: latest

steps:
- download: none
- task: DownloadPipelineArtifact@2
displayName: Download Pipeline Artifacts
inputs:
source: 'specific'
project: '${{ parameters.projectId }}'
pipeline: '${{ parameters.pipelineId }}'
preferTriggeringPipeline: true
${{ if eq(parameters.artifactBuildId, 'latest') }}:
buildVersionToDownload: 'latestFromBranch'
${{ if ne(parameters.artifactBuildId, 'latest') }}:
buildVersionToDownload: 'specific'
runId: '${{ parameters.artifactBuildId }}'
runBranch: '$(Build.SourceBranch)'
path: $(Build.SourcesDirectory)/bin
- task: Bash@3
displayName: Parse Json for Model Name and Version
inputs:
targetType: 'inline'
script: |
# Print JSON
cat $(Build.SourcesDirectory)/bin/model/model.json | jq '.'

# Set model name and version variables
MODEL_NAME=$(jq -r '.name' <$(Build.SourcesDirectory)/bin/model/model.json)
MODEL_VERSION=$(jq -r '.version' <$(Build.SourcesDirectory)/bin/model/model.json)

echo "Model Name: $MODEL_NAME"
echo "Model Version: $MODEL_VERSION"

# Set environment variables
echo "##vso[task.setvariable variable=MODEL_VERSION]$MODEL_VERSION"
echo "##vso[task.setvariable variable=MODEL_NAME]$MODEL_NAME"
39 changes: 39 additions & 0 deletions .pipelines/diabetes_regression-package-model-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Pipeline template that creates a model package and adds the package location to the environment for subsequent tasks to use.
parameters:
- name: modelId
type: string
default: ''
- name: scoringScriptPath
type: string
default: ''
- name: condaFilePath
type: string
default: ''

steps:
- task: AzureCLI@1
displayName: 'Install AzureML CLI'
inputs:
azureSubscription: '$(WORKSPACE_SVC_CONNECTION)'
scriptLocation: inlineScript
workingDirectory: $(Build.SourcesDirectory)
inlineScript: 'az extension add -n azure-cli-ml'
- task: AzureCLI@1
displayName: 'Create model package and set IMAGE_LOCATION variable'
inputs:
azureSubscription: '$(WORKSPACE_SVC_CONNECTION)'
scriptLocation: inlineScript
inlineScript: |
set -e # fail on error

# Create model package using CLI
IMAGE_LOCATION=$(\
az ml model package --workspace-name $(WORKSPACE_NAME) -g $(RESOURCE_GROUP) \
--model '${{ parameters.modelId }}' \
--entry-script '${{ parameters.scoringScriptPath }}' \
--cf '${{ parameters.condaFilePath }}' \
--rt python --query 'location' -o tsv)

# Set environment variable
echo $IMAGE_LOCATION
echo "##vso[task.setvariable variable=IMAGE_LOCATION]$IMAGE_LOCATION"
29 changes: 29 additions & 0 deletions .pipelines/diabetes_regression-publish-model-artifact-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Pipeline template to check if a model was registered for the build and publishes an artifact with the model JSON
steps:
- task: AzureCLI@1
displayName: 'Install AzureML CLI'
inputs:
azureSubscription: '$(WORKSPACE_SVC_CONNECTION)'
scriptLocation: inlineScript
workingDirectory: $(Build.SourcesDirectory)
inlineScript: 'az extension add -n azure-cli-ml'
- task: AzureCLI@1
inputs:
azureSubscription: '$(WORKSPACE_SVC_CONNECTION)'
scriptLocation: inlineScript
workingDirectory: $(Build.SourcesDirectory)
inlineScript: |
set -e # fail on error

# Get the model using the build ID tag
FOUND_MODEL=$(az ml model list -g $(RESOURCE_GROUP) --workspace-name $(WORKSPACE_NAME) --tag BuildId=$(modelbuildid) --query '[0]')

# If the variable is empty, print and fail
[[ -z "$FOUND_MODEL" ]] && { echo "Model was not registered for this run." ; exit 1; }

# Write to a file
echo $FOUND_MODEL >model.json
name: 'getversion'
displayName: "Determine if evaluation succeeded and new model is registered (CLI)"
- publish: model.json
artifact: model
1 change: 1 addition & 0 deletions diabetes_regression/ci_dependencies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ dependencies:
- r=3.6.0
- r-essentials=3.6.0

- conda-forge::jq
- pip=20.0.*

- pip:
Expand Down
Binary file added docs/images/model-deploy-configure.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/model-deploy-result.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/model-train-register-artifacts.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/model-train-register.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading