Blog Post

Azure Infrastructure Blog
12 MIN READ

Harnessing Microsoft Dev Box and Azure Deployment Environments

Devi_Priya's avatar
Devi_Priya
Icon for Microsoft rankMicrosoft
Nov 11, 2024

Streamlining Deployment Environments on Azure

Deploying applications efficiently and effectively requires a well-organized setup of deployment environments. Whether it's for development, testing, or staging, having a systematic approach can streamline the entire process and enhance productivity. In this guide, we'll walk through the process of setting up deployment environments on Azure, from dev centers to configuring Dev Boxes, ensuring a smooth and structured workflow.

Dev Centers

  • Centralized Repository: Dev centers serve as centralized repositories for diverse development projects.
  • Uniform Configurations: Establish uniform configurations for projects, including catalogs housing application templates and specifications for available environment types accessible to development teams.
  • Management by Platform Engineers: Platform engineering teams oversee dev centers, facilitating integration of external catalogs, project initiation, and team access provisioning.
  • Infrastructure as Code (IaC): Manage infrastructure as code templates via catalogs, ensuring accessibility across projects.
  • Configuration of Environment Types: Configure environment types to define permissible environment configurations for development teams.

Azure Deployment Environments

  • Azure Deployment Environments are a game-changer for development teams, offering a streamlined way to set up application infrastructure.
  • Azure Deployment Environments consist of pre-defined infrastructure resources, neatly packaged into templates.
  • They allow developers to quickly deploy these templates in their Azure subscriptions, saving time and effort.
  • Developers can focus on coding without worrying about infrastructure setup.
  • Platform engineers ensure access control and governance, keeping things secure and compliant.

Usage scenarios - Common scenarios for Azure Deployment Environments.

 

 

Image sourced from link. For more detailed explanations, please refer to the provided link.

The sequence of actions required to deploy an Azure deployment environment involves the following steps:

Establishing a Dev Center
  1. Create a Dev Center: Assign a descriptive name and place it within the previously created resource group.
  2. Enable system-assigned identity for effective management of environment templates and permissions.
Configuring Key vault and Storing GitHub Token
  1. Generate Token on GitHub: Create a token with necessary scopes, refer this to create token
  2. Create Keyvault: Create a Keyvault in Azure Portal within the resource group.
  3. Configure Access Policies in Keyvault: Allow the Dev Center to read the stored token for seamless integration with repositories.
Adding Catalog to Dev Center
  1. Navigate to Dev Center, Access "Catalogs" blade to add a new catalog.
  2. Specify Details: Provide the Git clone URI and other required details.
  3. Synchronize Catalog Items: Synchronize items from the repository to make them readily available for deployment.
Configure Identity
  1. To allow the creation of environments, the dev center requires permissions on the subscription. Attach an identity to the dev center, and then assign the necessary permissions to that identity.
  2. Attach either a system-assigned managed identity or a user-assigned managed identity. 
Access:
Dev center identity be granted at least Contributor to create resources and User Access Administrator to be able to assign permissions between resources.
Setting Up Environment Types
  1. Categorize environments effectively (e.g., "Sandbox," "Dev," "Test," "Staging").
  2. Customize settings for each environment type according to specific requirements.
Creating an Azure Deployment Environments Project
  1. Within the Dev Center, create a project where environment types can be attached.
  2. Project is required to manage team level settings and access.
Create a project environment type
  1. Project environment types are a subset of the environment types configured for the dev center.
  2. They allow you to predefine the types of environments that specific development teams can create.
Developer Portal for Environment Creation
  1. Access Developer Portal: Sign in and utilize the portal to create new environments.
  2. Select Catalog Items: Choose from available catalog items.
  3. Monitor Progress: Monitor environment creation progress and manage environments as needed.

 

 Example shell Script to deploy ADE using CLI commands
