How to securely automate adding keys into Azure Key Vault - azure

The scenario we're facing is that we have several secrets that have different values in each environment. Also, in the future, we are going to have new secrets.
So, the question is what is the best way for adding secrets to the key vault?
Manually: For each secret, we need to add it manually through either the portal or Azure CLI. We need to do it manually across all environments such as dev,qa, prod. The downside is that everything is manual and we need to hand over secrets to someone to add them to the key vault.
Automated: Is there any way for automating the whole process without putting secrets in files?

We need to do it manually across all environments such as dev,qa, prod.
We could save the key to different Azure DevOps Variable groups and set the value to secret, then use them in different environments.
We can add task Azure PowerShell and add the key vault via below script, then use it in the other task. Please refer to this ticket for more details.
$secretvalue = ConvertTo-SecureString $(Secret) -AsPlainText -Force
Set-AzureKeyVaultSecret -VaultName $(VaultName) -Name $(SecretName) -SecretValue (ConvertTo-SecureString $(Secret) -AsPlainText -Force)

Related

Connecting to Azure KeyVault via SPN

I need help accessing an Azure KeyVault via Service Principal. I currently have two subscriptions that need to communicate and access the other subscription's Key Vault but in order to do so I would need the connection to occur via SPN. I have looked at the documentation for Get-AzureRmKeyVault and it provides no way to authenticate via a SPN from what I can find.
If anyone has a solution I would greatly appreciate it!
Not sure what actually do you mean access keyvault, in azure keyvault, there are Management plane and Data plane, they use different access control mechanisms.
If you want your service principal to do Management plane operations(e.g. set the tag of your keyvault), you need to give it a role in Access control (IAM) of your keyvault in the portal. If you want to do Data plane operations(e.g. operate on the keys, secrets, certificates in the keyvault), you need to add your service principal with correct permissions to the Access policies of the keyvault.
For more details about access control of keyvault, you could check - Secure access to a key vault.
So make sure your service principal already had the correct permission, then use the command below.
$azureAplicationId ="<application-id>"
$azureTenantId= "<tenant-id>"
$azurePassword = ConvertTo-SecureString "<client-secret>" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAplicationId , $azurePassword)
Connect-AzAccount -Credential $psCred -TenantId $azureTenantId -ServicePrincipal
Then you can do the Management plane operations like Update-AzKeyVault, or the Data plane operations like Get-AzKeyVaultSecret.
To access the keyvault in a different subscription, just use the command below to select subscription.
Set-AzContext -Subscription <subscription-id>
And I notice seems you are using the old AzureRm module, it was deprecated and will not be updated anymore, I recommend you to use the new Az module, follow Migrate Azure PowerShell from AzureRM to Az.

Add/get secret to Azure Keyvault with Azure powershell task in Azure devops

I am trying to set the secrets inside my Azure Keyvault using the Azure Powershell Task in Azure DevOps.
I use the following code:
Set-AzureKeyVaultSecret -VaultName $KeyvaultName -Name $SecretName -SecretValue $secretvalue
With the names and the value all setup inside variables and tried to use this without also variables.
The value is saved as a secure string with the following code.ConvertTo-SecureString
But when I run this powershell code inside my Azure DevOps Release pipeline I keep getting following Error message:
Cannot retrieve access token for resource 'AzureKeyVaultServiceEndpointResourceId'. Please ensure that you have provided the appropriate access tokens when using access token login.
So I've made sure that the service principal and the build server are having the right access on the keyvault by adding them both to the access policies with the get,list,set secrets permission.
I've also added following lines of code to make sure that the profile is loaded correctly
########################################################################################
$azureRmProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile
$profileClient = New-Object -TypeName Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient -ArgumentList ($azureRmProfile)
$context = Get-AzureRmContext
$AzureToken = $profileClient.AcquireAccessToken($context.Tenant.Id)
Add-AzureRmAccount -AccessToken $AzureToken.AccessToken -AccountId $AzureToken.UserId
########################################################################################
By adding this code in the beginning of the inline script and using the profile with the commando as variable to the -DefaultProfile.
I also enabled the option to enable the script to access the Oauth token.
Is there someone who also tried to set the secret from the powershell task in Azure DevOps. Or know why the powershell script can't get access on the keyvault.
The azurermContext commando provided me with the right output, even tried the Get-AzureRmKeyvault command to figure out if the connection to the environment was already setup right. And that also didn't gave any problems.
below working for sure (using this reguarly)
Set-AzContext -SubscriptionId $SubscriptionId
## $SubscriptionId is a subscription ID where is the target KV
$Secretvalue = ConvertTo-SecureString $SecretValuePlainText -AsPlainText -Force
## $SecretValuePlainText is the secret to store
Set-AzKeyVaultSecret -VaultName $KeyVaultName -Name $SecretName -SecretValue $Secretvalue -ErrorVariable setSecretError -Expires $ExpirationDate -NotBefore $ActivationDate
## $SecretName, $ExpirationDate, $ActivationDate - obvious :)
of course if your refer to variable not from script or inline, but from release the use $(variable_name)
Service Principal/Service Connection we use for this is temporary an Owner of target subscription (or key vault, up to you).
I had the exact same issue.
Found that the problem was a missing access token.
Namely -KeyVaultAccessToken when you call Add-AzureRmAccount.
Found the solution here: https://github.com/Azure/azure-powershell/issues/4818#issuecomment-376155173
I fixed my question with the following.
I used a service connection that was based on a managed identity. And this needed some workaround to access the key vault like #john mentioned. But this was unnecessary. by creating a new service connection based on a service principal. This workaround was not necessary and fixed the issue.

