A great mentor of mine once said there are two things that are the true bottlenecks for developer productivity. And my experience constantly confirms these two are true.
The first is Chasing Down Information, and by that I mean the process of finding requirements and information on the work they want to do. We’re not going to cover that one in this post as there are whole books on this topic.
But for this one, the number one killer of time is the developer loop. Now what I mean by that is the time it takes a developer to run through a loop testing their changes and seeing the results of those changes. xkcd said it best….

If you are like me, you probably have a notepad off to one side where you write out commands you use to perform common operations, things like deleting a resource group, creating pre-reqs, etc. But the problem is that while I have those tools, anyone else cloning the repo doesn’t have these. Or just as likely, I come back to this repo and now can’t find those notes again.
Now the good news is if you are using VSCode, it’s got a helpful tool called “Tasks.”
This is where VSCode tasks can be really helpful. The goal being to make it easy for people to iterate quickly on the repo to test and make adjustments.
Sample for Building Tasks:
The following is an example of a task I put on a recent repo. A common situation when you’re doing infrastructure work is to need to clean up an environment. So for my repo, I build the following called “delete-rg.sh”:
# !/bin/bash
# This script deletes a resource group in Azure.
# It requires the Azure CLI to be installed and configured.
source "$(dirname "$0")/common.sh"
check_jq_installed
if [[ "$#" -eq 0 ]]; then
load_parameters
else
parse_passed_parameters "$@"
fi
# Delete the resource group
echo "Deleting infra resource group..."
az group delete --name "$PROJECT_PREFIX-$ENV_PREFIX-aro" --yes
echo "Infra resource group '$PROJECT_PREFIX-$ENV_PREFIX-aro' deleted successfully."
echo "Deleting ARO resource group..."
az group delete --name "$PROJECT_PREFIX-$ENV_PREFIX-aro-infra" --yes
echo "ARO resource group '$PROJECT_PREFIX-$ENV_PREFIX-aro-infra' deleted successfully."
echo "Deleting shared resource group..."
az group delete --name "$PROJECT_PREFIX-$ENV_PREFIX-shared" --yes
echo "Shared resource group '$PROJECT_PREFIX-$ENV_PREFIX-shared' deleted successfully."
sleep 5s
echo "Deleting resource group: $NETWORK_RESOURCE_GROUP_NAME"
az group delete --name $NETWORK_RESOURCE_GROUP_NAME --yes
echo "Resource group $NETWORK_RESOURCE_GROUP_NAME deleted successfully."
Now this makes use of a few functiions in a file called “common.sh” which is the following:
CONFIG_JSON="./envs/dev.json"
echo "Sourcing Functions..."
# Function to check if jq is installed
check_jq_installed() {
echo "Checking if jq is installed..."
if ! command -v jq &> /dev/null; then
echo "jq is not installed. Installing jq..."
if [[ $(uname -s) == "Linux" ]]; then
sudo apt-get update && sudo apt-get install -y jq
else
echo "Unsupported OS for automatic jq installation. Please install jq manually."
exit 1
fi
fi
}
# Function to load parameters from a JSON file
load_parameters() {
local env_file=${1:-"$CONFIG_JSON"} # Use "$CONFIG_JSON" if $1 is not provided
if [[ -f "$env_file" ]]; then
echo "Loading parameters from $env_file"
NETWORK_RESOURCE_GROUP_NAME=$(jq -r '.networkResourceGroupName' $CONFIG_JSON)
PROJECT_PREFIX=$(jq -r '.projectPrefix' $CONFIG_JSON)
ENV_PREFIX=$(jq -r '.envPrefix' $CONFIG_JSON)
VNET_NAME=$(jq -r '.vnetName' $CONFIG_JSON)
LOCATION=$(jq -r '.location' $CONFIG_JSON)
SUBNET_NAME=$(jq -r '.subnetName' $CONFIG_JSON)
DEFAULT_TAG_NAME=$(jq -r '.defaultTagName' $CONFIG_JSON)
DEFAULT_TAG_VALUE=$(jq -r '.defaultTagValue' $CONFIG_JSON)
SERVICE_PRINCIPAL_CLIENT_ID=$(jq -r '.servicePrincipalClientId' $CONFIG_JSON)
SERVICE_PRINCIPAL_CLIENT_SECRET=$(jq -r '.servicePrincipalClientSecret' $CONFIG_JSON)
SUBSCRIPTION_ID=$(jq -r '.subscriptionId' $CONFIG_JSON)
output_parameters
else
echo "Error: Configuration file $env_file not found."
exit 1
fi
}
output_parameters() {
echo "Loaded parameters:"
echo "--------------------------------"
echo "Resource Group Name: $NETWORK_RESOURCE_GROUP_NAME"
echo "Project Prefix: $PROJECT_PREFIX"
echo "Environment Prefix: $ENV_PREFIX"
echo "Virtual Network Name: $VNET_NAME"
echo "Location: $LOCATION"
echo "Default Tag Name: $DEFAULT_TAG_NAME"
echo "Default Tag Value: $DEFAULT_TAG_VALUE"
echo "Service Principal Client ID: $SERVICE_PRINCIPAL_CLIENT_ID"
echo "Subscription ID: $SUBSCRIPTION_ID"
echo "--------------------------------"
}
parse_passed_parameters() {
while [[ "$#" -gt 0 ]]; do
case $1 in
--resource-group-name) RESOURCE_GROUP_NAME="$2"; shift ;;
--project-prefix) PROJECT_PREFIX="$2"; shift ;;
--env-prefix) ENV_PREFIX="$2"; shift ;;
--vnet-name) VNET_NAME="$2"; shift ;;
--location) LOCATION="$2"; shift ;;
--default-tag-name) DEFAULT_TAG_NAME="$2"; shift ;;
--default-tag-value) DEFAULT_TAG_VALUE="$2"; shift ;;
*) echo "Unknown parameter passed: $1"; exit 1 ;;
esac
shift
done
output_parameters
}
Now the question becomes how do I wire this up to a task. The key for vscode is that all tasks need to be added to a file found at “.vscode/tasks.json”.
If you create this file, I can set the following to create my task:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Delete Resource Group",
"type": "shell",
"command": "./scripts/delete-rg.sh",
"args": [],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "shared",
"close": false
},
"problemMatcher": []
}
]
}
Well that’s it, and the tasks are officially configured.
Running Tasks:
Now, once that task is configured, to run this tasks, you can click “F1” or “Ctrl+Shift+P” or go to “Terminal” => “Run Task”.
And then select your task:

This will bring hope a new window which will run the task. If you flip this bit “close” then the task execution window will close when completed.
Links for more information:
The follow are some helpful links for more reading on this subject:
- Integrate with External Tools via Tasks: Great article on how these can be used to integrate with other tools using tasks.
- Deep Dive into VSCode Tasks: A great medium article I found on using tasks.
- Improve your daily productivity with Tasks: A great article on figuring out the common tasks you run and integrating them into VSCode.