Category Archives: Programming Languages

Things I’ve come across regarding various programing languages, hints, tips, etc.

Azure ARM Templates

Spending a lot of time working with customers to define an Azure adoption framework, so thought I would look into ARM templates to get a better feel for how to automate and code-ify the deployment of Azure resources and policies.

ARM templates can be deployed in a similar manner to GCP deployment manager templates. ARM templates are defined in JSON, GCP DM in YAML/Jinja. Both have a deployment manager where you can monitor the success or failure of the deployment in the console.

ARM templates consist of 3 basic parts; parameters, variables and resources. Parameters define the inputs needed to execute the template (including the type, default value and acceptable values if you need to limit them), variables are a way of providing parameter values dynamically or by building them based on a standard structure (e.g. a naming convention). Resources are the definition of which resources need to be deployed in the template.

{
 "$schema":"https://schema.management.azure.com/schemas/2018
 -05-01/subscriptionDeploymentTemplate.json#",
 "contentVersion": "1.0.0.0",
 "parameters": {
   "budgetName": {
      "type": "string",
      "defaultValue": "MyBudget",
      "metadata": {
         "description": "Name of the Budget. It should be
         unique within a resource group."
      }
    },
   "amount": {
     "type": "string",
     "defaultValue": "1000",
     "metadata": {
       "description": "The total amount of cost or usage to
       track with the budget"
     }
   },
...
 }
},
 "variables": {
   "uniquebudgetName": "[concat(parameters('amount'), '-',
   parameters('firstThreshold'), '-budget')]"
},
 "resources": [
   {
   "type": "Microsoft.Consumption/budgets",
   "apiVersion": "2019-10-01",
   "name": "[variables('uniquebudgetName')]",
   "properties": {
     "timePeriod": {
       "startDate": "2021-02-01T00:00:00Z",
       "endDate": "2022-02-01T00:00:00Z"
     },
   "timeGrain": "[parameters('timeGrain')]",
...
   }
 ]
}

Parameter inputs which are not defined already via variables, can be defined either at run time through the command line, via a parameter file or via the console with an input form.

{
 "$schema": "https://schema.management.azure.com/
 schemas/2019-04-01/deploymentParameters.json#",
 "contentVersion": "1.0.0.0",
 "parameters": {
   "budgetName": {
     "value": "budget1"
   },
   "startDate": {
   "value": "2021-02-01T00:00:00Z"
   },
   "endDate": {
     "value": "2022-02-01T00:00:00Z"
   },
   "timeGrain": {
     "value": "Monthly"
   },
   "amount": {
     "value": "10"
   },
   "firstThreshold": {
     "value": "10"
   },
   "contactEmails": {
     "value": [
       "chris@broccolifamily.net"
     ]
   }
 }
}

There are a couple of ways to execute a template file. Either through the console (didn’t bother with this since it seems counter productive), CLI, or a CI/CD pipeline.

az deployment group create \
  --name armbudget \
  --resource-group resourcegroup1 \
  --template-file $templateFile \
  --parameters $prodParameterFile

Of course the two environment variables, need to be set to point to the appropriate files. The –parameter flag can also have a list of parameters and their values instead of pointing to the file.

My tests followed one of the canned tutorials but I extended it to add my own parameter file. Executing a CI/CD pipeline requires a parameter file to be used if you don’t want to keep updating the pipeline every time you change a parameter value (just update the parameter file and the pipeline can just run triggering on the change to the parameter file).

The final template which I used, along with the working parameter file are located here.

The result in the console looks like this…

Git Commnads

These are the steps to follow to update a repository in Github using a new branch. Go to the command line tool…

git clone [repository] 

…or if you already have it, refresh it with

git pull origin main 

Create a new branch to work in and check it out…

git checkout -b [branchname]

… make any changes then add those changes to the local repo, commit them and push them to Github.

git add -A
git commit -m "message"
git push -u origin [branchname]

Go to Github. Create a pull request and merge the branch with the main. Once complete you can delete the branch.

git checkout main
git pull origin main 

All changes should now be reflected in the local main copy.

Other useful commands:

git branch (lists the branches)
git status (shows if the branch is up to date and if there is something to commit)

Infrastructure as Code on GCP

Recently I was involved in a professional services engagement along side Google Professional Services.  In that engagement I got to see first hand how Google implements solutions on GCP, including the deployment of a high-performance compute platform proof of concept.  One of the most interesting aspects of that engagement was how the Google team implemented the entire solution using the Infrastructure as Code IaC) paradigm.  At no point in the development of the POC did the team configure something directly in the console.  This allowed them to build and tear-down the environment as needed, and once complete, they could turn over a running POC to the customer for further development and implementation. So taking direction from how Google does things, I decided to do the same for the Ansible host configuration in the previous post.

My goal was to automate the implementation of the Ansible host using GCP Deployment manager so that in the future when I want to run Ansible tests, I can deploy the environment within 10 minutes and remove it instantly when I am done.  To keep the entire environment ephemeral, all of the configuration was put into GitHub.  Future Ansible playbooks will also be placed in GitHub so that all I need to do is spin up the environment, clone the latest playbook I am working on and continue where I left off.

You can see the full configuration on GitHub here:

Ansible Core on GCP with Deployment Manager

In building the configuration I relied on the code that the Google PS team used as an example along with other examples from the Google documentation and from StackOverflow.  Some of the python scripting is my own since it is fairly basic and unique to this project.