Skip to content

Commit 8fb12af

Browse files
authored
Add Terraform option to environment_setup (#268)
* setup basic folder and file structure * add tf backend file and bash script to create state storage * basic pipeline for infrastructure with tf - yaml, tf, bash * naming and deleting unnecessary bash script * updated documentation * added to the get_started.md guide * added terraform plan step
1 parent 32dd48f commit 8fb12af

File tree

6 files changed

+158
-4
lines changed

6 files changed

+158
-4
lines changed

docs/code_description.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ High level directory structure for this repository:
1818
│ ├── util <- Python script for various utility operations specific to this ML project.
1919
├── docs <- Extensive markdown documentation for entire project.
2020
├── environment_setup <- The top-level folder for everything related to infrastructure.
21-
│ ├── arm-templates <- Azure Resource Manager(ARM) templates to build infrastructure needed for this project.
21+
│ ├── arm-templates <- Azure Resource Manager(ARM) templates to build infrastructure needed for this project.
22+
│ ├── tf-templates <- Terraform templates to build infrastructure needed for this project.
2223
├── experimentation <- Jupyter notebooks with ML experimentation code.
2324
├── ml_service <- The top-level folder for all Azure Machine Learning resources.
2425
│ ├── pipelines <- Python script that builds Azure Machine Learning pipelines.
@@ -35,7 +36,11 @@ The repository provides a template with folders structure suitable for maintaini
3536

3637
- `environment_setup/install_requirements.sh` : This script prepares a local conda environment i.e. install the Azure ML SDK and the packages specified in environment definitions.
3738

38-
- `environment_setup/iac-*.yml, arm-templates` : Infrastructure as Code piplines to create and delete required resources along with corresponding arm-templates.
39+
- `environment_setup/iac-*-arm.yml, arm-templates` : Infrastructure as Code piplines to create required resources using ARM, along with corresponding arm-templates. Infrastructure as Code can be deployed with this template or with the Terraform template.
40+
41+
- `environment_setup/iac-*-tf.yml, tf-templates` : Infrastructure as Code piplines to create required resources using Terraform, along with corresponding tf-templates. Infrastructure as Code can be deployed with this template or with the ARM template.
42+
43+
- `environment_setup/iac-remove-environment.yml` : Infrastructure as Code piplines to delete the created required resources.
3944

4045
- `environment_setup/Dockerfile` : Dockerfile of a build agent containing Python 3.6 and all required packages.
4146

docs/getting_started.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ More variables are available for further tweaking, but the above variables are a
8181

8282
## Provisioning resources using Azure Pipelines
8383

84-
The easiest way to create all required Azure resources (Resource Group, Azure ML Workspace, Container Registry, and others) is to use the **Infrastructure as Code (IaC)** [pipeline in this repository](../environment_setup/iac-create-environment-pipeline.yml). The pipeline takes care of setting up all required resources based on these [Azure Resource Manager templates](../environment_setup/arm-templates/cloud-environment.json).
84+
The easiest way to create all required Azure resources (Resource Group, Azure ML Workspace, Container Registry, and others) is to use the **Infrastructure as Code (IaC)** [pipeline with ARM templates](../environment_setup/iac-create-environment-pipeline-arm.yml) or the [pipeline with Terraform templates](../environment_setup/iac-create-environment-pipeline-tf.yml). The pipeline takes care of setting up all required resources based on these [Azure Resource Manager templates](../environment_setup/arm-templates/cloud-environment.json), or based on these [Terraform templates](../environment_setup/tf-templates).
8585

8686
### Create an Azure DevOps Service Connection for the Azure Resource Manager
8787

@@ -100,10 +100,12 @@ In your Azure DevOps project, create a build pipeline from your forked repositor
100100

101101
![Build connect step](./images/build-connect.png)
102102

103-
Select the **Existing Azure Pipelines YAML file** option and set the path to [/environment_setup/iac-create-environment-pipeline.yml](../environment_setup/iac-create-environment-pipeline.yml):
103+
Select the **Existing Azure Pipelines YAML file** option and set the path to [/environment_setup/iac-create-environment-pipeline-arm.yml](../environment_setup/iac-create-environment-pipeline-arm.yml) or to [/environment_setup/iac-create-environment-pipeline-tf.yml](../environment_setup/iac-create-environment-pipeline-tf.yml), depending on if you want to deploy your infrastructure using ARM templates or Terraform:
104104

105105
![Configure step](./images/select-iac-pipeline.png)
106106

107+
If you decide to use Terraform, make sure the ['Terraform Build & Release Tasks' from Charles Zipp](https://marketplace.visualstudio.com/items?itemName=charleszipp.azure-pipelines-tasks-terraform) is installed.
108+
107109
Having done that, run the pipeline:
108110

109111
![IaC run](./images/run-iac-pipeline.png)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# CI/PR Pipeline that deploys an TF template to create or update the resources needed by the other pipelines.
2+
trigger:
3+
branches:
4+
include:
5+
- master
6+
paths:
7+
include:
8+
- environment_setup/tf-templates/*
9+
pr:
10+
branches:
11+
include:
12+
- master
13+
paths:
14+
include:
15+
- environment_setup/tf-templates/*
16+
17+
pool:
18+
vmImage: 'ubuntu-latest'
19+
20+
variables:
21+
- group: devopsforai-aml-vg
22+
23+
steps:
24+
- task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-installer.TerraformInstaller@0
25+
displayName: 'Use Terraform 0.12.24'
26+
inputs:
27+
terraformVersion: 0.12.24
28+
29+
- task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-cli.TerraformCLI@0
30+
displayName: 'TF init - Deploy MLOps resources to Azure'
31+
inputs:
32+
command: init
33+
commandOptions: '-backend=true -backend-config=$(Build.SourcesDirectory)/environment_setup/tf-templates/backend.tf'
34+
workingDirectory: '$(Build.SourcesDirectory)/environment_setup/tf-templates'
35+
backendType: azurerm
36+
backendServiceArm: $(AZURE_RM_SVC_CONNECTION)
37+
ensureBackend: true
38+
backendAzureRmResourceGroupLocation: $(LOCATION)
39+
backendAzureRmResourceGroupName: $(RESOURCE_GROUP)
40+
backendAzureRmStorageAccountName: 'statestor'
41+
backendAzureRmStorageAccountSku: 'Standard_LRS'
42+
backendAzureRmContainerName: 'tfstate-cont'
43+
backendAzureRmKey: 'mlopsinfra.tfstate'
44+
45+
- task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-cli.TerraformCLI@0
46+
displayName: 'TF validate - Deploy MLOps resources to Azure'
47+
inputs:
48+
command: validate
49+
workingDirectory: '$(Build.SourcesDirectory)/environment_setup/tf-templates'
50+
51+
- task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-cli.TerraformCLI@0
52+
displayName: 'TF plan - Deploy MLOps resources to Azure'
53+
inputs:
54+
command: plan
55+
workingDirectory: '$(Build.SourcesDirectory)/environment_setup/tf-templates'
56+
environmentServiceName: $(AZURE_RM_SVC_CONNECTION)
57+
env:
58+
TF_VAR_BASE_NAME: $(BASE_NAME)
59+
TF_VAR_RESOURCE_GROUP: $(RESOURCE_GROUP)
60+
TF_VAR_WORKSPACE_NAME: $(WORKSPACE_NAME)
61+
62+
- task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-cli.TerraformCLI@0
63+
displayName: 'TF apply - Deploy MLOps resources to Azure'
64+
inputs:
65+
command: apply
66+
workingDirectory: '$(Build.SourcesDirectory)/environment_setup/tf-templates'
67+
environmentServiceName: $(AZURE_RM_SVC_CONNECTION)
68+
env:
69+
TF_VAR_BASE_NAME: $(BASE_NAME)
70+
TF_VAR_RESOURCE_GROUP: $(RESOURCE_GROUP)
71+
TF_VAR_WORKSPACE_NAME: $(WORKSPACE_NAME)
72+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
terraform {
2+
backend "azurerm" {
3+
}
4+
}
+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
provider "azurerm" {
2+
version = "=2.3.0"
3+
features {}
4+
}
5+
6+
variable BASE_NAME {}
7+
variable RESOURCE_GROUP {}
8+
variable WORKSPACE_NAME {}
9+
10+
#--------------------------------------------------------------------------------
11+
12+
#Set the already-existing resource group
13+
data "azurerm_resource_group" "amlrg" {
14+
name = var.RESOURCE_GROUP
15+
}
16+
17+
#Set client config for a.o. tenant id
18+
data "azurerm_client_config" "currentconfig" {
19+
}
20+
21+
#--------------------------------------------------------------------------------
22+
23+
# Storage account for AML Service
24+
resource "azurerm_storage_account" "amlstor" {
25+
name = "${var.BASE_NAME}amlsa"
26+
location = data.azurerm_resource_group.amlrg.location
27+
resource_group_name = data.azurerm_resource_group.amlrg.name
28+
account_tier = "Standard"
29+
account_replication_type = "LRS"
30+
}
31+
32+
# Keyvault for AML Service
33+
resource "azurerm_key_vault" "amlkv" {
34+
name = "${var.BASE_NAME}-AML-KV"
35+
location = data.azurerm_resource_group.amlrg.location
36+
resource_group_name = data.azurerm_resource_group.amlrg.name
37+
tenant_id = data.azurerm_client_config.currentconfig.tenant_id
38+
sku_name = "standard"
39+
}
40+
41+
# App Insights for AML Service
42+
resource "azurerm_application_insights" "amlai" {
43+
name = "${var.BASE_NAME}-AML-AI"
44+
location = data.azurerm_resource_group.amlrg.location
45+
resource_group_name = data.azurerm_resource_group.amlrg.name
46+
application_type = "web"
47+
}
48+
49+
# Container registry for AML Service
50+
resource "azurerm_container_registry" "amlacr" {
51+
name = "${var.BASE_NAME}amlcr"
52+
resource_group_name = data.azurerm_resource_group.amlrg.name
53+
location = data.azurerm_resource_group.amlrg.location
54+
sku = "Standard"
55+
admin_enabled = true
56+
}
57+
58+
# ML Workspace for AML Service, depending on the storage account, Keyvault, App Insights and ACR.
59+
resource "azurerm_machine_learning_workspace" "amlws" {
60+
name = var.WORKSPACE_NAME
61+
location = data.azurerm_resource_group.amlrg.location
62+
resource_group_name = data.azurerm_resource_group.amlrg.name
63+
application_insights_id = azurerm_application_insights.amlai.id
64+
key_vault_id = azurerm_key_vault.amlkv.id
65+
storage_account_id = azurerm_storage_account.amlstor.id
66+
container_registry_id = azurerm_container_registry.amlacr.id
67+
68+
identity {
69+
type = "SystemAssigned"
70+
}
71+
}

0 commit comments

Comments
 (0)