build-vm-image-template.yml 7.17 KB
Newer Older
1
2
3
4
5
# BEFORE READING:
#
# 1. We are now running agents on 1ES, all the notes about VMSS can be safely ignored.
# 2. Many actions can be done on both cloud shell and web portal. Choose whichever you prefer.

6
7
8
9
10
steps:
- script: |
    curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
  displayName: Install azcli

11
# Update 2022/7 (running on Microsoft-hosted agents / 1ES agents).
Yuge Zhang's avatar
Yuge Zhang committed
12
# Use a service principal. This service principal must be assigned contributor access to the resource group.
13
14
15
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
#
# Alternative option: managed identity.
# Follow tutorial of [image builder](https://docs.microsoft.com/en-us/azure/virtual-machines/image-builder-overview).
#
# Either way, the identity / service principal must be assigned contributor access to the resource group.
# We also added the following role (but I'm not sure whether it's necessary):
#
# {
#   "properties": {
#     "roleName": "ImageBuilderRole",
#     "description": "Image Builder access to create resources for the image build, you should delete or split out as appropriate",
#     "assignableScopes": [
#       "/subscriptions/<subscription_id>/resourceGroups/<resource_group>"
#     ],
#     "permissions": [
#       {
#         "actions": [
#           "Microsoft.Compute/galleries/read",
#           "Microsoft.Compute/galleries/images/read",
#           "Microsoft.Compute/galleries/images/versions/read",
#           "Microsoft.Compute/galleries/images/versions/write",
#           "Microsoft.Compute/images/write",
#           "Microsoft.Compute/images/read",
#           "Microsoft.Compute/images/delete",
#           "Microsoft.VirtualMachineImages/imageTemplates/write",
#           "Microsoft.VirtualMachineImages/imageTemplates/read",
#           "Microsoft.VirtualMachineImages/imageTemplates/delete"
#         ],
#         "notActions": [],
#         "dataActions": [],
#         "notDataActions": []
#       }
#     ]
#   }
# }
#
49
- script: |
Yuge Zhang's avatar
Yuge Zhang committed
50
    az login --service-principal -u $(client_id) -p $(client_secret) --tenant $(tenant_id)
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
  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

66
67
# Need to create an image gallery before this.
# Only need to create once (can be done on web portal).
68
# az sig create --resource-group <resource_group> --gallery-name <sig_name>
69
70
71
#
# NOTE: Remember to add READER access to the image gallery for "1ES Resource Management".
#
72
73
74
75
76
77
78
79
80
81
82
83
84
# 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
85
86
#
# This can be done on web portal, remember to choose V2 for Hyper-V generation.
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

- 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
110
111
    sed -i -e "s/<client_id>/$(client_id)/g" $CONFIG_PATH
    sed -i -e "s/<client_secret>/$(client_secret)/g" $CONFIG_PATH
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
    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
138
    python3 packer_build_windows.py $(packer_config).json $(resource_group)
139
140
141
142
143
144
145
146
147
148
149
150
  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.

151
152
153
# No further actions are needed here. VM images are already set to latest. They should be auto-updated.
# In case you want to do it on your own:
#
154
155
156
157
# 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
#
158
159
# To deploy the image on 1ES, similar actions need to be performed on the web portal of 1ES managed images.
#
160
161
# 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