How Do You Troubleshoot This Message “ImportError: No module named ‘google.cloud’?

Problem scenario
You run a Python program or from the Python command prompt you receive this message:

Traceback (most recent call last):
  File "main.py", line 21, in <module>
    from google.cloud import pubsub_v1
 ImportError: No module named 'google.cloud'
...

ModuleNotFoundError: No module named 'google'

What should you do to eliminate this problem?

Possible Solution #1
Try to run the program as sudo:

sudo python nameOfProg.py

Possible Solution #2
Try this with or without sudo (depending on whether or not you are using "sudo" to run the Python program):

sudo pip install google-cloud-bigquery

# You may or may not want to omit the "sudo" in the above command.

Possible Solution #3
Prerequisite

This assumes that pip has been installed.  If you need assistance see this posting.

sudo pip uninstall google-cloud-bigquery
sudo pip install google-cloud-bigquery

How Do You Troubleshoot Azure Template Files?

Problem scenario
You are having problems with your ARM templates (the .json files).  You want to learn more techniques at troubleshoot ARM templates. What should you do?

Possible Solution #1   Follow these directions on Microsoft's website.
(You will need to download a .psm1 file and use the import-module command in PowerShell.)

Possible Solution #2
Clone this Git repo and use it to validate your ARM templates:  https://github.com/Azure/azure-arm-validator

Possible Solution #3
Substitute any very sensitive data from the JSON with dummy (fake or random) data.  (Although you can probably trust jsonlint.com.)  Copy what remains and validate the JSON itself with this site.

Possible Solution #4
Try this part of Azure: https://resources.azure.com/

Possible Solution #5
Are you using the latest version of the Azure CLI?  You may want to upgrade it.

Possible Solution #6
This page on Microsoft's website has a list of common errors and information to help you fix the problem.

Possible Solution #7
To learn about the formatting fundamentals you can read this Microsoft web page.

How Do You Troubleshoot the kubectl Error “Access denied status code: 403”

Problem scenario
You run a kubectl command but you get this error:

"could not get token: AccessDenied: Access denied
        status code: 403, request id:
Unable to connect to the server: getting credentials: exec: exit status 1"

What should you do?

Solution
The root cause is likely that your .kube directory has an incorrect configuration file. 

Possible Solution #1
If you are not using Amazon EKS, see this posting.

Possible Solution #2
Alternatively you may want to run these commands to see what you get:

kubectl config view
aws-iam-authenticator token -i foobar # but replace "foobar" with the name of your cluster
aws sts get-caller-identity 

You may want to back up your config-foobar file in your .kube directory.   This way you can experiment with different syntax and values.  You may want to read this external page.

Possible Solution #3
If you are using Amazon EKS (a Kubernetes PaaS), run this command to generate the correct configuration file (replace "contint" with the name of the Kubernetes cluster):
aws eks update-kubeconfig --name contint

How Do You Create the PowerShell Script, the Template.json and the Parameters.json Necessary to Utilize ARM?

Problem scenario
To use ARM templates you know know you should have three text files: 1) a PowerShell script 2) a template.json file and 3) a parameters.json file.

How do you create these for a given resource (e.g., a storage account, VM, or Function App)?

Solution
1.  In the Azure Portal web UI, start the process of creating a resource.  Right before you click "Create", and there may be a few intermediate steps before you get there, click on the nearby hyperlink that says "Download a template for automation" (or for a Function App it may say "Automation options").

2.  You can click on "Template" near the top.  The JSON should be copied into a file called template.json.

3.  You can click on "Parameters" near the top.  The JSON should be copied into a file called parameters.json.

4.  Click on "PowerShell" near the top.  This is the PowerShell you should use.  You should modify two PowerShell stanzas to have explicit paths to the template.json and parameters.json files:

 $templateFilePath = "C:\path\to\template.json",
 $parametersFilePath = "C:\path\to\parameters.json"

