2022-04-07

Azure Functions Provider Error

I started up a previously working Azure functions project today that I hadn’t touched in a week. It failed to start with an error like this

A host error has occurred during startup operation 'b59ba8b8-f264-4274-a9eb-e17ba0e02ed8'.
api: Could not load file or assembly 'Microsoft.Extensions.Options, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.
Value cannot be null. (Parameter 'provider')

This is the sort of error that terrifies me. Something is wrong but who knows what. No changes in git and an infinity of generic errors on google for Could not load file or assembly. Eventually after some digging it seems like I might be suffering from some corrupted tooling (some hints about that here: https://github.com/Azure/azure-functions-core-tools/issues/2232). I was able to fix mine by downloading the latest version of the tooling from https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local?tabs=v4%2Cwindows%2Ccsharp%2Cportal%2Cbash

2022-04-07

Which SQL Hosting Option is Right for Me?

There are a bunch of different ways to host SQL Server workloads on Azure. Answering some questions about how you use SQL server can help guide us to picking the right option for you.

The 3 options for hosting we’re considering are

  1. SQL Azure - https://azure.microsoft.com/en-us/products/azure-sql/database/#overview
  2. Azure SQL Managed Instance - https://azure.microsoft.com/en-us/products/azure-sql/managed-instance/
  3. SQL Server on VM - https://azure.microsoft.com/en-us/services/virtual-machines/sql-server/#overview

I’ve listed these in my order of preference. I’d rather push people to a more managed solution than a less managed one. There is a huge shortage of SQL server skills out there so if you can take a more managed approach then you’re less likely to run into problems that require you finding an SQL expert. I frequently say to companies that they’re not in the business of managing SQL server but in the business of building whatever widgets they build. Unless there is a real need don’t waste company resources building custom solutions when you can buy a 90% solution off the shelf.

When I talk with companies about migrating their existing workloads to the cloud from on premise SQL servers I find myself asking these questions:

  1. Does your solution use cross database joins?
  2. Does your solution make use of the SQL Agent to run jobs?
  3. Does your solution use FILESTREAM to access files on disk?
  4. Does your solution require fine tuning of availability groups?
  5. Does your solution require SQL logins from CERTIFICATE, ASYMMETRIC KEY or SID?
  6. Do you need to make use of a compatibility level below 100?
  7. Do you need to make use of database mirroring?
  8. Does your solution need to start and stop job scheduling?
  9. Are you making use of SQL Server Reporting Services (SSRS)?
  10. Are you using xp_cmdshell anywhere in your application (https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/xp-cmdshell-transact-sql?view=sql-server-ver15)

If the answer to any of the first 3 questions is yes then they can’t easily use SQL Azure* and should set the baseline to a managed instance. If the answer to any of the rest of the questions is yes then they should set the baseline to a VM running a full on version of SQL Server. Only if the answer to all these questions is no is SQL Azure the best solution.

  • Cross database joins and SQL Agent can be replaced by Elastic Query and Elastic Jobs but neither one is an easy drop in replacement so I typically don’t bother directing people to them for time constrained migrations.
2022-04-04

Redis Cheat Sheet

Running in Docker

Quickly get started with

docker run --name somename -p 6379:6379 redis

Connection

The simplest connection string is to use localhost which just connects to the localhost on port 6379.

Querying

Redis is a really simple server to which you can just telnet (or use the redis-cli) to run commands.

List All Keys

This might not be a great idea against a prod server with lots of keys

keys *

Get key type

Redis supports a bunch of different data primatives like a simple key value, a list, a hash, a zset, … to find the type of a key use type

type HereForElizabethAnneSlovak
+zset

Set key value

set blah 7

This works for updates too

Get key value

get blah

Get everything in a zset

ZRANGE "id" 0 -1

Count everything in a zset

zcount HereForjohnrufuscolginjr. -inf +inf

Get the first thing in a zset

ZRANGE "id" 0 0

Get everything in a set

SMEMBERS HereFeedHashTags
2022-03-18

Fixing VS Code Rubocop Issues

I run this rubocop extension in my VS Code

rubocop extension

Recently the project I was on did a Ruby update and my rubocop stopped working with an error like this

Rubocop error

The issue here was that the rubocop in the project was newer than the globally installed rubocop so it was returning empty output. This extension doesn’t look like it uses rbenv properly so I needed to globally update rubocop which I did with

/usr/local/bin/rubocop -v  -> 1.22.3
sudo gem install rubocop
/usr/local/bin/rubocop -v  -> 1.26

I still had some errors about missing rules and needed to also do

sudo gem install rubocop-rake
sudo gem install rubocop-rails
sudo gem install rubocop-performance

Ideally I’d like this extension to use the rbenv version of ruby but this gets me sorted for now.

2022-03-16

Unsupported Architecture for fsevents with Oryx

I updated the version of the lock file on a project the other day in the hopes it might restore a little bit more quickly. However for some steps in my build an older version of NPM was being used. This older version didn’t have support for the new lock file version and while it is supposed to be compatible it seemed like optional dependencies like fsevents were causing a legit issue

npm WARN read-shrinkwrap This version of npm is compatible with lockfileVersion@1, but package-lock.json was generated for lockfileVersion@2. I'll try to do my best with it!
npm ERR! code EBADPLATFORM
npm ERR! notsup Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm ERR! notsup Valid OS:    darwin
npm ERR! notsup Valid Arch:  any
npm ERR! notsup Actual OS:   linux
npm ERR! notsup Actual Arch: x64

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2022-03-09T13_58_42_006Z-debug.log

In theory these fsevent things should be warnings because they are optional dependencies. Updating the version of node used by Oryx, the build engine for Azure Static Web Apps, listens to the version of node defined in package.config. Adding this section to the package.config fixed everything

"engines": {
    "node": ">=16.0",
    "npm": ">=8.0"
  },
2022-02-20

Exclude node_modules from Backblaze Backups on Windows

There are some articles out there about how to exclude node_modules from Backblaze backups on OSX but I couldn’t find anything about windows.

What you want to do is open up C:\ProgramData\Backblaze\bzdata\bzexcluderules_editable.xml and add a new rule.

<excludefname_rule plat="win" osVers="*"  ruleIsOptional="t" skipFirstCharThenStartsWith="*" contains_1="node_modules" contains_2="*" doesNotContain="*" endsWith="*" hasFileExtension="*" />

If you want to exclude .git folders too (they can also contain a lot of small files that are slow to backup) also add

<excludefname_rule plat="win" osVers="*"  ruleIsOptional="t" skipFirstCharThenStartsWith="*" contains_1=".git" contains_2="*" doesNotContain="*" endsWith="*" hasFileExtension="*" />
2022-02-18

Parsing Vue Router Path Parameters

In the vue router you can set up path parameters that are bound into the rendered component. For instance you might have a route like this:

{
    path: '/reports/:reportId/:reportName/:favorite',
    name: 'Reports',
    component: ReportView,
    props: true
}

This will bind the parameters reportId, reportName and favorite on the component. However when you drop into that component and look at the values passed in you will see that they are strings. Of course that makes sense, the router doesn’t really know if the things you pass in are strings or something else. Consider the route /reports/17/awesome report/false. Here reportId and favorite are going to be strings.

You can work around that by giving props in the router a function rather than just a boolean.

{
    path: '/reports/:reportId/:reportName/:favorite',
    name: 'Reports',
    component: ReportView,
    props: (route) => ({
      ...route.params,
      reportId: parseInt(route.params.reportId),
      favorite: route.params.favorite === 'true',
    })
  }
2022-02-16

Installing the AzFilesHybrid PowerShell Module

If you don’t do a lot of powershell then the instructions on how to install the AzFilesHybrid module can be lacking. Here is how to do it

  1. Download the module from https://github.com/Azure-Samples/azure-files-samples/releases
  2. Unzip the file downloaded in step 1
  3. Go into the folder and run the copy command
./CopyToPSPath.ps1
  1. Install the module with
    Install-Module -Name AzFilesHybrid -Force
    

With this module installed you can then run things like Join-AzStorageAccount to get a fileshare joined to the domain

Join-AzStorageAccount -ResourceGroupName "rg-azfileshare" -StorageAccountName "sa-azfileshare" -DomainName "somedomain.com" -DomainUserName "jane" -DomainUserPassword "password"
2022-01-27

Purge CDN in DevOps

In order to purge a cache in the build pipeline you can use some random task that some dude wrote or you can just use the Azure CLI.

Here is an example of what it would look like to purge the entire CDN top to bottom

- task: AzureCLI@2
  displayName: 'Invalidate CDN Cache'
  inputs:
    azureSubscription: 'Azure'
    scriptType: 'batch'
    scriptLocation: 'inlineScript'
    inlineScript: 'az cdn endpoint purge --content-paths "/*"  -n devascacdnendpoint -g devasca-rg --no-wait --profile-name devascacdn'