This script is provided as an example for setting up Azure Dev Center projects and development environments.
Usage:
You are encouraged to review and modify the script based on your specific environment.
Prerequisites:
Before starting the Azure Dev Center deployment, ensure you have the following key resources:
1.Resource Group (RG)
2.Azure Dev Center
3.Catalog
4.A linked catalog and synced to your code repository

 

#!/bin/bash 

# Copyright (C) Microsoft Corporation. 

# Exit immediately if a command fails
set -e

# Fail if an unset variable is used
set -u

#declare command variables & functions
command=""
command_output=""
command_status=0

function clear_command_variables() {
    command=""
    command_output=""
    command_status=0
}

function execute_command_exit_on_failure() {
    local cmd=$1
    eval "$cmd"
    command_status=$?
    if [ $command_status -ne 0 ]; then
        echo "Error: Command failed with status $command_status"
        exit $command_status
    fi
}
#endregion declare command variables & functions

#region Declare Constants
DEV_CENTER_CATALOG_NAME="catalog name in dev center"
ENVIRONMENT_DEFINITION_NAME="defname" # Folder name where IaC template and environment file are hosted
ENVIRONMENT_TYPE="sandbox"
PROJECT_ADMIN_ID=$(az account get-access-token --query "accessToken" -o tsv | jq -R -r 'split(".") | .[1] | @base64d | fromjson | .oid')
echo "Object ID of the service principal or managed identity: $PROJECT_ADMIN_ID"
DEPLOYMENT_ENVIRONMENTS_USER="id of user"
PROJECT="name of the project"
description="This is my first project"
TARGET_SUBSCRIPTION_ID="id of subscription"
MANAGED_ID="Dev center's user managed identity"
RESOURCE_GROUP="RG name"
DEV_CENTER_NAME="Dev center name"
ENVIRONMENT_NAME="name of an environment"
KEY_VAULT_NAME="Keyvault name"
#endregion Declare Constants

#region Install Azure Dev Center extension
echo "Installing the Azure Dev Center extension"
clear_command_variables
command="az extension add --name devcenter --upgrade"
execute_command_exit_on_failure "$command"
echo "Extension installation complete!"
#endregion Install Azure Dev Center extension

#region Get Role Id for the Subscription Owner
echo "Getting Role Id for the Subscription Owner"
clear_command_variables
command="az role definition list -n \"Owner\" --scope \"/subscriptions/$TARGET_SUBSCRIPTION_ID\" --query [].name -o tsv"
owner_role_id=""
execute_command_exit_on_failure "$command"
owner_role_id=$(eval "$command")
echo "Got Subscription Owner Role ID: $owner_role_id"
#endregion Get Role Id for the Subscription Owner

#region Get Dev Center ID
echo "Getting Azure Dev Center Resource ID"
clear_command_variables
command="az devcenter admin devcenter show -n \"$DEV_CENTER_NAME\" --query id -o tsv"
dev_center_id=""
execute_command_exit_on_failure "$command"
dev_center_id=$(eval "$command")
echo "Got Azure Dev Center Resource ID: $dev_center_id"
#endregion Get Dev Center ID

#region Get Managed Identity ID, Object ID
echo "Getting Managed Identity Resource ID"
clear_command_variables
command="az identity show --name \"$MANAGED_ID\" --resource-group \"$RESOURCE_GROUP\" --query id -o tsv"
managed_identity_id=""
execute_command_exit_on_failure "$command"
managed_identity_id=$(eval "$command")
echo "Got Managed Identity Resource ID: $managed_identity_id"

echo "Getting Managed Identity Object ID"
clear_command_variables
command="az resource show --ids \"$managed_identity_id\" --query properties.principalId -o tsv"
managed_identity_object_id=""
execute_command_exit_on_failure "$command"
managed_identity_object_id=$(eval "$command")
echo "Got Managed Identity Object ID: $managed_identity_object_id"
#endregion Get Managed Identity ID, Object ID