5.  Now you can run the PowerShell script to use ARM templates for the resource you were about to create.  Infastructure as a code is great for simplifying your standards and keeping a record of the configuration deployed.

How Do You Use an ARM Template to Create an Azure Serverless Function App?

Problem scenario
As a proof-of-concept you want to use an ARM template to create an Azure Function that uses Azure storage.  You want the template to create the Azure storage account as it is a dependency of the Azure Serverless Function (also known as an App Service).  How do you do this?

Overview
This will create an Azure Function also known as an App Service.  The name of it will be entered interactively when the PowerShell script is run (when you are prompted for a "nameFromTemplate").

Prerequisites
1.  If you are using Windows 7, you have installed Azure PowerShell; if you need assistance, see this posting.  If you are using Windows 10, you have installed the modules for Azure and the storage resource; if you need assistance with this, see this posting.

2.  You know your subscription ID.  If you need assistance, see this posting.

Procedures
1.  Create a template.json file with the following content (and remember its location for step #3):

{
    "resources": [
        {
            "apiVersion": "2016-03-01",
            "name": "[parameters('name')]",
            "type": "Microsoft.Web/sites",
            "properties": {
                "name": "[parameters('name')]",
                "siteConfig": {
                    "appSettings": [
                        {
                            "name": "FUNCTIONS_WORKER_RUNTIME",
                            "value": "node"
                        },
                        {
                            "name": "AzureWebJobsStorage",
                            "value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), '2015-05-01-preview').key1)]"
                        },
                        {
                            "name": "FUNCTIONS_EXTENSION_VERSION",
                            "value": "~2"
                        },
                        {
                            "name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
                            "value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageName')), '2015-05-01-preview').key1)]"
                        },
                        {
                            "name": "WEBSITE_CONTENTSHARE",
                            "value": "[concat(toLower(parameters('name')), 'ba80')]"
                        },
                        {
                            "name": "WEBSITE_NODE_DEFAULT_VERSION",
                            "value": "8.11.1"
                        }
                    ]
                },
                "clientAffinityEnabled": false,
                "reserved": false
            },
            "dependsOn": [
                "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageName'))]"
            ],
            "location": "North Central US",
            "kind": "functionapp"
        },
        {
            "apiVersion": "2015-05-01-preview",
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[parameters('storageName')]",
            "location": "[parameters('location')]",
            "properties": {
                "accountType": "Standard_LRS"
            }
        }
    ],
    "parameters": {
        "name": {
            "type": "string"
        },
        "storageName": {
            "type": "string"
        },
        "location": {
            "type": "string"
        },
        "subscriptionId": {
            "type": "string"
        }
    },
    "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0"
}

2.  Create a parameters.json file, start with the "{" as the first line as a draft with the following content (and remember its location for step #3).  Replace 1234-abcd-5678-efgh with your subscription ID, replace zzzxxxyyywww with what you want your storage account name to be:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "name": {
            "value": "ne3c8dnmq40328"
        },
        "storageName": {
            "value": "zzzxxxyyywww"
        },
        "location": {
            "value": "North Central US"
        },
        "subscriptionId": {
            "value": "1234-abcd-5678-efgh"
        }
    }
}

3.  Use the following PowerShell script as a draft.  Change the "path\to" on the lines that assign where the respective template.json and parameters.json files should be (so they match where you created them in the above two steps).

<#
 .SYNOPSIS
    Deploys a template to Azure

 .DESCRIPTION
    Deploys an Azure Resource Manager template

 .PARAMETER subscriptionId
    The subscription id where the template will be deployed.

 .PARAMETER resourceGroupName
    The resource group where the template will be deployed. Can be the name of an existing or a new resource group.

 .PARAMETER resourceGroupLocation
    Optional, a resource group location. If specified, will try to create a new resource group in this location. If not specified, assumes resource group is existing.

 .PARAMETER deploymentName
    The deployment name.

 .PARAMETER templateFilePath
    Optional, path to the template file. Defaults to template.json.

 .PARAMETER parametersFilePath
    Optional, path to the parameters file. Defaults to parameters.json. If file is not found, will prompt for parameter values based on template.
