Azure PowerShell vs Azure CLI v2

I'm entirely re-doing my infrastructure for the entirely re-doing of my Magic The Gathering Collection Tracking Site.

I did it in powershell the first time, and it works. Mostly. It's clunky and there's some stuff Azure PowerShell can't do. I wrote about that in v1 of this toe-to-toe.

The rewrite is being done in Azure DevOps Task Groups. So it's not really IaC, it's ... Ia... Tasks. Anyway. In this I'm using the Azure CLI.

It's so much nicer.

The biggest win is that commands are idempotent. If you're an engineer and this word isn't ingrained in your head yet - ingrain it.

It's apparently the standard for the CLI - https://github.com/Azure/azure-cli/blob/dev/doc/command_guidelines.md#standard-command-types

Not all Create Commands respect it though... Like KeyVault. https://github.com/Azure/azure-cli/pull/18520#issuecomment-879035440

i·dem·po·tent
/ˌīdemˈpōt(ə)nt,ˈēdemˌpōt(ə)nt/

adjective
denoting an element of a set which is unchanged in value when multiplied or otherwise operated on by itself.

The reason this is huge - In the powershell I have to protect every create call with a "Does it already Exist?" check. EVERYTHING. ALL OVER. I created a class to do it  

class ResourceExists{

    [bool] Exists([string]$name,[ResourceGroup]$resourceGroup){
        [Log]::Info("Check if exists [$($name)] in [$($resourceGroup.Name())]")
        $result=(Get-AzResource `
            -Name $name `
            -ResourceGroupName $resourceGroup.Name() `
            -ErrorAction Ignore) -ne $null
        
        [Log]::Debug("[Exist=$($result)] for [$($name)] in [$($resourceGroup.Name())]")

        return $result
    }

    [bool] protected_Check([string]$name,[ResourceGroup]$resourceGroup){
        return (Get-AzResource `
            -Name $name `
            -ResourceGroupName $resourceGroup.Name() `
            -ErrorAction Ignore) -ne $null
    }
}

With Azure CLI, the operation is idempotent. I can attempt to create that which exists and ... IT DOES NOTHING!

It's so fucking nice. I could almost go back to wrapping it all in classes... except that part sucked... soo... No.
This isn't to knock powershell proper, I'm pushing it's edges, and it shows. I could do this faster/easier running Azure CLI from C# to get it back to proper IaC. I'm using Task Groups, and it'll be good enough for now.

I definitely would like it all to be configured as IaC and checked in... but gotta go with what allows me to iterate the fastest for now.

Resistance

I found myself resisting changing or adding stuff in my PowerShell IaC. When I feel this resistance, I know it's not as smooth as it could be. I needed a new Azure Function deployment... uggg... not hard... but it's practically a copy/paste of 20 lines of code. I don't have that bit well encapsulated.

Using the task groups I can pull all the infra/connection/keys into a "Make Function Infra" task group and just provide the values.

I'm just in the early stages and the idempotent-cy was so huge I started writing this, but it looks like I'll be able to tweak and iterate a lot more effectively in this set up.

Through using either of these you'll learn buckets. It's a fun journey.