Raw New Markdown
Generating updated version of doc...
Rendered New Markdown
Generating updated version of doc...
---
title: Use Azure VM Image Builder for Linux VMs to access an existing Azure virtual network
description: Use Azure VM Image Builder to create a basic, customized Linux image that has access to existing resources on a virtual network.
author: kof-f
ms.author: kofiforson
ms.reviewer: wwilliams
ms.date: 03/02/2021
ms.topic: how-to
ms.service: azure-virtual-machines
ms.subservice: image-builder
ms.custom: devx-track-azurecli, linux-related-content
# Customer intent: As a cloud engineer, I want to create a customized Linux VM image connected to an existing Azure virtual network, so that I can efficiently manage my resources without requiring public network connectivity.
---
# Use Azure VM Image Builder for Linux VMs to access an existing Azure virtual network
**Applies to:** :heavy_check_mark: Linux VMs :heavy_check_mark: Flexible scale sets
This article shows you how to use Azure VM Image Builder to create a basic, customized Linux image that has access to existing resources on a virtual network. The build virtual machine (VM) you create is deployed to a new or existing virtual network that you specify in your subscription. When you use an existing Azure virtual network, VM Image Builder doesn't require public network connectivity.
[!INCLUDE [azure-cli-prepare-your-environment.md](~/reusable-content/azure-cli/azure-cli-prepare-your-environment.md)]
## Set variables and permissions
For this task, you use some pieces of information repeatedly. Create some variables to store that information.
```azurecli-interactive
# set your environment variables here!!!!
# destination image resource group
imageResourceGroup=aibImageRG01
# location (see possible locations in main docs)
location=WestUS2
# your subscription
# get the current subID : 'az account show | grep id'
subscriptionID=$(az account show --query id --output tsv)
# name of the image to be created
imageName=aibCustomLinuxImg01
# image distribution metadata reference name
runOutputName=aibCustLinManImg01ro
# VNET properties (update to match your existing VNET, or leave as-is for demo)
# VNET name
vnetName=myexistingvnet01
# subnet name
subnetName=subnet01
# VNET resource group name
# NOTE! The VNET must always be in the same region as the Azure Image Builder service region.
vnetRgName=existingVnetRG
# Existing Subnet NSG Name or the demo will create it
nsgName=aibdemoNsg
```
Create the resource group.
```azurecli-interactive
az group create -n $imageResourceGroup -l $location
```
## Configure networking
If you don't have an existing virtual network, subnet, or network security group (NSG), use the following script to create one.
```azurecli
# Create a resource group
az group create -n $vnetRgName -l $location
# Create VNET
az network vnet create \
--resource-group $vnetRgName \
--name $vnetName --address-prefix 10.0.0.0/16 \
--subnet-name $subnetName --subnet-prefix 10.0.0.0/24
# Create base NSG to simulate an existing NSG
az network nsg create -g $vnetRgName -n $nsgName
az network vnet subnet update \
--resource-group $vnetRgName \
--vnet-name $vnetName \
--name $subnetName \
--network-security-group $nsgName
# NOTE! The virtual network must always be in the same region as the Azure Image Builder service region.
```
### Add an NSG rule
This rule allows connectivity from the VM Image Builder load balancer to the proxy VM. Port 60001 is for Linux, and port 60000 is for Windows. The proxy VM connects to the build VM by using port 22 for Linux, or port 5986 for Windows.
```azurecli-interactive
az network nsg rule create \
--resource-group $vnetRgName \
--nsg-name $nsgName \
-n AzureImageBuilderNsgRule \
--priority 400 \
--source-address-prefixes AzureLoadBalancer \
--destination-address-prefixes VirtualNetwork \
--destination-port-ranges 60000-60001 --direction inbound \
--access Allow --protocol Tcp \
--description "Allow Image Builder Private Link Access to Proxy VM"
```
### Disable private service policy on the subnet
Here's how:
```azurecli-interactive
az network vnet subnet update \
--name $subnetName \
--resource-group $vnetRgName \
--vnet-name $vnetName \
--private-link-service-network-policies Disabled
```
For more information, see [Azure VM Image Builder networking options](image-builder-networking.md).
## Modify the example template and create role
After you configure networking, you can modify the example template and create a role. Here's how:
```bash
# download the example and configure it with your vars
curl https://raw.githubusercontent.com/azure/azvmimagebuilder/master/quickquickstarts/1a_Creating_a_Custom_Linux_Image_on_Existing_VNET/existingVNETLinux.json -o existingVNETLinux.json
curl https://raw.githubusercontent.com/azure/azvmimagebuilder/master/solutions/12_Creating_AIB_Security_Roles/aibRoleNetworking.json -o aibRoleNetworking.json
curl https://raw.githubusercontent.com/azure/azvmimagebuilder/master/solutions/12_Creating_AIB_Security_Roles/aibRoleImageCreation.json -o aibRoleImageCreation.json
sed -i -e "s/<subscriptionID>/$subscriptionID/g" existingVNETLinux.json
sed -i -e "s/<rgName>/$imageResourceGroup/g" existingVNETLinux.json
sed -i -e "s/<region>/$location/g" existingVNETLinux.json
sed -i -e "s/<imageName>/$imageName/g" existingVNETLinux.json
sed -i -e "s/<runOutputName>/$runOutputName/g" existingVNETLinux.json
sed -i -e "s/<vnetName>/$vnetName/g" existingVNETLinux.json
sed -i -e "s/<subnetName>/$subnetName/g" existingVNETLinux.json
sed -i -e "s/<vnetRgName>/$vnetRgName/g" existingVNETLinux.json
sed -i -e "s/<subscriptionID>/$subscriptionID/g" aibRoleImageCreation.json
sed -i -e "s/<rgName>/$imageResourceGroup/g" aibRoleImageCreation.json
sed -i -e "s/<subscriptionID>/$subscriptionID/g" aibRoleNetworking.json
sed -i -e "s/<vnetRgName>/$vnetRgName/g" aibRoleNetworking.json
```
## Set permissions on the resource group
VM Image Builder uses the [user identity](/azure/active-directory/managed-identities-azure-resources/qs-configure-cli-windows-vm#user-assigned-managed-identity) provided to inject the image into Azure Compute Gallery. In this example, you create an Azure role definition that can distribute the image to the gallery. The role definition is then assigned to the user identity.
```azurecli
# create user assigned identity for image builder
identityName=aibBuiUserId$(date +'%s')
az identity create -g $imageResourceGroup -n $identityName
# get identity id
imgBuilderCliId=$(az identity show -g $imageResourceGroup -n $identityName --query clientId -o tsv)
# get the user identity URI, needed for the template
imgBuilderId=/subscriptions/$subscriptionID/resourcegroups/$imageResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$identityName
# update the template
sed -i -e "s%<imgBuilderId>%$imgBuilderId%g" existingVNETLinux.json
# make role name unique, to avoid clashes in the same Azure Active Directory domain
imageRoleDefName="Azure Image Builder Image Def"$(date +'%s')
netRoleDefName="Azure Image Builder Network Def"$(date +'%s')
# update the definitions
sed -i -e "s/Azure Image Builder Service Image Creation Role/$imageRoleDefName/g" aibRoleImageCreation.json
sed -i -e "s/Azure Image Builder Service Networking Role/$netRoleDefName/g" aibRoleNetworking.json
```
Instead of granting VM Image Builder lower granularity and increased privilege, you can create two roles. One role gives the builder permissions to create an image, and the other allows it to connect the build VM and load balancer to your virtual network.
```azurecli
# create role definitions
az role definition create --role-definition ./aibRoleImageCreation.json
az role definition create --role-definition ./aibRoleNetworking.json
# grant role definition to the user assigned identity
az role assignment create \
--assignee $imgBuilderCliId \
--role "$imageRoleDefName" \
--scope /subscriptions/$subscriptionID/resourceGroups/$imageResourceGroup
az role assignment create \
--assignee $imgBuilderCliId \
--role "$netRoleDefName" \
--scope /subscriptions/$subscriptionID/resourceGroups/$vnetRgName
```
For more information, see [Configure Azure VM Image Builder permissions by using the Azure CLI](image-builder-permissions-cli.md) or [Configure Azure VM Image Builder permissions by using PowerShell](image-builder-permissions-powershell.md).
## Create the image
Submit the image configuration to VM Image Builder.
```azurecli-interactive
az resource create \
--resource-group $imageResourceGroup \
--properties @existingVNETLinux.json \
--is-full-object \
--resource-type Microsoft.VirtualMachineImages/imageTemplates \
-n existingVNETLinuxTemplate01
# Wait approximately 1-3 mins (validation, permissions etc.)
```
Start the image build.
```azurecli-interactive
az resource invoke-action \
--resource-group $imageResourceGroup \
--resource-type Microsoft.VirtualMachineImages/imageTemplates \
-n existingVNETLinuxTemplate01 \
--action Run
# Wait approximately 15 mins
```
It can take a while to create the image and replicate it to both regions. Wait until this part is finished before moving on to creating a VM.
## Create a VM
Create a VM from the image version that was created by VM Image Builder.
```azurecli-interactive
az vm create \
--resource-group $imageResourceGroup \
--name aibImgVm0001 \
--admin-username aibuser \
--image $imageName \
--location $location \
--generate-ssh-keys
```
Use Secure Shell (SSH) to get into the VM.
```bash
ssh aibuser@<publicIpAddress>
```
You should see the image was customized with a *Message of the Day* as soon as your SSH connection is established!
```console
*******************************************************
** This VM was built from the: **
** !! AZURE VM IMAGE BUILDER Custom Image !! **
** You have just been Customized :-) **
*******************************************************
```
## Clean up resources
If you want to recustomize the image version to create a new version of the same image, skip the next steps and go on to [Use Azure VM Image Builder to create another image version](image-builder-gallery-update-image-version.md).
The following deletes the image that was created, along with all of the other resource files. Make sure you are finished with this deployment before deleting the resources.
When you delete gallery resources, you need to delete all of the image versions before you can delete the image definition used to create them. To delete a gallery, you first need to have deleted all of the image definitions in the gallery.
Delete the VM Image Builder template:
```azurecli
az resource delete \
--resource-group $imageResourceGroup \
--resource-type Microsoft.VirtualMachineImages/imageTemplates \
-n existingVNETLinuxTemplate01
```
Delete permissions assignments, roles, and identity:
```azurecli-interactive
az role assignment delete \
--assignee $imgBuilderCliId \
--role $imageRoleDefName \
--scope /subscriptions/$subscriptionID/resourceGroups/$imageResourceGroup
az role assignment delete \
--assignee $imgBuilderCliId \
--role $netRoleDefName \
--scope /subscriptions/$subscriptionID/resourceGroups/$vnetRgName
az role definition delete --name "$imageRoleDefName"
az role definition delete --name "$netRoleDefName"
az identity delete --ids $imgBuilderId
```
Delete the resource group:
```azurecli-interactive
az group delete -n $imageResourceGroup
```
If you created a virtual network for this quickstart, you can delete the virtual network if it's no longer being used.
## Next steps
[Azure Compute Galleries](../shared-image-galleries.md)