#>

param(
 [Parameter(Mandatory=$True)]
 [string]
 $subscriptionId,

 [Parameter(Mandatory=$True)]
 [string]
 $resourceGroupName,

 [string]
 $resourceGroupLocation,

 [Parameter(Mandatory=$True)]
 [string]
 $deploymentName,

 [string]
 $templateFilePath = "C:\Users\jdoe\Documents\WindowsPowerShell\c\template.json",

 [string]
 $parametersFilePath = "C:\Users\jdoe\Documents\WindowsPowerShell\c\parameters.json"
)

<#
.SYNOPSIS
    Registers RPs
#>
Function RegisterRP {
    Param(
        [string]$ResourceProviderNamespace
    )

    Write-Host "Registering resource provider '$ResourceProviderNamespace'";
    Register-AzureRmResourceProvider -ProviderNamespace $ResourceProviderNamespace;
}

#******************************************************************************
# Script body
# Execution begins here
#******************************************************************************
$ErrorActionPreference = "Stop"

# sign in
Write-Host "Logging in...";
Login-AzureRmAccount;

# select subscription
Write-Host "Selecting subscription '$subscriptionId'";
Select-AzureRmSubscription -SubscriptionID $subscriptionId;

# Register RPs
$resourceProviders = @("microsoft.web","microsoft.storage");
if($resourceProviders.length) {
    Write-Host "Registering resource providers"
    foreach($resourceProvider in $resourceProviders) {
        RegisterRP($resourceProvider);
    }
}

#Create or check for existing resource group
$resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue
if(!$resourceGroup)
{
    Write-Host "Resource group '$resourceGroupName' does not exist. To create a new resource group, please enter a location.";
    if(!$resourceGroupLocation) {
        $resourceGroupLocation = Read-Host "resourceGroupLocation";
    }
    Write-Host "Creating resource group '$resourceGroupName' in location '$resourceGroupLocation'";
    New-AzureRmResourceGroup -Name $resourceGroupName -Location $resourceGroupLocation
}
else{
    Write-Host "Using existing resource group '$resourceGroupName'";
}

# Start the deployment
Write-Host "Starting deployment...";
if(Test-Path $parametersFilePath) {
    New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile $templateFilePath -TemplateParameterFile $parametersFilePath;
} else {
    New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile $templateFilePath;
}

echo "If you are prompted for a nameFromTemplate (regarding a new-azurermresourcegroupdeployment), enter any arbitrary string.*"
echo "* The string must not already exist in the Microsoft Azure websites; so it must be unique.  It will be the name of your App Service"
echo "The above two-line FYI is for when you first run this script.  When the script is otherwise complete, ignore it."

In the future we want to re-write these directions to use write-verbose instead of write-host. We want to warn people that write-verbose is recommended instead of write-host (according to this posting).

How Do You Create a PowerShell Script to Create a Storage Account in Azure?

Problem scenario
You want to use an ARM template via a PowerShell script to create a storage account in Azure.  How do you do this?

Solution
Prerequisites

1.  If you are using Windows 7, you have installed Azure PowerShell; if you need assistance with this, see this posting.  If you are using Windows 10, you have installed the modules for Azure and the storage resource; if you need assistance with this, see this posting.

2.  You know your subscription ID.  If you need assistance, see this posting.

Procedures
1.  Create a parameters.json file with the following content, but replace foobar with the name you want this storage account to have:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "location": {
            "value": "northcentralus"
        },
        "storageAccountName": {
            "value": "foobar"
        },
        "accountType": {
            "value": "Standard_RAGRS"
        },
        "kind": {
            "value": "StorageV2"
        },
        "accessTier": {
            "value": "Hot"
        },
        "supportsHttpsTrafficOnly": {
            "value": true
        }
    }
}

