I'm sitting in my hotel room after the [deliver:Agile2019] conference (https://www.agilealliance.org/deliveragile-2019/) which was fantastic. I highly recommend attending it next year.
I have a little side project I'm trying to use to learn Azure and Azure Dev Ops. At work we use ARM templates to deploy our infrastructure. I think some teams are looking at moving to use yaml files.

First night of the conference, I'm looking at what I need to do deploy to have a "Hello World" site running. In Azure, the top level is a "Resource Group".
Great, I found an arm template for resource groups.

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.1",
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Resources/resourceGroups",
      "apiVersion": "2018-05-01",
      "location": "westus",
      "name": "HelloWordResourceGroup",
      "properties": {}
    }
  ],
  "outputs": {}
}

It's just one file in a small Azure Resource Group deployment project . I do an Azure Dev Ops Pipeline with a build to copy the file over Capture2.
And then onto the release which will actually deploy the ARM template. Like I've done before, I'll use the Azure Resource Group Deployment task Capture3. Nothing new here. It deploys resource groups, sounds perfect for deploying my resource group.

At this point, I'm just trying to get a resource group deployed. Nothing else. I'm starting from nothing and want EVERYTHING generated through the release process.

My goal is to have all values as variables and configure the hell out of this so that I can extend, grow, change without having to actually admin through Azure.

When I go to configure the task... find a problem... Capture4 ... I don't know what resource group... I don't HAVE a resource group. I'm trying to put IN a resource group.

There might be a way to use this to deploy an actual resource group... but I don't think it's how I want to drive down things. I want things much smoother. Next up - YAML.... OK. No. That was brief.

I started looking at the Azure CLI. Clearly by the title this is what I went with.
The reason for that is this

az group create --location westus --name HelloWorldResourceGroup

That's the infrastructure as code required to create a resource group. That's it.
I have the script executed with the Azure CLI task. Capture5

That's it.
Deployed.
Watching the logs, it creates the ARM template and runs that for me. What I have is easier to maintain and avoids all the little details.

I plan to use this for a lot of things.

Using ARM templates in the past required copy/pasting 20-30 lines of JSON and changing a few values. It sucks, but it's how we're doing it. This accomplishes the same in a few lines.

I went a little further the next night and added App Insights to the script.
It's a longer line

az resource create --resource-group %RESOURCEGROUP_NAME% --name %APPLICATIONINSIGHTS_NAME% --resource-type "Microsoft.Insights/components" --location %AZURE_REGION% --properties "{\"Application_Type\":\"web\"}"

and there's an annoying tiny bit of JSON it says is required; it's for properties that don't have any other home. Still, much shorter than the ARM templates to deploy App Insights.
One of the great savings I find is parameters. With ARM templates there's a separate file for parameter definitions. Then the values get defined in the template file. There's gotchas and challenges and silly things... that make some sense... but still quite annoying.

At work we stopped using the parameters. We have a json token replacement step in our release. We just define tokenized everything and got rid of the parts that annoyed us.

Using Azure CLI we use the release variables, but they get passed in as environment variables, so we just references them. No tokenization replacement, no extra parameter files... Just "Do This". It's fantastic.

I also created an app service in about 30 seconds. The longest part of that was waiting for the documentation to load.

az appservice plan create --resource-group %RESOURCEGROUP_NAME% --name %APPSERVICE_NAME% --sku %APPSERVICE_SKU%

That's it!
What's cool about the last argument there --sku as a variable is that I can change that in per environment. Right now, I have it set to F1, the free tier. I'm playing around. If I wanted to do different for a different environment; I create the environment, the appropriate variables and BAM - New environment with a different sku deployed. Zero commits. It's nice.

I'm planning to do a lot more with Azure CLI and azure. With the ability to get 100% running again with just a single button. I'm looking to include automated data restore. It's easy to test restoring data when you're comfortable nuking the entire resource group.

I haven't looked into that, but I'm confident it can be accomplished. My current thought is to use the Cosmos Data Feed to populate a database in a different resource group. If I hit the "delete all" button, I can then just copy over the data from that CosmosDb. It should be almost perfectly up to date. I'll see how that works out...
But it's an idea.

The other piece I plan to have is tests. All my stuff I want to get 100% tested. That includes spinning up and down entire environments to populate and test against. That'll be awesome. It'll get there. I've just started with deploying A SINGLE resource group. I giggled when it worked. It's such a clean, easy, repeatable way to create environments in Azure.

The confidence I feel for recoverability going forward is immense. If I NEVER manually create a resource in azure, I will ALWAYS be able to recover from the push of a button.

That's my goal.

Azure CLI is going to help me really get to "cattle not pets".