Pide tu presupuesto ya!

Automatización de la implementación de VM en Azure con PowerShell

La automatización de tareas en Azure puede ahorrar mucho tiempo y esfuerzo, especialmente al implementar recursos como máquinas virtuales (VM). En esta publicación de blog, explicaremos cómo automatizar la implementación de una máquina virtual Windows en Azure mediante PowerShell. Configuraremos las redes, la seguridad e instalaremos IIS para un servidor web, todo en un solo script.

¿Por qué automatizar la implementación de VM?

La automatización de tareas como la implementación de máquinas virtuales garantiza la coherencia, reduce los errores y acelera el proceso de configuración. Con PowerShell, puede definir todos los parámetros necesarios y dejar que el script maneje la implementación, en lugar de crear manualmente cada recurso a través del Portal de Azure.

A continuación se muestra un desglose paso a paso del script de PowerShell utilizado para implementar una máquina virtual de Azure, configurar redes, establecer reglas de seguridad e instalar IIS.

Aquí está el script si sólo quieres descargarlo.

[CmdletBinding()]
param(
    [Parameter(Mandatory)]
    [string]$ResourceGroupName="Admissions",

    [Parameter(Mandatory)]
    [string]$Location = 'East US',

    [Parameter(Mandatory)]
    [string]$VMName="ADMISSIONSWEB",

    [Parameter(Mandatory)]
    [string]$VMSize="Standard_DS3_v2",

    [Parameter(Mandatory)]
    [string]$PublicIPName="Admissions-PubIp",

    [Parameter(Mandatory)]
    [string]$NICName="Admissions-vNIC",

    [Parameter(Mandatory)]
    [string]$OSDiskName="Admissions-OSDisk",

    [Parameter(Mandatory)]
    [string]$NSGName="ADMISSIONSWEB-NSG",

    [Parameter(Mandatory)]
    [string]$AdminUsername="adam",

    [Parameter(Mandatory)]
    [SecureString]$AdminPassword = (ConvertTo-SecureString 'P@$$w0rd12' -AsPlainText -Force)
)

$ErrorActionPreference="Stop"

function CreateAzResource {
    param(
        [Parameter(Mandatory)]
        [string]$ResourceType,
        
        [Parameter(Mandatory)]
        [string]$Name,
        
        [Parameter(Mandatory)]
        [hashtable]$NewParameter
    )
    
    try {
        $resource = & "Get-Az$ResourceType" -Name $Name -ResourceGroupName $NewParameter.ResourceGroupName
    } catch {
        if ($_.Exception.Message -match "under resource group '.*' was not found") {
            $resource = & "New-Az$ResourceType" @NewParameter
        } else {
            throw $_
        }
    } finally {
        $resource
    }
}

#region VM Configuration
$vmconfig = New-AzVMConfig -VMName $VMName -VMSize $VMSize
#endregion

#region Public IP Creation
$newPublicIpParams = @{
    Name              = $PublicIPName
    ResourceGroupName = $ResourceGroupName
    AllocationMethod  = 'Static'
    Location          = $Location
}
$publicIp = CreateAzResource -ResourceType PublicIpAddress -Name $PublicIPName -NewParameter $newPublicIpParams
#endregion

#region Network Interface Configuration
$vNet = Get-AzVirtualNetwork -ResourceGroupName $ResourceGroupName
$subnetId = $vNet.Subnets[0].Id

$newVNicParams = @{
    Name              = $NICName
    ResourceGroupName = $ResourceGroupName
    Location          = $Location
    SubnetId          = $subnetId
    PublicIpAddressId = $publicIp.Id
}
$vNic = CreateAzResource -ResourceType NetworkInterface -Name $NICName -NewParameter $newVNicParams
#endregion

#region OS Configuration
$cred = New-Object System.Management.Automation.PSCredential ($AdminUsername, $AdminPassword)
$newVmOsParams = @{
    Windows          = $true
    ComputerName     = $VMName
    Credential       = $cred
    EnableAutoUpdate = $true
    VM               = $vmconfig
}
$vm = Set-AzVMOperatingSystem @newVmOsParams
#endregion

#region Image Configuration
$newSourceImageParams = @{
    PublisherName="MicrosoftWindowsServer"
    Offer="WindowsServer"
    Skus="2019-Datacenter"
    Version       = 'latest'
    VM            = $vm
}
$vm = Set-AzVMSourceImage @newSourceImageParams
#endregion

#region Disk Configuration
$vm = Set-AzVMOSDisk -VM $vm -Name $OSDiskName -CreateOption FromImage
#endregion

#region Network Interface Attachment
$vm = Add-AzVMNetworkInterface -VM $vm -Id $vNic.Id
#endregion

#region NSG Configuration
$newNsgParams = @{
    ResourceGroupName = $ResourceGroupName
    Location          = $Location
    Name              = $NSGName
}
$nsg = CreateAzResource -ResourceType NetworkSecurityGroup -Name $NSGName -NewParameter $newNsgParams

$ruleExists = $nsg.SecurityRules.Name -contains "Allow-RDP"
if (-not $ruleExists) {
    $ip = Invoke-RestMethod -Uri "https://api.ipify.org"
    $rdpRule = New-AzNetworkSecurityRuleConfig -Name "Allow-RDP" -Description "Allow RDP" -Access Allow -Protocol Tcp -Direction Inbound -Priority 1000 -SourceAddressPrefix $ip -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 3389
    $nsg.SecurityRules.Add($rdpRule)
    $nsg | Set-AzNetworkSecurityGroup
}
#endregion