#region Create Project in Dev Center
echo "Creating Project in Azure Dev Center"
clear_command_variables
command="az devcenter admin project create -n \"$PROJECT\" --description \"$description\" --dev-center-id \"$dev_center_id\""
execute_command_exit_on_failure "$command"
echo "Project created successfully!"
#endregion Create Project in Dev Center

#region Assign Roles to Managed Identity
echo "Assigning Contributor role to the Managed Identity Object ID on the subscription"
clear_command_variables
command="az role assignment create --role \"Contributor\" --assignee-object-id \"$managed_identity_object_id\" --scope \"/subscriptions/$TARGET_SUBSCRIPTION_ID\""
execute_command_exit_on_failure "$command"
echo "Assigned Contributor role to the Managed Identity Object ID on the subscription"

echo "Assigning User Access Administrator role to the Managed Identity Object ID on the subscription"
clear_command_variables
command="az role assignment create --role \"User Access Administrator\" --assignee-object-id \"$managed_identity_object_id\" --scope \"/subscriptions/$TARGET_SUBSCRIPTION_ID\""
execute_command_exit_on_failure "$command"
echo "Assigned User Access Administrator role to the Managed Identity Object ID on the subscription"
#endregion Assign Roles to Managed Identity

#region Create Environment Type for the Project
echo "Creating Project Environment Type"
clear_command_variables
command="az devcenter admin project-environment-type create -n \"$ENVIRONMENT_TYPE\" --project \"$PROJECT\" --identity-type \"SystemAssigned\" --roles \"{\\\"$owner_role_id\\\":{}}\" --deployment-target-id \"/subscriptions/$TARGET_SUBSCRIPTION_ID\" --status Enabled --query 'identity.principalId' --output tsv"
project_environment_type_object_id=""
execute_command_exit_on_failure "$command"
project_environment_type_object_id=$(eval "$command")
echo "Created Project Environment Type with Object ID: $project_environment_type_object_id"

echo "Assigning Contributor role to the Project Environment Type Object ID on the subscription"
clear_command_variables
command="az role assignment create --role \"Contributor\" --assignee-object-id $project_environment_type_object_id --scope \"/subscriptions/$TARGET_SUBSCRIPTION_ID\""
execute_command_exit_on_failure "$command"
echo "Assigned Contributor role to the Project Environment Type Object ID"
#endregion Create Environment Type for the Project

#region Assign Key Vault Secrets Officer Role
echo "Assigning Key Vault Secrets Officer role to the Project Environment Type Object ID on the keyvault"
clear_command_variables
command="az role assignment create --role \"Key Vault Secrets Officer\" --assignee-object-id $project_environment_type_object_id --scope \"/subscriptions/$TARGET_SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.KeyVault/vaults/$KEY_VAULT_NAME\""
execute_command_exit_on_failure "$command"
echo "Assigned Key Vault Secrets Officer role to the Project Environment Type Object ID on the keyvault"
#endregion Assign Key Vault Secrets Officer Role

#region Assign Dev Center Project Admin and Deployment Environments User Roles
echo "Assigning Dev Center Project Admin role to $PROJECT_ADMIN_ID"
clear_command_variables
command="az role assignment create --assignee \"$PROJECT_ADMIN_ID\" --role \"DevCenter Project Admin\" --scope \"/subscriptions/$TARGET_SUBSCRIPTION_ID\""
execute_command_exit_on_failure "$command"
echo "Assigned Dev Center Project Admin role to $PROJECT_ADMIN_ID"

echo "Assigning Deployment Environments User role to $DEPLOYMENT_ENVIRONMENTS_USER"
clear_command_variables
command="az role assignment create --assignee \"$DEPLOYMENT_ENVIRONMENTS_USER\" --role \"Deployment Environments User\" --scope \"/subscriptions/$TARGET_SUBSCRIPTION_ID\""
execute_command_exit_on_failure "$command"
echo "Assigned Deployment Environments User role to $DEPLOYMENT_ENVIRONMENTS_USER"
#endregion Assign Dev Center Project Admin and Deployment Environments User Roles