2.  Create a template.json file with the following content:

{
    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "location": {
            "type": "string"
        },
        "storageAccountName": {
            "type": "string"
        },
        "accountType": {
            "type": "string"
        },
        "kind": {
            "type": "string"
        },
        "accessTier": {
            "type": "string"
        },
        "supportsHttpsTrafficOnly": {
            "type": "bool"
        }
    },
    "variables": {},
    "resources": [
        {
            "name": "[parameters('storageAccountName')]",
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2018-07-01",
            "location": "[parameters('location')]",
            "properties": {
                "accessTier": "[parameters('accessTier')]",
                "supportsHttpsTrafficOnly": "[parameters('supportsHttpsTrafficOnly')]"
            },
            "dependsOn": [],
            "sku": {
                "name": "[parameters('accountType')]"
            },
            "kind": "[parameters('kind')]"
        }
    ],
    "outputs": {}
}

3.  Use this PowerShell script as a draft: first, modify "path\to" to be the paths of the respective files that are assigned.  Secondly change "foobargroup" to a Resource Group name; if you need assistance with finding an existing Resource Group, see this posting or this posting.

<#
 .SYNOPSIS
    Deploys a template to Azure

 .DESCRIPTION
    Deploys an Azure Resource Manager template

 .PARAMETER subscriptionId
    The subscription id where the template will be deployed.

 .PARAMETER resourceGroupName
    The resource group where the template will be deployed. Can be the name of an existing or a new resource group.

 .PARAMETER resourceGroupLocation
    Optional, a resource group location. If specified, will try to create a new resource group in this location. If not specified, assumes resource group is existing.

 .PARAMETER deploymentName
    The deployment name.

 .PARAMETER templateFilePath
    Optional, path to the template file. Defaults to template.json.

 .PARAMETER parametersFilePath
    Optional, path to the parameters file. Defaults to parameters.json. If file is not found, will prompt for parameter values based on template.
#>

param(
# [Parameter(Mandatory=$True)]
# [string]
# $subscriptionId,

# [Parameter(Mandatory=$True)]
# [string]
# $resourceGroupName = "foobargroup",

 [string]
 $resourceGroupLocation,

 [Parameter(Mandatory=$True)]
 [string]
 $deploymentName,

 [string]
 $templateFilePath = "C:\path\to\template.json",

 [string]
 $parametersFilePath = "C:\path\to\parameters.json"
)

<#
.SYNOPSIS
    Registers RPs
#>

Function RegisterRP {
    Param(
        [string]$ResourceProviderNamespace
    )

    Write-Host "Registering resource provider '$ResourceProviderNamespace'";
    Register-AzureRmResourceProvider -ProviderNamespace $ResourceProviderNamespace;
}

#******************************************************************************
# Script body
# Execution begins here
#******************************************************************************
$ErrorActionPreference = "Stop"

# sign in
Write-Host "Logging in...";
Login-AzureRmAccount;

$subscriptions= Get-AzureRmSubscription
$subscriptionId = $subscriptions.Id

$resourceGroupName = "contintgroup"

# select subscription
#Write-Host "Selecting subscription '$subscriptionId'";
echo "This PowerShell Program assumes you have only one subscription ID.  If you have more than one, you'll need to re-write it around this statement"
echo "and in the parameters section."

Select-AzureRmSubscription -SubscriptionID $subscriptionId;

# Register RPs
$resourceProviders = @("microsoft.storage");
if($resourceProviders.length) {
    Write-Host "Registering resource providers"
    foreach($resourceProvider in $resourceProviders) {
        RegisterRP($resourceProvider);
    }
}

