Cant read Key Vault secrets as plain text from Azure PowerShell task in Azure DevOps Build Pipeline - azure-devops

​I'm trying to login to Azure Subscription using Service Principal from Azure DevOps build Pipeline PowerShell task.
The reason I need to log in is, I need to execute a few Log analytics queries from the same PowerShell task, hence it requires authentication to the subscription.
Service Principal ID and Key are in Key Vault as secrets. I need to read them as plain text to pass and authenticate with Azure Subscription.
The problem is, I'm not able to read them as plain text or plain string as it comes as an encrypted string value in the Azure DevOps PowerShell task. I can't seem to find ways in order to read them as plain text directly.
I can't use the below command
(Get-AzKeyVaultSecret -VaultName $vaultName -Name $secretName).SecretValueText
because we need to be authenticated already to Azure Subscription to execute the other modules' commands.
Tried the below (i.e) Value for $Encrypted (Service Principal ID) is in KeyVault as plain text When I used the below it said, Input was not in a correct format
$AppId = (ConvertTo-SecureString $Encrypted) $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($AppId) $AppId = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
Looking for any other ways to accomplish this task.

Found out an answer for this. I was using PowerShell task type as AzurePowerShell#2
But changed that to task: AzurePowerShell#4 which made things very easier as I already have Service Connection, i can authenticate to subscription using that and also can read and pass the Key Vault secrets successfully.
you need to mention azurePowerShellVersion: LatestVersion in build task, it worked simply.
Also this eliminated the requirement of using Service principal and now i can authenticate to subscription using Azure DevOps Service connection.

Related

Is it possible to create resources in azure in multiple subscriptions using single pipeline?

I have a requirement to create resources based on the text file uploaded to the azure devops repos by my client. My client wants to keep it minimal and need only one file to be updated and single pipeline to deploy resources to multiple subscriptions (dev, test, prod).
Text file preview
I am able to read this file and create resources using powershell (using loop) in single subscription. I am not sure how to create single pipeline to read this file and create resources in multiple subscriptions.
Note: TargetSubscription is a service connection.
Is it possible? If yes, what is the best way to achieve this?
Any help would be appreciated. Thanks in advance!
If TargetSubscription is a service connection, I assume each service connection has necessary access in the relevant Subscription. Since you already said you have a PowerShell code, you can use Connect-AzAccount for every new service connection:
$SecureStringPwd = $sp.PasswordCredentials.SecretText | ConvertTo-SecureString -AsPlainText -Force
$pscredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $sp.AppId, $SecureStringPwd
Connect-AzAccount -ServicePrincipal -Credential $pscredential -Tenant $tenantId
Azure Docs link: https://learn.microsoft.com/en-us/powershell/azure/authenticate-azureps?view=azps-8.1.0#password-based-authentication
Your Azure DevOps service connections need to have a relevant service principal in Azure side. If that service principal has permission to deploy resources (for example, Contributor RBAC on subscription), you can create your resources in that Subscription after you sign in with it.
Call the Connect-AzAccount every time you read a new Service Connection from the text file, and then the remaining of your script will run to create resources. Your sign in session should only see that specific Subscription.
You can create client secret on Azure side for each service principal. Then you can put this secret into Key Vault, get the value securely from Key Vault in your script and pass it as a parameter to $SecureStringPwd, as displayed above.

How PowerShell Login-AzureRmAccount in Azure using Function Apps

Related to this tutorial (Using PowerShell Modules in Azure Functions) I can run PowerShell in my Function Apps. right now I want to run this PowerShell tutorial from microsoft (Build your first Azure data factory using Azure PowerShell). In first step I should run this PowerShell codes:
PowerShell Login-AzureRmAccount
PowerShell Get-AzureRmSubscription
#Run the following command to select the subscription that you want to work with. This subscription should be the same as the one you used in the Azure portal.
PowerShell Get-AzureRmSubscription -SubscriptionName <SUBSCRIPTION NAME> | Set-AzureRmContext
problem is that this tutorial is for using PowerShell in Local machine (using PoserShell from Windows), but I need to run this tutorial using Function Apps, then I need to change the scenarios...
can you please guide me how I should change or use Login-AzureRmAccount and Get-AzureRmSubscription?
By default, Login-AzureRmAccount does an interactive login, which won't work in an Azure Function. Instead, you'll need to log in using a Service Principal, e.g.
Login-AzureRmAccount -ServicePrincipal -ApplicationId "http://my-app" -Credential $pscredential -TenantId $tenantid
Azure PowerShell docs have more info on this.
As for selecting the subscription, there is no difference between doing it interactively or in a Function.
Please do keep in mind that PowerShell is an experimental language in Azure Functions, and is not fully supported.
Azure function is one kind of app service and only owns limited permission. If you want to Login Azure with it, you may need to using Azure Keyvault and Service Principle to help you login Azure automatically.
There are main steps you need to do:
Using powershell to create self-signed certificate and export it to local
Use powerhshell to create a service principal for signing in automatically
Upload the self-signed Certificate Thumbprint and configure SSL (Upload the PFX file) for the azure function
Create a keyvault and set the access policy for service principal
Create azure function app, then use self-signed certificate thumbprint , appid and other information in the azure function to sign
in automatically. Last you can use cmdlet Get-AzureKeyVaultSecret to
retrieve the contents of the certificate and rebuild the certificate.
You can refer to this article to create Azure Keyvault and Service Principle. Then you can use powershell in your Function App to login Azure automatically.
After Adding powershell to your Function App and configure all settings, you can run these scripts:Login-AzureRmAccount -ServicePrincipal -CertificateThumbprint $certThumbprint -ApplicationId $appId -TenantId $tenantId
See more details about Azure Service Principle in this document.
This blog can also be helpful to you.
NOTE:The self-signed certificate needs to be imported into the azure function through the portal and configured with WEBSITE_LOAD_CERTIFICATES in the app setting

