Noobie2021
Noobie2021

Reputation: 361

Connect-AzAccount with Azure Devops Pipeline?

I am finding difficulties in finding the best and secure way to use connect-azaccount with azure devops pipeline. I have in the pipeline the following this simple powershell script which is used to create azure resources. Just to simplify things I only used the creation of a resource group:

$Location = "Location Name"
$resourceGroupName = "Resource Group Name"

try {

    #Creation of Resource Group
    $resourceGroup = Get-AzResourceGroup -ResourceGroupName $resourceGroupName -ErrorAction SilentlyContinue 

    if($null -eq $resourceGroup)
    {
        New-AzResourceGroup -Name $resourceGroupName -Location $Location
    }

    else
    {
        Write-Host "The ResourceGroup with the name: $resourceGroupName already exists."
    }

} 


catch 
{
    Write-Host "Error occurred: $_"
}

The problem here is when the pipeline is being run and it reaches the Powershell task, it gives me an error, Error occurred: Run Connect-AzAccount to login.

My issue here is that I honestly don't know which way is the most secure way to connect without typing any user credentials. It should directly connect and create the resources. Note that I am using Multi-Factor Authentication. In order to achieve that I found several solutions but I need help in choosing the best way. I found several solutions by adding a powershell task in the Yaml file. Here is the Yaml showing the powershell task to run the script:

  - task: PowerShell@2
    inputs:
      filePath: '$(Pipeline.Workspace)/Deploy/functionapp.ps1'

Option 1:

Connect-AzAccount -Tenant 'xxxx-xxxx-xxxx-xxxx' -SubscriptionId 'yyyy-yyyy-yyyy-yyyy'

Now the problem here is that the Tenant ID and Subscription are going to be visible in the code and that is a very bad practice

Option 2 is to use the following script:

$User = "[email protected]"
$PWord = ConvertTo-SecureString -String "<Password>" -AsPlainText -Force
$tenant = "<tenant id>"
$subscription = "<subscription id>"
$Credential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $User,$PWord
Connect-AzAccount -Credential $Credential -Tenant $tenant -Subscription $subscription

This is very similar to the first, but if I am not mistaken it is limited to a specific user.

Option 3 is to use a service principal:

$azureAplicationId ="Azure AD Application Id"
$azureTenantId= "Your Tenant Id"
$azurePassword = ConvertTo-SecureString "strong password" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAplicationId , $azurePassword)
Connect-AzAccount -Credential $psCred -TenantId $azureTenantId  -ServicePrincipal

I don't know if creating a service principal will incur any costs and what steps should I do to make it work.

I am honestly new to all this, can someone please provide me what are the exact steps to achieve this. Thank you for your answers :)

Upvotes: 3

Views: 11299

Answers (2)

deadlydog
deadlydog

Reputation: 24384

If you use the AzurePowerShell task it will automatically run Connect-AzAccount for you using whichever Azure DevOps service connection you provide (instructions to create a service connection to Azure here), allowing you to skip the step entirely and just focus on writing/running the PowerShell code to do the actual work you want. Letting MS handle the code for connecting to your Azure subscription/resource group is generally the best and most secure practice.

Here is an example of what the YAML might look like for an inline script (you can also reference a script file in your repo):

- task: AzurePowerShell@5
  displayName: 'Run PowerShell code connected to Azure'
  inputs:
    azureSubscription: 'Your-Azure-DevOps-service-connection-name'
    ScriptType: 'InlineScript'
    Inline: |
      Write-Output "Connect-AzAccount has already been ran by the time we get to our custom code."
      $PSVersionTable
    azurePowerShellVersion: 'LatestVersion'
    pwsh: true

Upvotes: 0

Kamil Konderak
Kamil Konderak

Reputation: 424

The most secure way is to create an Azure Resource Manager service connection and use it in your pipeline. You can create it using automated way, or manually using previously created service principal.

Upvotes: 4

Related Questions