#region Create Dev Environment
echo "Creating Dev Environment"
clear_command_variables
command="az devcenter dev environment create --environment-name \"$ENVIRONMENT_NAME\" --environment-type \"$ENVIRONMENT_TYPE\" --dev-center-name \"$DEV_CENTER_NAME\" --project-name \"$PROJECT\" --catalog-name \"$DEV_CENTER_CATALOG_NAME\" --environment-definition-name \"$ENVIRONMENT_DEFINITION_NAME\""
execute_command_exit_on_failure "$command"
echo "Created Dev Environment: $ENVIRONMENT_NAME"
#endregion Create Dev Environment

Dev Box

  • Self-Service Cloud Workstations: Microsoft Dev Box provides developers with easy access to cloud-based workstations called dev boxes.

  • Custom Configuration: Dev boxes can be configured with project-specific tools, source code, and prebuilt binaries, enabling developers to swiftly commence work.

  • Image Options: Developers have the choice to create a customized image or utilize preconfigured images from Azure Marketplace, which may include Visual Studio pre-installed.

  • Versatile Usage: Developers can incorporate multiple dev boxes into their daily workflows, accessible through remote desktop clients or web browsers.

  • Organizational Roles: The Dev Box service is designed to cater to three key organizational roles: platform engineers, development team leads, and developers, facilitating seamless collaboration and efficient workflows.

Usage Scenarios - Common scenarios for Microsoft dev box.

Pre-requisites:

  1. Dev Center Creation: Ensure that a dev center has been created beforehand to serve as the central hub for project management and environment setup.

  2. Project Setup: Make sure that a project has been created under the dev center, as dev boxes will be associated with specific projects.

  3. Developer Portal Access: Users intending to create dev boxes must have access to the developer portal. Grant access by assigning the user the "DevCenter Dev Box User" role under the project.

  4. Network Configuration: Prior to creating dev boxes, ensure that a virtual network (VNet) and subnet have been set up to establish network connectivity for the dev boxes.

  5. Custom Image Preparation: If deploying a custom image, ensure that the image is prepared and available in the compute gallery. Link the custom image with the dev center to facilitate deployment.

Note: Microsoft Dev Box supports work and school accounts only. Guest accounts and personal accounts are not supported.

 

 

Image sourced from link. For more detailed explanations, please refer to the provided link.

Supercharge Your Platform Engineering with Microsoft Dev Box
Creating Dev Box Definition

1. Navigate to Dev Center Resources: Create a new Dev Box definition.
2. Provide Necessary Details: Name, image, compute, storage, etc., to tailor the Dev Box.

Dev Box Pool and Network Connection

1. Dev box pools define the location of dev boxes via the specified network connection.

2. You can deploy dev boxes either:

    • To a Microsoft-hosted network.
    • To a network that you manage.

3. Create Dev Box Pool: Specify details such as pool name, Dev Box definition, network connection, creator privileges, auto-stop settings, etc.
4. Standardized Access: Ensure developers have access to standardized Dev Boxes for their development needs.

Testing the Environment and Cleanup

1. Test Environment Setup: Utilize the developer portal to test thoroughly.
2. Verify Functionality: Create a Dev Box and verify functionality.
3. Minimize Costs: Delete unnecessary environments or Dev Boxes to minimize costs.

 

 Example shell Script to deploy resources before creating dev box in dev box portal
This script is provided as an example for setting up Dev Box definition and Dev center pool.
You are encouraged to review and modify the script based on your specific environment.
Prerequisites:
Before starting the Dev box, ensure you have the following key resources:
1.Resource Group
2.Azure Dev Center
3.Dev Center project
4.Vnet and subnet
 
