tools/e2etesting/DeployEdge.ps1 (133 lines of code) (raw):

Param( [string] $ResourceGroupName, [Guid] $TenantId, [string] $EdgeVmSize = "Standard_D2s_v3", [string] $EdgeVmLocation, [string] $KeysPath ) # Stop execution when an error occurs. $ErrorActionPreference = "Stop" if (!$ResourceGroupName) { Write-Error "ResourceGroupName not set." } if (!$KeysPath) { Write-Error "Path to store certifactes not set." } if (!(Test-Path -Path $KeysPath)) { New-Item -ItemType Directory -Path $KeysPath | Out-Null } $edgeVmUsername = 'sandboxuser' ## Login if required $context = Get-AzContext if (!$context) { Write-Host "Logging in..." Login-AzAccount -Tenant $TenantId $context = Get-AzContext } ## Check if resource group exists $resourceGroup = Get-AzResourceGroup -Name $resourceGroupName if (!$resourceGroup) { Write-Error "Could not find Resource Group '$($ResourceGroupName)'." } ## Determine suffix for testing resources $testSuffix = $resourceGroup.Tags["TestingResourcesSuffix"] if (!$testSuffix) { $testSuffix = Get-Random -Minimum 10000 -Maximum 99999 $tags = $resourceGroup.Tags $tags+= @{"TestingResourcesSuffix" = $testSuffix} Set-AzResourceGroup -Name $resourceGroup.ResourceGroupName -Tag $tags | Out-Null $resourceGroup = Get-AzResourceGroup -Name $resourceGroup.ResourceGroupName } Write-Host "Using suffix for testing resources: $($testSuffix)" ## Check if IoT Hub exists $iotHub = Get-AzIotHub -ResourceGroupName $ResourceGroupName if ($iotHub.Count -ne 1) { Write-Error "IotHub could not be automatically selected in Resource Group '$($ResourceGroupName)'." } Write-Host "IoT Hub Name: $($iotHub.Name)" ## Check if KeyVault exists $keyVault = Get-AzKeyVault -ResourceGroupName $ResourceGroupName if ($keyVault.Count -ne 1) { Write-Error "keyVault could not be automatically selected in Resource Group '$($ResourceGroupName)'." } Write-Host "Key Vault Name: $($keyVault.VaultName)" ## Ensure that Edge Device exists $deviceName = "e2etestdevice_$($testSuffix)" Write-Host "Iot Hub Device Identity: $($deviceName)" $edgeIdentity = Get-AzIotHubDevice -ResourceGroupName $ResourceGroupName -IotHubName $iotHub.Name -DeviceId $deviceName -ErrorAction SilentlyContinue if (!$edgeIdentity) { Write-Host "Creating edge-enabled device identity $($deviceName) in Iot Hub $($iotHub.Name)" $edgeIdentity = Add-AzIotHubDevice -ResourceGroupName $ResourceGroupName -IotHubName $iotHub.Name -DeviceId $deviceName -EdgeEnabled } if (!$edgeIdentity.Capabilities.IotEdge) { Write-Error "Device '$($edgeIdentity.Id)' Iot Hub: '$($iotHub.Name)') is not edge-enabled." } Write-Host "Adding/Updating KeyVault-Secret 'iot-edge-device-id' with value '$($edgeIdentity.Id)'..." [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")] $secret = ConvertTo-SecureString $edgeIdentity.Id -AsPlainText -Force Set-AzKeyVaultSecret -VaultName $keyVault.VaultName -Name 'iot-edge-device-id' -SecretValue $secret | Out-Null Write-Host "Updating 'os' and '__type__'-Tags in Device Twin..." Update-AzIotHubDeviceTwin -ResourceGroupName $ResourceGroupName -IotHubName $iotHub.Name -DeviceId $edgeIdentity.Id -Tag @{ "os" = "Linux"; "__type__" = "iiotedge"; } | Out-Null ## Generate SSH keys $privateKeyFilePath = Join-Path $KeysPath "id_rsa_iotedge" $publicKeyFilePath = $privateKeyFilePath + ".pub" $keypassphrase = '"$($testSuffix)"' Write-Output "y" | ssh-keygen -q -m PEM -b 4096 -t rsa -f $privateKeyFilePath -N $keypassphrase $sshPrivateKey = Get-Content $privateKeyFilePath -Raw $sshPublicKey = Get-Content $publicKeyFilePath -Raw ## Delete SSH keys from file system Remove-Item -Path $privateKeyFilePath | Out-Null Remove-Item -Path $publicKeyFilePath | Out-Null ## Deploy Edge VM Write-Host "Getting Device Connection String for IoT Edge Deployment..." $edgeDeviceConnectionString = Get-AzIotHubDeviceConnectionString -ResourceGroupName $ResourceGroupName -IotHubName $iotHub.Name -DeviceId $edgeIdentity.Id -KeyType primary $edgeDeviceConnectionString = $edgeDeviceConnectionString.ConnectionString $dnsPrefix = "e2etesting-edgevm-" + $testSuffix Write-Host "Using DNS prefix: $($dnsPrefix)" $edgeParameters = @{ "dnsLabelPrefix" = [string]$dnsPrefix "adminUsername" = [string]$edgeVmUsername "deviceConnectionString" = [string]$edgeDeviceConnectionString "authenticationType" = "sshPublicKey" "adminPasswordOrKey" = [string]$sshPublicKey "allowSsh" = $true "vmSize" = [string]$EdgeVmSize } if ($EdgeVmLocation) { $edgeParameters["location"] = [string]$EdgeVmLocation } $edgeTemplateUri = "https://raw.githubusercontent.com/Azure/iotedge-vm-deploy/1.4/edgeDeploy.json" Write-Host "Running IoT Edge VM Deployment..." $edgeDeployment = New-AzResourceGroupDeployment -ResourceGroupName $ResourceGroupName -TemplateUri $edgeTemplateUri -TemplateParameterObject $edgeParameters $edgeDeployment | ConvertTo-Json | Out-Host if ($edgeDeployment.ProvisioningState -ne "Succeeded") { Write-Error "Deployment $($edgeDeployment.ProvisioningState)." } ## This needs to be refactored. However, currently the SSH-Command is the only output from the Edge deployment script. And that command includes the FQDN of the VM. $sshUrl = $edgeDeployment.Outputs["public_SSH"].Value if ([string]::IsNullOrEmpty($sshUrl)) { Write-Error "Deployment did not provide Public_SSH output." } $fqdn = $sshUrl.Split("@")[1] Write-Host "Adding/Updating KeVault-Secret 'iot-edge-vm-username' with value '$($edgeVmUsername)'..." [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")] $secret = ConvertTo-SecureString $edgeVmUsername -AsPlainText -Force Set-AzKeyVaultSecret -VaultName $keyVault.VaultName -Name 'iot-edge-vm-username' -SecretValue $secret | Out-Null Write-Host "Adding/Updating KeVault-Certificate 'iot-edge-vm-privatekey'..." [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")] $secret = ConvertTo-SecureString $sshPrivateKey -AsPlainText -Force Set-AzKeyVaultSecret -VaultName $keyVault.VaultName -Name 'iot-edge-vm-privatekey' -SecretValue $secret | Out-Null Write-Host "Adding/Updating KeVault-Certificate 'iot-edge-vm-publickey'..." [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")] $secret = ConvertTo-SecureString $sshPublicKey -AsPlainText -Force Set-AzKeyVaultSecret -VaultName $keyVault.VaultName -Name 'iot-edge-vm-publickey' -SecretValue $secret | Out-Null Write-Host "Adding/Updating KeyVault-Secret 'iot-edge-device-dnsname' with value '$($fqdn)'..." [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")] $secret = ConvertTo-SecureString $fqdn -AsPlainText -Force Set-AzKeyVaultSecret -VaultName $keyVault.VaultName -Name 'iot-edge-device-dnsname' -SecretValue $secret | Out-Null Write-Host "Deployment finished."