Use Azure SDKs to create a virtual machine
Use the Azure SDKs to create and delete an Azure virtual machine.
Set up your development environment
- An Azure user account with an active subscription. Create one for free.
- Node.js LTS with NPM, the Node.js package manager installed to your local machine.
- Visual Studio Code installed to your local machine.
- Create a service principal and copy the
Tenant Id
,Client ID
,Client secret
. - Use the Azure portal's subscription page to find your subscription ID, copy that value to use in these scripts.
Azure Virtual machines
An Azure Virtual machine requires several resources to support the virtual machine. The best way to manage those resources is to create all the resources in a single resource group. The script creates the resource group and postpends a random number to make sure the resource group is unique, regardless of how many times you use the script.
Resources created in these scripts include:
- Resource group
- Virtual machines
- Storage
- Virtual network
Create a virtual machine
Create a file named
create-vm.js
or copy the file from GitHub.const util = require("util"); const { ClientSecretCredential, DefaultAzureCredential, } = require("@azure/identity"); const { ComputeManagementClient } = require("@azure/arm-compute"); const { ResourceManagementClient } = require("@azure/arm-resources"); const { StorageManagementClient } = require("@azure/arm-storage"); const { NetworkManagementClient } = require("@azure/arm-network"); // Store function output to be used elsewhere let randomIds = {}; let subnetInfo = null; let publicIPInfo = null; let vmImageInfo = null; let nicInfo = null; // CHANGE THIS - used as prefix for naming resources const yourAlias = "diberry"; // CHANGE THIS - used to add tags to resources const projectName = "azure-samples-create-vm"; // Resource configs const location = "eastus"; const accType = "Standard_LRS"; // Ubuntu config for VM const publisher = "Canonical"; const offer = "UbuntuServer"; const sku = "14.04.3-LTS"; const adminUsername = "notadmin"; const adminPassword = "Pa$$w0rd92"; // Azure authentication in environment variables for DefaultAzureCredential const tenantId = process.env["AZURE_TENANT_ID"] || "REPLACE-WITH-YOUR-TENANT-ID"; const clientId = process.env["AZURE_CLIENT_ID"] || "REPLACE-WITH-YOUR-CLIENT-ID"; const secret = process.env["AZURE_CLIENT_SECRET"] || "REPLACE-WITH-YOUR-CLIENT-SECRET"; const subscriptionId = process.env["AZURE_SUBSCRIPTION_ID"] || "REPLACE-WITH-YOUR-SUBSCRIPTION_ID"; let credentials = null; if (process.env.production) { // production credentials = new DefaultAzureCredential(); } else { // development credentials = new ClientSecretCredential(tenantId, clientId, secret); console.log("development"); } // Azure services const resourceClient = new ResourceManagementClient( credentials, subscriptionId ); const computeClient = new ComputeManagementClient(credentials, subscriptionId); const storageClient = new StorageManagementClient(credentials, subscriptionId); const networkClient = new NetworkManagementClient(credentials, subscriptionId); // Create resources then manage them (on/off) async function createResources() { try { result = await createResourceGroup(); accountInfo = await createStorageAccount(); vnetInfo = await createVnet(); subnetInfo = await getSubnetInfo(); publicIPInfo = await createPublicIP(); nicInfo = await createNIC(subnetInfo, publicIPInfo); vmImageInfo = await findVMImage(); nicResult = await getNICInfo(); vmInfo = await createVirtualMachine(nicInfo.id, vmImageInfo[0].name); return; } catch (err) { console.log(err); } } async function createResourceGroup() { console.log("\n1.Creating resource group: " + resourceGroupName); const groupParameters = { location: location, tags: { project: projectName }, }; const resCreate = await resourceClient.resourceGroups.createOrUpdate( resourceGroupName, groupParameters ); return resCreate; } async function createStorageAccount() { console.log("\n2.Creating storage account: " + storageAccountName); const createParameters = { location: location, sku: { name: accType, }, kind: "Storage", tags: { project: projectName, }, }; return await storageClient.storageAccounts.beginCreateAndWait( resourceGroupName, storageAccountName, createParameters ); } async function createVnet() { console.log("\n3.Creating vnet: " + vnetName); const vnetParameters = { location: location, addressSpace: { addressPrefixes: ["10.0.0.0/16"], }, dhcpOptions: { dnsServers: ["10.1.1.1", "10.1.2.4"], }, subnets: [{ name: subnetName, addressPrefix: "10.0.0.0/24" }], }; return await networkClient.virtualNetworks.beginCreateOrUpdateAndWait( resourceGroupName, vnetName, vnetParameters ); } async function getSubnetInfo() { console.log("\nGetting subnet info for: " + subnetName); const getResult = await networkClient.subnets.get( resourceGroupName, vnetName, subnetName ); return getResult; } async function createPublicIP() { console.log("\n4.Creating public IP: " + publicIPName); const publicIPParameters = { location: location, publicIPAllocationMethod: "Dynamic", dnsSettings: { domainNameLabel: domainNameLabel, }, }; return await networkClient.publicIPAddresses.beginCreateOrUpdateAndWait( resourceGroupName, publicIPName, publicIPParameters ); } async function createNIC(subnetInfo, publicIPInfo) { console.log("\n5.Creating Network Interface: " + networkInterfaceName); const nicParameters = { location: location, ipConfigurations: [ { name: ipConfigName, privateIPAllocationMethod: "Dynamic", subnet: subnetInfo, publicIPAddress: publicIPInfo, }, ], }; return await networkClient.networkInterfaces.beginCreateOrUpdateAndWait( resourceGroupName, networkInterfaceName, nicParameters ); } async function findVMImage() { console.log( util.format( "\nFinding a VM Image for location %s from " + "publisher %s with offer %s and sku %s", location, publisher, offer, sku ) ); const listResult = new Array(); for await (const item of computeClient.virtualMachineImages.list( location, publisher, offer, sku )) { listResult.push(item); } return listResult; } async function getNICInfo() { return await networkClient.networkInterfaces.get( resourceGroupName, networkInterfaceName ); } async function createVirtualMachine() { const vmParameters = { location: location, osProfile: { computerName: vmName, adminUsername: adminUsername, adminPassword: adminPassword, }, hardwareProfile: { vmSize: "Standard_B1ls", }, storageProfile: { imageReference: { publisher: publisher, offer: offer, sku: sku, version: vmImageVersionNumber, }, osDisk: { name: osDiskName, caching: "None", createOption: "fromImage", vhd: { uri: "https://" + storageAccountName + ".blob.core.windows.net/nodejscontainer/osnodejslinux.vhd", }, }, }, networkProfile: { networkInterfaces: [ { id: nicId, primary: true, }, ], }, }; console.log("6.Creating Virtual Machine: " + vmName); console.log( " VM create parameters: " + util.inspect(vmParameters, { depth: null }) ); const resCreate = await computeClient.virtualMachines.beginCreateOrUpdateAndWait( resourceGroupName, vmName, vmParameters ); return await computeClient.virtualMachines.get( resourceGroupName, vmName ); } const _generateRandomId = (prefix, existIds) => { var newNumber; while (true) { newNumber = prefix + Math.floor(Math.random() * 10000); if (!existIds || !(newNumber in existIds)) { break; } } return newNumber; }; //Random number generator for service names and settings const resourceGroupName = _generateRandomId(`${yourAlias}-testrg`, randomIds); const vmName = _generateRandomId(`${yourAlias}vm`, randomIds); const storageAccountName = _generateRandomId(`${yourAlias}ac`, randomIds); const vnetName = _generateRandomId(`${yourAlias}vnet`, randomIds); const subnetName = _generateRandomId(`${yourAlias}subnet`, randomIds); const publicIPName = _generateRandomId(`${yourAlias}pip`, randomIds); const networkInterfaceName = _generateRandomId(`${yourAlias}nic`, randomIds); const ipConfigName = _generateRandomId(`${yourAlias}crpip`, randomIds); const domainNameLabel = _generateRandomId(`${yourAlias}domainname`, randomIds); const osDiskName = _generateRandomId(`${yourAlias}osdisk`, randomIds); async function main() { await createResources(); } main() .then(() => { console.log( `success - resource group name: ${resourceGroupName}, vm resource name: ${vmName}` ); }) .catch((err) => { console.log(err); });
SDK methods used in this script include:
- Resource groups
- Storage
- Networks
- VMs
Install the npm packages used in the Azure work:
npm init -y && install @azure/identity @azure/arm-compute @azure/arm-network @azure/arm-resources @azure/arm-storage
For local development, change variables in file for authentication:
// Azure authentication in environment variables for DefaultAzureCredential const tenantId = process.env["AZURE_TENANT_ID"] || "REPLACE-WITH-YOUR-TENANT-ID"; const clientId = process.env["AZURE_CLIENT_ID"] || "REPLACE-WITH-YOUR-CLIENT-ID"; const secret = process.env["AZURE_CLIENT_SECRET"] || "REPLACE-WITH-YOUR-CLIENT-SECRET"; const subscriptionId = process.env["AZURE_SUBSCRIPTION_ID"] || "REPLACE-WITH-YOUR-SUBSCRIPTION_ID";
Change variables for resource naming:
// CHANGE THIS - used as prefix for naming resources const yourAlias = "johnsmith"; // CHANGE THIS - used to add tags to resources const projectName = "azure-samples-create-vm"
Run the code to create a VM:
node create-vm.js
The output includes the resource group name:
success - resource group name: johnsmith-testrg1689
Clean up resources
When you are done with the virtual machine, delete the resource group.
Create a file named
delete-resources.js
or copy the file from GitHub.const { ClientSecretCredential, DefaultAzureCredential, } = require("@azure/identity"); const { ResourceManagementClient } = require("@azure/arm-resources"); // Azure authentication in environment variables for DefaultAzureCredential let credentials = null; const tenantId = process.env["AZURE_TENANT_ID"] || "REPLACE-WITH-YOUR-TENANT-ID"; const clientId = process.env["AZURE_CLIENT_ID"] || "REPLACE-WITH-YOUR-CLIENT-ID"; const secret = process.env["AZURE_CLIENT_SECRET"] || "REPLACE-WITH-YOUR-CLIENT-SECRET"; const subscriptionId = process.env["AZURE_SUBSCRIPTION_ID"] || "REPLACE-WITH-YOUR-SUBSCRIPTION_ID"; const resourceGroupName = "REPLACE-WITH-YOUR-RESOURCE_GROUP-NAME"; if (process.env.production) { // production credentials = new DefaultAzureCredential(); } else { // development credentials = new ClientSecretCredential(tenantId, clientId, secret); console.log("development"); } async function deleteResourceGroup() { // Create Azure SDK client for Resource Management such as resource groups const resourceClient = new ResourceManagementClient( credentials, subscriptionId ); const result = await resourceClient.resourceGroups.deleteMethod( resourceGroupName ); console.log(JSON.stringify(result)); } deleteResourceGroup() .then((result) => { console.log(result); }) .catch((ex) => { console.log(ex); });
For local development, change variables in file for authentication:
// Azure authentication in environment variables for DefaultAzureCredential const tenantId = process.env["AZURE_TENANT_ID"] || "REPLACE-WITH-YOUR-TENANT-ID"; const clientId = process.env["AZURE_CLIENT_ID"] || "REPLACE-WITH-YOUR-CLIENT-ID"; const secret = process.env["AZURE_CLIENT_SECRET"] || "REPLACE-WITH-YOUR-CLIENT-SECRET"; const subscriptionId = process.env["AZURE_SUBSCRIPTION_ID"] || "REPLACE-WITH-YOUR-SUBSCRIPTION_ID";
Get the resource group name, which was returned as the last line from the creation script and change the variable in the delete script:
const resourceGroupName = "REPLACE-WITH-YOUR-RESOURCE_GROUP-NAME";
Run the code to create a VM:
node delete-resources.js
The delete may take a few minutes.
SDK methods used in this script include:
- Resource groups - resourceClient.resourcegroups.delete
Next steps
Feedback
https://aka.ms/ContentUserFeedback.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for