#!/bin/bash
# Copyright (C) Microsoft Corporation.

# Exit immediately if a command fails
set -e

# Fail if an unset variable is used
set -u

echo "Setting the variables"

#region Set the variables
RESOURCE_GROUP=""
DEV_CENTER_NAME=""
PROJECT=""
DEVBOX_DEF_NAME=""
VNET_NAME=""
DEV_CENTER_NETWORK_CONNECTION_NAME=""
NETWORK_CONNECTION_RG_NAME=""
DEV_CENTER_POOL_NAME=""
Subnet=""
attached_network_name=""
compute_gallery_name=""
osstoragetype=""
devbox_image_name=""
size=""
tier=""
compute=""
family=""
capacity=""
target_subscription_id=""
azure_region=""
#endregion Set the variables

#region Install Azure Dev Center extension
echo "Installing the Azure Dev Center extension"

commandInstallDevCenterExt="az extension add --name devcenter --upgrade"
commandInstallDevCenterExt_output=""
commandInstallDevCenterExt_status=0
execute_command_with_status_code "$commandInstallDevCenterExt" commandInstallDevCenterExt_output commandInstallDevCenterExt_status

if [ $commandInstallDevCenterExt_status -ne 0 ]; then
  echo "Failed to install the Azure Dev Center extension."
  echo_output_dictionary_to_output_file
  exit 0
fi

echo "Extension installation complete!"
#endregion Install Azure Dev Center extension

#region Create Dev Box definition
echo "Creating Dev Box definition"

commandCreateDevboxDef="az devcenter admin devbox-definition create \ 
  --dev-center $DEV_CENTER_NAME \ 
  --devbox-definition-name $DEVBOX_DEF_NAME \ 
  --image-reference \"{\\\"id\\\": \\\"/subscriptions/$target_subscription_id/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.DevCenter/devcenters/$DEV_CENTER_NAME/galleries/$compute_gallery_name/images/$devbox_image_name\\\"}\" \ 
  --os-storage-type $osstoragetype \ 
  --resource-group $RESOURCE_GROUP \ 
  --sku \"{\\\"capacity\\\": $capacity, \\\"family\\\": \\\"$family\\\", \\\"name\\\": \\\"$compute\\\", \\\"size\\\": \\\"$size\\\", \\\"tier\\\": \\\"$tier\\\"}\" \ 
  --hibernate-support \"Disabled\" \ 
  --location \"$azure_region\""

commandCreateDevboxDef_output=""
commandCreateDevboxDef_status=0
execute_command_with_status_code "$commandCreateDevboxDef" commandCreateDevboxDef_output commandCreateDevboxDef_status

if [ $commandCreateDevboxDef_status -ne 0 ]; then
  echo "Failed to create Dev Box definition."
  echo_output_dictionary_to_output_file
  exit 0
fi

echo "Dev Box definition created successfully."
#endregion Create Dev Box definition

#region Get subnet ID
echo "Getting subnet ID"

commandGetSubnetId="az network vnet subnet show --name $Subnet --vnet-name $VNET_NAME --resource-group $RESOURCE_GROUP --query id --output tsv"
commandGetSubnetId_output=""
commandGetSubnetId_status=0
execute_command_with_status_code "$commandGetSubnetId" commandGetSubnetId_output commandGetSubnetId_status

if [ $commandGetSubnetId_status -ne 0 ]; then
  echo "Failed to get subnet ID."
  echo_output_dictionary_to_output_file
  exit 0
fi

echo "Got subnet ID: $commandGetSubnetId_output"
#endregion Get subnet ID

#region Create Azure Dev Center Network Connection
echo "Creating Azure Dev Center Network Connection"

commandCreateNetworkConnection="az devcenter admin network-connection create \ 
  --domain-join-type \"AzureADJoin\" \ 
  --name \"$DEV_CENTER_NETWORK_CONNECTION_NAME\" \ 
  --resource-group $RESOURCE_GROUP \ 
  --subnet-id \"$commandGetSubnetId_output\" \ 
  --location \"$azure_region\" \ 
  --networking-resource-group-name \"$NETWORK_CONNECTION_RG_NAME\""