Adding the backup management service to keyvault in Azure powershell

In order to backup encrypted virtual machines in azure, Backup Management Service requires permissions in the key vault. There is a template for this in the portal that allows you to add the permissions required however I cannot find either documentation to do this in powershell nor can I find the object id for the backup management service to use Set-AzureRmKeyVaultAccessPolicy.
I dont want to have to manually add this access policy into every key vault I create for my encrypted virtual machines.
Editing for further clarity:
I know how to set access policy with powershell and I do so for my aad service principal for writing the keys to key vault at encryption time. However for Recovery Services Vault to work, the Azure backup service also needs access to the keys, I cannot find out how to add this Azure backup service to the key vault using Powershell, I can only see how to do it in the portal which is: Add access policy > Configure from template > Azure Backup. This adds the Service Principal "Backup Management Service" to the key vault. I cannot find this service principal in my subscription nor does Powershell accept this as a valid name.
I know this post is 2 months old, but I found a solution. run this to get the object ID of that "built in" service principal
$spobj = Get-AzureRmADServicePrincipal -SearchString "Backup Management Service"
then this should work against your keyvault.
Set-AzureRmKeyVaultAccessPolicy -ObjectId $spobj.Id -VaultName $kvname -PermissionsToKeys get,list,backup -PermissionsToSecrets get,list,backup

Azure PowerShell - Selecting Subscription

I need to select my Azure Subscription in Azure PowerShell.
I copy/paste the Subscription ID (to ensure no typos) from the Azure Management Portal, it's a hex-string:
When I run:
Select-AzureSubscription -SubscriptionId '0300...'
I get an error message:
Select-AzureSubscription : The subscription id 0300... doesn't exist.
I know my subscription ID is correctly copied from the settings in Azure Management Portal, I even did a BeyondCompare to make sure.
I'm wondering about security... am I missing something? Do I need to somehow provide my Azure credentials? It wouldn't make sense to just allow anyone to select any Azure subscription, unless the Subscription ID is supposed to be super-secret, like an SSN.
You need to log on to your Azure account first:
To start working with the Azure Service Management cmdlets, first log
on to your Azure account. To log on to your account, run the following
command:
Add-AzureAccount
After logging into Azure, Azure PowerShell creates a context for the
given session. That context contains the Azure PowerShell environment,
account, tenant, and subscription that will be used for all cmdlets
within that session. Now you are ready to use the modules below.
Source: https://learn.microsoft.com/en-us/powershell/azure/install-azure-ps?view=azuresmps-3.7.0

How to get Azure Key Vault secret using powershell with certificate auth?

I am including a Powershell startup task on an Azure Worker Role which needs to pull a secret from Azure Key Vault. I would like to use a client certificate to authenticate Key Vault request (cert gets installed on the VM when role comes up).
I took a look at this tutorial on azure documentation, but this needs me to write some C# methods and include bunch of nuget packages. Is there a simpler way?
See this article: Use Azure PowerShell to create a service principal to access resources
Add-AzureRmAccount -ServicePrincipal -CertificateThumbprint $cert.Thumbprint -ApplicationId $appId -TenantId $tenantId
It is possible to use powershell to access the keys in Keyvault .
use the Get-AzureKeyVaultSecret command to get the values. It has multiple parameters to suit different requirements such as get all secrets, specific secrets etc.
https://msdn.microsoft.com/en-us/library/dn868047.aspx
Details of all the keyvault module commandlets can be found here.
https://msdn.microsoft.com/library/azure/dn868052.aspx