AI DevOps initial commit: IaC, Model CICD, AzureML Code Quickstart
This commit is contained in:
Родитель
ac671c65c8
Коммит
e0a38ef9e8
|
@ -0,0 +1,7 @@
|
|||
.ipynb_checkpoints
|
||||
azureml-logs
|
||||
.azureml
|
||||
.git
|
||||
outputs
|
||||
azureml-setup
|
||||
docs
|
|
@ -0,0 +1,14 @@
|
|||
# ignore local folders and config files
|
||||
aml_config/*.json
|
||||
Sample_Data
|
||||
.vscode
|
||||
outputs
|
||||
assets
|
||||
|
||||
# ignore python cache
|
||||
*.pyc
|
||||
|
||||
# ignore faultive folders
|
||||
Code/Modeling/aml_config
|
||||
Code/Modeling/assets
|
||||
Code/Modeling/.amlignore
|
|
@ -1,3 +1,3 @@
|
|||
# This folder hosts code for data acquisition and understanding (exploratory analysis)
|
||||
|
||||
You can add detailed description in this markdown related to your specific data science project.
|
||||
You can add a detailed description in this markdown related to your specific data science project.
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# Databricks notebooks can be synced with Git. For code organization
|
||||
# in line with this template, provide `Code/Data_Acquistion_and_Understanding`
|
||||
# as a base path in Databricks.
|
|
@ -0,0 +1 @@
|
|||
{}
|
|
@ -0,0 +1 @@
|
|||
{}
|
|
@ -0,0 +1 @@
|
|||
{}
|
|
@ -1 +0,0 @@
|
|||
# Add your data pipe line spec. This is dependant on your tool. For Azure Data Factory (ADF) it is a set of JSON files.
|
|
@ -0,0 +1,2 @@
|
|||
# Logic to upload sample dataset (see Sample_Data folder) to AML Datastore
|
||||
# @TODO for starter template
|
|
@ -1,3 +1,8 @@
|
|||
# This folder contains code for modeling and related activities (such as feature engineering, model evaluation etc.)
|
||||
|
||||
You can add detailed description in this markdown related to your specific data science project.
|
||||
|
||||
The following project structure has been provided as an example.
|
||||
|
||||
* modelpackage
|
||||
* tests e.g. unit tests and integration tests
|
|
@ -0,0 +1 @@
|
|||
# This folder hosts production-intended data preparation logic
|
|
@ -1 +0,0 @@
|
|||
# R-code for models
|
|
@ -0,0 +1 @@
|
|||
# This folder represents an example of code organization where all code related to a specific ML model is shipped as modules, and is logically grouped as a package in Python
|
|
@ -0,0 +1,3 @@
|
|||
"""
|
||||
Model Explainability analysis
|
||||
"""
|
|
@ -0,0 +1,49 @@
|
|||
class Modeler:
|
||||
"""
|
||||
Model Factory Class
|
||||
Train a model
|
||||
"""
|
||||
def __init__(self):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
self.model = None
|
||||
|
||||
return
|
||||
|
||||
def validate_data(self, df):
|
||||
"""
|
||||
Validate data integrity before training
|
||||
Basic stasistics, data assumptions
|
||||
"""
|
||||
return
|
||||
|
||||
def splitData(self, df):
|
||||
"""
|
||||
Split dataset
|
||||
"""
|
||||
return df, df, df, df
|
||||
|
||||
def train(self, X_train, y_train):
|
||||
"""
|
||||
Cross validate and train a model
|
||||
"""
|
||||
|
||||
# sample model as template placeholder
|
||||
self.model = None
|
||||
|
||||
# return training results for logging
|
||||
cv_scores = {}
|
||||
return cv_scores
|
||||
|
||||
def score(self, df):
|
||||
"""
|
||||
Score a dataset using a trained model
|
||||
"""
|
||||
return
|
||||
|
||||
def explain(self, df):
|
||||
"""
|
||||
Explain a trained model's predictions
|
||||
"""
|
||||
return
|
|
@ -0,0 +1 @@
|
|||
# This folder contains definitions for ML Pipelines. ML Pipelines define machine learning workflows that may consist of multiple execution steps that could run on heterogenous compute types. Compute steps may share data resources to pipe in- and outputs
|
|
@ -0,0 +1,3 @@
|
|||
"""
|
||||
@TODO
|
||||
"""
|
|
@ -0,0 +1,89 @@
|
|||
"""
|
||||
Model Training Pipeline
|
||||
|
||||
Note: ML Pipelines are executed on registered compute resources.
|
||||
Run configurations hence cannot reference local compute.
|
||||
"""
|
||||
import os
|
||||
from azureml.core import Experiment, Workspace
|
||||
from azureml.pipeline.core import Pipeline, PipelineData
|
||||
from azureml.pipeline.steps import PythonScriptStep
|
||||
from azureml.core import RunConfiguration
|
||||
from azureml.core.authentication import AzureCliAuthentication
|
||||
from azureml.data.data_reference import DataReference
|
||||
|
||||
# Define run configuration (compute/environment/data references/..)
|
||||
run_config_name = 'dsvmcluster'
|
||||
exp_name = "Training_Pipeline"
|
||||
curr_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
output_dir = 'outputs'
|
||||
output_dir_local = os.path.join(curr_dir, '../../../', 'outputs')
|
||||
|
||||
# Pipeline parameters
|
||||
run_experiment = True
|
||||
register_model = False
|
||||
publish_pipeline = False
|
||||
|
||||
# load workspace config, load default datastore.
|
||||
ws = Workspace.from_config(auth=AzureCliAuthentication())
|
||||
default_ds = ws.get_default_datastore()
|
||||
|
||||
# load run config
|
||||
run_config = RunConfiguration.load(
|
||||
path=os.path.join(curr_dir, '../../../', 'aml_config'),
|
||||
name=run_config_name
|
||||
)
|
||||
|
||||
# define training pipeline with one AMLCompute step
|
||||
trainStep = PythonScriptStep(
|
||||
script_name="train.py",
|
||||
name="Model Training",
|
||||
arguments=[
|
||||
'--data-dir', str(default_ds.as_mount()),
|
||||
'--output-dir', output_dir
|
||||
],
|
||||
inputs=[
|
||||
DataReference(
|
||||
datastore=default_ds,
|
||||
mode="mount"
|
||||
)
|
||||
],
|
||||
outputs=[
|
||||
PipelineData(
|
||||
name="model",
|
||||
datastore=default_ds,
|
||||
output_path_on_compute="training"
|
||||
)
|
||||
],
|
||||
compute_target=run_config.target,
|
||||
runconfig=run_config,
|
||||
source_directory=os.path.join(curr_dir, '../')
|
||||
)
|
||||
|
||||
training_pipeline = Pipeline(workspace=ws, steps=[trainStep])
|
||||
training_pipeline.validate()
|
||||
print("Pipeline validation complete")
|
||||
|
||||
if run_experiment:
|
||||
# Submit pipeline run
|
||||
pipeline_run = Experiment(ws, exp_name).submit(training_pipeline)
|
||||
pipeline_run.wait_for_completion()
|
||||
|
||||
# create output folder
|
||||
os.makedirs(output_dir_local, exist_ok=True)
|
||||
|
||||
# Download trained model artifacts to local compute
|
||||
run_train_step = list(pipeline_run.get_children())[0]
|
||||
for file in ['model.pkl']:
|
||||
run_train_step.download_file(
|
||||
name=os.path.join(output_dir, file),
|
||||
output_file_path=os.path.join(output_dir_local, file)
|
||||
)
|
||||
|
||||
if register_model:
|
||||
# @TODO Register model, version by build id
|
||||
print('Registered model')
|
||||
|
||||
if publish_pipeline:
|
||||
# @TODO Publish pipeline, version by build id
|
||||
print('Published pipeline')
|
|
@ -0,0 +1,3 @@
|
|||
"""
|
||||
@TODO
|
||||
"""
|
|
@ -0,0 +1,43 @@
|
|||
"""
|
||||
Real Time Scoring Service
|
||||
@TODO
|
||||
"""
|
||||
import json
|
||||
import time
|
||||
import numpy as np
|
||||
from azureml.core.model import Model
|
||||
from sklearn.externals import joblib
|
||||
|
||||
|
||||
def init():
|
||||
"""
|
||||
Load model and other dependencies for inferencing
|
||||
"""
|
||||
global model
|
||||
# Print statement for appinsights custom traces:
|
||||
print("model initialized" + time.strftime("%H:%M:%S"))
|
||||
|
||||
# note here "sklearn_regression_model.pkl" is the name of the
|
||||
# model registered under the workspace this call should return
|
||||
# the path to the model.pkl file on the local disk.
|
||||
model_path = Model.get_model_path(model_name='model.pkl')
|
||||
|
||||
# deserialize the model file back into a sklearn model
|
||||
model = joblib.load(model_path)
|
||||
|
||||
|
||||
def run(raw_data):
|
||||
"""
|
||||
Score new data against model
|
||||
"""
|
||||
try:
|
||||
data = json.loads(raw_data)['data']
|
||||
data = np.array(data)
|
||||
result = model.predict(data)
|
||||
|
||||
# you can return any datatype as long as it is JSON-serializable
|
||||
return result.tolist()
|
||||
except Exception as e:
|
||||
error = str(e)
|
||||
print(error + time.strftime("%H:%M:%S"))
|
||||
return error
|
|
@ -0,0 +1 @@
|
|||
# Integration tests
|
|
@ -0,0 +1,2 @@
|
|||
# Integration test for inference code
|
||||
# @TODO
|
|
@ -0,0 +1 @@
|
|||
# This folder contains unit tests for the sample package modelpackage.
|
|
@ -0,0 +1 @@
|
|||
# Subpackage unit tests
|
|
@ -0,0 +1,2 @@
|
|||
def test_mock():
|
||||
return True
|
|
@ -0,0 +1,59 @@
|
|||
"""
|
||||
Model Trainer
|
||||
|
||||
Load data, train model(s), evaluate performance
|
||||
"""
|
||||
import os
|
||||
from azureml.core import Run
|
||||
import pandas as pd
|
||||
import argparse
|
||||
from modelpackage.modeler import Modeler
|
||||
from sklearn.externals import joblib
|
||||
|
||||
# parse arguments
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--data-dir', type=str, default="Sample_Data/Raw",
|
||||
dest='data_dir', help='data folder')
|
||||
parser.add_argument('--output-dir', type=str, default="outputs",
|
||||
dest='output_folder', help='experiment output folder')
|
||||
args = parser.parse_args()
|
||||
|
||||
# load experiment run for tracking
|
||||
run = Run.get_context()
|
||||
|
||||
# read a file from mounted storage
|
||||
df = pd.read_csv(os.path.join(args.data_dir, 'file.csv'))
|
||||
print(df.head())
|
||||
|
||||
# train model(s)
|
||||
modeler = Modeler()
|
||||
|
||||
print('Validate data integrity..')
|
||||
modeler.validate_data(df)
|
||||
|
||||
print('Splitting data..')
|
||||
X_train, X_test, y_train, y_test = modeler.splitData(df)
|
||||
|
||||
print('Training model..')
|
||||
cv_scores = modeler.train(X_train, y_train)
|
||||
|
||||
print('Scoring model..')
|
||||
y_pred = modeler.score(df)
|
||||
|
||||
# log metric values with experiment run
|
||||
print('Evaluating model performance..')
|
||||
run.log("r-squared", 0.84)
|
||||
run.log("rmse", 20)
|
||||
|
||||
# experiment run results, store model
|
||||
# files stored in the 'outputs' folder are automatically tracked by Azure ML
|
||||
try:
|
||||
os.makedirs(args.output_folder, exist_ok=True)
|
||||
|
||||
file = open(os.path.join(args.output_folder, 'model.pkl'), 'wb')
|
||||
joblib.dump(modeler.model, file)
|
||||
file.close()
|
||||
|
||||
print('Persisted trained model to path:', args.output_folder)
|
||||
except Exception as e:
|
||||
print('Error serializing model' + e)
|
|
@ -0,0 +1,52 @@
|
|||
"""
|
||||
Training submitter
|
||||
|
||||
Facilitates remote training execution through the Azure ML service.
|
||||
Compute and data references defined according to run configuration.
|
||||
"""
|
||||
import os
|
||||
import shutil
|
||||
from azureml.core import Workspace, Experiment
|
||||
from azureml.core import RunConfiguration, ScriptRunConfig
|
||||
from azureml.core.authentication import AzureCliAuthentication
|
||||
|
||||
# Define run configuration (compute/environment/data references/..)
|
||||
run_config_name = 'dsvmcluster' # local/docker/dsvmcluster
|
||||
exp_name = "TemplateExperiment"
|
||||
curr_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
output_dir = 'outputs'
|
||||
|
||||
# load workspace config, load default datastore.
|
||||
ws = Workspace.from_config(auth=AzureCliAuthentication())
|
||||
experiment = Experiment(workspace=ws, name=exp_name)
|
||||
default_ds = ws.get_default_datastore()
|
||||
|
||||
# load run config
|
||||
run_config = RunConfiguration.load(
|
||||
path=os.path.join(curr_dir, '../../', 'aml_config'),
|
||||
name=run_config_name
|
||||
)
|
||||
|
||||
# Submit experiment run
|
||||
# datastores will be attached as specified in the run configuration
|
||||
est = ScriptRunConfig(
|
||||
script='train.py',
|
||||
source_directory=curr_dir,
|
||||
run_config=run_config,
|
||||
arguments=[
|
||||
'--data-dir', str(default_ds.as_mount()),
|
||||
'--output-dir', output_dir
|
||||
]
|
||||
)
|
||||
|
||||
print('Submitting experiment.. if compute is idle, this may take some time')
|
||||
run = experiment.submit(est)
|
||||
|
||||
# wait for run completion to show logs
|
||||
run.wait_for_completion(show_output=True)
|
||||
print('View run results in portal:', run.get_portal_url(), '\n')
|
||||
|
||||
# ignore Azure ML service bug: delete redundant folders/files
|
||||
shutil.rmtree(os.path.join(curr_dir, 'assets'))
|
||||
shutil.rmtree(os.path.join(curr_dir, 'aml_config'))
|
||||
os.remove(os.path.join(curr_dir, '.amlignore'))
|
|
@ -0,0 +1 @@
|
|||
# Import Resources
|
|
@ -0,0 +1,296 @@
|
|||
{
|
||||
"options": [
|
||||
{
|
||||
"enabled": false,
|
||||
"definition": {
|
||||
"id": "5d58cc01-7c75-450c-be18-a388ddb129ec"
|
||||
},
|
||||
"inputs": {
|
||||
"branchFilters": "[\"+refs/heads/*\"]",
|
||||
"additionalFields": "{}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"definition": {
|
||||
"id": "a9db38f9-9fdc-478c-b0f9-464221e58316"
|
||||
},
|
||||
"inputs": {
|
||||
"workItemType": "2418250",
|
||||
"assignToRequestor": "true",
|
||||
"additionalFields": "{}"
|
||||
}
|
||||
}
|
||||
],
|
||||
"triggers": [
|
||||
{
|
||||
"branchFilters": [
|
||||
"+feature/*"
|
||||
],
|
||||
"pathFilters": [],
|
||||
"batchChanges": false,
|
||||
"maxConcurrentBuildsPerBranch": 1,
|
||||
"pollingInterval": 0,
|
||||
"triggerType": 2
|
||||
}
|
||||
],
|
||||
"variables": {
|
||||
"AMLWorkspaceName": {
|
||||
"value": ""
|
||||
},
|
||||
"ResourceGroupName": {
|
||||
"value": ""
|
||||
},
|
||||
"system.debug": {
|
||||
"value": "false",
|
||||
"allowOverride": true
|
||||
}
|
||||
},
|
||||
"retentionRules": [
|
||||
{
|
||||
"branches": [
|
||||
"+refs/heads/*"
|
||||
],
|
||||
"artifacts": [],
|
||||
"artifactTypesToDelete": [
|
||||
"FilePath",
|
||||
"SymbolStore"
|
||||
],
|
||||
"daysToKeep": 10,
|
||||
"minimumToKeep": 1,
|
||||
"deleteBuildRecord": true,
|
||||
"deleteTestResults": true
|
||||
}
|
||||
],
|
||||
"properties": {},
|
||||
"tags": [],
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": "https://dev.azure.com/account/123456789/_apis/build/Definitions/10?revision=7"
|
||||
},
|
||||
"web": {
|
||||
"href": "https://dev.azure.com/account/123456789/_build/definition?definitionId=10"
|
||||
},
|
||||
"editor": {
|
||||
"href": "https://dev.azure.com/account/123456789/_build/designer?id=10&_a=edit-build-definition"
|
||||
},
|
||||
"badge": {
|
||||
"href": "https://dev.azure.com/account/123456789/_apis/build/status/10"
|
||||
}
|
||||
},
|
||||
"jobAuthorizationScope": 1,
|
||||
"jobTimeoutInMinutes": 60,
|
||||
"jobCancelTimeoutInMinutes": 5,
|
||||
"process": {
|
||||
"phases": [
|
||||
{
|
||||
"steps": [
|
||||
{
|
||||
"environment": {},
|
||||
"enabled": true,
|
||||
"continueOnError": false,
|
||||
"alwaysRun": false,
|
||||
"displayName": "Create Conda Environment",
|
||||
"timeoutInMinutes": 0,
|
||||
"condition": "succeeded()",
|
||||
"task": {
|
||||
"id": "03dd16c3-43e0-4667-ba84-40515d27a410",
|
||||
"versionSpec": "1.*",
|
||||
"definitionType": "task"
|
||||
},
|
||||
"inputs": {
|
||||
"createCustomEnvironment": "true",
|
||||
"environmentName": "project_environment",
|
||||
"packageSpecs": "Python=3.6 cython numpy",
|
||||
"updateConda": "true",
|
||||
"installOptions": "",
|
||||
"createOptions": "",
|
||||
"cleanEnvironment": "false"
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"enabled": true,
|
||||
"continueOnError": true,
|
||||
"alwaysRun": false,
|
||||
"displayName": "Prepare Conda Environment (using yml)",
|
||||
"timeoutInMinutes": 0,
|
||||
"condition": "succeeded()",
|
||||
"task": {
|
||||
"id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9",
|
||||
"versionSpec": "2.*",
|
||||
"definitionType": "task"
|
||||
},
|
||||
"inputs": {
|
||||
"script": "conda env list;\n\nconda env update -f ./conda_dependencies.yml",
|
||||
"workingDirectory": "",
|
||||
"failOnStderr": "false"
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"enabled": true,
|
||||
"continueOnError": true,
|
||||
"alwaysRun": false,
|
||||
"displayName": "Unit tests (model code)",
|
||||
"timeoutInMinutes": 0,
|
||||
"condition": "succeeded()",
|
||||
"task": {
|
||||
"id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9",
|
||||
"versionSpec": "2.*",
|
||||
"definitionType": "task"
|
||||
},
|
||||
"inputs": {
|
||||
"script": "pip install setuptools\npip install pytest\npython -m pytest \\\n -k \"not integration\" \\\n --junit-xml $(Build.BinariesDirectory)/unittest_report.xml",
|
||||
"workingDirectory": "",
|
||||
"failOnStderr": "false"
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"enabled": true,
|
||||
"continueOnError": true,
|
||||
"alwaysRun": false,
|
||||
"displayName": "Code Quality (flake8)",
|
||||
"timeoutInMinutes": 0,
|
||||
"condition": "succeeded()",
|
||||
"task": {
|
||||
"id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9",
|
||||
"versionSpec": "2.*",
|
||||
"definitionType": "task"
|
||||
},
|
||||
"inputs": {
|
||||
"script": "pip install flake8\npip install flake8_formatter_junit_xml\nflake8 --format junit-xml --output-file $(Build.BinariesDirectory)/flake8_report.xml --exit-zero\n",
|
||||
"workingDirectory": "",
|
||||
"failOnStderr": "false"
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"enabled": true,
|
||||
"continueOnError": false,
|
||||
"alwaysRun": false,
|
||||
"displayName": "Publish Unit Test Results",
|
||||
"timeoutInMinutes": 0,
|
||||
"condition": "succeeded()",
|
||||
"task": {
|
||||
"id": "0b0f01ed-7dde-43ff-9cbb-e48954daf9b1",
|
||||
"versionSpec": "2.*",
|
||||
"definitionType": "task"
|
||||
},
|
||||
"inputs": {
|
||||
"testRunner": "JUnit",
|
||||
"testResultsFiles": "$(Build.BinariesDirectory)/*_report.xml",
|
||||
"searchFolder": "$(System.DefaultWorkingDirectory)/Code/Modeling",
|
||||
"mergeTestResults": "true",
|
||||
"failTaskOnFailedTests": "false",
|
||||
"testRunTitle": "",
|
||||
"platform": "",
|
||||
"configuration": "",
|
||||
"publishRunAttachments": "true"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "Agent Phase",
|
||||
"refName": "Phase_2",
|
||||
"condition": "succeeded()",
|
||||
"target": {
|
||||
"executionOptions": {
|
||||
"type": 0
|
||||
},
|
||||
"allowScriptsAuthAccessOption": false,
|
||||
"type": 1
|
||||
},
|
||||
"jobAuthorizationScope": 1,
|
||||
"jobCancelTimeoutInMinutes": 1
|
||||
}
|
||||
],
|
||||
"type": 1
|
||||
},
|
||||
"repository": {
|
||||
"properties": {
|
||||
"apiUrl": "https://api.github.com/repos/user/Azure-TDSP-DevOps-Template",
|
||||
"branchesUrl": "https://api.github.com/repos/user/Azure-TDSP-DevOps-Template/branches",
|
||||
"cloneUrl": "https://github.com/user/Azure-TDSP-DevOps-Template.git",
|
||||
"fullName": "user/Azure-TDSP-DevOps-Template",
|
||||
"manageUrl": "https://github.com/user/Azure-TDSP-DevOps-Template",
|
||||
"refsUrl": "https://api.github.com/repos/user/Azure-TDSP-DevOps-Template/git/refs",
|
||||
"defaultBranch": "master",
|
||||
"connectedServiceId": "8f189c40-5897-4ada-9cce-df147f88fa57",
|
||||
"isPrivate": "False",
|
||||
"isFork": "True",
|
||||
"ownerAvatarUrl": "https://avatars2.githubusercontent.com/u/872065?v=4",
|
||||
"lastUpdated": "02/08/2019 13:09:48",
|
||||
"nodeId": "MDEwOlJlcG9zaXRvcnkxNjE2OTgyMjc=",
|
||||
"hasAdminPermissions": "True",
|
||||
"safeOwnerId": "5848F3A00730FC1BBD623A19F26B0C66A2094333D2CF4382C9FD3483C02D5699D4A8932BB7FDE482121158ED9B8F66CE4A055D40DF47AB8C965FF7A9B8BA",
|
||||
"ownerId": "872065",
|
||||
"safeRepository": "Azure-TDSP-DevOps-Template",
|
||||
"ownerIsAUser": "True",
|
||||
"checkoutNestedSubmodules": "false",
|
||||
"cleanOptions": "0",
|
||||
"fetchDepth": "0",
|
||||
"gitLfsSupport": "false",
|
||||
"reportBuildStatus": "true",
|
||||
"skipSyncSource": "false",
|
||||
"labelSourcesFormat": "$(build.buildNumber)",
|
||||
"labelSources": "0"
|
||||
},
|
||||
"id": "user/Azure-TDSP-DevOps-Template",
|
||||
"type": "GitHub",
|
||||
"name": "user/Azure-TDSP-DevOps-Template",
|
||||
"url": "https://github.com/user/Azure-TDSP-DevOps-Template.git",
|
||||
"defaultBranch": "master",
|
||||
"clean": "false",
|
||||
"checkoutSubmodules": false
|
||||
},
|
||||
"processParameters": {},
|
||||
"quality": 1,
|
||||
"authoredBy": {
|
||||
"displayName": "user ",
|
||||
"url": "https://spsprodweu3.vssps.visualstudio.com/Ae8b74699-309d-4bdc-b628-67015b7fd300/_apis/Identities/73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"_links": {
|
||||
"avatar": {
|
||||
"href": "https://dev.azure.com/account/_apis/GraphProfile/MemberAvatars/aad.NzNkNGQyYjAtOWNhYi03YzZhLWFhYzYtNTUxZWFmNWM0Njcy"
|
||||
}
|
||||
},
|
||||
"id": "73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"uniqueName": "account@microsoft.com",
|
||||
"imageUrl": "https://dev.azure.com/account/_api/_common/identityImage?id=73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"descriptor": "aad.NzNkNGQyYjAtOWNhYi03YzZhLWFhYzYtNTUxZWFmNWM0Njcy"
|
||||
},
|
||||
"drafts": [],
|
||||
"queue": {
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": "https://dev.azure.com/account/_apis/build/Queues/35"
|
||||
}
|
||||
},
|
||||
"id": 35,
|
||||
"name": "Hosted Ubuntu 1604",
|
||||
"url": "https://dev.azure.com/account/_apis/build/Queues/35",
|
||||
"pool": {
|
||||
"id": 6,
|
||||
"name": "Hosted Ubuntu 1604",
|
||||
"isHosted": true
|
||||
}
|
||||
},
|
||||
"id": 10,
|
||||
"name": "Code Quality",
|
||||
"url": "https://dev.azure.com/account/123456789/_apis/build/Definitions/10?revision=7",
|
||||
"uri": "vstfs:///Build/Definition/10",
|
||||
"path": "\\",
|
||||
"type": 2,
|
||||
"queueStatus": 0,
|
||||
"revision": 7,
|
||||
"createdDate": "2019-02-09T17:14:45.473Z",
|
||||
"project": {
|
||||
"id": "123456789",
|
||||
"name": "DevOps for AI",
|
||||
"url": "https://dev.azure.com/account/_apis/projects/123456789",
|
||||
"state": 1,
|
||||
"revision": 57,
|
||||
"visibility": 0,
|
||||
"lastUpdateTime": "2018-08-15T15:07:27.100Z"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,208 @@
|
|||
{
|
||||
"options": [
|
||||
{
|
||||
"enabled": false,
|
||||
"definition": {
|
||||
"id": "5d58cc01-7c75-450c-be18-a388ddb129ec"
|
||||
},
|
||||
"inputs": {
|
||||
"branchFilters": "[\"+refs/heads/*\"]",
|
||||
"additionalFields": "{}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"definition": {
|
||||
"id": "a9db38f9-9fdc-478c-b0f9-464221e58316"
|
||||
},
|
||||
"inputs": {
|
||||
"workItemType": "2418250",
|
||||
"assignToRequestor": "true",
|
||||
"additionalFields": "{}"
|
||||
}
|
||||
}
|
||||
],
|
||||
"triggers": [
|
||||
{
|
||||
"branchFilters": [
|
||||
"+master"
|
||||
],
|
||||
"pathFilters": [
|
||||
"+Code/Operationalization/provisioning/"
|
||||
],
|
||||
"batchChanges": false,
|
||||
"maxConcurrentBuildsPerBranch": 1,
|
||||
"pollingInterval": 0,
|
||||
"triggerType": 2
|
||||
}
|
||||
],
|
||||
"variables": {
|
||||
"system.debug": {
|
||||
"value": "false",
|
||||
"allowOverride": true
|
||||
}
|
||||
},
|
||||
"retentionRules": [
|
||||
{
|
||||
"branches": [
|
||||
"+refs/heads/*"
|
||||
],
|
||||
"artifacts": [],
|
||||
"artifactTypesToDelete": [
|
||||
"FilePath",
|
||||
"SymbolStore"
|
||||
],
|
||||
"daysToKeep": 10,
|
||||
"minimumToKeep": 1,
|
||||
"deleteBuildRecord": true,
|
||||
"deleteTestResults": true
|
||||
}
|
||||
],
|
||||
"properties": {},
|
||||
"tags": [],
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": "https://dev.azure.com/user/3ec38c18-3edc-45c6-9a06-33069ee6e54e/_apis/build/Definitions/11?revision=4"
|
||||
},
|
||||
"web": {
|
||||
"href": "https://dev.azure.com/user/3ec38c18-3edc-45c6-9a06-33069ee6e54e/_build/definition?definitionId=11"
|
||||
},
|
||||
"editor": {
|
||||
"href": "https://dev.azure.com/user/3ec38c18-3edc-45c6-9a06-33069ee6e54e/_build/designer?id=11&_a=edit-build-definition"
|
||||
},
|
||||
"badge": {
|
||||
"href": "https://dev.azure.com/user/3ec38c18-3edc-45c6-9a06-33069ee6e54e/_apis/build/status/11"
|
||||
}
|
||||
},
|
||||
"jobAuthorizationScope": 1,
|
||||
"jobTimeoutInMinutes": 60,
|
||||
"jobCancelTimeoutInMinutes": 5,
|
||||
"process": {
|
||||
"phases": [
|
||||
{
|
||||
"steps": [
|
||||
{
|
||||
"environment": {},
|
||||
"enabled": true,
|
||||
"continueOnError": false,
|
||||
"alwaysRun": false,
|
||||
"displayName": "Publish Resource Templates",
|
||||
"timeoutInMinutes": 0,
|
||||
"condition": "succeeded()",
|
||||
"task": {
|
||||
"id": "2ff763a7-ce83-4e1f-bc89-0ae63477cebe",
|
||||
"versionSpec": "1.*",
|
||||
"definitionType": "task"
|
||||
},
|
||||
"inputs": {
|
||||
"PathtoPublish": "Code/Operationalization/provisioning",
|
||||
"ArtifactName": "resourcetemplates",
|
||||
"ArtifactType": "Container",
|
||||
"TargetPath": "",
|
||||
"Parallel": "false",
|
||||
"ParallelCount": "8"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "Agent job 1",
|
||||
"refName": "Phase_1",
|
||||
"condition": "succeeded()",
|
||||
"target": {
|
||||
"executionOptions": {
|
||||
"type": 0
|
||||
},
|
||||
"allowScriptsAuthAccessOption": false,
|
||||
"type": 1
|
||||
},
|
||||
"jobAuthorizationScope": 1,
|
||||
"jobCancelTimeoutInMinutes": 1
|
||||
}
|
||||
],
|
||||
"type": 1
|
||||
},
|
||||
"repository": {
|
||||
"properties": {
|
||||
"apiUrl": "https://api.github.com/repos/user/Azure-TDSP-DevOps-Template",
|
||||
"branchesUrl": "https://api.github.com/repos/user/Azure-TDSP-DevOps-Template/branches",
|
||||
"cloneUrl": "https://github.com/user/Azure-TDSP-DevOps-Template.git",
|
||||
"fullName": "user/Azure-TDSP-DevOps-Template",
|
||||
"manageUrl": "https://github.com/user/Azure-TDSP-DevOps-Template",
|
||||
"refsUrl": "https://api.github.com/repos/user/Azure-TDSP-DevOps-Template/git/refs",
|
||||
"defaultBranch": "master",
|
||||
"connectedServiceId": "8f189c40-5897-4ada-9cce-df147f88fa57",
|
||||
"isPrivate": "False",
|
||||
"isFork": "True",
|
||||
"ownerAvatarUrl": "https://avatars2.githubusercontent.com/u/872065?v=4",
|
||||
"lastUpdated": "01/31/2019 17:04:58",
|
||||
"nodeId": "MDEwOlJlcG9zaXRvcnkxNjE2OTgyMjc=",
|
||||
"hasAdminPermissions": "True",
|
||||
"safeOwnerId": "5848F3A00730FC1BBD623A19F26B0C66A2094333D2CF4382C9FD3483C02D5699D4A8932BB7FDE482121158ED9B8F66CE4A055D40DF47AB8C965FF7A9B8BA",
|
||||
"safeRepository": "Azure-TDSP-DevOps-Template",
|
||||
"ownerIsAUser": "True",
|
||||
"checkoutNestedSubmodules": "false",
|
||||
"cleanOptions": "0",
|
||||
"fetchDepth": "0",
|
||||
"gitLfsSupport": "false",
|
||||
"reportBuildStatus": "true",
|
||||
"skipSyncSource": "false",
|
||||
"labelSourcesFormat": "$(build.buildNumber)",
|
||||
"labelSources": "0"
|
||||
},
|
||||
"id": "user/Azure-TDSP-DevOps-Template",
|
||||
"type": "GitHub",
|
||||
"name": "user/Azure-TDSP-DevOps-Template",
|
||||
"url": "https://github.com/user/Azure-TDSP-DevOps-Template.git",
|
||||
"defaultBranch": "master",
|
||||
"clean": "false",
|
||||
"checkoutSubmodules": false
|
||||
},
|
||||
"processParameters": {},
|
||||
"quality": 1,
|
||||
"authoredBy": {
|
||||
"displayName": "user",
|
||||
"url": "https://spsprodweu3.vssps.visualstudio.com/Ae8b74699-309d-4bdc-b628-67015b7fd300/_apis/Identities/73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"_links": {
|
||||
"avatar": {
|
||||
"href": "https://dev.azure.com/user/_apis/GraphProfile/MemberAvatars/aad.NzNkNGQyYjAtOWNhYi03YzZhLWFhYzYtNTUxZWFmNWM0Njcy"
|
||||
}
|
||||
},
|
||||
"id": "73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"uniqueName": "user@microsoft.com",
|
||||
"imageUrl": "https://dev.azure.com/user/_api/_common/identityImage?id=73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"descriptor": "aad.NzNkNGQyYjAtOWNhYi03YzZhLWFhYzYtNTUxZWFmNWM0Njcy"
|
||||
},
|
||||
"drafts": [],
|
||||
"queue": {
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": "https://dev.azure.com/user/_apis/build/Queues/29"
|
||||
}
|
||||
},
|
||||
"id": 29,
|
||||
"name": "Hosted VS2017",
|
||||
"url": "https://dev.azure.com/user/_apis/build/Queues/29",
|
||||
"pool": {
|
||||
"id": 4,
|
||||
"name": "Hosted VS2017",
|
||||
"isHosted": true
|
||||
}
|
||||
},
|
||||
"id": 11,
|
||||
"name": "Publish Resource Templates",
|
||||
"url": "https://dev.azure.com/user/3ec38c18-3edc-45c6-9a06-33069ee6e54e/_apis/build/Definitions/11?revision=4",
|
||||
"uri": "vstfs:///Build/Definition/11",
|
||||
"path": "\\",
|
||||
"type": 2,
|
||||
"queueStatus": 0,
|
||||
"revision": 4,
|
||||
"createdDate": "2019-01-31T20:48:12.967Z",
|
||||
"project": {
|
||||
"id": "3ec38c18-3edc-45c6-9a06-33069ee6e54e",
|
||||
"name": "DevOps for AI",
|
||||
"url": "https://dev.azure.com/user/_apis/projects/3ec38c18-3edc-45c6-9a06-33069ee6e54e",
|
||||
"state": 1,
|
||||
"revision": 57,
|
||||
"visibility": 0,
|
||||
"lastUpdateTime": "2018-08-15T15:07:27.100Z"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,442 @@
|
|||
{
|
||||
"options": [
|
||||
{
|
||||
"enabled": false,
|
||||
"definition": {
|
||||
"id": "5d58cc01-7c75-450c-be18-a388ddb129ec"
|
||||
},
|
||||
"inputs": {
|
||||
"branchFilters": "[\"+refs/heads/*\"]",
|
||||
"additionalFields": "{}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"enabled": false,
|
||||
"definition": {
|
||||
"id": "a9db38f9-9fdc-478c-b0f9-464221e58316"
|
||||
},
|
||||
"inputs": {
|
||||
"workItemType": "2418250",
|
||||
"assignToRequestor": "true",
|
||||
"additionalFields": "{}"
|
||||
}
|
||||
}
|
||||
],
|
||||
"triggers": [
|
||||
{
|
||||
"branchFilters": [
|
||||
"+master"
|
||||
],
|
||||
"pathFilters": [],
|
||||
"batchChanges": false,
|
||||
"maxConcurrentBuildsPerBranch": 1,
|
||||
"pollingInterval": 0,
|
||||
"triggerType": 2
|
||||
}
|
||||
],
|
||||
"variables": {
|
||||
"AMLWorkspaceName": {
|
||||
"value": ""
|
||||
},
|
||||
"ResourceGroupName": {
|
||||
"value": ""
|
||||
},
|
||||
"system.debug": {
|
||||
"value": "false",
|
||||
"allowOverride": true
|
||||
}
|
||||
},
|
||||
"variableGroups": [
|
||||
{
|
||||
"variables": {
|
||||
"acrName": {
|
||||
"value": "containerregistrydev"
|
||||
},
|
||||
"appInsightsName": {
|
||||
"value": "appinsightsdev"
|
||||
},
|
||||
"azuremlwsname": {
|
||||
"value": "mlworkspacedev"
|
||||
},
|
||||
"azureregion": {
|
||||
"value": "westeurope"
|
||||
},
|
||||
"keyVaultName": {
|
||||
"value": "keyvaultdev"
|
||||
},
|
||||
"rgname": {
|
||||
"value": "devopsforaidev"
|
||||
},
|
||||
"storageAccountName": {
|
||||
"value": "storagedev"
|
||||
},
|
||||
"subscriptionId": {
|
||||
"value": "cf4e1704-b4bc-4554-bcd7-309394f2ee56"
|
||||
}
|
||||
},
|
||||
"type": "Vsts",
|
||||
"name": "dev",
|
||||
"id": 3
|
||||
}
|
||||
],
|
||||
"retentionRules": [
|
||||
{
|
||||
"branches": [
|
||||
"+refs/heads/*"
|
||||
],
|
||||
"artifacts": [],
|
||||
"artifactTypesToDelete": [
|
||||
"FilePath",
|
||||
"SymbolStore"
|
||||
],
|
||||
"daysToKeep": 10,
|
||||
"minimumToKeep": 1,
|
||||
"deleteBuildRecord": true,
|
||||
"deleteTestResults": true
|
||||
}
|
||||
],
|
||||
"properties": {},
|
||||
"tags": [],
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": "https://dev.azure.com//3ec38c18-3edc-45c6-9a06-33069ee6e54e/_apis/build/Definitions/13?revision=62"
|
||||
},
|
||||
"web": {
|
||||
"href": "https://dev.azure.com//3ec38c18-3edc-45c6-9a06-33069ee6e54e/_build/definition?definitionId=13"
|
||||
},
|
||||
"editor": {
|
||||
"href": "https://dev.azure.com//3ec38c18-3edc-45c6-9a06-33069ee6e54e/_build/designer?id=13&_a=edit-build-definition"
|
||||
},
|
||||
"badge": {
|
||||
"href": "https://dev.azure.com//3ec38c18-3edc-45c6-9a06-33069ee6e54e/_apis/build/status/13"
|
||||
}
|
||||
},
|
||||
"jobAuthorizationScope": 1,
|
||||
"jobTimeoutInMinutes": 60,
|
||||
"jobCancelTimeoutInMinutes": 5,
|
||||
"process": {
|
||||
"phases": [
|
||||
{
|
||||
"steps": [
|
||||
{
|
||||
"environment": {},
|
||||
"enabled": true,
|
||||
"continueOnError": false,
|
||||
"alwaysRun": false,
|
||||
"displayName": "Create env config file",
|
||||
"timeoutInMinutes": 0,
|
||||
"condition": "succeeded()",
|
||||
"task": {
|
||||
"id": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
|
||||
"versionSpec": "2.*",
|
||||
"definitionType": "task"
|
||||
},
|
||||
"inputs": {
|
||||
"targetType": "inline",
|
||||
"filePath": "",
|
||||
"arguments": "",
|
||||
"script": "Write-Host \"Writing config file\"\n\n@{ subscription_id=\"$(subscriptionId)\"; resource_group=\"$(rgname)\"; workspace_name=\"$(azuremlwsname)\"} | ConvertTo-Json -depth 100 | Out-File \"aml_config/config.json\"",
|
||||
"errorActionPreference": "stop",
|
||||
"failOnStderr": "false",
|
||||
"ignoreLASTEXITCODE": "false",
|
||||
"pwsh": "false",
|
||||
"workingDirectory": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"enabled": true,
|
||||
"continueOnError": false,
|
||||
"alwaysRun": false,
|
||||
"displayName": "Conda: Create Environment",
|
||||
"timeoutInMinutes": 0,
|
||||
"condition": "succeeded()",
|
||||
"task": {
|
||||
"id": "03dd16c3-43e0-4667-ba84-40515d27a410",
|
||||
"versionSpec": "1.*",
|
||||
"definitionType": "task"
|
||||
},
|
||||
"inputs": {
|
||||
"createCustomEnvironment": "true",
|
||||
"environmentName": "project_environment",
|
||||
"packageSpecs": "",
|
||||
"updateConda": "false",
|
||||
"installOptions": "",
|
||||
"createOptions": "",
|
||||
"cleanEnvironment": "false"
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"enabled": true,
|
||||
"continueOnError": true,
|
||||
"alwaysRun": false,
|
||||
"displayName": "Conda: Prepare Env (using requirements)",
|
||||
"timeoutInMinutes": 0,
|
||||
"condition": "succeeded()",
|
||||
"task": {
|
||||
"id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9",
|
||||
"versionSpec": "2.*",
|
||||
"definitionType": "task"
|
||||
},
|
||||
"inputs": {
|
||||
"script": "conda env list;\n\nconda env update -f ./conda_dependencies.yml",
|
||||
"workingDirectory": "",
|
||||
"failOnStderr": "false"
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"enabled": true,
|
||||
"continueOnError": true,
|
||||
"alwaysRun": false,
|
||||
"displayName": "Unit tests (model code)",
|
||||
"timeoutInMinutes": 0,
|
||||
"condition": "succeeded()",
|
||||
"task": {
|
||||
"id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9",
|
||||
"versionSpec": "2.*",
|
||||
"definitionType": "task"
|
||||
},
|
||||
"inputs": {
|
||||
"script": "pip install setuptools\npip install pytest\npython -m pytest \\\n -k \"not integration\" \\\n --junit-xml $(Build.BinariesDirectory)/unittest_report.xml",
|
||||
"workingDirectory": "",
|
||||
"failOnStderr": "false"
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"enabled": true,
|
||||
"continueOnError": true,
|
||||
"alwaysRun": false,
|
||||
"displayName": "Code Quality (flake8 linting)",
|
||||
"timeoutInMinutes": 0,
|
||||
"condition": "succeeded()",
|
||||
"task": {
|
||||
"id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9",
|
||||
"versionSpec": "2.*",
|
||||
"definitionType": "task"
|
||||
},
|
||||
"inputs": {
|
||||
"script": "pip install flake8\npip install flake8_formatter_junit_xml\nflake8 --format junit-xml --output-file $(Build.BinariesDirectory)/flake8_report.xml --exit-zero\n",
|
||||
"workingDirectory": "",
|
||||
"failOnStderr": "false"
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"enabled": true,
|
||||
"continueOnError": false,
|
||||
"alwaysRun": false,
|
||||
"displayName": "Publish Unit Test Results",
|
||||
"timeoutInMinutes": 0,
|
||||
"condition": "succeeded()",
|
||||
"task": {
|
||||
"id": "0b0f01ed-7dde-43ff-9cbb-e48954daf9b1",
|
||||
"versionSpec": "2.*",
|
||||
"definitionType": "task"
|
||||
},
|
||||
"inputs": {
|
||||
"testRunner": "JUnit",
|
||||
"testResultsFiles": "$(Build.BinariesDirectory)/*_report.xml",
|
||||
"searchFolder": "$(System.DefaultWorkingDirectory)/Code/Modeling",
|
||||
"mergeTestResults": "true",
|
||||
"failTaskOnFailedTests": "false",
|
||||
"testRunTitle": "",
|
||||
"platform": "",
|
||||
"configuration": "",
|
||||
"publishRunAttachments": "true"
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"enabled": true,
|
||||
"continueOnError": false,
|
||||
"alwaysRun": false,
|
||||
"displayName": "ML Pipeline: Train Model",
|
||||
"timeoutInMinutes": 0,
|
||||
"condition": "succeeded()",
|
||||
"task": {
|
||||
"id": "46e4be58-730b-4389-8a2f-ea10b3e5e815",
|
||||
"versionSpec": "1.*",
|
||||
"definitionType": "task"
|
||||
},
|
||||
"inputs": {
|
||||
"connectedServiceNameARM": "b324cb93-5a35-4117-bd1d-03a0438c86a3",
|
||||
"scriptLocation": "inlineScript",
|
||||
"scriptPath": "",
|
||||
"inlineScript": "python Code/Modeling/pipelines/pipeline_train.py",
|
||||
"args": "",
|
||||
"addSpnToEnvironment": "false",
|
||||
"useGlobalConfig": "false",
|
||||
"cwd": "",
|
||||
"failOnStandardError": "false"
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"enabled": true,
|
||||
"continueOnError": true,
|
||||
"alwaysRun": false,
|
||||
"displayName": "Integration + model validation tests",
|
||||
"timeoutInMinutes": 0,
|
||||
"condition": "succeeded()",
|
||||
"task": {
|
||||
"id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9",
|
||||
"versionSpec": "2.*",
|
||||
"definitionType": "task"
|
||||
},
|
||||
"inputs": {
|
||||
"script": "echo \"integration\"",
|
||||
"workingDirectory": "",
|
||||
"failOnStderr": "false"
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"enabled": true,
|
||||
"continueOnError": false,
|
||||
"alwaysRun": false,
|
||||
"displayName": "Copy Model Training Artifacts",
|
||||
"timeoutInMinutes": 0,
|
||||
"condition": "succeeded()",
|
||||
"task": {
|
||||
"id": "5bfb729a-a7c8-4a78-a7c3-8d717bb7c13c",
|
||||
"versionSpec": "2.*",
|
||||
"definitionType": "task"
|
||||
},
|
||||
"inputs": {
|
||||
"SourceFolder": "outputs",
|
||||
"Contents": "**",
|
||||
"TargetFolder": "Code/Modeling/buildartifacts",
|
||||
"CleanTargetFolder": "false",
|
||||
"OverWrite": "false",
|
||||
"flattenFolders": "false"
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"enabled": true,
|
||||
"continueOnError": false,
|
||||
"alwaysRun": false,
|
||||
"displayName": "Publish Model Artifacts",
|
||||
"timeoutInMinutes": 0,
|
||||
"condition": "succeeded()",
|
||||
"task": {
|
||||
"id": "2ff763a7-ce83-4e1f-bc89-0ae63477cebe",
|
||||
"versionSpec": "1.*",
|
||||
"definitionType": "task"
|
||||
},
|
||||
"inputs": {
|
||||
"PathtoPublish": "Code/Modeling",
|
||||
"ArtifactName": "modelartifacts",
|
||||
"ArtifactType": "Container",
|
||||
"TargetPath": "",
|
||||
"Parallel": "false",
|
||||
"ParallelCount": "8"
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "Agent Phase",
|
||||
"refName": "Phase_2",
|
||||
"condition": "succeeded()",
|
||||
"target": {
|
||||
"executionOptions": {
|
||||
"type": 0
|
||||
},
|
||||
"allowScriptsAuthAccessOption": false,
|
||||
"type": 1
|
||||
},
|
||||
"jobAuthorizationScope": 1,
|
||||
"jobCancelTimeoutInMinutes": 1
|
||||
}
|
||||
],
|
||||
"type": 1
|
||||
},
|
||||
"repository": {
|
||||
"properties": {
|
||||
"apiUrl": "https://api.github.com/repos/user/Azure-TDSP-DevOps-Template",
|
||||
"branchesUrl": "https://api.github.com/repos/user/Azure-TDSP-DevOps-Template/branches",
|
||||
"cloneUrl": "https://github.com/user/Azure-TDSP-DevOps-Template.git",
|
||||
"fullName": "user/Azure-TDSP-DevOps-Template",
|
||||
"manageUrl": "https://github.com/user/Azure-TDSP-DevOps-Template",
|
||||
"refsUrl": "https://api.github.com/repos/user/Azure-TDSP-DevOps-Template/git/refs",
|
||||
"defaultBranch": "master",
|
||||
"connectedServiceId": "8f189c40-5897-4ada-9cce-df147f88fa57",
|
||||
"isPrivate": "False",
|
||||
"isFork": "True",
|
||||
"ownerAvatarUrl": "https://avatars2.githubusercontent.com/u/872065?v=4",
|
||||
"lastUpdated": "02/09/2019 21:51:45",
|
||||
"nodeId": "MDEwOlJlcG9zaXRvcnkxNjE2OTgyMjc=",
|
||||
"hasAdminPermissions": "True",
|
||||
"safeOwnerId": "5848F3A00730FC1BBD623A19F26B0C66A2094333D2CF4382C9FD3483C02D5699D4A8932BB7FDE482121158ED9B8F66CE4A055D40DF47AB8C965FF7A9B8BA",
|
||||
"ownerId": "872065",
|
||||
"safeRepository": "Azure-TDSP-DevOps-Template",
|
||||
"ownerIsAUser": "True",
|
||||
"checkoutNestedSubmodules": "false",
|
||||
"cleanOptions": "0",
|
||||
"fetchDepth": "0",
|
||||
"gitLfsSupport": "false",
|
||||
"reportBuildStatus": "true",
|
||||
"skipSyncSource": "false",
|
||||
"labelSourcesFormat": "$(build.buildNumber)",
|
||||
"labelSources": "0"
|
||||
},
|
||||
"id": "user/Azure-TDSP-DevOps-Template",
|
||||
"type": "GitHub",
|
||||
"name": "user/Azure-TDSP-DevOps-Template",
|
||||
"url": "https://github.com/user/Azure-TDSP-DevOps-Template.git",
|
||||
"defaultBranch": "master",
|
||||
"clean": "false",
|
||||
"checkoutSubmodules": false
|
||||
},
|
||||
"processParameters": {},
|
||||
"quality": 1,
|
||||
"authoredBy": {
|
||||
"displayName": "user",
|
||||
"url": "https://spsprodweu3.vssps.visualstudio.com/Ae8b74699-309d-4bdc-b628-67015b7fd300/_apis/Identities/73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"_links": {
|
||||
"avatar": {
|
||||
"href": "https://dev.azure.com//_apis/GraphProfile/MemberAvatars/aad.NzNkNGQyYjAtOWNhYi03YzZhLWFhYzYtNTUxZWFmNWM0Njcy"
|
||||
}
|
||||
},
|
||||
"id": "73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"uniqueName": "@microsoft.com",
|
||||
"imageUrl": "https://dev.azure.com//_api/_common/identityImage?id=73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"descriptor": "aad.NzNkNGQyYjAtOWNhYi03YzZhLWFhYzYtNTUxZWFmNWM0Njcy"
|
||||
},
|
||||
"drafts": [],
|
||||
"queue": {
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": "https://dev.azure.com//_apis/build/Queues/35"
|
||||
}
|
||||
},
|
||||
"id": 35,
|
||||
"name": "Hosted Ubuntu 1604",
|
||||
"url": "https://dev.azure.com//_apis/build/Queues/35",
|
||||
"pool": {
|
||||
"id": 6,
|
||||
"name": "Hosted Ubuntu 1604",
|
||||
"isHosted": true
|
||||
}
|
||||
},
|
||||
"id": 13,
|
||||
"name": "Build Model",
|
||||
"url": "https://dev.azure.com//3ec38c18-3edc-45c6-9a06-33069ee6e54e/_apis/build/Definitions/13?revision=62",
|
||||
"uri": "vstfs:///Build/Definition/13",
|
||||
"path": "\\",
|
||||
"type": 2,
|
||||
"queueStatus": 0,
|
||||
"revision": 62,
|
||||
"createdDate": "2019-02-10T20:19:04.293Z",
|
||||
"project": {
|
||||
"id": "3ec38c18-3edc-45c6-9a06-33069ee6e54e",
|
||||
"name": "DevOps for AI",
|
||||
"url": "https://dev.azure.com//_apis/projects/3ec38c18-3edc-45c6-9a06-33069ee6e54e",
|
||||
"state": 1,
|
||||
"revision": 57,
|
||||
"visibility": 0,
|
||||
"lastUpdateTime": "2018-08-15T15:07:27.100Z"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,515 @@
|
|||
{
|
||||
"source": 2,
|
||||
"revision": 108,
|
||||
"description": null,
|
||||
"createdBy": {
|
||||
"displayName": "",
|
||||
"url": "https://spsprodweu3.vssps.visualstudio.com/Ae8b74699-309d-4bdc-b628-67015b7fd300/_apis/Identities/73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"_links": {
|
||||
"avatar": {
|
||||
"href": "https://dev.azure.com/account/_apis/GraphProfile/MemberAvatars/aad.NzNkNGQyYjAtOWNhYi03YzZhLWFhYzYtNTUxZWFmNWM0Njcy"
|
||||
}
|
||||
},
|
||||
"id": "73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"uniqueName": "account@microsoft.com",
|
||||
"imageUrl": "https://dev.azure.com/account/_api/_common/identityImage?id=73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"descriptor": "aad.NzNkNGQyYjAtOWNhYi03YzZhLWFhYzYtNTUxZWFmNWM0Njcy"
|
||||
},
|
||||
"createdOn": "2019-01-24T09:38:09.313Z",
|
||||
"modifiedBy": {
|
||||
"displayName": "user",
|
||||
"url": "https://spsprodweu3.vssps.visualstudio.com/Ae8b74699-309d-4bdc-b628-67015b7fd300/_apis/Identities/73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"_links": {
|
||||
"avatar": {
|
||||
"href": "https://dev.azure.com/account/_apis/GraphProfile/MemberAvatars/aad.NzNkNGQyYjAtOWNhYi03YzZhLWFhYzYtNTUxZWFmNWM0Njcy"
|
||||
}
|
||||
},
|
||||
"id": "73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"uniqueName": "account@microsoft.com",
|
||||
"imageUrl": "https://dev.azure.com/account/_api/_common/identityImage?id=73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"descriptor": "aad.NzNkNGQyYjAtOWNhYi03YzZhLWFhYzYtNTUxZWFmNWM0Njcy"
|
||||
},
|
||||
"modifiedOn": "2019-02-07T15:25:50.063Z",
|
||||
"isDeleted": false,
|
||||
"variables": {},
|
||||
"variableGroups": [],
|
||||
"environments": [
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Dev",
|
||||
"rank": 1,
|
||||
"owner": {
|
||||
"displayName": "Name",
|
||||
"url": "https://spsprodweu3.vssps.visualstudio.com/Ae8b74699-309d-4bdc-b628-67015b7fd300/_apis/Identities/73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"_links": {
|
||||
"avatar": {
|
||||
"href": "https://dev.azure.com/account/_apis/GraphProfile/MemberAvatars/aad.NzNkNGQyYjAtOWNhYi03YzZhLWFhYzYtNTUxZWFmNWM0Njcy"
|
||||
}
|
||||
},
|
||||
"id": "73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"uniqueName": "account@microsoft.com",
|
||||
"imageUrl": "https://dev.azure.com/account/_api/_common/identityImage?id=73d4d2b0-9cab-6c6a-aac6-551eaf5c4672",
|
||||
"descriptor": "aad.NzNkNGQyYjAtOWNhYi03YzZhLWFhYzYtNTUxZWFmNWM0Njcy"
|
||||
},
|
||||
"variables": {},
|
||||
"variableGroups": [
|
||||
3
|
||||
],
|
||||
"preDeployApprovals": {
|
||||
"approvals": [
|
||||
{
|
||||
"rank": 1,
|
||||
"isAutomated": true,
|
||||
"isNotificationOn": false,
|
||||
"id": 18
|
||||
}
|
||||
],
|
||||
"approvalOptions": {
|
||||
"requiredApproverCount": null,
|
||||
"releaseCreatorCanBeApprover": false,
|
||||
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
|
||||
"enforceIdentityRevalidation": false,
|
||||
"timeoutInMinutes": 0,
|
||||
"executionOrder": 1
|
||||
}
|
||||
},
|
||||
"deployStep": {
|
||||
"id": 19
|
||||
},
|
||||
"postDeployApprovals": {
|
||||
"approvals": [
|
||||
{
|
||||
"rank": 1,
|
||||
"isAutomated": true,
|
||||
"isNotificationOn": false,
|
||||
"id": 20
|
||||
}
|
||||
],
|
||||
"approvalOptions": {
|
||||
"requiredApproverCount": null,
|
||||
"releaseCreatorCanBeApprover": false,
|
||||
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
|
||||
"enforceIdentityRevalidation": false,
|
||||
"timeoutInMinutes": 0,
|
||||
"executionOrder": 2
|
||||
}
|
||||
},
|
||||
"deployPhases": [
|
||||
{
|
||||
"deploymentInput": {
|
||||
"parallelExecution": {
|
||||
"parallelExecutionType": 0
|
||||
},
|
||||
"skipArtifactsDownload": false,
|
||||
"artifactsDownloadInput": {
|
||||
"downloadInputs": [
|
||||
{
|
||||
"artifactItems": [],
|
||||
"alias": "resourcetemplates",
|
||||
"artifactType": "Build",
|
||||
"artifactDownloadMode": "All"
|
||||
}
|
||||
]
|
||||
},
|
||||
"queueId": 35,
|
||||
"demands": [],
|
||||
"enableAccessToken": false,
|
||||
"timeoutInMinutes": 0,
|
||||
"jobCancelTimeoutInMinutes": 1,
|
||||
"condition": "succeeded()",
|
||||
"overrideInputs": {}
|
||||
},
|
||||
"rank": 1,
|
||||
"phaseType": 1,
|
||||
"name": "Agent job",
|
||||
"refName": null,
|
||||
"workflowTasks": [
|
||||
{
|
||||
"environment": {},
|
||||
"taskId": "94a74903-f93f-4075-884f-dc11f34058b4",
|
||||
"version": "2.*",
|
||||
"name": "Azure Deployment: Application Insights",
|
||||
"refName": "",
|
||||
"enabled": true,
|
||||
"alwaysRun": false,
|
||||
"continueOnError": false,
|
||||
"timeoutInMinutes": 0,
|
||||
"definitionType": "task",
|
||||
"overrideInputs": {},
|
||||
"condition": "succeeded()",
|
||||
"inputs": {
|
||||
"ConnectedServiceName": "b324cb93-5a35-4117-bd1d-03a0438c86a3",
|
||||
"action": "Create Or Update Resource Group",
|
||||
"resourceGroupName": "$(rgname)",
|
||||
"location": "$(azureregion)",
|
||||
"templateLocation": "Linked artifact",
|
||||
"csmFileLink": "",
|
||||
"csmParametersFileLink": "",
|
||||
"csmFile": "$(System.DefaultWorkingDirectory)/resourcetemplates/resourcetemplates/appinsights/template.json",
|
||||
"csmParametersFile": "$(System.DefaultWorkingDirectory)/resourcetemplates/resourcetemplates/appinsights/parameters.json",
|
||||
"overrideParameters": "-name $(appInsightsName) -type \"other\" -regionId $(azureregion) -requestSource \"IbizaAIExtension\"",
|
||||
"deploymentMode": "Incremental",
|
||||
"enableDeploymentPrerequisites": "None",
|
||||
"deploymentGroupEndpoint": "",
|
||||
"project": "",
|
||||
"deploymentGroupName": "",
|
||||
"copyAzureVMTags": "true",
|
||||
"runAgentServiceAsUser": "false",
|
||||
"userName": "",
|
||||
"password": "",
|
||||
"outputVariable": "",
|
||||
"deploymentName": "",
|
||||
"deploymentOutputs": "AppInsightsOutput"
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"taskId": "94a74903-f93f-4075-884f-dc11f34058b4",
|
||||
"version": "2.*",
|
||||
"name": "Azure Deployment: Storage",
|
||||
"refName": "",
|
||||
"enabled": true,
|
||||
"alwaysRun": false,
|
||||
"continueOnError": false,
|
||||
"timeoutInMinutes": 0,
|
||||
"definitionType": "task",
|
||||
"overrideInputs": {},
|
||||
"condition": "succeeded()",
|
||||
"inputs": {
|
||||
"ConnectedServiceName": "b324cb93-5a35-4117-bd1d-03a0438c86a3",
|
||||
"action": "Create Or Update Resource Group",
|
||||
"resourceGroupName": "$(rgname)",
|
||||
"location": "$(azureregion)",
|
||||
"templateLocation": "Linked artifact",
|
||||
"csmFileLink": "",
|
||||
"csmParametersFileLink": "",
|
||||
"csmFile": "$(System.DefaultWorkingDirectory)/resourcetemplates/resourcetemplates/storage/template.json",
|
||||
"csmParametersFile": "$(System.DefaultWorkingDirectory)/resourcetemplates/resourcetemplates/storage/parameters.json",
|
||||
"overrideParameters": "-location $(azureRegion) -storageAccountName $(storageAccountName) -accountType \"Standard_RAGRS\" -kind \"StorageV2\" -accessTier \"Hot\" -supportsHttpsTrafficOnly true",
|
||||
"deploymentMode": "Incremental",
|
||||
"enableDeploymentPrerequisites": "None",
|
||||
"deploymentGroupEndpoint": "",
|
||||
"project": "",
|
||||
"deploymentGroupName": "",
|
||||
"copyAzureVMTags": "true",
|
||||
"runAgentServiceAsUser": "false",
|
||||
"userName": "",
|
||||
"password": "",
|
||||
"outputVariable": "",
|
||||
"deploymentName": "",
|
||||
"deploymentOutputs": "StorageOutput"
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"taskId": "94a74903-f93f-4075-884f-dc11f34058b4",
|
||||
"version": "2.*",
|
||||
"name": "Azure Deployment: Key Vault",
|
||||
"refName": "",
|
||||
"enabled": true,
|
||||
"alwaysRun": false,
|
||||
"continueOnError": false,
|
||||
"timeoutInMinutes": 0,
|
||||
"definitionType": "task",
|
||||
"overrideInputs": {},
|
||||
"condition": "succeeded()",
|
||||
"inputs": {
|
||||
"ConnectedServiceName": "b324cb93-5a35-4117-bd1d-03a0438c86a3",
|
||||
"action": "Create Or Update Resource Group",
|
||||
"resourceGroupName": "$(rgname)",
|
||||
"location": "$(azureregion)",
|
||||
"templateLocation": "Linked artifact",
|
||||
"csmFileLink": "",
|
||||
"csmParametersFileLink": "",
|
||||
"csmFile": "$(System.DefaultWorkingDirectory)/resourcetemplates/resourcetemplates/keyvault/template.json",
|
||||
"csmParametersFile": "$(System.DefaultWorkingDirectory)/resourcetemplates/resourcetemplates/keyvault/parameters.json",
|
||||
"overrideParameters": "-name $(keyVaultName) -location $(azureregion) -tenantId \"72f988bf-86f1-41af-91ab-2d7cd011db47\" -objectId \"357e0b82-f4db-4e11-b279-654fd1b93629\"",
|
||||
"deploymentMode": "Incremental",
|
||||
"enableDeploymentPrerequisites": "None",
|
||||
"deploymentGroupEndpoint": "",
|
||||
"project": "",
|
||||
"deploymentGroupName": "",
|
||||
"copyAzureVMTags": "true",
|
||||
"runAgentServiceAsUser": "false",
|
||||
"userName": "",
|
||||
"password": "",
|
||||
"outputVariable": "",
|
||||
"deploymentName": "",
|
||||
"deploymentOutputs": "KeyVaultOutput"
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"taskId": "94a74903-f93f-4075-884f-dc11f34058b4",
|
||||
"version": "2.*",
|
||||
"name": "Azure Deployment: Container Registry",
|
||||
"refName": "",
|
||||
"enabled": true,
|
||||
"alwaysRun": false,
|
||||
"continueOnError": false,
|
||||
"timeoutInMinutes": 0,
|
||||
"definitionType": "task",
|
||||
"overrideInputs": {},
|
||||
"condition": "succeeded()",
|
||||
"inputs": {
|
||||
"ConnectedServiceName": "b324cb93-5a35-4117-bd1d-03a0438c86a3",
|
||||
"action": "Create Or Update Resource Group",
|
||||
"resourceGroupName": "$(rgname)",
|
||||
"location": "$(azureregion)",
|
||||
"templateLocation": "Linked artifact",
|
||||
"csmFileLink": "",
|
||||
"csmParametersFileLink": "",
|
||||
"csmFile": "$(System.DefaultWorkingDirectory)/resourcetemplates/resourcetemplates/containerregistry/template.json",
|
||||
"csmParametersFile": "$(System.DefaultWorkingDirectory)/resourcetemplates/resourcetemplates/containerregistry/parameters.json",
|
||||
"overrideParameters": "-name $(acrName) -location $(azureregion)",
|
||||
"deploymentMode": "Incremental",
|
||||
"enableDeploymentPrerequisites": "None",
|
||||
"deploymentGroupEndpoint": "",
|
||||
"project": "",
|
||||
"deploymentGroupName": "",
|
||||
"copyAzureVMTags": "true",
|
||||
"runAgentServiceAsUser": "false",
|
||||
"userName": "",
|
||||
"password": "",
|
||||
"outputVariable": "",
|
||||
"deploymentName": "",
|
||||
"deploymentOutputs": "ContainerRegistryOutput"
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"taskId": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
|
||||
"version": "2.*",
|
||||
"name": "Parse outputs: collect resource IDs",
|
||||
"refName": "",
|
||||
"enabled": true,
|
||||
"alwaysRun": false,
|
||||
"continueOnError": false,
|
||||
"timeoutInMinutes": 0,
|
||||
"definitionType": "task",
|
||||
"overrideInputs": {},
|
||||
"condition": "succeeded()",
|
||||
"inputs": {
|
||||
"targetType": "inline",
|
||||
"filePath": "$(System.DefaultWorkingDirectory)/resourcetemplates/resourcetemplates/parseresourceids.ps1",
|
||||
"arguments": "",
|
||||
"script": "# parse ARM deployment json output\n$appInsights = '$(AppInsightsOutput)' | ConvertFrom-Json\n$storage = '$(StorageOutput)' | ConvertFrom-Json\n$keyvault = '$(KeyVaultOutput)' | ConvertFrom-Json\n$acr = '$(ContainerRegistryOutput)' | ConvertFrom-Json\n\nWrite-Output \"Parsed JSON\"\n\n# save temporary variable\n$appInsightsId = $appInsights.resourceId.value\n$storageId = $storage.resourceId.value\n$keyvaultId = $keyvault.resourceId.value\n$acrId = $acr.resourceId.value\n\n# export Azure DevOps Pipelines variables\nWrite-Host \"Writing resource ids as variables\"\nWrite-Host \"##vso[task.setvariable variable=appInsightsId]$appInsightsId\"\nWrite-Host \"##vso[task.setvariable variable=storageId]$storageId\"\nWrite-Host \"##vso[task.setvariable variable=keyvaultId]$keyvaultId\"\nWrite-Host \"##vso[task.setvariable variable=acrId]$acrId\"",
|
||||
"errorActionPreference": "stop",
|
||||
"failOnStderr": "false",
|
||||
"ignoreLASTEXITCODE": "false",
|
||||
"pwsh": "false",
|
||||
"workingDirectory": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"taskId": "94a74903-f93f-4075-884f-dc11f34058b4",
|
||||
"version": "2.*",
|
||||
"name": "Azure Deployment: ML Workspace",
|
||||
"refName": "",
|
||||
"enabled": true,
|
||||
"alwaysRun": false,
|
||||
"continueOnError": false,
|
||||
"timeoutInMinutes": 0,
|
||||
"definitionType": "task",
|
||||
"overrideInputs": {},
|
||||
"condition": "succeeded()",
|
||||
"inputs": {
|
||||
"ConnectedServiceName": "b324cb93-5a35-4117-bd1d-03a0438c86a3",
|
||||
"action": "Create Or Update Resource Group",
|
||||
"resourceGroupName": "$(rgname)",
|
||||
"location": "$(azureregion)",
|
||||
"templateLocation": "Linked artifact",
|
||||
"csmFileLink": "",
|
||||
"csmParametersFileLink": "",
|
||||
"csmFile": "$(System.DefaultWorkingDirectory)/resourcetemplates/resourcetemplates/mlworkspace/template.json",
|
||||
"csmParametersFile": "$(System.DefaultWorkingDirectory)/resourcetemplates/resourcetemplates/mlworkspace/parameters.json",
|
||||
"overrideParameters": "-machineLearningApiVersion \"2018-11-19\" -description \"\" -friendlyName \"\" -location $(azureregion) -name $(azuremlwsname) -storageAccountId $(storageId) -appInsightsId $(appInsightsId) -containerRegistryId $(acrId) -keyVaultId $(keyvaultId)",
|
||||
"deploymentMode": "Incremental",
|
||||
"enableDeploymentPrerequisites": "None",
|
||||
"deploymentGroupEndpoint": "",
|
||||
"project": "",
|
||||
"deploymentGroupName": "",
|
||||
"copyAzureVMTags": "true",
|
||||
"runAgentServiceAsUser": "false",
|
||||
"userName": "",
|
||||
"password": "",
|
||||
"outputVariable": "",
|
||||
"deploymentName": "",
|
||||
"deploymentOutputs": "workspace"
|
||||
}
|
||||
},
|
||||
{
|
||||
"environment": {},
|
||||
"taskId": "94a74903-f93f-4075-884f-dc11f34058b4",
|
||||
"version": "2.*",
|
||||
"name": "Azure Deployment: ML Compute",
|
||||
"refName": "",
|
||||
"enabled": true,
|
||||
"alwaysRun": false,
|
||||
"continueOnError": false,
|
||||
"timeoutInMinutes": 0,
|
||||
"definitionType": "task",
|
||||
"overrideInputs": {},
|
||||
"condition": "succeeded()",
|
||||
"inputs": {
|
||||
"ConnectedServiceName": "b324cb93-5a35-4117-bd1d-03a0438c86a3",
|
||||
"action": "Create Or Update Resource Group",
|
||||
"resourceGroupName": "$(rgname)",
|
||||
"location": "$(azureregion)",
|
||||
"templateLocation": "Linked artifact",
|
||||
"csmFileLink": "",
|
||||
"csmParametersFileLink": "",
|
||||
"csmFile": "$(System.DefaultWorkingDirectory)/resourcetemplates/resourcetemplates/mlcompute/template.json",
|
||||
"csmParametersFile": "$(System.DefaultWorkingDirectory)/resourcetemplates/resourcetemplates/mlcompute/parameters.json",
|
||||
"overrideParameters": "-workspaceName $(azuremlwsname) -clusterName \"dsvmcluster\" -minNodeCount 0 -maxNodeCount 1 -workspacelocation $(azureregion) -adminUserName \"account\" -adminUserPassword \"tdspTemplate1!\" -vmSize \"Standard_D3_V2\"",
|
||||
"deploymentMode": "Incremental",
|
||||
"enableDeploymentPrerequisites": "None",
|
||||
"deploymentGroupEndpoint": "",
|
||||
"project": "",
|
||||
"deploymentGroupName": "",
|
||||
"copyAzureVMTags": "true",
|
||||
"runAgentServiceAsUser": "false",
|
||||
"userName": "",
|
||||
"password": "",
|
||||
"outputVariable": "",
|
||||
"deploymentName": "",
|
||||
"deploymentOutputs": "workspace"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"environmentOptions": {
|
||||
"emailNotificationType": "OnlyOnFailure",
|
||||
"emailRecipients": "release.environment.owner;release.creator",
|
||||
"skipArtifactsDownload": false,
|
||||
"timeoutInMinutes": 0,
|
||||
"enableAccessToken": false,
|
||||
"publishDeploymentStatus": true,
|
||||
"badgeEnabled": false,
|
||||
"autoLinkWorkItems": false,
|
||||
"pullRequestDeploymentEnabled": false
|
||||
},
|
||||
"demands": [],
|
||||
"conditions": [
|
||||
{
|
||||
"name": "ReleaseStarted",
|
||||
"conditionType": 1,
|
||||
"value": ""
|
||||
}
|
||||
],
|
||||
"executionPolicy": {
|
||||
"concurrencyCount": 1,
|
||||
"queueDepthCount": 0
|
||||
},
|
||||
"schedules": [],
|
||||
"currentRelease": {
|
||||
"id": 174,
|
||||
"url": "https://vsrm.dev.azure.com/account/12345678/_apis/Release/releases/174",
|
||||
"_links": {}
|
||||
},
|
||||
"retentionPolicy": {
|
||||
"daysToKeep": 30,
|
||||
"releasesToKeep": 3,
|
||||
"retainBuild": true
|
||||
},
|
||||
"processParameters": {},
|
||||
"properties": {},
|
||||
"preDeploymentGates": {
|
||||
"id": 0,
|
||||
"gatesOptions": null,
|
||||
"gates": []
|
||||
},
|
||||
"postDeploymentGates": {
|
||||
"id": 0,
|
||||
"gatesOptions": null,
|
||||
"gates": []
|
||||
},
|
||||
"environmentTriggers": [],
|
||||
"badgeUrl": "https://vsrm.dev.azure.com/account/_apis/public/Release/badge/12345678/2/4"
|
||||
}
|
||||
],
|
||||
"artifacts": [
|
||||
{
|
||||
"sourceId": "12345678:11",
|
||||
"type": "Build",
|
||||
"alias": "resourcetemplates",
|
||||
"definitionReference": {
|
||||
"artifactSourceDefinitionUrl": {
|
||||
"id": "https://dev.azure.com/account/_permalink/_build/index?collectionId=d7938a7e-2dbb-412d-bce1-3608e05e59c0&projectId=12345678&definitionId=11",
|
||||
"name": ""
|
||||
},
|
||||
"defaultVersionBranch": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
},
|
||||
"defaultVersionSpecific": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
},
|
||||
"defaultVersionTags": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
},
|
||||
"defaultVersionType": {
|
||||
"id": "selectDuringReleaseCreationType",
|
||||
"name": "Specify at the time of release creation"
|
||||
},
|
||||
"definition": {
|
||||
"id": "11",
|
||||
"name": "Publish Resource Templates"
|
||||
},
|
||||
"definitions": {
|
||||
"id": "",
|
||||
"name": ""
|
||||
},
|
||||
"IsMultiDefinitionType": {
|
||||
"id": "False",
|
||||
"name": "False"
|
||||
},
|
||||
"project": {
|
||||
"id": "12345678",
|
||||
"name": "DevOps for AI"
|
||||
},
|
||||
"repository": {
|
||||
"id": "b5f121ca-e7e2-4e25-9e63-636960663e94",
|
||||
"name": "DevOpsforAI-template"
|
||||
}
|
||||
},
|
||||
"isPrimary": true,
|
||||
"isRetained": false
|
||||
}
|
||||
],
|
||||
"triggers": [
|
||||
{
|
||||
"artifactAlias": "resourcetemplates",
|
||||
"triggerConditions": [],
|
||||
"triggerType": 1
|
||||
}
|
||||
],
|
||||
"releaseNameFormat": "Release-$(rev:r)",
|
||||
"tags": [],
|
||||
"pipelineProcess": {
|
||||
"type": 1
|
||||
},
|
||||
"properties": {
|
||||
"DefinitionCreationSource": {
|
||||
"$type": "System.String",
|
||||
"$value": "Other"
|
||||
}
|
||||
},
|
||||
"id": 2,
|
||||
"name": "Provision Resources",
|
||||
"path": "\\",
|
||||
"projectReference": null,
|
||||
"url": "https://vsrm.dev.azure.com/account/12345678/_apis/Release/definitions/2",
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": "https://vsrm.dev.azure.com/account/12345678/_apis/Release/definitions/2"
|
||||
},
|
||||
"web": {
|
||||
"href": "https://dev.azure.com/account/12345678/_release?definitionId=2"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
# @TODO
|
||||
# Deserialize training pipeline
|
||||
# Run training pipeline
|
||||
# Deserialize scoring pipeline
|
||||
# Deploy scoring pipeline
|
|
@ -0,0 +1 @@
|
|||
# @TODO
|
|
@ -0,0 +1,3 @@
|
|||
# This folder contains dashboards e.g. end-user facing or for reporting purposes #
|
||||
|
||||
Use git-lfs for large binary files such as PowerBI reports.
|
|
@ -0,0 +1 @@
|
|||
# model monitoring
|
|
@ -0,0 +1,13 @@
|
|||
"""
|
||||
Model monitoring pipeline
|
||||
|
||||
Runs monitoring script by schedule (e.g. using Azure ML Pipelines and
|
||||
Azure Data Factory or as an Azure Function)
|
||||
@TODO read model training data
|
||||
@TODO read model collected data
|
||||
"""
|
||||
# Monitor Data Quality
|
||||
|
||||
# Monitor Model Performance
|
||||
|
||||
# Monitor Business KPIs
|
|
@ -0,0 +1,2 @@
|
|||
# Deployment templates #
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
// Requires the following Azure NuGet packages and related dependencies:
|
||||
// package id="Microsoft.Azure.Management.Authorization" version="2.0.0"
|
||||
// package id="Microsoft.Azure.Management.ResourceManager" version="1.4.0-preview"
|
||||
// package id="Microsoft.Rest.ClientRuntime.Azure.Authentication" version="2.2.8-preview"
|
||||
|
||||
using Microsoft.Azure.Management.ResourceManager;
|
||||
using Microsoft.Azure.Management.ResourceManager.Models;
|
||||
using Microsoft.Rest.Azure.Authentication;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace PortalGenerated
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a helper class for deploying an Azure Resource Manager template
|
||||
/// More info about template deployments can be found here https://go.microsoft.com/fwLink/?LinkID=733371
|
||||
/// </summary>
|
||||
class DeploymentHelper
|
||||
{
|
||||
string subscriptionId = "your-subscription-id";
|
||||
string clientId = "your-service-principal-clientId";
|
||||
string clientSecret = "your-service-principal-client-secret";
|
||||
string resourceGroupName = "resource-group-name";
|
||||
string deploymentName = "deployment-name";
|
||||
string resourceGroupLocation = "resource-group-location"; // must be specified for creating a new resource group
|
||||
string pathToTemplateFile = "path-to-template.json-on-disk";
|
||||
string pathToParameterFile = "path-to-parameters.json-on-disk";
|
||||
string tenantId = "tenant-id";
|
||||
|
||||
public async void Run()
|
||||
{
|
||||
// Try to obtain the service credentials
|
||||
var serviceCreds = await ApplicationTokenProvider.LoginSilentAsync(tenantId, clientId, clientSecret);
|
||||
|
||||
// Read the template and parameter file contents
|
||||
JObject templateFileContents = GetJsonFileContents(pathToTemplateFile);
|
||||
JObject parameterFileContents = GetJsonFileContents(pathToParameterFile);
|
||||
|
||||
// Create the resource manager client
|
||||
var resourceManagementClient = new ResourceManagementClient(serviceCreds);
|
||||
resourceManagementClient.SubscriptionId = subscriptionId;
|
||||
|
||||
// Create or check that resource group exists
|
||||
EnsureResourceGroupExists(resourceManagementClient, resourceGroupName, resourceGroupLocation);
|
||||
|
||||
// Start a deployment
|
||||
DeployTemplate(resourceManagementClient, resourceGroupName, deploymentName, templateFileContents, parameterFileContents);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a JSON file from the specified path
|
||||
/// </summary>
|
||||
/// <param name="pathToJson">The full path to the JSON file</param>
|
||||
/// <returns>The JSON file contents</returns>
|
||||
private JObject GetJsonFileContents(string pathToJson)
|
||||
{
|
||||
JObject templatefileContent = new JObject();
|
||||
using (StreamReader file = File.OpenText(pathToJson))
|
||||
{
|
||||
using (JsonTextReader reader = new JsonTextReader(file))
|
||||
{
|
||||
templatefileContent = (JObject)JToken.ReadFrom(reader);
|
||||
return templatefileContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that a resource group with the specified name exists. If it does not, will attempt to create one.
|
||||
/// </summary>
|
||||
/// <param name="resourceManagementClient">The resource manager client.</param>
|
||||
/// <param name="resourceGroupName">The name of the resource group.</param>
|
||||
/// <param name="resourceGroupLocation">The resource group location. Required when creating a new resource group.</param>
|
||||
private static void EnsureResourceGroupExists(ResourceManagementClient resourceManagementClient, string resourceGroupName, string resourceGroupLocation)
|
||||
{
|
||||
if (resourceManagementClient.ResourceGroups.CheckExistence(resourceGroupName) != true)
|
||||
{
|
||||
Console.WriteLine(string.Format("Creating resource group '{0}' in location '{1}'", resourceGroupName, resourceGroupLocation));
|
||||
var resourceGroup = new ResourceGroup();
|
||||
resourceGroup.Location = resourceGroupLocation;
|
||||
resourceManagementClient.ResourceGroups.CreateOrUpdate(resourceGroupName, resourceGroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(string.Format("Using existing resource group '{0}'", resourceGroupName));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a template deployment.
|
||||
/// </summary>
|
||||
/// <param name="resourceManagementClient">The resource manager client.</param>
|
||||
/// <param name="resourceGroupName">The name of the resource group.</param>
|
||||
/// <param name="deploymentName">The name of the deployment.</param>
|
||||
/// <param name="templateFileContents">The template file contents.</param>
|
||||
/// <param name="parameterFileContents">The parameter file contents.</param>
|
||||
private static void DeployTemplate(ResourceManagementClient resourceManagementClient, string resourceGroupName, string deploymentName, JObject templateFileContents, JObject parameterFileContents)
|
||||
{
|
||||
Console.WriteLine(string.Format("Starting template deployment '{0}' in resource group '{1}'", deploymentName, resourceGroupName));
|
||||
var deployment = new Deployment();
|
||||
|
||||
deployment.Properties = new DeploymentProperties
|
||||
{
|
||||
Mode = DeploymentMode.Incremental,
|
||||
Template = templateFileContents,
|
||||
Parameters = parameterFileContents["parameters"].ToObject<JObject>()
|
||||
};
|
||||
|
||||
var deploymentResult = resourceManagementClient.Deployments.CreateOrUpdate(resourceGroupName, deploymentName, deployment);
|
||||
Console.WriteLine(string.Format("Deployment status: {0}", deploymentResult.Properties.ProvisioningState));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
<#
|
||||
.SYNOPSIS
|
||||
Deploys a template to Azure
|
||||
|
||||
.DESCRIPTION
|
||||
Deploys an Azure Resource Manager template
|
||||
|
||||
.PARAMETER subscriptionId
|
||||
The subscription id where the template will be deployed.
|
||||
|
||||
.PARAMETER resourceGroupName
|
||||
The resource group where the template will be deployed. Can be the name of an existing or a new resource group.
|
||||
|
||||
.PARAMETER resourceGroupLocation
|
||||
Optional, a resource group location. If specified, will try to create a new resource group in this location. If not specified, assumes resource group is existing.
|
||||
|
||||
.PARAMETER deploymentName
|
||||
The deployment name.
|
||||
|
||||
.PARAMETER templateFilePath
|
||||
Optional, path to the template file. Defaults to template.json.
|
||||
|
||||
.PARAMETER parametersFilePath
|
||||
Optional, path to the parameters file. Defaults to parameters.json. If file is not found, will prompt for parameter values based on template.
|
||||
#>
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$subscriptionId,
|
||||
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$resourceGroupName,
|
||||
|
||||
[string]
|
||||
$resourceGroupLocation,
|
||||
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$deploymentName,
|
||||
|
||||
[string]
|
||||
$templateFilePath = "template.json",
|
||||
|
||||
[string]
|
||||
$parametersFilePath = "parameters.json"
|
||||
)
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Registers RPs
|
||||
#>
|
||||
Function RegisterRP {
|
||||
Param(
|
||||
[string]$ResourceProviderNamespace
|
||||
)
|
||||
|
||||
Write-Host "Registering resource provider '$ResourceProviderNamespace'";
|
||||
Register-AzureRmResourceProvider -ProviderNamespace $ResourceProviderNamespace;
|
||||
}
|
||||
|
||||
#******************************************************************************
|
||||
# Script body
|
||||
# Execution begins here
|
||||
#******************************************************************************
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# sign in
|
||||
Write-Host "Logging in...";
|
||||
Login-AzureRmAccount;
|
||||
|
||||
# select subscription
|
||||
Write-Host "Selecting subscription '$subscriptionId'";
|
||||
Select-AzureRmSubscription -SubscriptionID $subscriptionId;
|
||||
|
||||
# Register RPs
|
||||
$resourceProviders = @("microsoft.insights");
|
||||
if($resourceProviders.length) {
|
||||
Write-Host "Registering resource providers"
|
||||
foreach($resourceProvider in $resourceProviders) {
|
||||
RegisterRP($resourceProvider);
|
||||
}
|
||||
}
|
||||
|
||||
#Create or check for existing resource group
|
||||
$resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue
|
||||
if(!$resourceGroup)
|
||||
{
|
||||
Write-Host "Resource group '$resourceGroupName' does not exist. To create a new resource group, please enter a location.";
|
||||
if(!$resourceGroupLocation) {
|
||||
$resourceGroupLocation = Read-Host "resourceGroupLocation";
|
||||
}
|
||||
Write-Host "Creating resource group '$resourceGroupName' in location '$resourceGroupLocation'";
|
||||
New-AzureRmResourceGroup -Name $resourceGroupName -Location $resourceGroupLocation
|
||||
}
|
||||
else{
|
||||
Write-Host "Using existing resource group '$resourceGroupName'";
|
||||
}
|
||||
|
||||
# Start the deployment
|
||||
Write-Host "Starting deployment...";
|
||||
if(Test-Path $parametersFilePath) {
|
||||
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName -TemplateFile $templateFilePath -TemplateParameterFile $parametersFilePath;
|
||||
} else {
|
||||
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName -TemplateFile $templateFilePath;
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
# -e: immediately exit if any command has a non-zero exit status
|
||||
# -o: prevents errors in a pipeline from being masked
|
||||
# IFS new value is less likely to cause confusing bugs when looping arrays or arguments (e.g. $@)
|
||||
|
||||
usage() { echo "Usage: $0 -i <subscriptionId> -g <resourceGroupName> -n <deploymentName> -l <resourceGroupLocation>" 1>&2; exit 1; }
|
||||
|
||||
declare subscriptionId=""
|
||||
declare resourceGroupName=""
|
||||
declare deploymentName=""
|
||||
declare resourceGroupLocation=""
|
||||
|
||||
# Initialize parameters specified from command line
|
||||
while getopts ":i:g:n:l:" arg; do
|
||||
case "${arg}" in
|
||||
i)
|
||||
subscriptionId=${OPTARG}
|
||||
;;
|
||||
g)
|
||||
resourceGroupName=${OPTARG}
|
||||
;;
|
||||
n)
|
||||
deploymentName=${OPTARG}
|
||||
;;
|
||||
l)
|
||||
resourceGroupLocation=${OPTARG}
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
#Prompt for parameters is some required parameters are missing
|
||||
if [[ -z "$subscriptionId" ]]; then
|
||||
echo "Your subscription ID can be looked up with the CLI using: az account show --out json "
|
||||
echo "Enter your subscription ID:"
|
||||
read subscriptionId
|
||||
[[ "${subscriptionId:?}" ]]
|
||||
fi
|
||||
|
||||
if [[ -z "$resourceGroupName" ]]; then
|
||||
echo "This script will look for an existing resource group, otherwise a new one will be created "
|
||||
echo "You can create new resource groups with the CLI using: az group create "
|
||||
echo "Enter a resource group name"
|
||||
read resourceGroupName
|
||||
[[ "${resourceGroupName:?}" ]]
|
||||
fi
|
||||
|
||||
if [[ -z "$deploymentName" ]]; then
|
||||
echo "Enter a name for this deployment:"
|
||||
read deploymentName
|
||||
fi
|
||||
|
||||
if [[ -z "$resourceGroupLocation" ]]; then
|
||||
echo "If creating a *new* resource group, you need to set a location "
|
||||
echo "You can lookup locations with the CLI using: az account list-locations "
|
||||
|
||||
echo "Enter resource group location:"
|
||||
read resourceGroupLocation
|
||||
fi
|
||||
|
||||
#templateFile Path - template file to be used
|
||||
templateFilePath="template.json"
|
||||
|
||||
if [ ! -f "$templateFilePath" ]; then
|
||||
echo "$templateFilePath not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#parameter file path
|
||||
parametersFilePath="parameters.json"
|
||||
|
||||
if [ ! -f "$parametersFilePath" ]; then
|
||||
echo "$parametersFilePath not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$subscriptionId" ] || [ -z "$resourceGroupName" ] || [ -z "$deploymentName" ]; then
|
||||
echo "Either one of subscriptionId, resourceGroupName, deploymentName is empty"
|
||||
usage
|
||||
fi
|
||||
|
||||
#login to azure using your credentials
|
||||
az account show 1> /dev/null
|
||||
|
||||
if [ $? != 0 ];
|
||||
then
|
||||
az login
|
||||
fi
|
||||
|
||||
#set the default subscription id
|
||||
az account set --subscription $subscriptionId
|
||||
|
||||
set +e
|
||||
|
||||
#Check for existing RG
|
||||
az group show --name $resourceGroupName 1> /dev/null
|
||||
|
||||
if [ $? != 0 ]; then
|
||||
echo "Resource group with name" $resourceGroupName "could not be found. Creating new resource group.."
|
||||
set -e
|
||||
(
|
||||
set -x
|
||||
az group create --name $resourceGroupName --location $resourceGroupLocation 1> /dev/null
|
||||
)
|
||||
else
|
||||
echo "Using existing resource group..."
|
||||
fi
|
||||
|
||||
#Start deployment
|
||||
echo "Starting deployment..."
|
||||
(
|
||||
set -x
|
||||
az group deployment create --name "$deploymentName" --resource-group "$resourceGroupName" --template-file "$templateFilePath" --parameters "@${parametersFilePath}"
|
||||
)
|
||||
|
||||
if [ $? == 0 ];
|
||||
then
|
||||
echo "Template has been successfully deployed"
|
||||
fi
|
|
@ -0,0 +1,71 @@
|
|||
require 'azure_mgmt_resources'
|
||||
|
||||
class Deployer
|
||||
|
||||
# Initialize the deployer class with subscription, resource group and resource group location. The class will raise an
|
||||
# ArgumentError if there are empty values for Tenant Id, Client Id or Client Secret environment variables.
|
||||
#
|
||||
# @param [String] subscription_id the subscription to deploy the template
|
||||
# @param [String] resource_group the resource group to create or update and then deploy the template
|
||||
# @param [String] resource_group_location the location of the resource group
|
||||
def initialize(subscription_id, resource_group, resource_group_location)
|
||||
raise ArgumentError.new("Missing template file 'template.json' in current directory.") unless File.exist?('template.json')
|
||||
raise ArgumentError.new("Missing parameters file 'parameters.json' in current directory.") unless File.exist?('parameters.json')
|
||||
@resource_group = resource_group
|
||||
@subscription_id = subscription_id
|
||||
@resource_group_location = resource_group_location
|
||||
provider = MsRestAzure::ApplicationTokenProvider.new(
|
||||
ENV['AZURE_TENANT_ID'],
|
||||
ENV['AZURE_CLIENT_ID'],
|
||||
ENV['AZURE_CLIENT_SECRET'])
|
||||
credentials = MsRest::TokenCredentials.new(provider)
|
||||
@client = Azure::ARM::Resources::ResourceManagementClient.new(credentials)
|
||||
@client.subscription_id = @subscription_id
|
||||
end
|
||||
|
||||
# Deploy the template to a resource group
|
||||
def deploy
|
||||
# ensure the resource group is created
|
||||
params = Azure::ARM::Resources::Models::ResourceGroup.new.tap do |rg|
|
||||
rg.location = @resource_group_location
|
||||
end
|
||||
@client.resource_groups.create_or_update(@resource_group, params).value!
|
||||
|
||||
# build the deployment from a json file template from parameters
|
||||
template = File.read(File.expand_path(File.join(__dir__, 'template.json')))
|
||||
deployment = Azure::ARM::Resources::Models::Deployment.new
|
||||
deployment.properties = Azure::ARM::Resources::Models::DeploymentProperties.new
|
||||
deployment.properties.template = JSON.parse(template)
|
||||
deployment.properties.mode = Azure::ARM::Resources::Models::DeploymentMode::Incremental
|
||||
|
||||
# build the deployment template parameters from Hash to {key: {value: value}} format
|
||||
deploy_params = File.read(File.expand_path(File.join(__dir__, 'parameters.json')))
|
||||
deployment.properties.parameters = JSON.parse(deploy_params)["parameters"]
|
||||
|
||||
# put the deployment to the resource group
|
||||
@client.deployments.create_or_update(@resource_group, 'azure-sample', deployment)
|
||||
end
|
||||
end
|
||||
|
||||
# Get user inputs and execute the script
|
||||
if(ARGV.empty?)
|
||||
puts "Please specify subscriptionId resourceGroupName resourceGroupLocation as command line arguments"
|
||||
exit
|
||||
end
|
||||
|
||||
subscription_id = ARGV[0] # Azure Subscription Id
|
||||
resource_group = ARGV[1] # The resource group for deployment
|
||||
resource_group_location = ARGV[2] # The resource group location
|
||||
|
||||
msg = "\nInitializing the Deployer class with subscription id: #{subscription_id}, resource group: #{resource_group}"
|
||||
msg += "\nand resource group location: #{resource_group_location}...\n\n"
|
||||
puts msg
|
||||
|
||||
# Initialize the deployer class
|
||||
deployer = Deployer.new(subscription_id, resource_group, resource_group_location)
|
||||
|
||||
puts "Beginning the deployment... \n\n"
|
||||
# Deploy the template
|
||||
deployment = deployer.deploy
|
||||
|
||||
puts "Done deploying!!"
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"type": {
|
||||
"value": "other"
|
||||
},
|
||||
"name": {
|
||||
"value": "appinsights"
|
||||
},
|
||||
"regionId": {
|
||||
"value": "westeurope"
|
||||
},
|
||||
"requestSource": {
|
||||
"value": "IbizaAIExtension"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"regionId": {
|
||||
"type": "string"
|
||||
},
|
||||
"requestSource": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"name": "[parameters('name')]",
|
||||
"type": "microsoft.insights/components",
|
||||
"location": "[parameters('regionId')]",
|
||||
"apiVersion": "2014-08-01",
|
||||
"properties": {
|
||||
"ApplicationId": "[parameters('name')]",
|
||||
"Application_Type": "[parameters('type')]",
|
||||
"Flow_Type": "Redfield",
|
||||
"Request_Source": "[parameters('requestSource')]"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": {
|
||||
"resourceId": {
|
||||
"value": "[resourceId('microsoft.insights/components', parameters('name'))]",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
// Requires the following Azure NuGet packages and related dependencies:
|
||||
// package id="Microsoft.Azure.Management.Authorization" version="2.0.0"
|
||||
// package id="Microsoft.Azure.Management.ResourceManager" version="1.4.0-preview"
|
||||
// package id="Microsoft.Rest.ClientRuntime.Azure.Authentication" version="2.2.8-preview"
|
||||
|
||||
using Microsoft.Azure.Management.ResourceManager;
|
||||
using Microsoft.Azure.Management.ResourceManager.Models;
|
||||
using Microsoft.Rest.Azure.Authentication;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace PortalGenerated
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a helper class for deploying an Azure Resource Manager template
|
||||
/// More info about template deployments can be found here https://go.microsoft.com/fwLink/?LinkID=733371
|
||||
/// </summary>
|
||||
class DeploymentHelper
|
||||
{
|
||||
string subscriptionId = "your-subscription-id";
|
||||
string clientId = "your-service-principal-clientId";
|
||||
string clientSecret = "your-service-principal-client-secret";
|
||||
string resourceGroupName = "resource-group-name";
|
||||
string deploymentName = "deployment-name";
|
||||
string resourceGroupLocation = "resource-group-location"; // must be specified for creating a new resource group
|
||||
string pathToTemplateFile = "path-to-template.json-on-disk";
|
||||
string pathToParameterFile = "path-to-parameters.json-on-disk";
|
||||
string tenantId = "tenant-id";
|
||||
|
||||
public async void Run()
|
||||
{
|
||||
// Try to obtain the service credentials
|
||||
var serviceCreds = await ApplicationTokenProvider.LoginSilentAsync(tenantId, clientId, clientSecret);
|
||||
|
||||
// Read the template and parameter file contents
|
||||
JObject templateFileContents = GetJsonFileContents(pathToTemplateFile);
|
||||
JObject parameterFileContents = GetJsonFileContents(pathToParameterFile);
|
||||
|
||||
// Create the resource manager client
|
||||
var resourceManagementClient = new ResourceManagementClient(serviceCreds);
|
||||
resourceManagementClient.SubscriptionId = subscriptionId;
|
||||
|
||||
// Create or check that resource group exists
|
||||
EnsureResourceGroupExists(resourceManagementClient, resourceGroupName, resourceGroupLocation);
|
||||
|
||||
// Start a deployment
|
||||
DeployTemplate(resourceManagementClient, resourceGroupName, deploymentName, templateFileContents, parameterFileContents);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a JSON file from the specified path
|
||||
/// </summary>
|
||||
/// <param name="pathToJson">The full path to the JSON file</param>
|
||||
/// <returns>The JSON file contents</returns>
|
||||
private JObject GetJsonFileContents(string pathToJson)
|
||||
{
|
||||
JObject templatefileContent = new JObject();
|
||||
using (StreamReader file = File.OpenText(pathToJson))
|
||||
{
|
||||
using (JsonTextReader reader = new JsonTextReader(file))
|
||||
{
|
||||
templatefileContent = (JObject)JToken.ReadFrom(reader);
|
||||
return templatefileContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that a resource group with the specified name exists. If it does not, will attempt to create one.
|
||||
/// </summary>
|
||||
/// <param name="resourceManagementClient">The resource manager client.</param>
|
||||
/// <param name="resourceGroupName">The name of the resource group.</param>
|
||||
/// <param name="resourceGroupLocation">The resource group location. Required when creating a new resource group.</param>
|
||||
private static void EnsureResourceGroupExists(ResourceManagementClient resourceManagementClient, string resourceGroupName, string resourceGroupLocation)
|
||||
{
|
||||
if (resourceManagementClient.ResourceGroups.CheckExistence(resourceGroupName) != true)
|
||||
{
|
||||
Console.WriteLine(string.Format("Creating resource group '{0}' in location '{1}'", resourceGroupName, resourceGroupLocation));
|
||||
var resourceGroup = new ResourceGroup();
|
||||
resourceGroup.Location = resourceGroupLocation;
|
||||
resourceManagementClient.ResourceGroups.CreateOrUpdate(resourceGroupName, resourceGroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(string.Format("Using existing resource group '{0}'", resourceGroupName));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a template deployment.
|
||||
/// </summary>
|
||||
/// <param name="resourceManagementClient">The resource manager client.</param>
|
||||
/// <param name="resourceGroupName">The name of the resource group.</param>
|
||||
/// <param name="deploymentName">The name of the deployment.</param>
|
||||
/// <param name="templateFileContents">The template file contents.</param>
|
||||
/// <param name="parameterFileContents">The parameter file contents.</param>
|
||||
private static void DeployTemplate(ResourceManagementClient resourceManagementClient, string resourceGroupName, string deploymentName, JObject templateFileContents, JObject parameterFileContents)
|
||||
{
|
||||
Console.WriteLine(string.Format("Starting template deployment '{0}' in resource group '{1}'", deploymentName, resourceGroupName));
|
||||
var deployment = new Deployment();
|
||||
|
||||
deployment.Properties = new DeploymentProperties
|
||||
{
|
||||
Mode = DeploymentMode.Incremental,
|
||||
Template = templateFileContents,
|
||||
Parameters = parameterFileContents["parameters"].ToObject<JObject>()
|
||||
};
|
||||
|
||||
var deploymentResult = resourceManagementClient.Deployments.CreateOrUpdate(resourceGroupName, deploymentName, deployment);
|
||||
Console.WriteLine(string.Format("Deployment status: {0}", deploymentResult.Properties.ProvisioningState));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
<#
|
||||
.SYNOPSIS
|
||||
Deploys a template to Azure
|
||||
|
||||
.DESCRIPTION
|
||||
Deploys an Azure Resource Manager template
|
||||
|
||||
.PARAMETER subscriptionId
|
||||
The subscription id where the template will be deployed.
|
||||
|
||||
.PARAMETER resourceGroupName
|
||||
The resource group where the template will be deployed. Can be the name of an existing or a new resource group.
|
||||
|
||||
.PARAMETER resourceGroupLocation
|
||||
Optional, a resource group location. If specified, will try to create a new resource group in this location. If not specified, assumes resource group is existing.
|
||||
|
||||
.PARAMETER deploymentName
|
||||
The deployment name.
|
||||
|
||||
.PARAMETER templateFilePath
|
||||
Optional, path to the template file. Defaults to template.json.
|
||||
|
||||
.PARAMETER parametersFilePath
|
||||
Optional, path to the parameters file. Defaults to parameters.json. If file is not found, will prompt for parameter values based on template.
|
||||
#>
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$subscriptionId,
|
||||
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$resourceGroupName,
|
||||
|
||||
[string]
|
||||
$resourceGroupLocation,
|
||||
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$deploymentName,
|
||||
|
||||
[string]
|
||||
$templateFilePath = "template.json",
|
||||
|
||||
[string]
|
||||
$parametersFilePath = "parameters.json"
|
||||
)
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Registers RPs
|
||||
#>
|
||||
Function RegisterRP {
|
||||
Param(
|
||||
[string]$ResourceProviderNamespace
|
||||
)
|
||||
|
||||
Write-Host "Registering resource provider '$ResourceProviderNamespace'";
|
||||
Register-AzureRmResourceProvider -ProviderNamespace $ResourceProviderNamespace;
|
||||
}
|
||||
|
||||
#******************************************************************************
|
||||
# Script body
|
||||
# Execution begins here
|
||||
#******************************************************************************
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# sign in
|
||||
Write-Host "Logging in...";
|
||||
Login-AzureRmAccount;
|
||||
|
||||
# select subscription
|
||||
Write-Host "Selecting subscription '$subscriptionId'";
|
||||
Select-AzureRmSubscription -SubscriptionID $subscriptionId;
|
||||
|
||||
# Register RPs
|
||||
$resourceProviders = @("microsoft.containerregistry");
|
||||
if($resourceProviders.length) {
|
||||
Write-Host "Registering resource providers"
|
||||
foreach($resourceProvider in $resourceProviders) {
|
||||
RegisterRP($resourceProvider);
|
||||
}
|
||||
}
|
||||
|
||||
#Create or check for existing resource group
|
||||
$resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue
|
||||
if(!$resourceGroup)
|
||||
{
|
||||
Write-Host "Resource group '$resourceGroupName' does not exist. To create a new resource group, please enter a location.";
|
||||
if(!$resourceGroupLocation) {
|
||||
$resourceGroupLocation = Read-Host "resourceGroupLocation";
|
||||
}
|
||||
Write-Host "Creating resource group '$resourceGroupName' in location '$resourceGroupLocation'";
|
||||
New-AzureRmResourceGroup -Name $resourceGroupName -Location $resourceGroupLocation
|
||||
}
|
||||
else{
|
||||
Write-Host "Using existing resource group '$resourceGroupName'";
|
||||
}
|
||||
|
||||
# Start the deployment
|
||||
Write-Host "Starting deployment...";
|
||||
if(Test-Path $parametersFilePath) {
|
||||
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName -TemplateFile $templateFilePath -TemplateParameterFile $parametersFilePath;
|
||||
} else {
|
||||
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName -TemplateFile $templateFilePath;
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
# -e: immediately exit if any command has a non-zero exit status
|
||||
# -o: prevents errors in a pipeline from being masked
|
||||
# IFS new value is less likely to cause confusing bugs when looping arrays or arguments (e.g. $@)
|
||||
|
||||
usage() { echo "Usage: $0 -i <subscriptionId> -g <resourceGroupName> -n <deploymentName> -l <resourceGroupLocation>" 1>&2; exit 1; }
|
||||
|
||||
declare subscriptionId=""
|
||||
declare resourceGroupName=""
|
||||
declare deploymentName=""
|
||||
declare resourceGroupLocation=""
|
||||
|
||||
# Initialize parameters specified from command line
|
||||
while getopts ":i:g:n:l:" arg; do
|
||||
case "${arg}" in
|
||||
i)
|
||||
subscriptionId=${OPTARG}
|
||||
;;
|
||||
g)
|
||||
resourceGroupName=${OPTARG}
|
||||
;;
|
||||
n)
|
||||
deploymentName=${OPTARG}
|
||||
;;
|
||||
l)
|
||||
resourceGroupLocation=${OPTARG}
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
#Prompt for parameters is some required parameters are missing
|
||||
if [[ -z "$subscriptionId" ]]; then
|
||||
echo "Your subscription ID can be looked up with the CLI using: az account show --out json "
|
||||
echo "Enter your subscription ID:"
|
||||
read subscriptionId
|
||||
[[ "${subscriptionId:?}" ]]
|
||||
fi
|
||||
|
||||
if [[ -z "$resourceGroupName" ]]; then
|
||||
echo "This script will look for an existing resource group, otherwise a new one will be created "
|
||||
echo "You can create new resource groups with the CLI using: az group create "
|
||||
echo "Enter a resource group name"
|
||||
read resourceGroupName
|
||||
[[ "${resourceGroupName:?}" ]]
|
||||
fi
|
||||
|
||||
if [[ -z "$deploymentName" ]]; then
|
||||
echo "Enter a name for this deployment:"
|
||||
read deploymentName
|
||||
fi
|
||||
|
||||
if [[ -z "$resourceGroupLocation" ]]; then
|
||||
echo "If creating a *new* resource group, you need to set a location "
|
||||
echo "You can lookup locations with the CLI using: az account list-locations "
|
||||
|
||||
echo "Enter resource group location:"
|
||||
read resourceGroupLocation
|
||||
fi
|
||||
|
||||
#templateFile Path - template file to be used
|
||||
templateFilePath="template.json"
|
||||
|
||||
if [ ! -f "$templateFilePath" ]; then
|
||||
echo "$templateFilePath not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#parameter file path
|
||||
parametersFilePath="parameters.json"
|
||||
|
||||
if [ ! -f "$parametersFilePath" ]; then
|
||||
echo "$parametersFilePath not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$subscriptionId" ] || [ -z "$resourceGroupName" ] || [ -z "$deploymentName" ]; then
|
||||
echo "Either one of subscriptionId, resourceGroupName, deploymentName is empty"
|
||||
usage
|
||||
fi
|
||||
|
||||
#login to azure using your credentials
|
||||
az account show 1> /dev/null
|
||||
|
||||
if [ $? != 0 ];
|
||||
then
|
||||
az login
|
||||
fi
|
||||
|
||||
#set the default subscription id
|
||||
az account set --subscription $subscriptionId
|
||||
|
||||
set +e
|
||||
|
||||
#Check for existing RG
|
||||
az group show --name $resourceGroupName 1> /dev/null
|
||||
|
||||
if [ $? != 0 ]; then
|
||||
echo "Resource group with name" $resourceGroupName "could not be found. Creating new resource group.."
|
||||
set -e
|
||||
(
|
||||
set -x
|
||||
az group create --name $resourceGroupName --location $resourceGroupLocation 1> /dev/null
|
||||
)
|
||||
else
|
||||
echo "Using existing resource group..."
|
||||
fi
|
||||
|
||||
#Start deployment
|
||||
echo "Starting deployment..."
|
||||
(
|
||||
set -x
|
||||
az group deployment create --name "$deploymentName" --resource-group "$resourceGroupName" --template-file "$templateFilePath" --parameters "@${parametersFilePath}"
|
||||
)
|
||||
|
||||
if [ $? == 0 ];
|
||||
then
|
||||
echo "Template has been successfully deployed"
|
||||
fi
|
|
@ -0,0 +1,71 @@
|
|||
require 'azure_mgmt_resources'
|
||||
|
||||
class Deployer
|
||||
|
||||
# Initialize the deployer class with subscription, resource group and resource group location. The class will raise an
|
||||
# ArgumentError if there are empty values for Tenant Id, Client Id or Client Secret environment variables.
|
||||
#
|
||||
# @param [String] subscription_id the subscription to deploy the template
|
||||
# @param [String] resource_group the resource group to create or update and then deploy the template
|
||||
# @param [String] resource_group_location the location of the resource group
|
||||
def initialize(subscription_id, resource_group, resource_group_location)
|
||||
raise ArgumentError.new("Missing template file 'template.json' in current directory.") unless File.exist?('template.json')
|
||||
raise ArgumentError.new("Missing parameters file 'parameters.json' in current directory.") unless File.exist?('parameters.json')
|
||||
@resource_group = resource_group
|
||||
@subscription_id = subscription_id
|
||||
@resource_group_location = resource_group_location
|
||||
provider = MsRestAzure::ApplicationTokenProvider.new(
|
||||
ENV['AZURE_TENANT_ID'],
|
||||
ENV['AZURE_CLIENT_ID'],
|
||||
ENV['AZURE_CLIENT_SECRET'])
|
||||
credentials = MsRest::TokenCredentials.new(provider)
|
||||
@client = Azure::ARM::Resources::ResourceManagementClient.new(credentials)
|
||||
@client.subscription_id = @subscription_id
|
||||
end
|
||||
|
||||
# Deploy the template to a resource group
|
||||
def deploy
|
||||
# ensure the resource group is created
|
||||
params = Azure::ARM::Resources::Models::ResourceGroup.new.tap do |rg|
|
||||
rg.location = @resource_group_location
|
||||
end
|
||||
@client.resource_groups.create_or_update(@resource_group, params).value!
|
||||
|
||||
# build the deployment from a json file template from parameters
|
||||
template = File.read(File.expand_path(File.join(__dir__, 'template.json')))
|
||||
deployment = Azure::ARM::Resources::Models::Deployment.new
|
||||
deployment.properties = Azure::ARM::Resources::Models::DeploymentProperties.new
|
||||
deployment.properties.template = JSON.parse(template)
|
||||
deployment.properties.mode = Azure::ARM::Resources::Models::DeploymentMode::Incremental
|
||||
|
||||
# build the deployment template parameters from Hash to {key: {value: value}} format
|
||||
deploy_params = File.read(File.expand_path(File.join(__dir__, 'parameters.json')))
|
||||
deployment.properties.parameters = JSON.parse(deploy_params)["parameters"]
|
||||
|
||||
# put the deployment to the resource group
|
||||
@client.deployments.create_or_update(@resource_group, 'azure-sample', deployment)
|
||||
end
|
||||
end
|
||||
|
||||
# Get user inputs and execute the script
|
||||
if(ARGV.empty?)
|
||||
puts "Please specify subscriptionId resourceGroupName resourceGroupLocation as command line arguments"
|
||||
exit
|
||||
end
|
||||
|
||||
subscription_id = ARGV[0] # Azure Subscription Id
|
||||
resource_group = ARGV[1] # The resource group for deployment
|
||||
resource_group_location = ARGV[2] # The resource group location
|
||||
|
||||
msg = "\nInitializing the Deployer class with subscription id: #{subscription_id}, resource group: #{resource_group}"
|
||||
msg += "\nand resource group location: #{resource_group_location}...\n\n"
|
||||
puts msg
|
||||
|
||||
# Initialize the deployer class
|
||||
deployer = Deployer.new(subscription_id, resource_group, resource_group_location)
|
||||
|
||||
puts "Beginning the deployment... \n\n"
|
||||
# Deploy the template
|
||||
deployment = deployer.deploy
|
||||
|
||||
puts "Done deploying!!"
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"name": {
|
||||
"value": "containerregistry"
|
||||
},
|
||||
"location": {
|
||||
"value": "westeurope"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"location": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"variables": {},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.ContainerRegistry/registries",
|
||||
"sku": {
|
||||
"name": "Standard",
|
||||
"tier": "Standard"
|
||||
},
|
||||
"name": "[parameters('name')]",
|
||||
"apiVersion": "2017-10-01",
|
||||
"location": "[parameters('location')]",
|
||||
"tags": {},
|
||||
"scale": null,
|
||||
"properties": {
|
||||
"adminUserEnabled": true
|
||||
},
|
||||
"dependsOn": []
|
||||
}
|
||||
],
|
||||
"outputs": {
|
||||
"resourceId": {
|
||||
"value": "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
// Requires the following Azure NuGet packages and related dependencies:
|
||||
// package id="Microsoft.Azure.Management.Authorization" version="2.0.0"
|
||||
// package id="Microsoft.Azure.Management.ResourceManager" version="1.4.0-preview"
|
||||
// package id="Microsoft.Rest.ClientRuntime.Azure.Authentication" version="2.2.8-preview"
|
||||
|
||||
using Microsoft.Azure.Management.ResourceManager;
|
||||
using Microsoft.Azure.Management.ResourceManager.Models;
|
||||
using Microsoft.Rest.Azure.Authentication;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace PortalGenerated
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a helper class for deploying an Azure Resource Manager template
|
||||
/// More info about template deployments can be found here https://go.microsoft.com/fwLink/?LinkID=733371
|
||||
/// </summary>
|
||||
class DeploymentHelper
|
||||
{
|
||||
string subscriptionId = "your-subscription-id";
|
||||
string clientId = "your-service-principal-clientId";
|
||||
string clientSecret = "your-service-principal-client-secret";
|
||||
string resourceGroupName = "resource-group-name";
|
||||
string deploymentName = "deployment-name";
|
||||
string resourceGroupLocation = "resource-group-location"; // must be specified for creating a new resource group
|
||||
string pathToTemplateFile = "path-to-template.json-on-disk";
|
||||
string pathToParameterFile = "path-to-parameters.json-on-disk";
|
||||
string tenantId = "tenant-id";
|
||||
|
||||
public async void Run()
|
||||
{
|
||||
// Try to obtain the service credentials
|
||||
var serviceCreds = await ApplicationTokenProvider.LoginSilentAsync(tenantId, clientId, clientSecret);
|
||||
|
||||
// Read the template and parameter file contents
|
||||
JObject templateFileContents = GetJsonFileContents(pathToTemplateFile);
|
||||
JObject parameterFileContents = GetJsonFileContents(pathToParameterFile);
|
||||
|
||||
// Create the resource manager client
|
||||
var resourceManagementClient = new ResourceManagementClient(serviceCreds);
|
||||
resourceManagementClient.SubscriptionId = subscriptionId;
|
||||
|
||||
// Create or check that resource group exists
|
||||
EnsureResourceGroupExists(resourceManagementClient, resourceGroupName, resourceGroupLocation);
|
||||
|
||||
// Start a deployment
|
||||
DeployTemplate(resourceManagementClient, resourceGroupName, deploymentName, templateFileContents, parameterFileContents);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a JSON file from the specified path
|
||||
/// </summary>
|
||||
/// <param name="pathToJson">The full path to the JSON file</param>
|
||||
/// <returns>The JSON file contents</returns>
|
||||
private JObject GetJsonFileContents(string pathToJson)
|
||||
{
|
||||
JObject templatefileContent = new JObject();
|
||||
using (StreamReader file = File.OpenText(pathToJson))
|
||||
{
|
||||
using (JsonTextReader reader = new JsonTextReader(file))
|
||||
{
|
||||
templatefileContent = (JObject)JToken.ReadFrom(reader);
|
||||
return templatefileContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that a resource group with the specified name exists. If it does not, will attempt to create one.
|
||||
/// </summary>
|
||||
/// <param name="resourceManagementClient">The resource manager client.</param>
|
||||
/// <param name="resourceGroupName">The name of the resource group.</param>
|
||||
/// <param name="resourceGroupLocation">The resource group location. Required when creating a new resource group.</param>
|
||||
private static void EnsureResourceGroupExists(ResourceManagementClient resourceManagementClient, string resourceGroupName, string resourceGroupLocation)
|
||||
{
|
||||
if (resourceManagementClient.ResourceGroups.CheckExistence(resourceGroupName) != true)
|
||||
{
|
||||
Console.WriteLine(string.Format("Creating resource group '{0}' in location '{1}'", resourceGroupName, resourceGroupLocation));
|
||||
var resourceGroup = new ResourceGroup();
|
||||
resourceGroup.Location = resourceGroupLocation;
|
||||
resourceManagementClient.ResourceGroups.CreateOrUpdate(resourceGroupName, resourceGroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(string.Format("Using existing resource group '{0}'", resourceGroupName));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a template deployment.
|
||||
/// </summary>
|
||||
/// <param name="resourceManagementClient">The resource manager client.</param>
|
||||
/// <param name="resourceGroupName">The name of the resource group.</param>
|
||||
/// <param name="deploymentName">The name of the deployment.</param>
|
||||
/// <param name="templateFileContents">The template file contents.</param>
|
||||
/// <param name="parameterFileContents">The parameter file contents.</param>
|
||||
private static void DeployTemplate(ResourceManagementClient resourceManagementClient, string resourceGroupName, string deploymentName, JObject templateFileContents, JObject parameterFileContents)
|
||||
{
|
||||
Console.WriteLine(string.Format("Starting template deployment '{0}' in resource group '{1}'", deploymentName, resourceGroupName));
|
||||
var deployment = new Deployment();
|
||||
|
||||
deployment.Properties = new DeploymentProperties
|
||||
{
|
||||
Mode = DeploymentMode.Incremental,
|
||||
Template = templateFileContents,
|
||||
Parameters = parameterFileContents["parameters"].ToObject<JObject>()
|
||||
};
|
||||
|
||||
var deploymentResult = resourceManagementClient.Deployments.CreateOrUpdate(resourceGroupName, deploymentName, deployment);
|
||||
Console.WriteLine(string.Format("Deployment status: {0}", deploymentResult.Properties.ProvisioningState));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
<#
|
||||
.SYNOPSIS
|
||||
Deploys a template to Azure
|
||||
|
||||
.DESCRIPTION
|
||||
Deploys an Azure Resource Manager template
|
||||
|
||||
.PARAMETER subscriptionId
|
||||
The subscription id where the template will be deployed.
|
||||
|
||||
.PARAMETER resourceGroupName
|
||||
The resource group where the template will be deployed. Can be the name of an existing or a new resource group.
|
||||
|
||||
.PARAMETER resourceGroupLocation
|
||||
Optional, a resource group location. If specified, will try to create a new resource group in this location. If not specified, assumes resource group is existing.
|
||||
|
||||
.PARAMETER deploymentName
|
||||
The deployment name.
|
||||
|
||||
.PARAMETER templateFilePath
|
||||
Optional, path to the template file. Defaults to template.json.
|
||||
|
||||
.PARAMETER parametersFilePath
|
||||
Optional, path to the parameters file. Defaults to parameters.json. If file is not found, will prompt for parameter values based on template.
|
||||
#>
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$subscriptionId,
|
||||
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$resourceGroupName,
|
||||
|
||||
[string]
|
||||
$resourceGroupLocation,
|
||||
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$deploymentName,
|
||||
|
||||
[string]
|
||||
$templateFilePath = "template.json",
|
||||
|
||||
[string]
|
||||
$parametersFilePath = "parameters.json"
|
||||
)
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Registers RPs
|
||||
#>
|
||||
Function RegisterRP {
|
||||
Param(
|
||||
[string]$ResourceProviderNamespace
|
||||
)
|
||||
|
||||
Write-Host "Registering resource provider '$ResourceProviderNamespace'";
|
||||
Register-AzureRmResourceProvider -ProviderNamespace $ResourceProviderNamespace;
|
||||
}
|
||||
|
||||
#******************************************************************************
|
||||
# Script body
|
||||
# Execution begins here
|
||||
#******************************************************************************
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# sign in
|
||||
Write-Host "Logging in...";
|
||||
Login-AzureRmAccount;
|
||||
|
||||
# select subscription
|
||||
Write-Host "Selecting subscription '$subscriptionId'";
|
||||
Select-AzureRmSubscription -SubscriptionID $subscriptionId;
|
||||
|
||||
# Register RPs
|
||||
$resourceProviders = @("microsoft.databricks");
|
||||
if($resourceProviders.length) {
|
||||
Write-Host "Registering resource providers"
|
||||
foreach($resourceProvider in $resourceProviders) {
|
||||
RegisterRP($resourceProvider);
|
||||
}
|
||||
}
|
||||
|
||||
#Create or check for existing resource group
|
||||
$resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue
|
||||
if(!$resourceGroup)
|
||||
{
|
||||
Write-Host "Resource group '$resourceGroupName' does not exist. To create a new resource group, please enter a location.";
|
||||
if(!$resourceGroupLocation) {
|
||||
$resourceGroupLocation = Read-Host "resourceGroupLocation";
|
||||
}
|
||||
Write-Host "Creating resource group '$resourceGroupName' in location '$resourceGroupLocation'";
|
||||
New-AzureRmResourceGroup -Name $resourceGroupName -Location $resourceGroupLocation
|
||||
}
|
||||
else{
|
||||
Write-Host "Using existing resource group '$resourceGroupName'";
|
||||
}
|
||||
|
||||
# Start the deployment
|
||||
Write-Host "Starting deployment...";
|
||||
if(Test-Path $parametersFilePath) {
|
||||
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName -TemplateFile $templateFilePath -TemplateParameterFile $parametersFilePath;
|
||||
} else {
|
||||
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName -TemplateFile $templateFilePath;
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
# -e: immediately exit if any command has a non-zero exit status
|
||||
# -o: prevents errors in a pipeline from being masked
|
||||
# IFS new value is less likely to cause confusing bugs when looping arrays or arguments (e.g. $@)
|
||||
|
||||
usage() { echo "Usage: $0 -i <subscriptionId> -g <resourceGroupName> -n <deploymentName> -l <resourceGroupLocation>" 1>&2; exit 1; }
|
||||
|
||||
declare subscriptionId=""
|
||||
declare resourceGroupName=""
|
||||
declare deploymentName=""
|
||||
declare resourceGroupLocation=""
|
||||
|
||||
# Initialize parameters specified from command line
|
||||
while getopts ":i:g:n:l:" arg; do
|
||||
case "${arg}" in
|
||||
i)
|
||||
subscriptionId=${OPTARG}
|
||||
;;
|
||||
g)
|
||||
resourceGroupName=${OPTARG}
|
||||
;;
|
||||
n)
|
||||
deploymentName=${OPTARG}
|
||||
;;
|
||||
l)
|
||||
resourceGroupLocation=${OPTARG}
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
#Prompt for parameters is some required parameters are missing
|
||||
if [[ -z "$subscriptionId" ]]; then
|
||||
echo "Your subscription ID can be looked up with the CLI using: az account show --out json "
|
||||
echo "Enter your subscription ID:"
|
||||
read subscriptionId
|
||||
[[ "${subscriptionId:?}" ]]
|
||||
fi
|
||||
|
||||
if [[ -z "$resourceGroupName" ]]; then
|
||||
echo "This script will look for an existing resource group, otherwise a new one will be created "
|
||||
echo "You can create new resource groups with the CLI using: az group create "
|
||||
echo "Enter a resource group name"
|
||||
read resourceGroupName
|
||||
[[ "${resourceGroupName:?}" ]]
|
||||
fi
|
||||
|
||||
if [[ -z "$deploymentName" ]]; then
|
||||
echo "Enter a name for this deployment:"
|
||||
read deploymentName
|
||||
fi
|
||||
|
||||
if [[ -z "$resourceGroupLocation" ]]; then
|
||||
echo "If creating a *new* resource group, you need to set a location "
|
||||
echo "You can lookup locations with the CLI using: az account list-locations "
|
||||
|
||||
echo "Enter resource group location:"
|
||||
read resourceGroupLocation
|
||||
fi
|
||||
|
||||
#templateFile Path - template file to be used
|
||||
templateFilePath="template.json"
|
||||
|
||||
if [ ! -f "$templateFilePath" ]; then
|
||||
echo "$templateFilePath not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#parameter file path
|
||||
parametersFilePath="parameters.json"
|
||||
|
||||
if [ ! -f "$parametersFilePath" ]; then
|
||||
echo "$parametersFilePath not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$subscriptionId" ] || [ -z "$resourceGroupName" ] || [ -z "$deploymentName" ]; then
|
||||
echo "Either one of subscriptionId, resourceGroupName, deploymentName is empty"
|
||||
usage
|
||||
fi
|
||||
|
||||
#login to azure using your credentials
|
||||
az account show 1> /dev/null
|
||||
|
||||
if [ $? != 0 ];
|
||||
then
|
||||
az login
|
||||
fi
|
||||
|
||||
#set the default subscription id
|
||||
az account set --subscription $subscriptionId
|
||||
|
||||
set +e
|
||||
|
||||
#Check for existing RG
|
||||
az group show --name $resourceGroupName 1> /dev/null
|
||||
|
||||
if [ $? != 0 ]; then
|
||||
echo "Resource group with name" $resourceGroupName "could not be found. Creating new resource group.."
|
||||
set -e
|
||||
(
|
||||
set -x
|
||||
az group create --name $resourceGroupName --location $resourceGroupLocation 1> /dev/null
|
||||
)
|
||||
else
|
||||
echo "Using existing resource group..."
|
||||
fi
|
||||
|
||||
#Start deployment
|
||||
echo "Starting deployment..."
|
||||
(
|
||||
set -x
|
||||
az group deployment create --name "$deploymentName" --resource-group "$resourceGroupName" --template-file "$templateFilePath" --parameters "@${parametersFilePath}"
|
||||
)
|
||||
|
||||
if [ $? == 0 ];
|
||||
then
|
||||
echo "Template has been successfully deployed"
|
||||
fi
|
|
@ -0,0 +1,71 @@
|
|||
require 'azure_mgmt_resources'
|
||||
|
||||
class Deployer
|
||||
|
||||
# Initialize the deployer class with subscription, resource group and resource group location. The class will raise an
|
||||
# ArgumentError if there are empty values for Tenant Id, Client Id or Client Secret environment variables.
|
||||
#
|
||||
# @param [String] subscription_id the subscription to deploy the template
|
||||
# @param [String] resource_group the resource group to create or update and then deploy the template
|
||||
# @param [String] resource_group_location the location of the resource group
|
||||
def initialize(subscription_id, resource_group, resource_group_location)
|
||||
raise ArgumentError.new("Missing template file 'template.json' in current directory.") unless File.exist?('template.json')
|
||||
raise ArgumentError.new("Missing parameters file 'parameters.json' in current directory.") unless File.exist?('parameters.json')
|
||||
@resource_group = resource_group
|
||||
@subscription_id = subscription_id
|
||||
@resource_group_location = resource_group_location
|
||||
provider = MsRestAzure::ApplicationTokenProvider.new(
|
||||
ENV['AZURE_TENANT_ID'],
|
||||
ENV['AZURE_CLIENT_ID'],
|
||||
ENV['AZURE_CLIENT_SECRET'])
|
||||
credentials = MsRest::TokenCredentials.new(provider)
|
||||
@client = Azure::ARM::Resources::ResourceManagementClient.new(credentials)
|
||||
@client.subscription_id = @subscription_id
|
||||
end
|
||||
|
||||
# Deploy the template to a resource group
|
||||
def deploy
|
||||
# ensure the resource group is created
|
||||
params = Azure::ARM::Resources::Models::ResourceGroup.new.tap do |rg|
|
||||
rg.location = @resource_group_location
|
||||
end
|
||||
@client.resource_groups.create_or_update(@resource_group, params).value!
|
||||
|
||||
# build the deployment from a json file template from parameters
|
||||
template = File.read(File.expand_path(File.join(__dir__, 'template.json')))
|
||||
deployment = Azure::ARM::Resources::Models::Deployment.new
|
||||
deployment.properties = Azure::ARM::Resources::Models::DeploymentProperties.new
|
||||
deployment.properties.template = JSON.parse(template)
|
||||
deployment.properties.mode = Azure::ARM::Resources::Models::DeploymentMode::Incremental
|
||||
|
||||
# build the deployment template parameters from Hash to {key: {value: value}} format
|
||||
deploy_params = File.read(File.expand_path(File.join(__dir__, 'parameters.json')))
|
||||
deployment.properties.parameters = JSON.parse(deploy_params)["parameters"]
|
||||
|
||||
# put the deployment to the resource group
|
||||
@client.deployments.create_or_update(@resource_group, 'azure-sample', deployment)
|
||||
end
|
||||
end
|
||||
|
||||
# Get user inputs and execute the script
|
||||
if(ARGV.empty?)
|
||||
puts "Please specify subscriptionId resourceGroupName resourceGroupLocation as command line arguments"
|
||||
exit
|
||||
end
|
||||
|
||||
subscription_id = ARGV[0] # Azure Subscription Id
|
||||
resource_group = ARGV[1] # The resource group for deployment
|
||||
resource_group_location = ARGV[2] # The resource group location
|
||||
|
||||
msg = "\nInitializing the Deployer class with subscription id: #{subscription_id}, resource group: #{resource_group}"
|
||||
msg += "\nand resource group location: #{resource_group_location}...\n\n"
|
||||
puts msg
|
||||
|
||||
# Initialize the deployer class
|
||||
deployer = Deployer.new(subscription_id, resource_group, resource_group_location)
|
||||
|
||||
puts "Beginning the deployment... \n\n"
|
||||
# Deploy the template
|
||||
deployment = deployer.deploy
|
||||
|
||||
puts "Done deploying!!"
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"workspaceName": {
|
||||
"value": "databricks"
|
||||
},
|
||||
"location": {
|
||||
"value": "westeurope"
|
||||
},
|
||||
"tier": {
|
||||
"value": "standard"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"location": {
|
||||
"type": "string"
|
||||
},
|
||||
"workspaceName": {
|
||||
"type": "string"
|
||||
},
|
||||
"tier": {
|
||||
"defaultValue": "premium",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"apiVersion": "2018-04-01",
|
||||
"location": "[parameters('location')]",
|
||||
"name": "[parameters('workspaceName')]",
|
||||
"sku": {
|
||||
"name": "[parameters('tier')]"
|
||||
},
|
||||
"comments": "Please do not use an existing resource group for ManagedResourceGroupId.",
|
||||
"properties": {
|
||||
"ManagedResourceGroupId": "[variables('managedResourceGroupId')]"
|
||||
},
|
||||
"type": "Microsoft.Databricks/workspaces"
|
||||
}
|
||||
],
|
||||
"variables": {
|
||||
"managedResourceGroupId": "[concat(subscription().id, '/resourceGroups/', variables('managedResourceGroupName'))]",
|
||||
"managedResourceGroupName": "[concat('databricks-rg-', parameters('workspaceName'), '-', uniqueString(parameters('workspaceName'), resourceGroup().id))]"
|
||||
},
|
||||
"outputs": {
|
||||
"resourceId": {
|
||||
"value": "[resourceId('Microsoft.Databricks/workspaces', parameters('workspaceName'))]",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
// Requires the following Azure NuGet packages and related dependencies:
|
||||
// package id="Microsoft.Azure.Management.Authorization" version="2.0.0"
|
||||
// package id="Microsoft.Azure.Management.ResourceManager" version="1.4.0-preview"
|
||||
// package id="Microsoft.Rest.ClientRuntime.Azure.Authentication" version="2.2.8-preview"
|
||||
|
||||
using Microsoft.Azure.Management.ResourceManager;
|
||||
using Microsoft.Azure.Management.ResourceManager.Models;
|
||||
using Microsoft.Rest.Azure.Authentication;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace PortalGenerated
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a helper class for deploying an Azure Resource Manager template
|
||||
/// More info about template deployments can be found here https://go.microsoft.com/fwLink/?LinkID=733371
|
||||
/// </summary>
|
||||
class DeploymentHelper
|
||||
{
|
||||
string subscriptionId = "your-subscription-id";
|
||||
string clientId = "your-service-principal-clientId";
|
||||
string clientSecret = "your-service-principal-client-secret";
|
||||
string resourceGroupName = "resource-group-name";
|
||||
string deploymentName = "deployment-name";
|
||||
string resourceGroupLocation = "resource-group-location"; // must be specified for creating a new resource group
|
||||
string pathToTemplateFile = "path-to-template.json-on-disk";
|
||||
string pathToParameterFile = "path-to-parameters.json-on-disk";
|
||||
string tenantId = "tenant-id";
|
||||
|
||||
public async void Run()
|
||||
{
|
||||
// Try to obtain the service credentials
|
||||
var serviceCreds = await ApplicationTokenProvider.LoginSilentAsync(tenantId, clientId, clientSecret);
|
||||
|
||||
// Read the template and parameter file contents
|
||||
JObject templateFileContents = GetJsonFileContents(pathToTemplateFile);
|
||||
JObject parameterFileContents = GetJsonFileContents(pathToParameterFile);
|
||||
|
||||
// Create the resource manager client
|
||||
var resourceManagementClient = new ResourceManagementClient(serviceCreds);
|
||||
resourceManagementClient.SubscriptionId = subscriptionId;
|
||||
|
||||
// Create or check that resource group exists
|
||||
EnsureResourceGroupExists(resourceManagementClient, resourceGroupName, resourceGroupLocation);
|
||||
|
||||
// Start a deployment
|
||||
DeployTemplate(resourceManagementClient, resourceGroupName, deploymentName, templateFileContents, parameterFileContents);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a JSON file from the specified path
|
||||
/// </summary>
|
||||
/// <param name="pathToJson">The full path to the JSON file</param>
|
||||
/// <returns>The JSON file contents</returns>
|
||||
private JObject GetJsonFileContents(string pathToJson)
|
||||
{
|
||||
JObject templatefileContent = new JObject();
|
||||
using (StreamReader file = File.OpenText(pathToJson))
|
||||
{
|
||||
using (JsonTextReader reader = new JsonTextReader(file))
|
||||
{
|
||||
templatefileContent = (JObject)JToken.ReadFrom(reader);
|
||||
return templatefileContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that a resource group with the specified name exists. If it does not, will attempt to create one.
|
||||
/// </summary>
|
||||
/// <param name="resourceManagementClient">The resource manager client.</param>
|
||||
/// <param name="resourceGroupName">The name of the resource group.</param>
|
||||
/// <param name="resourceGroupLocation">The resource group location. Required when creating a new resource group.</param>
|
||||
private static void EnsureResourceGroupExists(ResourceManagementClient resourceManagementClient, string resourceGroupName, string resourceGroupLocation)
|
||||
{
|
||||
if (resourceManagementClient.ResourceGroups.CheckExistence(resourceGroupName) != true)
|
||||
{
|
||||
Console.WriteLine(string.Format("Creating resource group '{0}' in location '{1}'", resourceGroupName, resourceGroupLocation));
|
||||
var resourceGroup = new ResourceGroup();
|
||||
resourceGroup.Location = resourceGroupLocation;
|
||||
resourceManagementClient.ResourceGroups.CreateOrUpdate(resourceGroupName, resourceGroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(string.Format("Using existing resource group '{0}'", resourceGroupName));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a template deployment.
|
||||
/// </summary>
|
||||
/// <param name="resourceManagementClient">The resource manager client.</param>
|
||||
/// <param name="resourceGroupName">The name of the resource group.</param>
|
||||
/// <param name="deploymentName">The name of the deployment.</param>
|
||||
/// <param name="templateFileContents">The template file contents.</param>
|
||||
/// <param name="parameterFileContents">The parameter file contents.</param>
|
||||
private static void DeployTemplate(ResourceManagementClient resourceManagementClient, string resourceGroupName, string deploymentName, JObject templateFileContents, JObject parameterFileContents)
|
||||
{
|
||||
Console.WriteLine(string.Format("Starting template deployment '{0}' in resource group '{1}'", deploymentName, resourceGroupName));
|
||||
var deployment = new Deployment();
|
||||
|
||||
deployment.Properties = new DeploymentProperties
|
||||
{
|
||||
Mode = DeploymentMode.Incremental,
|
||||
Template = templateFileContents,
|
||||
Parameters = parameterFileContents["parameters"].ToObject<JObject>()
|
||||
};
|
||||
|
||||
var deploymentResult = resourceManagementClient.Deployments.CreateOrUpdate(resourceGroupName, deploymentName, deployment);
|
||||
Console.WriteLine(string.Format("Deployment status: {0}", deploymentResult.Properties.ProvisioningState));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
<#
|
||||
.SYNOPSIS
|
||||
Deploys a template to Azure
|
||||
|
||||
.DESCRIPTION
|
||||
Deploys an Azure Resource Manager template
|
||||
|
||||
.PARAMETER subscriptionId
|
||||
The subscription id where the template will be deployed.
|
||||
|
||||
.PARAMETER resourceGroupName
|
||||
The resource group where the template will be deployed. Can be the name of an existing or a new resource group.
|
||||
|
||||
.PARAMETER resourceGroupLocation
|
||||
Optional, a resource group location. If specified, will try to create a new resource group in this location. If not specified, assumes resource group is existing.
|
||||
|
||||
.PARAMETER deploymentName
|
||||
The deployment name.
|
||||
|
||||
.PARAMETER templateFilePath
|
||||
Optional, path to the template file. Defaults to template.json.
|
||||
|
||||
.PARAMETER parametersFilePath
|
||||
Optional, path to the parameters file. Defaults to parameters.json. If file is not found, will prompt for parameter values based on template.
|
||||
#>
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$subscriptionId,
|
||||
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$resourceGroupName,
|
||||
|
||||
[string]
|
||||
$resourceGroupLocation,
|
||||
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$deploymentName,
|
||||
|
||||
[string]
|
||||
$templateFilePath = "template.json",
|
||||
|
||||
[string]
|
||||
$parametersFilePath = "parameters.json"
|
||||
)
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Registers RPs
|
||||
#>
|
||||
Function RegisterRP {
|
||||
Param(
|
||||
[string]$ResourceProviderNamespace
|
||||
)
|
||||
|
||||
Write-Host "Registering resource provider '$ResourceProviderNamespace'";
|
||||
Register-AzureRmResourceProvider -ProviderNamespace $ResourceProviderNamespace;
|
||||
}
|
||||
|
||||
#******************************************************************************
|
||||
# Script body
|
||||
# Execution begins here
|
||||
#******************************************************************************
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# sign in
|
||||
Write-Host "Logging in...";
|
||||
Login-AzureRmAccount;
|
||||
|
||||
# select subscription
|
||||
Write-Host "Selecting subscription '$subscriptionId'";
|
||||
Select-AzureRmSubscription -SubscriptionID $subscriptionId;
|
||||
|
||||
# Register RPs
|
||||
$resourceProviders = @("microsoft.keyvault");
|
||||
if($resourceProviders.length) {
|
||||
Write-Host "Registering resource providers"
|
||||
foreach($resourceProvider in $resourceProviders) {
|
||||
RegisterRP($resourceProvider);
|
||||
}
|
||||
}
|
||||
|
||||
#Create or check for existing resource group
|
||||
$resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue
|
||||
if(!$resourceGroup)
|
||||
{
|
||||
Write-Host "Resource group '$resourceGroupName' does not exist. To create a new resource group, please enter a location.";
|
||||
if(!$resourceGroupLocation) {
|
||||
$resourceGroupLocation = Read-Host "resourceGroupLocation";
|
||||
}
|
||||
Write-Host "Creating resource group '$resourceGroupName' in location '$resourceGroupLocation'";
|
||||
New-AzureRmResourceGroup -Name $resourceGroupName -Location $resourceGroupLocation
|
||||
}
|
||||
else{
|
||||
Write-Host "Using existing resource group '$resourceGroupName'";
|
||||
}
|
||||
|
||||
# Start the deployment
|
||||
Write-Host "Starting deployment...";
|
||||
if(Test-Path $parametersFilePath) {
|
||||
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName -TemplateFile $templateFilePath -TemplateParameterFile $parametersFilePath;
|
||||
} else {
|
||||
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName -TemplateFile $templateFilePath;
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
# -e: immediately exit if any command has a non-zero exit status
|
||||
# -o: prevents errors in a pipeline from being masked
|
||||
# IFS new value is less likely to cause confusing bugs when looping arrays or arguments (e.g. $@)
|
||||
|
||||
usage() { echo "Usage: $0 -i <subscriptionId> -g <resourceGroupName> -n <deploymentName> -l <resourceGroupLocation>" 1>&2; exit 1; }
|
||||
|
||||
declare subscriptionId=""
|
||||
declare resourceGroupName=""
|
||||
declare deploymentName=""
|
||||
declare resourceGroupLocation=""
|
||||
|
||||
# Initialize parameters specified from command line
|
||||
while getopts ":i:g:n:l:" arg; do
|
||||
case "${arg}" in
|
||||
i)
|
||||
subscriptionId=${OPTARG}
|
||||
;;
|
||||
g)
|
||||
resourceGroupName=${OPTARG}
|
||||
;;
|
||||
n)
|
||||
deploymentName=${OPTARG}
|
||||
;;
|
||||
l)
|
||||
resourceGroupLocation=${OPTARG}
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
#Prompt for parameters is some required parameters are missing
|
||||
if [[ -z "$subscriptionId" ]]; then
|
||||
echo "Your subscription ID can be looked up with the CLI using: az account show --out json "
|
||||
echo "Enter your subscription ID:"
|
||||
read subscriptionId
|
||||
[[ "${subscriptionId:?}" ]]
|
||||
fi
|
||||
|
||||
if [[ -z "$resourceGroupName" ]]; then
|
||||
echo "This script will look for an existing resource group, otherwise a new one will be created "
|
||||
echo "You can create new resource groups with the CLI using: az group create "
|
||||
echo "Enter a resource group name"
|
||||
read resourceGroupName
|
||||
[[ "${resourceGroupName:?}" ]]
|
||||
fi
|
||||
|
||||
if [[ -z "$deploymentName" ]]; then
|
||||
echo "Enter a name for this deployment:"
|
||||
read deploymentName
|
||||
fi
|
||||
|
||||
if [[ -z "$resourceGroupLocation" ]]; then
|
||||
echo "If creating a *new* resource group, you need to set a location "
|
||||
echo "You can lookup locations with the CLI using: az account list-locations "
|
||||
|
||||
echo "Enter resource group location:"
|
||||
read resourceGroupLocation
|
||||
fi
|
||||
|
||||
#templateFile Path - template file to be used
|
||||
templateFilePath="template.json"
|
||||
|
||||
if [ ! -f "$templateFilePath" ]; then
|
||||
echo "$templateFilePath not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#parameter file path
|
||||
parametersFilePath="parameters.json"
|
||||
|
||||
if [ ! -f "$parametersFilePath" ]; then
|
||||
echo "$parametersFilePath not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$subscriptionId" ] || [ -z "$resourceGroupName" ] || [ -z "$deploymentName" ]; then
|
||||
echo "Either one of subscriptionId, resourceGroupName, deploymentName is empty"
|
||||
usage
|
||||
fi
|
||||
|
||||
#login to azure using your credentials
|
||||
az account show 1> /dev/null
|
||||
|
||||
if [ $? != 0 ];
|
||||
then
|
||||
az login
|
||||
fi
|
||||
|
||||
#set the default subscription id
|
||||
az account set --subscription $subscriptionId
|
||||
|
||||
set +e
|
||||
|
||||
#Check for existing RG
|
||||
az group show --name $resourceGroupName 1> /dev/null
|
||||
|
||||
if [ $? != 0 ]; then
|
||||
echo "Resource group with name" $resourceGroupName "could not be found. Creating new resource group.."
|
||||
set -e
|
||||
(
|
||||
set -x
|
||||
az group create --name $resourceGroupName --location $resourceGroupLocation 1> /dev/null
|
||||
)
|
||||
else
|
||||
echo "Using existing resource group..."
|
||||
fi
|
||||
|
||||
#Start deployment
|
||||
echo "Starting deployment..."
|
||||
(
|
||||
set -x
|
||||
az group deployment create --name "$deploymentName" --resource-group "$resourceGroupName" --template-file "$templateFilePath" --parameters "@${parametersFilePath}"
|
||||
)
|
||||
|
||||
if [ $? == 0 ];
|
||||
then
|
||||
echo "Template has been successfully deployed"
|
||||
fi
|
|
@ -0,0 +1,71 @@
|
|||
require 'azure_mgmt_resources'
|
||||
|
||||
class Deployer
|
||||
|
||||
# Initialize the deployer class with subscription, resource group and resource group location. The class will raise an
|
||||
# ArgumentError if there are empty values for Tenant Id, Client Id or Client Secret environment variables.
|
||||
#
|
||||
# @param [String] subscription_id the subscription to deploy the template
|
||||
# @param [String] resource_group the resource group to create or update and then deploy the template
|
||||
# @param [String] resource_group_location the location of the resource group
|
||||
def initialize(subscription_id, resource_group, resource_group_location)
|
||||
raise ArgumentError.new("Missing template file 'template.json' in current directory.") unless File.exist?('template.json')
|
||||
raise ArgumentError.new("Missing parameters file 'parameters.json' in current directory.") unless File.exist?('parameters.json')
|
||||
@resource_group = resource_group
|
||||
@subscription_id = subscription_id
|
||||
@resource_group_location = resource_group_location
|
||||
provider = MsRestAzure::ApplicationTokenProvider.new(
|
||||
ENV['AZURE_TENANT_ID'],
|
||||
ENV['AZURE_CLIENT_ID'],
|
||||
ENV['AZURE_CLIENT_SECRET'])
|
||||
credentials = MsRest::TokenCredentials.new(provider)
|
||||
@client = Azure::ARM::Resources::ResourceManagementClient.new(credentials)
|
||||
@client.subscription_id = @subscription_id
|
||||
end
|
||||
|
||||
# Deploy the template to a resource group
|
||||
def deploy
|
||||
# ensure the resource group is created
|
||||
params = Azure::ARM::Resources::Models::ResourceGroup.new.tap do |rg|
|
||||
rg.location = @resource_group_location
|
||||
end
|
||||
@client.resource_groups.create_or_update(@resource_group, params).value!
|
||||
|
||||
# build the deployment from a json file template from parameters
|
||||
template = File.read(File.expand_path(File.join(__dir__, 'template.json')))
|
||||
deployment = Azure::ARM::Resources::Models::Deployment.new
|
||||
deployment.properties = Azure::ARM::Resources::Models::DeploymentProperties.new
|
||||
deployment.properties.template = JSON.parse(template)
|
||||
deployment.properties.mode = Azure::ARM::Resources::Models::DeploymentMode::Incremental
|
||||
|
||||
# build the deployment template parameters from Hash to {key: {value: value}} format
|
||||
deploy_params = File.read(File.expand_path(File.join(__dir__, 'parameters.json')))
|
||||
deployment.properties.parameters = JSON.parse(deploy_params)["parameters"]
|
||||
|
||||
# put the deployment to the resource group
|
||||
@client.deployments.create_or_update(@resource_group, 'azure-sample', deployment)
|
||||
end
|
||||
end
|
||||
|
||||
# Get user inputs and execute the script
|
||||
if(ARGV.empty?)
|
||||
puts "Please specify subscriptionId resourceGroupName resourceGroupLocation as command line arguments"
|
||||
exit
|
||||
end
|
||||
|
||||
subscription_id = ARGV[0] # Azure Subscription Id
|
||||
resource_group = ARGV[1] # The resource group for deployment
|
||||
resource_group_location = ARGV[2] # The resource group location
|
||||
|
||||
msg = "\nInitializing the Deployer class with subscription id: #{subscription_id}, resource group: #{resource_group}"
|
||||
msg += "\nand resource group location: #{resource_group_location}...\n\n"
|
||||
puts msg
|
||||
|
||||
# Initialize the deployer class
|
||||
deployer = Deployer.new(subscription_id, resource_group, resource_group_location)
|
||||
|
||||
puts "Beginning the deployment... \n\n"
|
||||
# Deploy the template
|
||||
deployment = deployer.deploy
|
||||
|
||||
puts "Done deploying!!"
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"name": {
|
||||
"value": "keyvault"
|
||||
},
|
||||
"location": {
|
||||
"value": "westeurope"
|
||||
},
|
||||
"tenantId": {
|
||||
"value": "tenantid"
|
||||
},
|
||||
"objectId": {
|
||||
"value": "357e0b82-f4db-4e11-b279-654fd1b93629"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"location": {
|
||||
"type": "string"
|
||||
} ,
|
||||
"tenantId": {
|
||||
"type": "string"
|
||||
},
|
||||
"objectId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"variables": {},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.KeyVault/vaults",
|
||||
"name": "[parameters('name')]",
|
||||
"apiVersion": "2016-10-01",
|
||||
"location": "[parameters('location')]",
|
||||
"tags": {},
|
||||
"scale": null,
|
||||
"properties": {
|
||||
"sku": {
|
||||
"family": "A",
|
||||
"name": "Standard"
|
||||
},
|
||||
"tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47",
|
||||
"accessPolicies": [
|
||||
{
|
||||
"tenantId": "[parameters('tenantId')]",
|
||||
"objectId": "[parameters('objectId')]",
|
||||
"permissions": {
|
||||
"keys": [
|
||||
"Get",
|
||||
"List",
|
||||
"Update",
|
||||
"Create",
|
||||
"Import",
|
||||
"Delete",
|
||||
"Recover",
|
||||
"Backup",
|
||||
"Restore"
|
||||
],
|
||||
"secrets": [
|
||||
"Get",
|
||||
"List",
|
||||
"Set",
|
||||
"Delete",
|
||||
"Recover",
|
||||
"Backup",
|
||||
"Restore"
|
||||
],
|
||||
"certificates": [
|
||||
"Get",
|
||||
"List",
|
||||
"Update",
|
||||
"Create",
|
||||
"Import",
|
||||
"Delete",
|
||||
"Recover",
|
||||
"Backup",
|
||||
"Restore",
|
||||
"ManageContacts",
|
||||
"ManageIssuers",
|
||||
"GetIssuers",
|
||||
"ListIssuers",
|
||||
"SetIssuers",
|
||||
"DeleteIssuers"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"enabledForDeployment": false,
|
||||
"enabledForDiskEncryption": false,
|
||||
"enabledForTemplateDeployment": false
|
||||
},
|
||||
"dependsOn": []
|
||||
}
|
||||
],
|
||||
"outputs": {
|
||||
"resourceId": {
|
||||
"value": "[resourceId('Microsoft.KeyVault/vaults', parameters('name'))]",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"workspaceName": {
|
||||
"value": "myworkspace"
|
||||
},
|
||||
"clusterName": {
|
||||
"value": "mycluster"
|
||||
},
|
||||
"minNodeCount": {
|
||||
"value": 0
|
||||
},
|
||||
"maxNodeCount": {
|
||||
"value": 1
|
||||
},
|
||||
"adminUserName": {
|
||||
"value": "<Fill-here>"
|
||||
},
|
||||
"adminUserPassword": {
|
||||
"value": "<Fill-here>"
|
||||
},
|
||||
"workspacelocation": {
|
||||
"value": "<Fill-here>"
|
||||
},
|
||||
"vmSize": {
|
||||
"value": "Standard_D3_V2"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"workspaceName": {
|
||||
"type": "string"
|
||||
},
|
||||
"clusterName": {
|
||||
"type": "string"
|
||||
},
|
||||
"minNodeCount": {
|
||||
"type": "int"
|
||||
},
|
||||
"maxNodeCount": {
|
||||
"type": "int"
|
||||
},
|
||||
"workspacelocation": {
|
||||
"type": "string"
|
||||
},
|
||||
"adminUserName": {
|
||||
"type": "string"
|
||||
},
|
||||
"adminUserPassword": {
|
||||
"type": "string"
|
||||
},
|
||||
"vmSize": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"variables": {},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.MachineLearningServices/workspaces/computes",
|
||||
"name": "[concat(parameters('workspaceName'), '/', parameters('clusterName'))]",
|
||||
"apiVersion": "2018-11-19",
|
||||
"location" : "[parameters('workspacelocation')]",
|
||||
"properties": {
|
||||
"computeType": "AmlCompute",
|
||||
"computeLocation" : "[parameters('workspacelocation')]",
|
||||
"properties":
|
||||
{
|
||||
"vmSize" : "[parameters('vmSize')]",
|
||||
"scaleSettings":
|
||||
{
|
||||
"minNodeCount" : "[parameters('minNodeCount')]",
|
||||
"maxNodeCount" : "[parameters('maxNodeCount')]"
|
||||
},
|
||||
"userAccountCredentials" :
|
||||
{
|
||||
"adminUserName" : "[parameters('adminUserName')]",
|
||||
"adminUserPassword" : "[parameters('adminUserPassword')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
// Requires the following Azure NuGet packages and related dependencies:
|
||||
// package id="Microsoft.Azure.Management.Authorization" version="2.0.0"
|
||||
// package id="Microsoft.Azure.Management.ResourceManager" version="1.4.0-preview"
|
||||
// package id="Microsoft.Rest.ClientRuntime.Azure.Authentication" version="2.2.8-preview"
|
||||
|
||||
using Microsoft.Azure.Management.ResourceManager;
|
||||
using Microsoft.Azure.Management.ResourceManager.Models;
|
||||
using Microsoft.Rest.Azure.Authentication;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace PortalGenerated
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a helper class for deploying an Azure Resource Manager template
|
||||
/// More info about template deployments can be found here https://go.microsoft.com/fwLink/?LinkID=733371
|
||||
/// </summary>
|
||||
class DeploymentHelper
|
||||
{
|
||||
string subscriptionId = "your-subscription-id";
|
||||
string clientId = "your-service-principal-clientId";
|
||||
string clientSecret = "your-service-principal-client-secret";
|
||||
string resourceGroupName = "resource-group-name";
|
||||
string deploymentName = "deployment-name";
|
||||
string resourceGroupLocation = "resource-group-location"; // must be specified for creating a new resource group
|
||||
string pathToTemplateFile = "path-to-template.json-on-disk";
|
||||
string pathToParameterFile = "path-to-parameters.json-on-disk";
|
||||
string tenantId = "tenant-id";
|
||||
|
||||
public async void Run()
|
||||
{
|
||||
// Try to obtain the service credentials
|
||||
var serviceCreds = await ApplicationTokenProvider.LoginSilentAsync(tenantId, clientId, clientSecret);
|
||||
|
||||
// Read the template and parameter file contents
|
||||
JObject templateFileContents = GetJsonFileContents(pathToTemplateFile);
|
||||
JObject parameterFileContents = GetJsonFileContents(pathToParameterFile);
|
||||
|
||||
// Create the resource manager client
|
||||
var resourceManagementClient = new ResourceManagementClient(serviceCreds);
|
||||
resourceManagementClient.SubscriptionId = subscriptionId;
|
||||
|
||||
// Create or check that resource group exists
|
||||
EnsureResourceGroupExists(resourceManagementClient, resourceGroupName, resourceGroupLocation);
|
||||
|
||||
// Start a deployment
|
||||
DeployTemplate(resourceManagementClient, resourceGroupName, deploymentName, templateFileContents, parameterFileContents);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a JSON file from the specified path
|
||||
/// </summary>
|
||||
/// <param name="pathToJson">The full path to the JSON file</param>
|
||||
/// <returns>The JSON file contents</returns>
|
||||
private JObject GetJsonFileContents(string pathToJson)
|
||||
{
|
||||
JObject templatefileContent = new JObject();
|
||||
using (StreamReader file = File.OpenText(pathToJson))
|
||||
{
|
||||
using (JsonTextReader reader = new JsonTextReader(file))
|
||||
{
|
||||
templatefileContent = (JObject)JToken.ReadFrom(reader);
|
||||
return templatefileContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that a resource group with the specified name exists. If it does not, will attempt to create one.
|
||||
/// </summary>
|
||||
/// <param name="resourceManagementClient">The resource manager client.</param>
|
||||
/// <param name="resourceGroupName">The name of the resource group.</param>
|
||||
/// <param name="resourceGroupLocation">The resource group location. Required when creating a new resource group.</param>
|
||||
private static void EnsureResourceGroupExists(ResourceManagementClient resourceManagementClient, string resourceGroupName, string resourceGroupLocation)
|
||||
{
|
||||
if (resourceManagementClient.ResourceGroups.CheckExistence(resourceGroupName) != true)
|
||||
{
|
||||
Console.WriteLine(string.Format("Creating resource group '{0}' in location '{1}'", resourceGroupName, resourceGroupLocation));
|
||||
var resourceGroup = new ResourceGroup();
|
||||
resourceGroup.Location = resourceGroupLocation;
|
||||
resourceManagementClient.ResourceGroups.CreateOrUpdate(resourceGroupName, resourceGroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(string.Format("Using existing resource group '{0}'", resourceGroupName));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a template deployment.
|
||||
/// </summary>
|
||||
/// <param name="resourceManagementClient">The resource manager client.</param>
|
||||
/// <param name="resourceGroupName">The name of the resource group.</param>
|
||||
/// <param name="deploymentName">The name of the deployment.</param>
|
||||
/// <param name="templateFileContents">The template file contents.</param>
|
||||
/// <param name="parameterFileContents">The parameter file contents.</param>
|
||||
private static void DeployTemplate(ResourceManagementClient resourceManagementClient, string resourceGroupName, string deploymentName, JObject templateFileContents, JObject parameterFileContents)
|
||||
{
|
||||
Console.WriteLine(string.Format("Starting template deployment '{0}' in resource group '{1}'", deploymentName, resourceGroupName));
|
||||
var deployment = new Deployment();
|
||||
|
||||
deployment.Properties = new DeploymentProperties
|
||||
{
|
||||
Mode = DeploymentMode.Incremental,
|
||||
Template = templateFileContents,
|
||||
Parameters = parameterFileContents["parameters"].ToObject<JObject>()
|
||||
};
|
||||
|
||||
var deploymentResult = resourceManagementClient.Deployments.CreateOrUpdate(resourceGroupName, deploymentName, deployment);
|
||||
Console.WriteLine(string.Format("Deployment status: {0}", deploymentResult.Properties.ProvisioningState));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
<#
|
||||
.SYNOPSIS
|
||||
Deploys a template to Azure
|
||||
|
||||
.DESCRIPTION
|
||||
Deploys an Azure Resource Manager template
|
||||
|
||||
.PARAMETER subscriptionId
|
||||
The subscription id where the template will be deployed.
|
||||
|
||||
.PARAMETER resourceGroupName
|
||||
The resource group where the template will be deployed. Can be the name of an existing or a new resource group.
|
||||
|
||||
.PARAMETER resourceGroupLocation
|
||||
Optional, a resource group location. If specified, will try to create a new resource group in this location. If not specified, assumes resource group is existing.
|
||||
|
||||
.PARAMETER deploymentName
|
||||
The deployment name.
|
||||
|
||||
.PARAMETER templateFilePath
|
||||
Optional, path to the template file. Defaults to template.json.
|
||||
|
||||
.PARAMETER parametersFilePath
|
||||
Optional, path to the parameters file. Defaults to parameters.json. If file is not found, will prompt for parameter values based on template.
|
||||
#>
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$subscriptionId,
|
||||
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$resourceGroupName,
|
||||
|
||||
[string]
|
||||
$resourceGroupLocation,
|
||||
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$deploymentName,
|
||||
|
||||
[string]
|
||||
$templateFilePath = "template.json",
|
||||
|
||||
[string]
|
||||
$parametersFilePath = "parameters.json"
|
||||
)
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Registers RPs
|
||||
#>
|
||||
Function RegisterRP {
|
||||
Param(
|
||||
[string]$ResourceProviderNamespace
|
||||
)
|
||||
|
||||
Write-Host "Registering resource provider '$ResourceProviderNamespace'";
|
||||
Register-AzureRmResourceProvider -ProviderNamespace $ResourceProviderNamespace;
|
||||
}
|
||||
|
||||
#******************************************************************************
|
||||
# Script body
|
||||
# Execution begins here
|
||||
#******************************************************************************
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# sign in
|
||||
Write-Host "Logging in...";
|
||||
Login-AzureRmAccount;
|
||||
|
||||
# select subscription
|
||||
Write-Host "Selecting subscription '$subscriptionId'";
|
||||
Select-AzureRmSubscription -SubscriptionID $subscriptionId;
|
||||
|
||||
# Register RPs
|
||||
$resourceProviders = @("microsoft.machinelearningservices","microsoft.storage","microsoft.containerregistry","microsoft.keyvault","microsoft.insights");
|
||||
if($resourceProviders.length) {
|
||||
Write-Host "Registering resource providers"
|
||||
foreach($resourceProvider in $resourceProviders) {
|
||||
RegisterRP($resourceProvider);
|
||||
}
|
||||
}
|
||||
|
||||
#Create or check for existing resource group
|
||||
$resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue
|
||||
if(!$resourceGroup)
|
||||
{
|
||||
Write-Host "Resource group '$resourceGroupName' does not exist. To create a new resource group, please enter a location.";
|
||||
if(!$resourceGroupLocation) {
|
||||
$resourceGroupLocation = Read-Host "resourceGroupLocation";
|
||||
}
|
||||
Write-Host "Creating resource group '$resourceGroupName' in location '$resourceGroupLocation'";
|
||||
New-AzureRmResourceGroup -Name $resourceGroupName -Location $resourceGroupLocation
|
||||
}
|
||||
else{
|
||||
Write-Host "Using existing resource group '$resourceGroupName'";
|
||||
}
|
||||
|
||||
# Start the deployment
|
||||
Write-Host "Starting deployment...";
|
||||
if(Test-Path $parametersFilePath) {
|
||||
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName -TemplateFile $templateFilePath -TemplateParameterFile $parametersFilePath;
|
||||
} else {
|
||||
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -Name $deploymentName -TemplateFile $templateFilePath;
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
# -e: immediately exit if any command has a non-zero exit status
|
||||
# -o: prevents errors in a pipeline from being masked
|
||||
# IFS new value is less likely to cause confusing bugs when looping arrays or arguments (e.g. $@)
|
||||
|
||||
usage() { echo "Usage: $0 -i <subscriptionId> -g <resourceGroupName> -n <deploymentName> -l <resourceGroupLocation>" 1>&2; exit 1; }
|
||||
|
||||
declare subscriptionId=""
|
||||
declare resourceGroupName=""
|
||||
declare deploymentName=""
|
||||
declare resourceGroupLocation=""
|
||||
|
||||
# Initialize parameters specified from command line
|
||||
while getopts ":i:g:n:l:" arg; do
|
||||
case "${arg}" in
|
||||
i)
|
||||
subscriptionId=${OPTARG}
|
||||
;;
|
||||
g)
|
||||
resourceGroupName=${OPTARG}
|
||||
;;
|
||||
n)
|
||||
deploymentName=${OPTARG}
|
||||
;;
|
||||
l)
|
||||
resourceGroupLocation=${OPTARG}
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
#Prompt for parameters is some required parameters are missing
|
||||
if [[ -z "$subscriptionId" ]]; then
|
||||
echo "Your subscription ID can be looked up with the CLI using: az account show --out json "
|
||||
echo "Enter your subscription ID:"
|
||||
read subscriptionId
|
||||
[[ "${subscriptionId:?}" ]]
|
||||
fi
|
||||
|
||||
if [[ -z "$resourceGroupName" ]]; then
|
||||
echo "This script will look for an existing resource group, otherwise a new one will be created "
|
||||
echo "You can create new resource groups with the CLI using: az group create "
|
||||
echo "Enter a resource group name"
|
||||
read resourceGroupName
|
||||
[[ "${resourceGroupName:?}" ]]
|
||||
fi
|
||||
|
||||
if [[ -z "$deploymentName" ]]; then
|
||||
echo "Enter a name for this deployment:"
|
||||
read deploymentName
|
||||
fi
|
||||
|
||||
if [[ -z "$resourceGroupLocation" ]]; then
|
||||
echo "If creating a *new* resource group, you need to set a location "
|
||||
echo "You can lookup locations with the CLI using: az account list-locations "
|
||||
|
||||
echo "Enter resource group location:"
|
||||
read resourceGroupLocation
|
||||
fi
|
||||
|
||||
#templateFile Path - template file to be used
|
||||
templateFilePath="template.json"
|
||||
|
||||
if [ ! -f "$templateFilePath" ]; then
|
||||
echo "$templateFilePath not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#parameter file path
|
||||
parametersFilePath="parameters.json"
|
||||
|
||||
if [ ! -f "$parametersFilePath" ]; then
|
||||
echo "$parametersFilePath not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$subscriptionId" ] || [ -z "$resourceGroupName" ] || [ -z "$deploymentName" ]; then
|
||||
echo "Either one of subscriptionId, resourceGroupName, deploymentName is empty"
|
||||
usage
|
||||
fi
|
||||
|
||||
#login to azure using your credentials
|
||||
az account show 1> /dev/null
|
||||
|
||||
if [ $? != 0 ];
|
||||
then
|
||||
az login
|
||||
fi
|
||||
|
||||
#set the default subscription id
|
||||
az account set --subscription $subscriptionId
|
||||
|
||||
set +e
|
||||
|
||||
#Check for existing RG
|
||||
az group show --name $resourceGroupName 1> /dev/null
|
||||
|
||||
if [ $? != 0 ]; then
|
||||
echo "Resource group with name" $resourceGroupName "could not be found. Creating new resource group.."
|
||||
set -e
|
||||
(
|
||||
set -x
|
||||
az group create --name $resourceGroupName --location $resourceGroupLocation 1> /dev/null
|
||||
)
|
||||
else
|
||||
echo "Using existing resource group..."
|
||||
fi
|
||||
|
||||
#Start deployment
|
||||
echo "Starting deployment..."
|
||||
(
|
||||
set -x
|
||||
az group deployment create --name "$deploymentName" --resource-group "$resourceGroupName" --template-file "$templateFilePath" --parameters "@${parametersFilePath}"
|
||||
)
|
||||
|
||||
if [ $? == 0 ];
|
||||
then
|
||||
echo "Template has been successfully deployed"
|
||||
fi
|
|
@ -0,0 +1,71 @@
|
|||
require 'azure_mgmt_resources'
|
||||
|
||||
class Deployer
|
||||
|
||||
# Initialize the deployer class with subscription, resource group and resource group location. The class will raise an
|
||||
# ArgumentError if there are empty values for Tenant Id, Client Id or Client Secret environment variables.
|
||||
#
|
||||
# @param [String] subscription_id the subscription to deploy the template
|
||||
# @param [String] resource_group the resource group to create or update and then deploy the template
|
||||
# @param [String] resource_group_location the location of the resource group
|
||||
def initialize(subscription_id, resource_group, resource_group_location)
|
||||
raise ArgumentError.new("Missing template file 'template.json' in current directory.") unless File.exist?('template.json')
|
||||
raise ArgumentError.new("Missing parameters file 'parameters.json' in current directory.") unless File.exist?('parameters.json')
|
||||
@resource_group = resource_group
|
||||
@subscription_id = subscription_id
|
||||
@resource_group_location = resource_group_location
|
||||
provider = MsRestAzure::ApplicationTokenProvider.new(
|
||||
ENV['AZURE_TENANT_ID'],
|
||||
ENV['AZURE_CLIENT_ID'],
|
||||
ENV['AZURE_CLIENT_SECRET'])
|
||||
credentials = MsRest::TokenCredentials.new(provider)
|
||||
@client = Azure::ARM::Resources::ResourceManagementClient.new(credentials)
|
||||
@client.subscription_id = @subscription_id
|
||||
end
|
||||
|
||||
# Deploy the template to a resource group
|
||||
def deploy
|
||||
# ensure the resource group is created
|
||||
params = Azure::ARM::Resources::Models::ResourceGroup.new.tap do |rg|
|
||||
rg.location = @resource_group_location
|
||||
end
|
||||
@client.resource_groups.create_or_update(@resource_group, params).value!
|
||||
|
||||
# build the deployment from a json file template from parameters
|
||||
template = File.read(File.expand_path(File.join(__dir__, 'template.json')))
|
||||
deployment = Azure::ARM::Resources::Models::Deployment.new
|
||||
deployment.properties = Azure::ARM::Resources::Models::DeploymentProperties.new
|
||||
deployment.properties.template = JSON.parse(template)
|
||||
deployment.properties.mode = Azure::ARM::Resources::Models::DeploymentMode::Incremental
|
||||
|
||||
# build the deployment template parameters from Hash to {key: {value: value}} format
|
||||
deploy_params = File.read(File.expand_path(File.join(__dir__, 'parameters.json')))
|
||||
deployment.properties.parameters = JSON.parse(deploy_params)["parameters"]
|
||||
|
||||
# put the deployment to the resource group
|
||||
@client.deployments.create_or_update(@resource_group, 'azure-sample', deployment)
|
||||
end
|
||||
end
|
||||
|
||||
# Get user inputs and execute the script
|
||||
if(ARGV.empty?)
|
||||
puts "Please specify subscriptionId resourceGroupName resourceGroupLocation as command line arguments"
|
||||
exit
|
||||
end
|
||||
|
||||
subscription_id = ARGV[0] # Azure Subscription Id
|
||||
resource_group = ARGV[1] # The resource group for deployment
|
||||
resource_group_location = ARGV[2] # The resource group location
|
||||
|
||||
msg = "\nInitializing the Deployer class with subscription id: #{subscription_id}, resource group: #{resource_group}"
|
||||
msg += "\nand resource group location: #{resource_group_location}...\n\n"
|
||||
puts msg
|
||||
|
||||
# Initialize the deployer class
|
||||
deployer = Deployer.new(subscription_id, resource_group, resource_group_location)
|
||||
|
||||
puts "Beginning the deployment... \n\n"
|
||||
# Deploy the template
|
||||
deployment = deployer.deploy
|
||||
|
||||
puts "Done deploying!!"
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"appInsightsId": {
|
||||
"value": ""
|
||||
},
|
||||
"containerRegistryId": {
|
||||
"value": ""
|
||||
},
|
||||
"description": {
|
||||
"value": ""
|
||||
},
|
||||
"friendlyName": {
|
||||
"value": ""
|
||||
},
|
||||
"keyVaultId": {
|
||||
"value": ""
|
||||
},
|
||||
"location": {
|
||||
"value": "westeurope"
|
||||
},
|
||||
"machineLearningApiVersion": {
|
||||
"value": "2018-11-19"
|
||||
},
|
||||
"name": {
|
||||
"value": ""
|
||||
},
|
||||
"storageAccountId": {
|
||||
"value": ""
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
# register datastore
|
||||
az ml datastore register-blob -n $datastorename -a $accountname -k $accountkey -c $containername
|
||||
|
||||
# set default datastore
|
||||
az ml datastore set-default -n $datastorename
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"machineLearningApiVersion": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"friendlyName": {
|
||||
"type": "string"
|
||||
},
|
||||
"location": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"storageAccountId": {
|
||||
"type": "string"
|
||||
},
|
||||
"appInsightsId": {
|
||||
"type": "string"
|
||||
},
|
||||
"containerRegistryId": {
|
||||
"type": "string"
|
||||
},
|
||||
"keyVaultId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"name": "[parameters('name')]",
|
||||
"type": "Microsoft.MachineLearningServices/workspaces",
|
||||
"apiVersion": "2018-11-19",
|
||||
"location": "[parameters('location')]",
|
||||
"identity": {
|
||||
"type": "systemAssigned"
|
||||
},
|
||||
"tags": {},
|
||||
"properties": {
|
||||
"description": "[parameters('description')]",
|
||||
"friendlyName": "[parameters('friendlyName')]",
|
||||
"keyVault": "[parameters('keyVaultId')]",
|
||||
"applicationInsights": "[parameters('appInsightsId')]",
|
||||
"containerRegistry": "[parameters('containerRegistryId')]",
|
||||
"storageAccount": "[parameters('storageAccountId')]"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
// Requires the following Azure NuGet packages and related dependencies:
|
||||
// package id="Microsoft.Azure.Management.Authorization" version="2.0.0"
|
||||
// package id="Microsoft.Azure.Management.ResourceManager" version="1.4.0-preview"
|
||||
// package id="Microsoft.Rest.ClientRuntime.Azure.Authentication" version="2.2.8-preview"
|
||||
|
||||
using Microsoft.Azure.Management.ResourceManager;
|
||||
using Microsoft.Azure.Management.ResourceManager.Models;
|
||||
using Microsoft.Rest.Azure.Authentication;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace PortalGenerated
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a helper class for deploying an Azure Resource Manager template
|
||||
/// More info about template deployments can be found here https://go.microsoft.com/fwLink/?LinkID=733371
|
||||
/// </summary>
|
||||
class DeploymentHelper
|
||||
{
|
||||
string subscriptionId = "your-subscription-id";
|
||||
string clientId = "your-service-principal-clientId";
|
||||
string clientSecret = "your-service-principal-client-secret";
|
||||
string resourceGroupName = "resource-group-name";
|
||||
string deploymentName = "deployment-name";
|
||||
string resourceGroupLocation = "resource-group-location"; // must be specified for creating a new resource group
|
||||
string pathToTemplateFile = "path-to-template.json-on-disk";
|
||||
string pathToParameterFile = "path-to-parameters.json-on-disk";
|
||||
string tenantId = "tenant-id";
|
||||
|
||||
public async void Run()
|
||||
{
|
||||
// Try to obtain the service credentials
|
||||
var serviceCreds = await ApplicationTokenProvider.LoginSilentAsync(tenantId, clientId, clientSecret);
|
||||
|
||||
// Read the template and parameter file contents
|
||||
JObject templateFileContents = GetJsonFileContents(pathToTemplateFile);
|
||||
JObject parameterFileContents = GetJsonFileContents(pathToParameterFile);
|
||||
|
||||
// Create the resource manager client
|
||||
var resourceManagementClient = new ResourceManagementClient(serviceCreds);
|
||||
resourceManagementClient.SubscriptionId = subscriptionId;
|
||||
|
||||
// Create or check that resource group exists
|
||||
EnsureResourceGroupExists(resourceManagementClient, resourceGroupName, resourceGroupLocation);
|
||||
|
||||
// Start a deployment
|
||||
DeployTemplate(resourceManagementClient, resourceGroupName, deploymentName, templateFileContents, parameterFileContents);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a JSON file from the specified path
|
||||
/// </summary>
|
||||
/// <param name="pathToJson">The full path to the JSON file</param>
|
||||
/// <returns>The JSON file contents</returns>
|
||||
private JObject GetJsonFileContents(string pathToJson)
|
||||
{
|
||||
JObject templatefileContent = new JObject();
|
||||
using (StreamReader file = File.OpenText(pathToJson))
|
||||
{
|
||||
using (JsonTextReader reader = new JsonTextReader(file))
|
||||
{
|
||||
templatefileContent = (JObject)JToken.ReadFrom(reader);
|
||||
return templatefileContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that a resource group with the specified name exists. If it does not, will attempt to create one.
|
||||
/// </summary>
|
||||
/// <param name="resourceManagementClient">The resource manager client.</param>
|
||||
/// <param name="resourceGroupName">The name of the resource group.</param>
|
||||
/// <param name="resourceGroupLocation">The resource group location. Required when creating a new resource group.</param>
|
||||
private static void EnsureResourceGroupExists(ResourceManagementClient resourceManagementClient, string resourceGroupName, string resourceGroupLocation)
|
||||
{
|
||||
if (resourceManagementClient.ResourceGroups.CheckExistence(resourceGroupName) != true)
|
||||
{
|
||||
Console.WriteLine(string.Format("Creating resource group '{0}' in location '{1}'", resourceGroupName, resourceGroupLocation));
|
||||
var resourceGroup = new ResourceGroup();
|
||||
resourceGroup.Location = resourceGroupLocation;
|
||||
resourceManagementClient.ResourceGroups.CreateOrUpdate(resourceGroupName, resourceGroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(string.Format("Using existing resource group '{0}'", resourceGroupName));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a template deployment.
|
||||
/// </summary>
|
||||
/// <param name="resourceManagementClient">The resource manager client.</param>
|
||||
/// <param name="resourceGroupName">The name of the resource group.</param>
|
||||
/// <param name="deploymentName">The name of the deployment.</param>
|
||||
/// <param name="templateFileContents">The template file contents.</param>
|
||||
/// <param name="parameterFileContents">The parameter file contents.</param>
|
||||
private static void DeployTemplate(ResourceManagementClient resourceManagementClient, string resourceGroupName, string deploymentName, JObject templateFileContents, JObject parameterFileContents)
|
||||
{
|
||||
Console.WriteLine(string.Format("Starting template deployment '{0}' in resource group '{1}'", deploymentName, resourceGroupName));
|
||||
var deployment = new Deployment();
|
||||
|
||||
deployment.Properties = new DeploymentProperties
|
||||
{
|
||||
Mode = DeploymentMode.Incremental,
|
||||
Template = templateFileContents,
|
||||
Parameters = parameterFileContents["parameters"].ToObject<JObject>()
|
||||
};
|
||||
|
||||
var deploymentResult = resourceManagementClient.Deployments.CreateOrUpdate(resourceGroupName, deploymentName, deployment);
|
||||
Console.WriteLine(string.Format("Deployment status: {0}", deploymentResult.Properties.ProvisioningState));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
<#
|
||||
.SYNOPSIS
|
||||
Deploys a template to Azure
|
||||
|
||||
.DESCRIPTION
|
||||
Deploys an Azure Resource Manager template
|
||||
|
||||
.PARAMETER subscriptionId
|
||||
The subscription id where the template will be deployed.
|
||||
|
||||
.PARAMETER resourceGroupName
|
||||
The resource group where the template will be deployed. Can be the name of an existing or a new resource group.
|
||||
|
||||
.PARAMETER resourceGroupLocation
|
||||
Optional, a resource group location. If specified, will try to create a new resource group in this location. If not specified, assumes resource group is existing.
|
||||
|
||||
.PARAMETER deploymentName
|
||||
The deployment name.
|
||||
|
||||
.PARAMETER templateFilePath
|
||||
Optional, path to the template file. Defaults to template.json.
|
||||
|
||||
.PARAMETER parametersFilePath
|
||||
Optional, path to the parameters file. Defaults to parameters.json. If file is not found, will prompt for parameter values based on template.
|
||||
#>
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$subscriptionId,
|
||||
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$resourceGroupName,
|
||||
|
||||
[string]
|
||||
$resourceGroupLocation,
|
||||
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$deploymentName,
|
||||
|
||||
[string]
|
||||
$templateFilePath = "template.json",
|
||||
|
||||
[string]
|
||||
$parametersFilePath = "parameters.json"
|
||||
)
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Registers RPs
|
||||
#>
|
||||
Function RegisterRP {
|
||||
Param(
|
||||
[string]$ResourceProviderNamespace
|
||||
)
|
||||
|
||||
Write-Host "Registering resource provider '$ResourceProviderNamespace'";
|
||||
Register-AzureRmResourceProvider -ProviderNamespace $ResourceProviderNamespace;
|
||||
}
|
||||
|
||||
#******************************************************************************
|
||||
# Script body
|
||||
# Execution begins here
|
||||
#******************************************************************************
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# sign in
|
||||
Write-Host "Logging in...";
|
||||
Login-AzureRmAccount;
|
||||
|
||||
# select subscription
|
||||
Write-Host "Selecting subscription '$subscriptionId'";
|
||||
Select-AzureRmSubscription -SubscriptionID $subscriptionId;
|
||||
|
||||
# Register RPs
|
||||
$resourceProviders = @("microsoft.storage");
|
||||
if($resourceProviders.length) {
|
||||
Write-Host "Registering resource providers"
|
||||
foreach($resourceProvider in $resourceProviders) {
|
||||
RegisterRP($resourceProvider);
|
||||
}
|
||||
}
|
||||
|
||||
#Create or check for existing resource group
|
||||
$resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue
|
||||
if(!$resourceGroup)
|
||||
{
|
||||
Write-Host "Resource group '$resourceGroupName' does not exist. To create a new resource group, please enter a location.";
|
||||
if(!$resourceGroupLocation) {
|
||||
$resourceGroupLocation = Read-Host "resourceGroupLocation";
|
||||
}
|
||||
Write-Host "Creating resource group '$resourceGroupName' in location '$resourceGroupLocation'";
|
||||
New-AzureRmResourceGroup -Name $resourceGroupName -Location $resourceGroupLocation
|
||||
}
|
||||
else{
|
||||
Write-Host "Using existing resource group '$resourceGroupName'";
|
||||
}
|
||||
|
||||
# Start the deployment
|
||||
Write-Host "Starting deployment...";
|
||||
if(Test-Path $parametersFilePath) {
|
||||
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile $templateFilePath -TemplateParameterFile $parametersFilePath;
|
||||
} else {
|
||||
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile $templateFilePath;
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
# -e: immediately exit if any command has a non-zero exit status
|
||||
# -o: prevents errors in a pipeline from being masked
|
||||
# IFS new value is less likely to cause confusing bugs when looping arrays or arguments (e.g. $@)
|
||||
|
||||
usage() { echo "Usage: $0 -i <subscriptionId> -g <resourceGroupName> -n <deploymentName> -l <resourceGroupLocation>" 1>&2; exit 1; }
|
||||
|
||||
declare subscriptionId=""
|
||||
declare resourceGroupName=""
|
||||
declare deploymentName=""
|
||||
declare resourceGroupLocation=""
|
||||
|
||||
# Initialize parameters specified from command line
|
||||
while getopts ":i:g:n:l:" arg; do
|
||||
case "${arg}" in
|
||||
i)
|
||||
subscriptionId=${OPTARG}
|
||||
;;
|
||||
g)
|
||||
resourceGroupName=${OPTARG}
|
||||
;;
|
||||
n)
|
||||
deploymentName=${OPTARG}
|
||||
;;
|
||||
l)
|
||||
resourceGroupLocation=${OPTARG}
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
#Prompt for parameters is some required parameters are missing
|
||||
if [[ -z "$subscriptionId" ]]; then
|
||||
echo "Your subscription ID can be looked up with the CLI using: az account show --out json "
|
||||
echo "Enter your subscription ID:"
|
||||
read subscriptionId
|
||||
[[ "${subscriptionId:?}" ]]
|
||||
fi
|
||||
|
||||
if [[ -z "$resourceGroupName" ]]; then
|
||||
echo "This script will look for an existing resource group, otherwise a new one will be created "
|
||||
echo "You can create new resource groups with the CLI using: az group create "
|
||||
echo "Enter a resource group name"
|
||||
read resourceGroupName
|
||||
[[ "${resourceGroupName:?}" ]]
|
||||
fi
|
||||
|
||||
if [[ -z "$deploymentName" ]]; then
|
||||
echo "Enter a name for this deployment:"
|
||||
read deploymentName
|
||||
fi
|
||||
|
||||
if [[ -z "$resourceGroupLocation" ]]; then
|
||||
echo "If creating a *new* resource group, you need to set a location "
|
||||
echo "You can lookup locations with the CLI using: az account list-locations "
|
||||
|
||||
echo "Enter resource group location:"
|
||||
read resourceGroupLocation
|
||||
fi
|
||||
|
||||
#templateFile Path - template file to be used
|
||||
templateFilePath="template.json"
|
||||
|
||||
if [ ! -f "$templateFilePath" ]; then
|
||||
echo "$templateFilePath not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#parameter file path
|
||||
parametersFilePath="parameters.json"
|
||||
|
||||
if [ ! -f "$parametersFilePath" ]; then
|
||||
echo "$parametersFilePath not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$subscriptionId" ] || [ -z "$resourceGroupName" ] || [ -z "$deploymentName" ]; then
|
||||
echo "Either one of subscriptionId, resourceGroupName, deploymentName is empty"
|
||||
usage
|
||||
fi
|
||||
|
||||
#login to azure using your credentials
|
||||
az account show 1> /dev/null
|
||||
|
||||
if [ $? != 0 ];
|
||||
then
|
||||
az login
|
||||
fi
|
||||
|
||||
#set the default subscription id
|
||||
az account set --subscription $subscriptionId
|
||||
|
||||
set +e
|
||||
|
||||
#Check for existing RG
|
||||
az group show --name $resourceGroupName 1> /dev/null
|
||||
|
||||
if [ $? != 0 ]; then
|
||||
echo "Resource group with name" $resourceGroupName "could not be found. Creating new resource group.."
|
||||
set -e
|
||||
(
|
||||
set -x
|
||||
az group create --name $resourceGroupName --location $resourceGroupLocation 1> /dev/null
|
||||
)
|
||||
else
|
||||
echo "Using existing resource group..."
|
||||
fi
|
||||
|
||||
#Start deployment
|
||||
echo "Starting deployment..."
|
||||
(
|
||||
set -x
|
||||
az group deployment create --name "$deploymentName" --resource-group "$resourceGroupName" --template-file "$templateFilePath" --parameters "@${parametersFilePath}"
|
||||
)
|
||||
|
||||
if [ $? == 0 ];
|
||||
then
|
||||
echo "Template has been successfully deployed"
|
||||
fi
|
|
@ -0,0 +1,71 @@
|
|||
require 'azure_mgmt_resources'
|
||||
|
||||
class Deployer
|
||||
|
||||
# Initialize the deployer class with subscription, resource group and resource group location. The class will raise an
|
||||
# ArgumentError if there are empty values for Tenant Id, Client Id or Client Secret environment variables.
|
||||
#
|
||||
# @param [String] subscription_id the subscription to deploy the template
|
||||
# @param [String] resource_group the resource group to create or update and then deploy the template
|
||||
# @param [String] resource_group_location the location of the resource group
|
||||
def initialize(subscription_id, resource_group, resource_group_location)
|
||||
raise ArgumentError.new("Missing template file 'template.json' in current directory.") unless File.exist?('template.json')
|
||||
raise ArgumentError.new("Missing parameters file 'parameters.json' in current directory.") unless File.exist?('parameters.json')
|
||||
@resource_group = resource_group
|
||||
@subscription_id = subscription_id
|
||||
@resource_group_location = resource_group_location
|
||||
provider = MsRestAzure::ApplicationTokenProvider.new(
|
||||
ENV['AZURE_TENANT_ID'],
|
||||
ENV['AZURE_CLIENT_ID'],
|
||||
ENV['AZURE_CLIENT_SECRET'])
|
||||
credentials = MsRest::TokenCredentials.new(provider)
|
||||
@client = Azure::ARM::Resources::ResourceManagementClient.new(credentials)
|
||||
@client.subscription_id = @subscription_id
|
||||
end
|
||||
|
||||
# Deploy the template to a resource group
|
||||
def deploy
|
||||
# ensure the resource group is created
|
||||
params = Azure::ARM::Resources::Models::ResourceGroup.new.tap do |rg|
|
||||
rg.location = @resource_group_location
|
||||
end
|
||||
@client.resource_groups.create_or_update(@resource_group, params).value!
|
||||
|
||||
# build the deployment from a json file template from parameters
|
||||
template = File.read(File.expand_path(File.join(__dir__, 'template.json')))
|
||||
deployment = Azure::ARM::Resources::Models::Deployment.new
|
||||
deployment.properties = Azure::ARM::Resources::Models::DeploymentProperties.new
|
||||
deployment.properties.template = JSON.parse(template)
|
||||
deployment.properties.mode = Azure::ARM::Resources::Models::DeploymentMode::Incremental
|
||||
|
||||
# build the deployment template parameters from Hash to {key: {value: value}} format
|
||||
deploy_params = File.read(File.expand_path(File.join(__dir__, 'parameters.json')))
|
||||
deployment.properties.parameters = JSON.parse(deploy_params)["parameters"]
|
||||
|
||||
# put the deployment to the resource group
|
||||
@client.deployments.create_or_update(@resource_group, 'azure-sample', deployment)
|
||||
end
|
||||
end
|
||||
|
||||
# Get user inputs and execute the script
|
||||
if(ARGV.empty?)
|
||||
puts "Please specify subscriptionId resourceGroupName resourceGroupLocation as command line arguments"
|
||||
exit
|
||||
end
|
||||
|
||||
subscription_id = ARGV[0] # Azure Subscription Id
|
||||
resource_group = ARGV[1] # The resource group for deployment
|
||||
resource_group_location = ARGV[2] # The resource group location
|
||||
|
||||
msg = "\nInitializing the Deployer class with subscription id: #{subscription_id}, resource group: #{resource_group}"
|
||||
msg += "\nand resource group location: #{resource_group_location}...\n\n"
|
||||
puts msg
|
||||
|
||||
# Initialize the deployer class
|
||||
deployer = Deployer.new(subscription_id, resource_group, resource_group_location)
|
||||
|
||||
puts "Beginning the deployment... \n\n"
|
||||
# Deploy the template
|
||||
deployment = deployer.deploy
|
||||
|
||||
puts "Done deploying!!"
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"location": {
|
||||
"value": "northeurope"
|
||||
},
|
||||
"storageAccountName": {
|
||||
"value": "deeikelestorage"
|
||||
},
|
||||
"accountType": {
|
||||
"value": "Standard_RAGRS"
|
||||
},
|
||||
"kind": {
|
||||
"value": "StorageV2"
|
||||
},
|
||||
"accessTier": {
|
||||
"value": "Hot"
|
||||
},
|
||||
"supportsHttpsTrafficOnly": {
|
||||
"value": true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"location": {
|
||||
"type": "String"
|
||||
},
|
||||
"storageAccountName": {
|
||||
"type": "String"
|
||||
},
|
||||
"accountType": {
|
||||
"type": "String"
|
||||
},
|
||||
"kind": {
|
||||
"type": "String"
|
||||
},
|
||||
"accessTier": {
|
||||
"type": "String"
|
||||
},
|
||||
"supportsHttpsTrafficOnly": {
|
||||
"type": "Bool"
|
||||
}
|
||||
},
|
||||
"variables": {},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"sku": {
|
||||
"name": "[parameters('accountType')]"
|
||||
},
|
||||
"kind": "[parameters('kind')]",
|
||||
"name": "[parameters('storageAccountName')]",
|
||||
"apiVersion": "2018-07-01",
|
||||
"location": "[parameters('location')]",
|
||||
"properties": {
|
||||
"accessTier": "[parameters('accessTier')]",
|
||||
"supportsHttpsTrafficOnly": "[parameters('supportsHttpsTrafficOnly')]"
|
||||
},
|
||||
"dependsOn": []
|
||||
}
|
||||
],
|
||||
"outputs": {
|
||||
"resourceId": {
|
||||
"value": "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
# The script to run.
|
||||
script: train.py
|
||||
# The arguments to the script file.
|
||||
arguments: []
|
||||
# The name of the compute target to use for this run.
|
||||
target: local
|
||||
# Framework to execute inside. Allowed values are "Python" , "PySpark", "CNTK", "TensorFlow", and "PyTorch".
|
||||
framework: PySpark
|
||||
# Communicator for the given framework. Allowed values are "None" , "ParameterServer", "OpenMpi", and "IntelMpi".
|
||||
communicator: None
|
||||
# Automatically prepare the run environment as part of the run itself.
|
||||
autoPrepareEnvironment: true
|
||||
# Maximum allowed duration for the run.
|
||||
maxRunDurationSeconds:
|
||||
# Number of nodes to use for running job.
|
||||
nodeCount: 1
|
||||
# Environment details.
|
||||
environment:
|
||||
# Environment variables set for the run.
|
||||
environmentVariables:
|
||||
EXAMPLE_ENV_VAR: EXAMPLE_VALUE
|
||||
# Python details
|
||||
python:
|
||||
# user_managed_dependencies=True indicates that the environmentwill be user managed. False indicates that AzureML willmanage the user environment.
|
||||
userManagedDependencies: false
|
||||
# The python interpreter path
|
||||
interpreterPath: python
|
||||
# Path to the conda dependencies file to use for this run. If a project
|
||||
# contains multiple programs with different sets of dependencies, it may be
|
||||
# convenient to manage those environments with separate files.
|
||||
condaDependenciesFile: ../conda_dependencies.yml
|
||||
# Docker details
|
||||
docker:
|
||||
# Set True to perform this run inside a Docker container.
|
||||
enabled: true
|
||||
# Base image used for Docker-based runs.
|
||||
baseImage: mcr.microsoft.com/azureml/base:0.2.0
|
||||
# Set False if necessary to work around shared volume bugs.
|
||||
sharedVolumes: true
|
||||
# Run with NVidia Docker extension to support GPUs.
|
||||
gpuSupport: false
|
||||
# Extra arguments to the Docker run command.
|
||||
arguments: []
|
||||
# Image registry that contains the base image.
|
||||
baseImageRegistry:
|
||||
# DNS name or IP address of azure container registry(ACR)
|
||||
address:
|
||||
# The username for ACR
|
||||
username:
|
||||
# The password for ACR
|
||||
password:
|
||||
# Spark details
|
||||
spark:
|
||||
# List of spark repositories.
|
||||
repositories:
|
||||
- https://mmlspark.azureedge.net/maven
|
||||
packages:
|
||||
- group: com.microsoft.ml.spark
|
||||
artifact: mmlspark_2.11
|
||||
version: '0.12'
|
||||
precachePackages: true
|
||||
# Databricks details
|
||||
databricks:
|
||||
# List of maven libraries.
|
||||
mavenLibraries: []
|
||||
# List of PyPi libraries
|
||||
pypiLibraries: []
|
||||
# List of RCran libraries
|
||||
rcranLibraries: []
|
||||
# List of JAR libraries
|
||||
jarLibraries: []
|
||||
# List of Egg libraries
|
||||
eggLibraries: []
|
||||
# History details.
|
||||
history:
|
||||
# Enable history tracking -- this allows status, logs, metrics, and outputs
|
||||
# to be collected for a run.
|
||||
outputCollection: true
|
||||
# whether to take snapshots for history.
|
||||
snapshotProject: true
|
||||
# Spark configuration details.
|
||||
spark:
|
||||
configuration:
|
||||
spark.app.name: Azure ML Experiment
|
||||
spark.yarn.maxAppAttempts: 1
|
||||
# HDI details.
|
||||
hdi:
|
||||
# Yarn deploy mode. Options are cluster and client.
|
||||
yarnDeployMode: cluster
|
||||
# Tensorflow details.
|
||||
tensorflow:
|
||||
# The number of worker tasks.
|
||||
workerCount: 1
|
||||
# The number of parameter server tasks.
|
||||
parameterServerCount: 1
|
||||
# Mpi details.
|
||||
mpi:
|
||||
# When using MPI, number of processes per node.
|
||||
processCountPerNode: 1
|
||||
# data reference configuration details
|
||||
dataReferences: {}
|
||||
# Project share datastore reference.
|
||||
sourceDirectoryDataStore:
|
||||
# AmlCompute details.
|
||||
amlcompute:
|
||||
# VM size of the Cluster to be created.Allowed values are Azure vm sizes.The list of vm sizes is available in 'https://docs.microsoft.com/en-us/azure/cloud-services/cloud-services-sizes-specs
|
||||
vmSize:
|
||||
# VM priority of the Cluster to be created.Allowed values are "dedicated" , "lowpriority".
|
||||
vmPriority:
|
||||
# A bool that indicates if the cluster has to be retained after job completion.
|
||||
retainCluster: false
|
||||
# Name of the cluster to be created. If not specified, runId will be used as cluster name.
|
||||
name:
|
||||
# Maximum number of nodes in the AmlCompute cluster to be created. Minimum number of nodes will always be set to 0.
|
||||
clusterMaxNodeCount: 1
|
|
@ -0,0 +1,126 @@
|
|||
# The script to run.
|
||||
script: train.py
|
||||
# The arguments to the script file.
|
||||
arguments: []
|
||||
# The name of the compute target to use for this run.
|
||||
target: dsvmcluster
|
||||
# Framework to execute inside. Allowed values are "Python" , "PySpark", "CNTK", "TensorFlow", and "PyTorch".
|
||||
framework: Python
|
||||
# Communicator for the given framework. Allowed values are "None" , "ParameterServer", "OpenMpi", and "IntelMpi".
|
||||
communicator: None
|
||||
# Automatically prepare the run environment as part of the run itself.
|
||||
autoPrepareEnvironment: true
|
||||
# Maximum allowed duration for the run.
|
||||
maxRunDurationSeconds:
|
||||
# Number of nodes to use for running job.
|
||||
nodeCount: 1
|
||||
# Environment details.
|
||||
environment:
|
||||
# Environment variables set for the run.
|
||||
environmentVariables:
|
||||
EXAMPLE_ENV_VAR: EXAMPLE_VALUE
|
||||
# Python details
|
||||
python:
|
||||
# user_managed_dependencies=True indicates that the environmentwill be user managed. False indicates that AzureML willmanage the user environment.
|
||||
userManagedDependencies: false
|
||||
# The python interpreter path
|
||||
interpreterPath: python
|
||||
# Path to the conda dependencies file to use for this run. If a project
|
||||
# contains multiple programs with different sets of dependencies, it may be
|
||||
# convenient to manage those environments with separate files.
|
||||
condaDependenciesFile: ../conda_dependencies.yml
|
||||
# Docker details
|
||||
docker:
|
||||
# Set True to perform this run inside a Docker container.
|
||||
enabled: true
|
||||
# Base image used for Docker-based runs.
|
||||
baseImage: mcr.microsoft.com/azureml/base:0.2.0
|
||||
# Set False if necessary to work around shared volume bugs.
|
||||
sharedVolumes: true
|
||||
# Run with NVidia Docker extension to support GPUs.
|
||||
gpuSupport: false
|
||||
# Extra arguments to the Docker run command.
|
||||
arguments: []
|
||||
# Image registry that contains the base image.
|
||||
baseImageRegistry:
|
||||
# DNS name or IP address of azure container registry(ACR)
|
||||
address:
|
||||
# The username for ACR
|
||||
username:
|
||||
# The password for ACR
|
||||
password:
|
||||
# Spark details
|
||||
spark:
|
||||
# List of spark repositories.
|
||||
repositories:
|
||||
- https://mmlspark.azureedge.net/maven
|
||||
packages:
|
||||
- group: com.microsoft.ml.spark
|
||||
artifact: mmlspark_2.11
|
||||
version: '0.12'
|
||||
precachePackages: true
|
||||
# Databricks details
|
||||
databricks:
|
||||
# List of maven libraries.
|
||||
mavenLibraries: []
|
||||
# List of PyPi libraries
|
||||
pypiLibraries: []
|
||||
# List of RCran libraries
|
||||
rcranLibraries: []
|
||||
# List of JAR libraries
|
||||
jarLibraries: []
|
||||
# List of Egg libraries
|
||||
eggLibraries: []
|
||||
# History details.
|
||||
history:
|
||||
# Enable history tracking -- this allows status, logs, metrics, and outputs
|
||||
# to be collected for a run.
|
||||
outputCollection: true
|
||||
# whether to take snapshots for history.
|
||||
snapshotProject: true
|
||||
# Spark configuration details.
|
||||
spark:
|
||||
configuration:
|
||||
spark.app.name: Azure ML Experiment
|
||||
spark.yarn.maxAppAttempts: 1
|
||||
# HDI details.
|
||||
hdi:
|
||||
# Yarn deploy mode. Options are cluster and client.
|
||||
yarnDeployMode: cluster
|
||||
# Tensorflow details.
|
||||
tensorflow:
|
||||
# The number of worker tasks.
|
||||
workerCount: 1
|
||||
# The number of parameter server tasks.
|
||||
parameterServerCount: 1
|
||||
# Mpi details.
|
||||
mpi:
|
||||
# When using MPI, number of processes per node.
|
||||
processCountPerNode: 1
|
||||
# data reference configuration details
|
||||
dataReferences:
|
||||
workspaceblobstore:
|
||||
# Name of the datastore.
|
||||
dataStoreName: workspaceblobstore
|
||||
# relative path on the datastore.
|
||||
pathOnDataStore:
|
||||
# operation on the datastore, mount, download, upload
|
||||
mode: mount
|
||||
# whether to overwrite the data if existing
|
||||
overwrite: false
|
||||
# the path on the compute target.
|
||||
pathOnCompute:
|
||||
# Project share datastore reference.
|
||||
sourceDirectoryDataStore:
|
||||
# AmlCompute details.
|
||||
amlcompute:
|
||||
# VM size of the Cluster to be created.Allowed values are Azure vm sizes.The list of vm sizes is available in 'https://docs.microsoft.com/en-us/azure/cloud-services/cloud-services-sizes-specs
|
||||
vmSize:
|
||||
# VM priority of the Cluster to be created.Allowed values are "dedicated" , "lowpriority".
|
||||
vmPriority:
|
||||
# A bool that indicates if the cluster has to be retained after job completion.
|
||||
retainCluster: false
|
||||
# Name of the cluster to be created. If not specified, runId will be used as cluster name.
|
||||
name:
|
||||
# Maximum number of nodes in the AmlCompute cluster to be created. Minimum number of nodes will always be set to 0.
|
||||
clusterMaxNodeCount: 1
|
|
@ -0,0 +1,126 @@
|
|||
# The script to run.
|
||||
script: train.py
|
||||
# The arguments to the script file.
|
||||
arguments: []
|
||||
# The name of the compute target to use for this run.
|
||||
target: local
|
||||
# Framework to execute inside. Allowed values are "Python" , "PySpark", "CNTK", "TensorFlow", and "PyTorch".
|
||||
framework: Python
|
||||
# Communicator for the given framework. Allowed values are "None" , "ParameterServer", "OpenMpi", and "IntelMpi".
|
||||
communicator: None
|
||||
# Automatically prepare the run environment as part of the run itself.
|
||||
autoPrepareEnvironment: true
|
||||
# Maximum allowed duration for the run.
|
||||
maxRunDurationSeconds:
|
||||
# Number of nodes to use for running job.
|
||||
nodeCount: 1
|
||||
# Environment details.
|
||||
environment:
|
||||
# Environment variables set for the run.
|
||||
environmentVariables:
|
||||
EXAMPLE_ENV_VAR: EXAMPLE_VALUE
|
||||
# Python details
|
||||
python:
|
||||
# user_managed_dependencies=True indicates that the environmentwill be user managed. False indicates that AzureML willmanage the user environment.
|
||||
userManagedDependencies: false
|
||||
# The python interpreter path
|
||||
interpreterPath: python
|
||||
# Path to the conda dependencies file to use for this run. If a project
|
||||
# contains multiple programs with different sets of dependencies, it may be
|
||||
# convenient to manage those environments with separate files.
|
||||
condaDependenciesFile: ../conda_dependencies.yml
|
||||
# Docker details
|
||||
docker:
|
||||
# Set True to perform this run inside a Docker container.
|
||||
enabled: false
|
||||
# Base image used for Docker-based runs.
|
||||
baseImage: mcr.microsoft.com/azureml/base:0.2.0
|
||||
# Set False if necessary to work around shared volume bugs.
|
||||
sharedVolumes: true
|
||||
# Run with NVidia Docker extension to support GPUs.
|
||||
gpuSupport: false
|
||||
# Extra arguments to the Docker run command.
|
||||
arguments: []
|
||||
# Image registry that contains the base image.
|
||||
baseImageRegistry:
|
||||
# DNS name or IP address of azure container registry(ACR)
|
||||
address:
|
||||
# The username for ACR
|
||||
username:
|
||||
# The password for ACR
|
||||
password:
|
||||
# Spark details
|
||||
spark:
|
||||
# List of spark repositories.
|
||||
repositories:
|
||||
- https://mmlspark.azureedge.net/maven
|
||||
packages:
|
||||
- group: com.microsoft.ml.spark
|
||||
artifact: mmlspark_2.11
|
||||
version: '0.12'
|
||||
precachePackages: true
|
||||
# Databricks details
|
||||
databricks:
|
||||
# List of maven libraries.
|
||||
mavenLibraries: []
|
||||
# List of PyPi libraries
|
||||
pypiLibraries: []
|
||||
# List of RCran libraries
|
||||
rcranLibraries: []
|
||||
# List of JAR libraries
|
||||
jarLibraries: []
|
||||
# List of Egg libraries
|
||||
eggLibraries: []
|
||||
# History details.
|
||||
history:
|
||||
# Enable history tracking -- this allows status, logs, metrics, and outputs
|
||||
# to be collected for a run.
|
||||
outputCollection: true
|
||||
# whether to take snapshots for history.
|
||||
snapshotProject: true
|
||||
# Spark configuration details.
|
||||
spark:
|
||||
configuration:
|
||||
spark.app.name: Azure ML Experiment
|
||||
spark.yarn.maxAppAttempts: 1
|
||||
# HDI details.
|
||||
hdi:
|
||||
# Yarn deploy mode. Options are cluster and client.
|
||||
yarnDeployMode: cluster
|
||||
# Tensorflow details.
|
||||
tensorflow:
|
||||
# The number of worker tasks.
|
||||
workerCount: 1
|
||||
# The number of parameter server tasks.
|
||||
parameterServerCount: 1
|
||||
# Mpi details.
|
||||
mpi:
|
||||
# When using MPI, number of processes per node.
|
||||
processCountPerNode: 1
|
||||
# data reference configuration details
|
||||
dataReferences:
|
||||
workspaceblobstore:
|
||||
# Name of the datastore.
|
||||
dataStoreName: workspaceblobstore
|
||||
# relative path on the datastore.
|
||||
pathOnDataStore:
|
||||
# operation on the datastore, mount, download, upload
|
||||
mode: download
|
||||
# whether to overwrite the data if existing
|
||||
overwrite: false
|
||||
# the path on the compute target.
|
||||
pathOnCompute:
|
||||
# Project share datastore reference.
|
||||
sourceDirectoryDataStore:
|
||||
# AmlCompute details.
|
||||
amlcompute:
|
||||
# VM size of the Cluster to be created.Allowed values are Azure vm sizes.The list of vm sizes is available in 'https://docs.microsoft.com/en-us/azure/cloud-services/cloud-services-sizes-specs
|
||||
vmSize:
|
||||
# VM priority of the Cluster to be created.Allowed values are "dedicated" , "lowpriority".
|
||||
vmPriority:
|
||||
# A bool that indicates if the cluster has to be retained after job completion.
|
||||
retainCluster: false
|
||||
# Name of the cluster to be created. If not specified, runId will be used as cluster name.
|
||||
name:
|
||||
# Maximum number of nodes in the AmlCompute cluster to be created. Minimum number of nodes will always be set to 0.
|
||||
clusterMaxNodeCount: 1
|
|
@ -0,0 +1,19 @@
|
|||
name: project_environment
|
||||
dependencies:
|
||||
- python=3.6.2
|
||||
- pip:
|
||||
- numpy==1.15.4
|
||||
- pandas==0.23.4
|
||||
- scikit-learn==0.20.1
|
||||
- scipy==1.0.0
|
||||
- matplotlib==3.0.2
|
||||
- utils==0.9.0
|
||||
# Required packages for AzureML execution, history, and data preparation.
|
||||
- azureml-sdk==1.0.10
|
||||
- azureml-defaults==1.0.10
|
||||
- azure-cli==2.0.58
|
||||
# Dev Tools
|
||||
- setuptools
|
||||
- flake8
|
||||
- flake8_formatter_junit_xml
|
||||
- pytest
|
Загрузка…
Ссылка в новой задаче