336 строки
10 KiB
PowerShell
336 строки
10 KiB
PowerShell
Param(
|
|
[Parameter(Mandatory=$true)]
|
|
[string] $SubscriptionId,
|
|
[Parameter(Mandatory=$true)]
|
|
[string] $AadClientId,
|
|
[Parameter(Mandatory=$true)]
|
|
[string] $AadClientSecret,
|
|
[Parameter(Mandatory=$true)]
|
|
[string] $ResourcePrefix,
|
|
[Parameter(Mandatory=$true)]
|
|
[string] $Username,
|
|
[Parameter(Mandatory=$true)]
|
|
[string] $Password,
|
|
[string] $ExtensionName="AzureDiskEncryptionForLinux",
|
|
[string] $SshPubKey,
|
|
[string] $SshPrivKeyPath,
|
|
[string] $Location="eastus",
|
|
[string] $VolumeType="data",
|
|
[string] $GalleryImage="RedHat:RHEL:7.2",
|
|
[string] $VMSize="Standard_D2",
|
|
[switch] $DryRun=$false,
|
|
[switch] $Force=$false
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
Set-AzureRmContext -SubscriptionId $SubscriptionId
|
|
|
|
Write-Host "Set AzureRmContext successfully"
|
|
|
|
## Resource Group
|
|
$global:ResourceGroupName = $ResourcePrefix + "ResourceGroup"
|
|
|
|
if(!$DryRun)
|
|
{
|
|
New-AzureRmResourceGroup -Name $ResourceGroupName -Location $Location
|
|
}
|
|
|
|
Write-Host "Created ResourceGroup successfully: $ResourceGroupName"
|
|
|
|
## KeyVault
|
|
$global:KeyVaultName = $ResourcePrefix + "KeyVault"
|
|
|
|
if(!$DryRun)
|
|
{
|
|
$global:KeyVault = New-AzureRmKeyVault -VaultName $KeyVaultName -ResourceGroupName $ResourceGroupName -Location $Location
|
|
}
|
|
else
|
|
{
|
|
$global:KeyVault = Get-AzureRmKeyVault -VaultName $KeyVaultName -ResourceGroupName $ResourceGroupName
|
|
}
|
|
|
|
Write-Host "Created KeyVault successfully: $KeyVaultName"
|
|
|
|
if(!$DryRun)
|
|
{
|
|
Set-AzureRmKeyVaultAccessPolicy -VaultName $KeyVaultName -ResourceGroupName $ResourceGroupName -ServicePrincipalName $AadClientId -PermissionsToKeys all -PermissionsToSecrets all
|
|
Set-AzureRmKeyVaultAccessPolicy -VaultName $KeyVaultName -ResourceGroupName $ResourceGroupName -EnabledForDiskEncryption
|
|
}
|
|
|
|
Write-Host "Set AzureRmKeyVaultAccessPolicy successfully"
|
|
|
|
if(!$DryRun)
|
|
{
|
|
Add-AzureKeyVaultKey -VaultName $KeyVaultName -Name "keyencryptionkey" -Destination Software
|
|
}
|
|
|
|
Write-Host "Added AzureRmKeyVaultKey successfully"
|
|
|
|
$global:KeyEncryptionKey = Get-AzureKeyVaultKey -VaultName $KeyVault.OriginalVault.Name -Name "keyencryptionkey"
|
|
|
|
Write-Host "Fetched KeyEncryptionKey successfully"
|
|
|
|
## Storage
|
|
$global:StorageName = ($ResourcePrefix + "Storage").ToLower()
|
|
$global:StorageType = "Standard_GRS"
|
|
$global:ContainerName = "vhds"
|
|
|
|
if(!$DryRun)
|
|
{
|
|
$global:StorageAccount = New-AzureRmStorageAccount -ResourceGroupName $ResourceGroupName -Name $StorageName -Type $StorageType -Location $Location
|
|
}
|
|
else
|
|
{
|
|
$global:StorageAccount = Get-AzureRmStorageAccount -ResourceGroupName $ResourceGroupName -Name $StorageName
|
|
}
|
|
|
|
Write-Host "Created StorageAccount successfully: $StorageName"
|
|
|
|
## Network
|
|
$global:PublicIpName = $ResourcePrefix + "PublicIp"
|
|
$global:InterfaceName = $ResourcePrefix + "NetworkInterface"
|
|
$global:SubnetName = $ResourcePrefix + "Subnet"
|
|
$global:VNetName = $ResourcePrefix + "VNet"
|
|
$global:VNetAddressPrefix = "10.0.0.0/16"
|
|
$global:VNetSubnetAddressPrefix = "10.0.0.0/24"
|
|
$global:DomainNameLabel = ($ResourcePrefix + "VM").ToLower()
|
|
|
|
if(!$DryRun)
|
|
{
|
|
$global:PublicIp = New-AzureRmPublicIpAddress -Name $PublicIpName -ResourceGroupName $ResourceGroupName -Location $Location -AllocationMethod Dynamic -DomainNameLabel $DomainNameLabel
|
|
}
|
|
else
|
|
{
|
|
$global:PublicIp = Get-AzureRmPublicIpAddress -Name $PublicIpName -ResourceGroupName $ResourceGroupName
|
|
}
|
|
|
|
Write-Host "Created PublicIp successfully: " $PublicIp.DnsSettings.Fqdn.ToString()
|
|
|
|
if(!$DryRun)
|
|
{
|
|
$global:SubnetConfig = New-AzureRmVirtualNetworkSubnetConfig -Name $SubnetName -AddressPrefix $VNetSubnetAddressPrefix
|
|
}
|
|
|
|
Write-Host "Created SubnetConfig successfully: $SubnetName"
|
|
|
|
if(!$DryRun)
|
|
{
|
|
$global:VNet = New-AzureRmVirtualNetwork -Name $VNetName -ResourceGroupName $ResourceGroupName -Location $Location -AddressPrefix $VNetAddressPrefix -Subnet $SubnetConfig
|
|
}
|
|
else
|
|
{
|
|
$global:VNet = Get-AzureRmVirtualNetwork -Name $VNetName -ResourceGroupName $ResourceGroupName
|
|
$global:SubnetConfig = Get-AzureRmVirtualNetworkSubnetConfig -Name $SubnetName -VirtualNetwork $VNet
|
|
}
|
|
|
|
Write-Host "Created AzureRmVirtualNetwork successfully: $VNetName"
|
|
|
|
if(!$DryRun)
|
|
{
|
|
$global:Interface = New-AzureRmNetworkInterface -Name $InterfaceName -ResourceGroupName $ResourceGroupName -Location $Location -SubnetId $VNet.Subnets[0].Id -PublicIpAddressId $PublicIp.Id
|
|
}
|
|
else
|
|
{
|
|
$global:Interface = Get-AzureRmNetworkInterface -Name $InterfaceName -ResourceGroupName $ResourceGroupName
|
|
}
|
|
|
|
Write-Host "Created AzureNetworkInterface successfully: $InterfaceName"
|
|
|
|
## Compute
|
|
$global:VMName = $ResourcePrefix + "VM"
|
|
$global:ComputerName = $ResourcePrefix + "VM"
|
|
$global:OSDiskName = $VMName + "OsDisk"
|
|
$global:OSDiskUri = $StorageAccount.PrimaryEndpoints.Blob.ToString() + "vhds/" + $OSDiskName + ".vhd"
|
|
$global:DataDisk1Name = $VMName + "DataDisk1"
|
|
$global:DataDisk1Uri = $StorageAccount.PrimaryEndpoints.Blob.ToString() + "vhds/" + $DataDisk1Name + ".vhd"
|
|
$global:DataDisk2Name = $VMName + "DataDisk2"
|
|
$global:DataDisk2Uri = $StorageAccount.PrimaryEndpoints.Blob.ToString() + "vhds/" + $DataDisk2Name + ".vhd"
|
|
|
|
## Setup local VM object
|
|
$SecString = ($Password | ConvertTo-SecureString -AsPlainText -Force)
|
|
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList @($Username, $SecString)
|
|
|
|
Write-Host "Created credentials successfully"
|
|
|
|
$global:VirtualMachine = New-AzureRmVMConfig -VMName $VMName -VMSize $VMSize
|
|
|
|
Write-Host "Created AzureRmVMConfig successfully"
|
|
|
|
$VirtualMachine = Set-AzureRmVMOperatingSystem -VM $VirtualMachine -Linux -ComputerName $ComputerName -Credential $Credential
|
|
|
|
Write-Host "Set AzureRmVMOperatingSystem successfully"
|
|
|
|
$PublisherName = $GalleryImage.Split(":")[0]
|
|
$Offer = $GalleryImage.Split(":")[1]
|
|
$Skus = $GalleryImage.Split(":")[2]
|
|
|
|
Write-Host "PublisherName: $PublisherName, Offer: $Offer, Skus: $Skus"
|
|
|
|
$VirtualMachine = Set-AzureRmVMSourceImage -VM $VirtualMachine -PublisherName $PublisherName -Offer $Offer -Skus $Skus -Version "latest"
|
|
|
|
Write-Host "Set AzureVMSourceImage successfully"
|
|
|
|
$VirtualMachine = Add-AzureRmVMNetworkInterface -VM $VirtualMachine -Id $Interface.Id
|
|
|
|
Write-Host "Added AzureVMNetworkInterface successfully"
|
|
|
|
$VirtualMachine = Set-AzureRmVMOSDisk -VM $VirtualMachine -Name $OSDiskName -VhdUri $OSDiskUri -CreateOption FromImage
|
|
|
|
Write-Host "Created AzureVMOSDisk successfully"
|
|
|
|
if ($SshPubKey)
|
|
{
|
|
$VirtualMachine = Add-AzureRmVMSshPublicKey -VM $VirtualMachine -KeyData $SshPubKey -Path ("/home/" + $Username + "/.ssh/authorized_keys")
|
|
|
|
Write-Host "Added SSH public key successfully"
|
|
}
|
|
|
|
## Create the VM in Azure
|
|
if(!$DryRun)
|
|
{
|
|
New-AzureRmVM -ResourceGroupName $ResourceGroupName -Location $Location -VM $VirtualMachine
|
|
}
|
|
|
|
Write-Host "Created AzureVM successfully: $VMName"
|
|
|
|
$VirtualMachine = Get-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $VMName
|
|
|
|
Write-Host "Fetched VM successfully"
|
|
|
|
if(!$DryRun)
|
|
{
|
|
Add-AzureRmVMDataDisk -VM $VirtualMachine -Name $DataDisk1Name -Caching None -DiskSizeInGB 1 -Lun 0 -VhdUri $DataDisk1Uri -CreateOption Empty
|
|
Add-AzureRmVMDataDisk -VM $VirtualMachine -Name $DataDisk2Name -Caching None -DiskSizeInGB 1 -Lun 1 -VhdUri $DataDisk2Uri -CreateOption Empty
|
|
}
|
|
|
|
Write-Host "Added DataDisks successfully: $DataDisk1Name, $DataDisk2Name"
|
|
|
|
if(!$DryRun)
|
|
{
|
|
Update-AzureRmVM -ResourceGroupName $ResourceGroupName -VM $VirtualMachine
|
|
}
|
|
|
|
Write-Host "Updated VM successfully"
|
|
|
|
## SSH preparation
|
|
|
|
$global:Hostname = $PublicIp.DnsSettings.Fqdn.ToString()
|
|
|
|
if ($SshPrivKeyPath -and !$DryRun)
|
|
{
|
|
$commandFileName = $ResourcePrefix + "Commands.txt"
|
|
|
|
$commands = @"
|
|
sudo mkdir /root/.ssh
|
|
sudo cp .ssh/authorized_keys /root/.ssh/
|
|
sudo chmod 700 /root/.ssh
|
|
sudo chmod 600 /root/.ssh/authorized_keys
|
|
sudo restorecon -R -v /root/.ssh
|
|
sudo echo "PermitRootLogin yes" >>/etc/ssh/sshd_config
|
|
sudo service sshd restart
|
|
exit
|
|
"@
|
|
|
|
$commands | Out-File -Encoding ascii $commandFileName
|
|
dos2unix $commandFileName
|
|
cmd /c "ssh -tt -o UserKnownHostsFile=C:\Windows\System32\NUL -o StrictHostKeyChecking=no -i $SshPrivKeyPath ${Username}@${Hostname} <$commandFileName"
|
|
Remove-Item $commandFileName
|
|
|
|
Write-Host "Copied SSH public key for root"
|
|
|
|
$commands = @"
|
|
(cat <<EOF
|
|
alias adetail='tail -f /var/log/azure/Microsoft.Azure.Security.A*D*E*ForLinux*/*/extension.log'
|
|
alias adecat='cat /var/log/azure/Microsoft.Azure.Security.A*D*E*ForLinux*/*/extension.log'
|
|
EOF
|
|
) >> /root/.bashrc
|
|
|
|
parted /dev/sdc
|
|
mklabel msdos
|
|
mkpart pri ext2 0% 100%
|
|
quit
|
|
|
|
parted /dev/sdd
|
|
mklabel msdos
|
|
mkpart pri ext2 0% 100%
|
|
quit
|
|
|
|
mkfs.ext4 /dev/sdc1
|
|
mkfs.ext4 /dev/sdd1
|
|
|
|
UUID1="`$(blkid -s UUID -o value /dev/sdc1)"
|
|
UUID2="`$(blkid -s UUID -o value /dev/sdd1)"
|
|
|
|
echo "UUID=`$UUID1 /data1 ext4 defaults 0 0" >>/etc/fstab
|
|
echo "UUID=`$UUID2 /data2 ext4 defaults 0 0" >>/etc/fstab
|
|
|
|
mkdir /data1
|
|
mkdir /data2
|
|
|
|
mount -a
|
|
exit
|
|
"@
|
|
|
|
$commands | Out-File -Encoding ascii $commandFileName
|
|
dos2unix $commandFileName
|
|
cmd /c "ssh -o UserKnownHostsFile=C:\Windows\System32\NUL -o StrictHostKeyChecking=no -i $SshPrivKeyPath root@${Hostname} <$commandFileName"
|
|
Remove-Item $commandFileName
|
|
|
|
Write-Host "Mounted data partitions"
|
|
|
|
$commands = @"
|
|
sed -i 's/SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config
|
|
reboot
|
|
"@
|
|
|
|
$commands | Out-File -Encoding ascii $commandFileName
|
|
dos2unix $commandFileName
|
|
cmd /c "ssh -o UserKnownHostsFile=C:\Windows\System32\NUL -o StrictHostKeyChecking=no -i $SshPrivKeyPath root@${Hostname} <$commandFileName"
|
|
Remove-Item $commandFileName
|
|
|
|
Start-Sleep 5
|
|
|
|
$vmRunning = $false
|
|
|
|
while(!$vmRunning)
|
|
{
|
|
try
|
|
{
|
|
$tcpClient = New-Object System.Net.Sockets.TcpClient
|
|
$tcpClient.Connect($Hostname, "22")
|
|
$vmRunning = $true
|
|
}
|
|
catch
|
|
{
|
|
Write-Host "VM is not up yet"
|
|
}
|
|
}
|
|
|
|
Write-Host "SELinux disabled"
|
|
}
|
|
|
|
## Encryption
|
|
|
|
if(!$DryRun)
|
|
{
|
|
$global:EncryptionEnableOutput = Set-AzureRmVMDiskEncryptionExtension `
|
|
-ExtensionName $ExtensionName `
|
|
-ResourceGroupName $ResourceGroupName `
|
|
-VMName $VMName `
|
|
-AadClientID $AadClientId `
|
|
-AadClientSecret $AadClientSecret `
|
|
-DiskEncryptionKeyVaultId $KeyVault.ResourceId `
|
|
-DiskEncryptionKeyVaultUrl $KeyVault.VaultUri `
|
|
-KeyEncryptionKeyVaultId $KeyVault.ResourceId `
|
|
-KeyEncryptionKeyURL $KeyEncryptionKey.Id `
|
|
-KeyEncryptionAlgorithm "RSA-OAEP" `
|
|
-VolumeType $VolumeType `
|
|
-SequenceVersion "1" `
|
|
-Force:$Force 3>&1 | Out-String
|
|
|
|
Write-Host "Set AzureRmVMDiskEncryptionExtension successfully"
|
|
|
|
$global:BackupTag = [regex]::match($EncryptionEnableOutput, '(AzureEnc.*?),').Groups[1].Value
|
|
}
|