build-vm-image-template.yml 5.67 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
steps:
- script: |
    curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
  displayName: Install azcli

# Please follow the tutorial of [image builder](https://docs.microsoft.com/en-us/azure/virtual-machines/image-builder-overview)
# to set up a managed identity, and,
# 1. Assign the role following the instruction.
# 2. Assign contributor role of the resource group to the identity.
# 3. Add the identity to VMSS.
Yuge Zhang's avatar
Yuge Zhang committed
11
12
13
#
# Update 2022/7 (running on Microsoft-hosted agents).
# Use a service principal. This service principal must be assigned contributor access to the resource group.
14
- script: |
Yuge Zhang's avatar
Yuge Zhang committed
15
    az login --service-principal -u $(client_id) -p $(client_secret) --tenant $(tenant_id)
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
  displayName: Login to Azure

# Make sure all these are registered.
# If not, might need az provider register -n xxx
# Need subscription-write access.

- script: |
    set -e
    az provider show -n Microsoft.VirtualMachineImages -o json
    az provider show -n Microsoft.KeyVault -o json
    az provider show -n Microsoft.Compute -o json
    az provider show -n Microsoft.Storage -o json
    az provider show -n Microsoft.Network -o json
  displayName: Register features

# Need to create an image gallerybefore this.
# Only need to create once.
# az sig create --resource-group <resource_group> --gallery-name <sig_name>

# Add a image definition (also only once).
# az sig image-definition create -g <resource_group> \
#   --gallery-name <sig_name> \
#   --gallery-image-definition <image_def>
#
# For example,
# az sig image-definition create -g nni --gallery-name nniImageGallery \
#   --gallery-image-definition nniLinuxImage \
#   --publisher NNI \
#   --offer ubuntu \
#   --sku 20_04-nni \
#   --os-type Linux \
#   --hyper-v-generation V2

- script: |
    set -e
    set -x
    az image list -g $(resource_group)
    if az image list -g $(resource_group) --query [].'name' | grep -q $(managed_image_name); then
      az image delete -n $(managed_image_name) -g $(resource_group)
    fi
  displayName: List existing images (and delete)

- script: |
    set -e
    curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
    sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
    sudo apt-get update && sudo apt-get install packer
  displayName: Install packer

- script: |
    set -e
    cd test/vso_tools/build_vm
    export IP_ADDRESS=$(curl -s ifconfig.me)
    export VERSION=$(date "+%Y").$(date "+%m%d").$(date "+%H%M%S")
    export CONFIG_PATH=$(packer_config).json
Yuge Zhang's avatar
Yuge Zhang committed
71
72
    sed -i -e "s/<client_id>/$(client_id)/g" $CONFIG_PATH
    sed -i -e "s/<client_secret>/$(client_secret)/g" $CONFIG_PATH
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
    sed -i -e "s/<subscription_id>/$(subscription_id)/g" $CONFIG_PATH
    sed -i -e "s/<managed_image_name>/$(managed_image_name)/g" $CONFIG_PATH
    sed -i -e "s/<resource_group>/$(resource_group)/g" $CONFIG_PATH
    sed -i -e "s/<network_security_group>/$(network_security_group)/g" $CONFIG_PATH
    sed -i -e "s/<gallery_name>/$(gallery_name)/g" $CONFIG_PATH
    sed -i -e "s/<image_name>/$(image_definition_name)/g" $CONFIG_PATH
    sed -i -e "s/<image_version>/${VERSION}/g" $CONFIG_PATH
    sed -i -e "s/<ip_address>/${IP_ADDRESS}/g" $CONFIG_PATH
    cat $CONFIG_PATH
    echo "##vso[task.logissue type=warning]During packer build, please avoid cancelling this task. Otherwise, created resources might need manual cleanup."
  displayName: Prepare configuration

# Microsoft has a security group for VM created under their subscriptions, that,
# based on my observations (though I had no clearance to see it myself):
# 1. A low priority deny all that denies all unintended incoming traffic.
# 2. A medium-high priority denial for all traffic coming from small ports (lower than 8000 probably).
# 3. A high priority allowance for traffics from Microsoft-internal IPs.
#
# We can only insert new rules below medium. Therefore,
# 1. For Linux, we change the ssh port to 10022. This is done at provisioning by injecting user / custom data.
# 2. For Windows, they can't execute the user data script: https://stackoverflow.com/questions/62888359/custom-data-with-azure-windows-vm-run-powersell-script
#    We can't use custom script extensions either because it's not supported in packer.
#    We also can't use shell-local provisioner to invoke command, because when the VM is ready, packer always try to connect to WinRM.
#    The workaround here is to use a monitor to detect the machine ready signal and change its WinRM port.
- script: |
    cd test/vso_tools/build_vm
    python3 packer_build_windows.py
  displayName: (Windows) Packer build
  condition: and(succeeded(), contains(variables['packer_config'], 'windows'))

- script: |
    cd test/vso_tools/build_vm
    PACKER_LOG=1 packer build $(packer_config).json
  displayName: (Linux) Packer build
  condition: and(succeeded(), contains(variables['packer_config'], 'linux'))

# TODO: Should delete the managed image after build is done.
# Image gallery alone is enough. Keeping it for now for debugging purposes.

# To deploy the image on VMSS, run this in Cloud Shell:
# az vmss update --resource-group nni --name nni-windows-it \
#   --set virtualMachineProfile.storageProfile.imageReference.id=/subscriptions/{subscriptionId}/resourceGroups/nni/providers/Microsoft.Compute/galleries/nniImageGallery/images/nniWindowsImage/versions/Latest
#
# Probably need to enlarge the disk size, in case it's too small:
# az vmss update -n nni-it -g nni --set virtualMachineProfile.storageProfile.osDisk.diskSizeGb=50
#
# No need to update the image every time, because it's already set to latest.
Yuge Zhang's avatar
Yuge Zhang committed
120
121
122
#
# NOTE: After using 1ES pool, the pool image has to be updated manually to the latest version.
# However, no successful build has been performed yet, because of resource shortage in Southeast Asia.