nni/pipelines/templates/build-vm-image-template.yml

162 строки
7.2 KiB
YAML

# 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.
steps:
- script: |
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
displayName: Install azcli
# Update 2022/7 (running on Microsoft-hosted agents / 1ES agents).
# Use a service principal. This service principal must be assigned contributor access to the resource group.
#
# 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": []
# }
# ]
# }
# }
#
- script: |
az login --service-principal -u $(client_id) -p $(client_secret) --tenant $(tenant_id)
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 gallery before this.
# Only need to create once (can be done on web portal).
# az sig create --resource-group <resource_group> --gallery-name <sig_name>
#
# NOTE: Remember to add READER access to the image gallery for "1ES Resource Management".
#
# 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
#
# This can be done on web portal, remember to choose V2 for Hyper-V generation.
- 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
sed -i -e "s/<client_id>/$(client_id)/g" $CONFIG_PATH
sed -i -e "s/<client_secret>/$(client_secret)/g" $CONFIG_PATH
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 $(packer_config).json $(resource_group)
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.
# 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:
#
# 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
#
# To deploy the image on 1ES, similar actions need to be performed on the web portal of 1ES managed images.
#
# 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