#region Web Traffic Rule Configuration
$webRuleExists = $nsg.SecurityRules.Name -contains "Allow-Web"
if (-not $webRuleExists) {
    $webRule = New-AzNetworkSecurityRuleConfig -Name "Allow-Web" -Description "Allow HTTP" -Access Allow -Protocol Tcp -Direction Inbound -Priority 200 -SourceAddressPrefix * -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 80
    $nsg.SecurityRules.Add($webRule)
    $nsg | Set-AzNetworkSecurityGroup
}
#endregion

$vNic.NetworkSecurityGroup = $nsg
$vNic | Set-AzNetworkInterface

#region VM Creation
$newVmParams = @{
    ResourceGroupName = $ResourceGroupName
    VM                = $vm
    Location          = $Location
}
CreateAzResource -ResourceType VM -Name $VMName -NewParameter $newVmParams
#endregion

#region IIS Installation
$installIIS = {
    Install-WindowsFeature -Name Web-Server -IncludeManagementTools
}
$installScript = [scriptblock]::create($installIIS)
Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroupName -VMName $VMName -CommandId 'RunPowerShellScript' -ScriptString $installScript
#endregion

#region Output Public IP
$publicIp.IpAddress

Definir parámetros

El script comienza definiendo los parámetros que se utilizarán durante toda la implementación. Estos incluyen información básica como grupo de recursos, nombre de VM, ubicación y credenciales de administrador. El uso de parámetros garantiza que el script sea flexible y pueda reutilizarse en diferentes entornos.

param(
    [Parameter(Mandatory)]
    [string]$ResourceGroupName="Admissions",
    [Parameter(Mandatory)]
    [string]$Location = 'East US',
    [Parameter(Mandatory)]
    [string]$VMName="ADMISSIONSWEB",
    [Parameter(Mandatory)]
    [string]$VMSize="Standard_DS3_v2",
    [Parameter(Mandatory)]
    [string]$PublicIPName="Admissions-PubIp",
    [Parameter(Mandatory)]
    [string]$NICName="Admissions-vNIC",
    [Parameter(Mandatory)]
    [string]$OSDiskName="Admissions-OSDisk",
    [Parameter(Mandatory)]
    [string]$NSGName="ADMISSIONSWEB-NSG",
    [Parameter(Mandatory)]
    [string]$AdminUsername="adam",
    [Parameter(Mandatory)]
    [SecureString]$AdminPassword = (ConvertTo-SecureString 'P@$$w0rd12' -AsPlainText -Force)
)

Crear recursos de Azure

La función `CreateAzResource` ayuda a crear varios recursos de Azure, como IP públicas, interfaces de red y grupos de seguridad de red (NSG). Intenta obtener un recurso y lo crea si no existe, haciendo el proceso más eficiente.

function CreateAzResource {
    param(
        [Parameter(Mandatory)]
        [string]$ResourceType,
        [Parameter(Mandatory)]
        [string]$Name,
        [Parameter(Mandatory)]
        [hashtable]$NewParameter
    )
    
    try {
        $resource = & "Get-Az$ResourceType" -Name $Name -ResourceGroupName $NewParameter.ResourceGroupName
    } catch {
        if ($_.Exception.Message -match "not found") {
            $resource = & "New-Az$ResourceType" @NewParameter
        } else {
            throw $_
        }
    } finally {
        $resource
    }
}

Configuración de VM y configuración de redes

Una vez que se crean recursos como IP pública y redes virtuales, el script configura una máquina virtual (VM) usando “New-AzVMConfig”, conecta una interfaz de red y configura el sistema operativo y el disco.

$vmconfig = New-AzVMConfig -VMName $VMName -VMSize $VMSize

$vNic = CreateAzResource -ResourceType NetworkInterface -Name $NICName -NewParameter $newVNicParams
$vm = Set-AzVMOperatingSystem @newVmOsParams
$vm = Set-AzVMSourceImage @newSourceImageParams
$vm = Set-AzVMOSDisk -VM $vm -Name $OSDiskName -CreateOption FromImage

Configurar reglas de seguridad de red

El script agrega reglas de seguridad al NSG para permitir el RDP (escritorio remoto) entrante y el tráfico web en el puerto 80 (HTTP). Esto es fundamental para administrar la máquina virtual y alojar aplicaciones web.

$ruleExists = $nsg.SecurityRules.Name -contains "Allow-RDP"
if (-not $ruleExists) {
    $ip = Invoke-RestMethod -Uri "https://api.ipify.org"
    $rdpRule = New-AzNetworkSecurityRuleConfig -Name "Allow-RDP" -Access Allow -Protocol Tcp -SourceAddressPrefix $ip -DestinationPortRange 3389
    $nsg.SecurityRules.Add($rdpRule)
    $nsg | Set-AzNetworkSecurityGroup
}

Instalación de IIS

Una vez creada la VM, el script instala IIS (Internet Information Services), lo que permitirá que la VM actúe como un servidor web. Esto se hace ejecutando un comando de PowerShell en la VM.

$installIIS = {
    Install-WindowsFeature -Name Web-Server -IncludeManagementTools
}
Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroupName -VMName $VMName -CommandId 'RunPowerShellScript' -ScriptString $installIIS

Salida de la IP pública

Finalmente, se genera la IP pública de la VM para facilitar el acceso al servidor web.

Conclusión

Con este script de PowerShell, la implementación de una máquina virtual Windows en Azure con la red, la seguridad y la configuración de IIS configuradas se vuelve perfecta. Este nivel de automatización es invaluable para tareas repetitivas y garantiza que su infraestructura esté configurada de manera consistente.

Si sigue esta guía, podrá implementar máquinas virtuales rápidamente y concentrarse más en configurar aplicaciones en lugar de perder tiempo configurando recursos manualmente.

Written by

Leave a comment