commandCreateNetworkConnection_output=""
commandCreateNetworkConnection_status=0
execute_command_with_status_code "$commandCreateNetworkConnection" commandCreateNetworkConnection_output commandCreateNetworkConnection_status

if [ $commandCreateNetworkConnection_status -ne 0 ]; then
  echo "Failed to create Azure Dev Center Network Connection."
  echo_output_dictionary_to_output_file
  exit 0
fi

echo "Azure Dev Center Network Connection created successfully."
#endregion Create Azure Dev Center Network Connection

#region Get Network Connection ID
echo "Getting Network Connection ID"

commandGetNetworkConnectionId="az devcenter admin network-connection show --name \"$DEV_CENTER_NETWORK_CONNECTION_NAME\" --resource-group $RESOURCE_GROUP --query id --output tsv"
commandGetNetworkConnectionId_output=""
commandGetNetworkConnectionId_status=0
if [ $commandGetNetworkConnectionId_status -ne 0 ]; then
  echo "Failed to get Network Connection ID."
  echo_output_dictionary_to_output_file
  exit 0
fi

echo "Got Network Connection ID: $commandGetNetworkConnectionId_output"
#endregion Get Network Connection ID

#region Create Dev Center Attached Network
echo "Creating Azure Dev Center attached network"

commandCreateAttachedNetwork="az devcenter admin attached-network create \ 
  --attached-network-connection-name $attached_network_name \ 
  --network-connection-id \"/subscriptions/$target_subscription_id/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.DevCenter/networkConnections/$DEV_CENTER_NETWORK_CONNECTION_NAME\" \ 
  --resource-group $RESOURCE_GROUP \ 
  --dev-center $DEV_CENTER_NAME"

commandCreateAttachedNetwork_output=""
commandCreateAttachedNetwork_status=0
execute_command_with_status_code "$commandCreateAttachedNetwork" commandCreateAttachedNetwork_output commandCreateAttachedNetwork_status

if [ $commandCreateAttachedNetwork_status -ne 0 ]; then
  echo "Failed to create Azure Dev Center attached network."
  echo_output_dictionary_to_output_file
  exit 0
fi

echo "Created Azure Dev Center attached network successfully."
#endregion Create Dev Center Attached Network

#region Create Dev Center Pool
echo "Creating Azure Dev Center pool"

commandCreatePool="az devcenter admin pool create \ 
  --devbox-definition-name \"$DEVBOX_DEF_NAME\" \ 
  --local-administrator \"Enabled\" \ 
  --name \"$DEV_CENTER_POOL_NAME\" \ 
  --project \"$PROJECT\" \ 
  --resource-group \"$RESOURCE_GROUP\" \ 
  --location \"$azure_region\" \ 
  --network-connection-name \"$attached_network_name\" \ 
  --single-sign-on-status \"Enabled\""

commandCreatePool_output=""
commandCreatePool_status=0
execute_command_with_status_code "$commandCreatePool" commandCreatePool_output commandCreatePool_status

if [ $commandCreatePool_status -ne 0 ]; then
  echo "Failed to create Azure Dev Center pool."
  echo_output_dictionary_to_output_file
  exit 0
fi

echo "Azure Dev Center Pool created successfully."
#endregion Create Dev Center Pool

echo_output_dictionary_to_output_file
Essential Links to Get Started:

Learn how to create a Dev Center

Guide to creating a catalog

Instructions for creating environment types

Steps to create a project

How to create a project environment type

Guide for creating a Dev Box definition

Instructions for setting up a network connection

Steps for creating a Dev Box pool

Updated Nov 13, 2024
Version 2.0
No CommentsBe the first to comment