#Create or check for existing resource group
$resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue
if(!$resourceGroup)
{
    Write-Host "Resource group '$resourceGroupName' does not exist. To create a new resource group, please enter a location.";
    if(!$resourceGroupLocation) {
        $resourceGroupLocation = Read-Host "resourceGroupLocation";
    }
    Write-Host "Creating resource group '$resourceGroupName' in location '$resourceGroupLocation'";
    New-AzureRmResourceGroup -Name $resourceGroupName -Location $resourceGroupLocation
}
else{
    Write-Host "Using existing resource group '$resourceGroupName'";
}

# Start the deployment
Write-Host "Starting deployment...";
if(Test-Path $parametersFilePath) {
    New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile $templateFilePath -TemplateParameterFile $parametersFilePath;
} else {
    New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile $templateFilePath;
}
echo "***********************************************"
echo "The deploymentName can be any arbitrary string.  (this statement is for when the program initially runs and prompts user for a deploymentname; ignore it later)"

In the future we want to re-write these directions to use write-verbose instead of write-host. We want to warn people that write-verbose is recommended instead of write-host (according to this posting).

How Do You Install Azure PowerShell on Windows 10?

Problem scenario
You want to run ARM templates to declaratively create resources such as servers, databases, and subnets in Azure.  You need the PowerShell module for Azure to be installed for certain "reserved" words to work.  How do you install the Azure PowerShell?

Solution
1.  Open PowerShell as administrator.  (PowerShellGet is built into Windows 10 by default.  It may appear uninstalled, but it is natively part of the OS.)
2.  Run this command:  Install-Module Azure
3.  You can choose "Y" to the prompt.*
4.  Run this command:  Install-Module AzureRM.storage
5.  You can choose "Y" to the prompt.*
6.  Run this command: Install-Module AzureRM.resources
7.  You can choose "Y" to the prompt.*
8.  Run this command:  Install-Module AzureRM.Compute
9.  You can choose "Y" to the prompt.*
10.  Run this command:  Install-Module AzureRM.sql
11.  You can choose "Y" to the prompt.*
12.  Run this command:  Install-Module AzureRM.network
13.  You can choose "Y" to the prompt.*

*  If you have been running anti-malware applications on your desktop, and your laptop is reasonably secure, you can choose the "Y" option to the prompt about an untrusted repository and proceeding to install the modules from "PSGallery".

How Do You Create the Pound Sterling Symbol (aka the GBP Symbol) £ when You Are Using a U.S. Keyboard?

Problem scenario
You type emails or type text in Notepad or Wordpad (e.g., in Windows).  Sometimes you use a web browser in Windows.  You want to create this symbol £.  What do you do?

Solution
Hold the "Alt" key and type "156" (with no quotes).

How Do You Troubleshoot the SonarScanner Error “java.lang.IllegalStateException: Failed to create lock in /opt/app/sonar-scanner/conf/…sonar_locak…DirectoryLock…”?

Problem scenario
You try to run sonarscanner from a command prompt.  But you get this message:

"java.lang.IllegalStateException: Failed to create lock in /opt/app/sonar-scanner/conf/...sonar_locak...DirectoryLock..."

What should you do?

Solution
Become a different user to run the sonarscanner command or use "sudo " before your command.

How Do You Find the Data Type of a Variable in an Ansible Playbook?

Problem scenario
Through the register keyword you assign a variable.  You want to know what variable type it is (e.g., a string, a dictionary or a JSON).  You know the data type is not a Boolean.  What do you do?

Solution
If you have a variable (e.g., foobar) and you want to know what data type it is, do this:

debug:
  msg:
when:  foobar.stdout == ""

The playbook will tell you if foobar is a dictionary with an error.  If there is no error, it is a string.  If foobar is a JSON you will see a message when you run the playbook about "ansible.utils.unsafe.proxy.AnsibleUnsafeText"

(The above will not help you if it is a Boolean.  You should compare it to "TRUE" or "FALSE" instead of "" if you think the value may be a Boolean.)