How to use Azure KeyVault Secrets in AzureDevOps as varibles in CI/CD Definitions?

Am working on Azure DevOps and Azure KeyVault. Here, am trying to login my Azure account using KeyVault secrets in Azure DevOps Pipelines. For that I followed the Link-1 which is used for fetching the secrets. All the setup is done properly and for checking it, I taken PowerShell task with Inline script as shown in figure where Password is KeyVault Secret:
When the Build is run, it's runned without any error. But, here am getting KeyVault secrets(Password) values as following:
After that, when I tried it for further steps by adding some code for login purpose am getting the error as following:
Could you please suggest me how to get out of this situation
First, Azure Devops will not output varaibles defined as secrets.
Then you have a typo in your script. you should double-quote the password:
$securePassword = "$(Password)" | ConvertTo-SecureString -AsPlainText -Force
Secrets variables need to be mapped before using it in pipeline.You can try below steps.
First, map the secrets to an environment variable in the powershell task
Then use below scripts to refer to the password
$SecurePassword=$env:PASSWORDMAP
Click here For more information about how to use secret variables.

Problem with azure application settings variables

I'm trying to set a new application setting for azure storage key, the problem is that the '==' at the end of the key is not been recognized, I try to generate a new key but it seems that very key ends in '=='
I test with portal and powershell, they all could work.
In the portal, go to your app service->Configuration->+New application setting and set your key there.
With powershell I use the below code to update it:
Set-AzureRMWebApp -ResourceGroupName $myResourceGroup -Name $mySite -AppSettings $hash
With these two ways, the key could be recognized, I check them in the kudu.
So if you are not using these way and you still fail to set it please feel free to let me know.

Change Azure Backup Vault Redundancy

We use Azure Backup and set our backup vaults to use GRS. We want to use LRS instead. It is understood that this cannot be changed once machines have been added to the vault, and we need to start from scratch. Two questions:
Do I need to remove the current vault first before I set up a new vault for that same server?
Can the current backups be transferred to the new vault?
Changing a Recovery Service Vault's storage replication type can be achieved via the Portal or PowerShell. Unfortunately, this option is greyed-out in the Portal, and whilst the cmdlet successfully executes, it doesn't change the underlying value: if there is one or more Protected Instances already contained in the vault.
Because of this, and because the default value is GeoRedundant, this must be set before any items have been protected.
To set the storage to Locally Redundant via the Portal:
Create/Open the Recovery Services Vault
Scroll-down and select Backup Infrastructure
Select Backup Configuration
Set Storage replication type to Locally-redundant
To achieve the same via PowerShell:
$RG = 'testResourceGroup'
$VaultName = 'testVault'
$Location = 'Central US'
$vault = Get-AzureRmRecoveryServicesVault -ResourceGroupName $RG -Name $VaultName
If (-not $vault) {
$vault = New-AzureRmRecoveryServicesVault -ResourceGroupName $RG -Location $Location -Name $VaultName
}
Set-AzureRmRecoveryServicesBackupProperties -Vault $vault -BackupStorageRedundancy LocallyRedundant
With regards removing existing vaults and transferring existing backup points:
The existing vault does not need to be deleted, however any protected items will need to be removed from the vault before they can be added to a new vault. It is not sufficient to simply stop backup on the protected item - all the restore points must also be deleted before the item can be added to the new vault
I cannot find any documentation, facility in the Portal or PowerShell which would allow the migration of existing protected items and/or restore points
The only way I've been able to change from Geo-Redundant Storage (GRS) to Locally Redundant Storage (LRS) is to create a new empty vault in the old portal (https://manage.windowsazure.com).
In the old portal you can change storage type in "Configuration".
I expect you will also be able to do it with PowerShell, but haven't tried it though.
You can register your server with 1 vault. In order to register your server with the new vault, you need to use the new vault credentials downloaded from manage.windowsazure.com
You can have multiple vaults. If you do not use your current vault in the future, it will stay there. You have to pay for each vault. So, if you don't need it in the future, it may be better to remove it completely.
There is a comprehensive documentation here:
https://azure.microsoft.com/en-us/documentation/services/backup/

Resources