General Purpose to Business Critical Azure SQL database upgrade

This article is contributed. See the original author and article here.

Recently, we faced a requirement to upgrade large number of Azure SQL databases from general-purpose to business-critical.


 


As you’re aware, this scaling-up operation can be executed via PowerShell, CLI, or the Azure portal and follow the guidance mentioned here – Failover groups overview & best practices – Azure SQL Managed Instance | Microsoft Learn


 


Given the need to perform this task across a large number of databases, individually running commands for each server is not practical. Hence, I have created a PowerShell script to facilitate such extensive migrations.




# Scenarios tested:

# 1) Jobs will be executed in parallel.

# 2) The script will upgrade secondary databases first, then the primary.

# 3) Upgrade the database based on the primary listed in the database info list.

# 4) Script will perform the check prior to the migration in case of the role has changed from primary to secondary of the database mentioned in the database info list.

# 5) Upgrade individual databases in case of no primary/secondary found for a given database.

# 6) Upgrade the database if secondary is upgraded but primary has not been upgraded. Running the script again will skip the secondary and upgrade the primary database.

#    In other words, SLO mismatch will be handled based on the SKU defined in the database info list.

# 7) Track the database progress and display the progress in the console.


 


Important consideration:


 


# This script performs an upgrade of Azure SQL databases to a specified SKU.


# The script also handles geo-replicated databases by upgrading the secondary first, then the primary, and finally any other databases without replication links.


# The script logs the progress and outcome of each database upgrade to the console and a log file.


# Disclaimer: This script is provided as-is, without any warranty or support. Use it at your own risk.


# Before running this script, make sure to test it in a non-production environment and review the impact of the upgrade on your databases and applications.


# The script may take a long time to complete, depending on the number and size of the databases to be upgraded.


# The script may incur additional charges for the upgraded databases, depending on the target SKU and the duration of the upgrade process.


# The script requires the Az PowerShell module and the appropriate permissions to access and modify the Azure SQL databases.


 





 
# Define the list of database information
$DatabaseInfoList = @(
  #@{ DatabaseName = '{DatabaseName}'; PartnerResourceGroupName = '{PartnerResourcegroupName}'; ServerName = '{ServerName}'  ; ResourceGroupName = '{ResourceGroupName}'; RequestedServiceObjectiveName =  '{SLODetails}'; subscriptionID = '{SubscriptionID}' }
   )

# Define the script block that performs the update
$ScriptBlock = {
    param (
        $DatabaseInfo
    )

    Set-AzContext -subscriptionId $DatabaseInfo.subscriptionID

        ###store output in txt file
        $OutputFilePath = "C:temp$($DatabaseInfo.DatabaseName)_$($env:USERNAME)_$($Job.Id)_Output.txt"
        $OutputCapture = @()
        $OutputCapture += "Database: $($DatabaseInfo.DatabaseName)"

    
    $ReplicationLink = Get-AzSqlDatabaseReplicationLink -DatabaseName $DatabaseInfo.DatabaseName -PartnerResourceGroupName $DatabaseInfo.PartnerResourceGroupName -ServerName $DatabaseInfo.ServerName -ResourceGroupName $DatabaseInfo.ResourceGroupName
    $PrimaryServerRole = $ReplicationLink.Role
    $PrimaryResourceGroupName = $ReplicationLink.ResourceGroupName
    $PrimaryServerName = $ReplicationLink.ServerName
    $PrimaryDatabaseName = $ReplicationLink.DatabaseName

    $PartnerRole = $ReplicationLink.PartnerRole
    $PartnerServerName = $ReplicationLink.PartnerServerName
    $PartnerDatabaseName = $ReplicationLink.PartnerDatabaseName
    $PartnerResourceGroupName = $ReplicationLink.PartnerResourceGroupName


    $UpdateSecondary = $false
    $UpdatePrimary = $false

    if ($PartnerRole -eq "Secondary" -and $PrimaryServerRole -eq "Primary") {
        $UpdateSecondary = $true
        $UpdatePrimary = $true
    }
    #For Failover Scenarios only
    elseif ($PartnerRole -eq "Primary" -and $PrimaryServerRole -eq "Secondary") {
        $UpdateSecondary = $true
        $UpdatePrimary = $true

        $PartnerRole = $ReplicationLink.Role
        $PartnerServerName = $ReplicationLink.ServerName
        $PartnerDatabaseName = $ReplicationLink.DatabaseName
        $PartnerResourceGroupName = $ReplicationLink.ResourceGroupName
        
        $PrimaryServerRole = $ReplicationLink.PartnerRole
        $PrimaryResourceGroupName = $ReplicationLink.PartnerResourceGroupName
        $PrimaryServerName = $ReplicationLink.PartnerServerName
        $PrimaryDatabaseName = $ReplicationLink.PartnerDatabaseName
    }

    Try
    {
        if ($UpdateSecondary) {
            $DatabaseProperties = Get-AzSqlDatabase -ResourceGroupName $PartnerResourceGroupName -ServerName $PartnerServerName -DatabaseName $PartnerDatabaseName
            #$DatabaseEdition = $DatabaseProperties.Edition
            $DatabaseSKU = $DatabaseProperties.RequestedServiceObjectiveName
            if ($DatabaseSKU -ne $DatabaseInfo.RequestedServiceObjectiveName)  {
                Write-host "Secondary started at $(Get-Date) of DB $UpdateSecondary"
                $OutputCapture += "Secondary started at $(Get-Date) of DB $UpdateSecondary"
               
                Set-AzSqlDatabase -ResourceGroupName $PartnerResourceGroupName -DatabaseName $PartnerDatabaseName -ServerName $PartnerServerName -Edition "BusinessCritical"  -RequestedServiceObjectiveName $DatabaseInfo.RequestedServiceObjectiveName
                Write-host "Secondary end at $(Get-Date)"
                $OutputCapture += "Secondary end at $(Get-Date)"
        
                
                # Start Track Progress
                $activities = Get-AzSqlDatabaseActivity -ResourceGroupName $PartnerResourceGroupName -ServerName $PartnerServerName -DatabaseName $PartnerDatabaseName |
                Where-Object {$_.State -eq "InProgress" -or $_.State -eq "Succeeded" -or $_.State -eq "Failed"} |  Sort-Object -Property StartTime -Descending | Select-Object -First 1

                if ($activities.Count -gt 0) {
                    Write-Host "Operations in progress or completed for $($PartnerDatabaseName):"
                    $OutputCapture += "Operations in progress or completed for $($PartnerDatabaseName):"
                    foreach ($activity in $activities) {
                    Write-Host "Activity Start Time: $($activity.StartTime) , Activity Estimated Completed Time: $($activity.EstimatedCompletionTime) , Activity ID: $($activity.OperationId), Server Name: $($activity.ServerName), Database Name: $($activity.DatabaseName), Status: $($activity.State), Percent Complete: $($activity.PercentComplete)%, Description: $($activity.Description)"
                    $OutputCapture += "Activity Start Time: $($activity.StartTime) , Activity Estimated Completed Time: $($activity.EstimatedCompletionTime) , Activity ID: $($activity.OperationId), Server Name: $($activity.ServerName), Database Name: $($activity.DatabaseName), Status: $($activity.State), Percent Complete: $($activity.PercentComplete)%, Description: $($activity.Description)"
                    }
                    Write-Host  "$PartnerDatabaseName Upgrade Successfully Completed!"
                    $OutputCapture += "$PartnerDatabaseName Upgrade Successfully Completed!"
                } else {
                    Write-Host "No operations in progress or completed for $($PartnerDatabaseName)"
                    $OutputCapture += "No operations in progress or completed for $($PartnerDatabaseName)"
                }
                # End Track Progress
               # 
            }
            else {
                Write-host "Database $PartnerDatabaseName is already upgraded."
                $OutputCapture += "Database $PartnerDatabaseName is already upgraded."
            }
        }

        if ($UpdatePrimary) {
            $DatabaseProperties = Get-AzSqlDatabase -ResourceGroupName $PrimaryResourceGroupName -ServerName $PrimaryServerName -DatabaseName $PrimaryDatabaseName
           # $DatabaseEdition = $DatabaseProperties.Edition
            $DatabaseSKU = $DatabaseProperties.RequestedServiceObjectiveName
            if ($DatabaseSKU -ne $DatabaseInfo.RequestedServiceObjectiveName){
            Write-host "Primary started at $(Get-Date) of DB $UpdatePrimary"
            $OutputCapture += "Primary started at $(Get-Date) of DB $UpdatePrimary"
            Set-AzSqlDatabase -ResourceGroupName $PrimaryResourceGroupName -DatabaseName $PrimaryDatabaseName -ServerName $PrimaryServerName -Edition "BusinessCritical"  -RequestedServiceObjectiveName $DatabaseInfo.RequestedServiceObjectiveName
            Write-host "Primary end at $(Get-Date)" 
            $OutputCapture += "Primary end at $(Get-Date)"
            

            # Start Track Progress
            $activities = Get-AzSqlDatabaseActivity -ResourceGroupName $PrimaryResourceGroupName -ServerName $PrimaryServerName -DatabaseName $PrimaryDatabaseName |
            Where-Object {$_.State -eq "InProgress" -or $_.State -eq "Succeeded" -or $_.State -eq "Failed"} |  Sort-Object -Property StartTime -Descending | Select-Object -First 1

            if ($activities.Count -gt 0) {
                Write-Host "Operations in progress or completed for $($PrimaryDatabaseName):"
                $OutputCapture += "Operations in progress or completed for $($PrimaryDatabaseName):"
                foreach ($activity in $activities) {
                Write-Host "Activity Start Time: $($activity.StartTime) , Activity Estimated Completed Time: $($activity.EstimatedCompletionTime) , Activity ID: $($activity.OperationId), Server Name: $($activity.ServerName), Database Name: $($activity.DatabaseName), Status: $($activity.State), Percent Complete: $($activity.PercentComplete)%, Description: $($activity.Description)"
                $OutputCapture += "Activity Start Time: $($activity.StartTime) , Activity Estimated Completed Time: $($activity.EstimatedCompletionTime) , Activity ID: $($activity.OperationId), Server Name: $($activity.ServerName), Database Name: $($activity.DatabaseName), Status: $($activity.State), Percent Complete: $($activity.PercentComplete)%, Description: $($activity.Description)"
                }
                Write-Host  "$PrimaryDatabaseName Upgrade Successfully Completed!" 
                $OutputCapture += "$PrimaryDatabaseName Upgrade Successfully Completed!"
            } else {
                Write-Host "No operations in progress or completed for $($PrimaryDatabaseName)"
                $OutputCapture += "No operations in progress or completed for $($PrimaryDatabaseName)"
            }
            # End Track Progress
           #           
            }
            else {
                Write-host "Database $PrimaryDatabaseName is already upgraded."
                $OutputCapture += "Database $PrimaryDatabaseName is already upgraded."
            }
        }
        
        if (!$UpdateSecondary -and !$UpdatePrimary) {
            $DatabaseProperties = Get-AzSqlDatabase -ResourceGroupName $DatabaseInfo.ResourceGroupName -ServerName $DatabaseInfo.ServerName -DatabaseName $DatabaseInfo.DatabaseName
            # $DatabaseEdition = $DatabaseProperties.Edition
             $DatabaseSKU = $DatabaseProperties.RequestedServiceObjectiveName
        If ($DatabaseSKU -ne $DatabaseInfo.RequestedServiceObjectiveName)  {
            Write-Host "No Replica Found."
            $OutputCapture += "No Replica Found."
            Write-host "Upgrade started at $(Get-Date)"
            $OutputCapture += "Upgrade started at $(Get-Date)"
            Set-AzSqlDatabase -ResourceGroupName $DatabaseInfo.ResourceGroupName -DatabaseName $DatabaseInfo.DatabaseName -ServerName $DatabaseInfo.ServerName -Edition "BusinessCritical"  -RequestedServiceObjectiveName $DatabaseInfo.RequestedServiceObjectiveName
            Write-host "Upgrade completed at $(Get-Date)"
            $OutputCapture += "Upgrade completed at $(Get-Date)"

            # Start Track Progress
            $activities = Get-AzSqlDatabaseActivity -ResourceGroupName $DatabaseInfo.ResourceGroupName -ServerName $DatabaseInfo.ServerName -DatabaseName $DatabaseInfo.DatabaseName |
            Where-Object {$_.State -eq "InProgress" -or $_.State -eq "Succeeded" -or $_.State -eq "Failed"} |  Sort-Object -Property StartTime -Descending | Select-Object -First 1

            if ($activities.Count -gt 0) {
                Write-Host "Operations in progress or completed for $($DatabaseInfo.DatabaseName):"
                $OutputCapture += "Operations in progress or completed for $($DatabaseInfo.DatabaseName):"
                foreach ($activity in $activities) {
                Write-Host "Activity Start Time: $($activity.StartTime) , Activity Estimated Completed Time: $($activity.EstimatedCompletionTime) , Activity ID: $($activity.OperationId), Server Name: $($activity.ServerName), Database Name: $($activity.DatabaseName), Status: $($activity.State), Percent Complete: $($activity.PercentComplete)%, Description: $($activity.Description)"
                $OutputCapture += "Activity Start Time: $($activity.StartTime) , Activity Estimated Completed Time: $($activity.EstimatedCompletionTime) , Activity ID: $($activity.OperationId), Server Name: $($activity.ServerName), Database Name: $($activity.DatabaseName), Status: $($activity.State), Percent Complete: $($activity.PercentComplete)%, Description: $($activity.Description)"
                }
                Write-Host  " "$DatabaseInfo.DatabaseName" Upgrade Successfully Completed!"
                $OutputCapture += "$($DatabaseInfo.DatabaseName) Upgrade Successfully Completed!"
            } else {
                Write-Host "No operations in progress or completed for $($DatabaseInfo.DatabaseName)"
                $OutputCapture += "No operations in progress or completed for $($DatabaseInfo.DatabaseName)"
            }
            # End Track Progress
           # Write-Host  " "$DatabaseInfo.DatabaseName" Upgrade Successfully Completed!"
        }
        else {
            Write-host "Database "$DatabaseInfo.DatabaseName" is already upgraded."
            $OutputCapture += "Database $($DatabaseInfo.DatabaseName) is already upgraded."
        }
        $OutputCapture += "Secondary started at $(Get-Date) of DB $UpdateSecondary"
    }
    }
    Catch
    {
        # Catch any error
        Write-Output "Error occurred: $_"
        $OutputCapture += "Error occurred: $_"
    }
    Finally
    {
        Write-Host "Upgrade Successfully Completed!"
        $OutputCapture += "Upgrade Successfully Completed!"
            # Output the captured messages to the file
            $OutputCapture | Out-File -FilePath $OutputFilePath
    }
  
}

# Loop through each database and start a background job
foreach ($DatabaseInfo in $DatabaseInfoList) {
    Start-Job -ScriptBlock $ScriptBlock -ArgumentList $DatabaseInfo
}

# Wait for all background jobs to complete
Get-Job | Wait-Job

# Retrieve and display job results
#Get-Job | Receive-Job
Get-Job | ForEach-Object {
    $Job = $_
    $OutputFilePath = "C:temp$($Job.Id)_Output.txt"
    Receive-Job -Job $Job | Out-File -FilePath $OutputFilePath  # Append job output to the text file
}

# Clean up background jobs
Get-Job | Remove-Job -Force
write-host "Execution Completed successfully."
$OutputCapture += "Execution Completed successfully."

 

Este Mês no Azure Static Web Apps | 07/2024

Este Mês no Azure Static Web Apps | 07/2024

This article is contributed. See the original author and article here.

aswa-community.jpg


 


Sejam bem-vindos a primeira edição da Comunidade do Azure Static Web Apps! Todo mês, nós compartilharemos os conteúdos que a Comunidade Técnica criou, seja em formato de artigos, vídeos, podcasts que falam sobre o Azure Static Web Apps.


 


Quer ter o seu conteúdo compartilhado no TechCommunity no #ThisMonthInAzureStaticWebApps? Veja como!


 




  • 1 – Crie um artigo, vídeo, podcast ou até mesmo algum projeto Open Source que fale ou tenha relação com o Azure Static Web Apps.




  • 2 – Compartilhe o seu conteúdo no Twitter, LinkedIn ou Instagram com a hashtag #AzureStaticWebApps




  • 3 – Compartilhe também no nosso repositório oficial do Azure Static Web Apps no GitHub, na aba Discussions. Lá você encontrar um tópico chamado: This Month In Azure Static Web Apps. Compartilhe o link do seu conteúdo lá de acordo com o mês que você deseja que ele seja compartilhado.




  • 4 – Pronto! Nós iremos compartilhar o seu conteúdo no TechCommunity da Microsoft no mês seguinte!




 


repo-community-aswa.png


 


 


 


Independente do idioma que você escreva, seja em português, inglês, espanhol, francês, alemão, entre outros, nós queremos compartilhar o seu conteúdo!


 


Também se você estiver o Azure Static Web Apps com algum outro serviço ou Tecnologia, fique à vontade para compartilhar o seu conteúdo. Difere também da linguagem de programação que você está utilizando. Seja JavaScript, TypeScript, Python, Java, C#, Go, Rust, entre outras, nós queremos compartilhar o seu conteúdo!


 


Outro detalhe: você não precisa ser um especialista no Azure Static Web Apps para compartilhar o seu conteúdo. Se você está aprendendo sobre o serviço e quer compartilhar a sua jornada, fique à vontade para compartilhar o seu conteúdo!


 


Agora, vamos para os conteúdos do mês de Julho!


 


Agradecimentos!


 


Antes de começar a compartilhar os conteúdos, gostaríamos de agradecer a todas as pessoas que compartilharam os seus conteúdos no mês de Julho! Vocês são incríveis!


 


Conteúdos Compartilhados | Julho 2024


 


Agora vamos para os conteúdos compartilhados no mês de Julho de 2024!


 



Adding an API to an Azure hosted React Static Web App


 




  • Autor: Janek Fellien


 


 


01-article.png


 


O artigo explica como adicionar uma API a um aplicativo React Static Web App hospedado no Azure, configurando um ambiente de desenvolvimento com SWA CLI e VS Code, criando uma função HTTP em C#, e integrando a API ao app React para exibir dados no site.


 


Quer aprender a conectar seu aplicativo React a uma API no Azure? Leia o artigo completo e descubra como adicionar funcionalidades dinâmicas ao seu projeto.


 


Link: Adding an API to an Azure hosted React Static Web App


 


 



Hosting Next.JS Static Websites on Azure Static Web App


 




  • Autor: Parveen Singh


 


02-article.png


 


O artigo explica como hospedar sites estáticos criados com Next.js usando Azure Static Web Apps, abordando desde a configuração do repositório GitHub até a implantação contínua na Azure. É uma solução ideal para desenvolvedores que buscam simplicidade, segurança e escalabilidade em seus sites.


 


Quer aprender como hospedar seu site Next.js de forma simples e eficiente na Azure? Leia o artigo completo e descubra como aproveitar os recursos do Azure Static Web Apps!



 


 


Link: Hosting Next.JS Static Websites on Azure Static Web App


 



How to Deploy a React PWA to Azure Static Web Apps


 




  • Autor: Petkir


 


03-article.png


 


Este artigo ensina como implementar e automatizar o processo de deploy de uma aplicação React PWA para o Azure Static Web Apps usando GitHub Actions e Azure DevOps, além de gerar os recursos necessários com Bicep.


 


Quer aprender a simplificar o deploy de suas aplicações React PWA? Leia o artigo completo e descubra como automatizar tudo usando GitHub Actions e Azure DevOps!


 


Link: How to Deploy a React PWA to Azure Static Web Apps


 


 



Azure Static Web App: Seamless Microsoft Entra (Azure AD) Integration with Angular


 




  • Autor: Sparrow Note YouTube Channel | Althaf Moideen Konnola


 


 


Este vídeo ensina como integrar Microsoft Entra (Azure AD) com uma Azure Static Web App usando Angular, incluindo configuração de SSO, registro de aplicação e exibição de informações do usuário.


 


Quer aprender a integrar autenticação com Microsoft Entra em suas aplicações Angular? Assista agora e domine essa integração essencial para uma experiência de login unificada!


 


Link: Azure Static Web App: Seamless Microsoft Entra (Azure AD) Integration with Angular


 



Trimble Connect Workspace API 007 – Deployment


 




  • Autor: LetsConstructIT YouTube Channel


 


 


O vídeo demonstra como implantar uma aplicação local na nuvem usando Azure Static Web Apps, tornando-a acessível na web e integrada ao Trimble Connect, incluindo a configuração de extensões personalizadas.


 


Quer aprender a implantar suas aplicações na nuvem de forma simples e integrada com Trimble Connect? Assista ao vídeo completo e descubra como!


 


Link: Trimble Connect Workspace API 007 – Deployment


 



Blazor WASM Publishing to Azure Static Web Apps


 




  • Autor: Abdul Rahman | Regina Sharon


 


04-article.png


 


O artigo ensina como publicar aplicações Blazor WebAssembly (WASM) no Azure Static Web Apps, cobrindo desde a configuração inicial do projeto até a resolução de problemas comuns, como o erro 404 em atualizações de página. Ele também explica como personalizar o processo de build e configurar domínios personalizados.


 


Quer aprender a publicar suas aplicações Blazor WASM no Azure de forma simples e eficaz? Leia o artigo completo e descubra como configurar tudo passo a passo, garantindo que sua aplicação funcione perfeitamente!


 


Link: Blazor WASM Publishing to Azure Static Web Apps


 



Azure Static Web Apps Community Standup: Create a RAG App with App Spaces


 




  • Autor: Skyler Hartle | Dheeraj Bandaru


 


 


O vídeo apresenta o App Spaces, uma nova ferramenta do Azure que simplifica a criação e o gerenciamento de aplicativos inteligentes, especialmente ao integrar Azure Static Web Apps e Azure Container Apps. Durante a sessão, é demonstrado como criar e implantar um aplicativo de Recuperação Aumentada por Geração (RAG), utilizando uma interface simples que conecta repositórios do GitHub e automatiza o processo de CI/CD.


 


Descubra como simplificar a criação de aplicativos inteligentes com o Azure App Spaces! Assista ao vídeo completo e aprenda a implantar rapidamente um aplicativo RAG em minutos. Não perca essa oportunidade de elevar suas habilidades de desenvolvimento na nuvem!


 


Link: Azure Static Web Apps Community Standup: Create a RAG App with App Spaces


 



Serverless Single Page Application (Vue.js) mit Azure Static Web Apps


 




  • Autor: Florian Lenz

  • Idioma: Alemão


 


 


Este artigo mostra como criar e implantar uma aplicação de página única (SPA) usando Vue.js e Azure Static Web Apps. Ele guia o leitor desde a criação do projeto até a adição de um backend serverless com Azure Functions, destacando a facilidade de uso e as vantagens do modelo serverless para aplicações full-stack.


 


Quer aprender a implantar sua aplicação Vue.js na nuvem com Azure Static Web Apps e aproveitar os benefícios do serverless? Leia o artigo completo e descubra como criar e gerenciar uma aplicação full-stack de forma simples e eficiente!


 


Link: Serverless Single Page Application (Vue.js) mit Azure Static Web Apps


 


Conclusão


 


Se você deseja ser destaque no próximo artigo do #ThisMonthInAzureStaticWebApps, compartilhe o seu conteúdo nas redes sociais com a hashtag #AzureStaticWebApps e também no nosso repositório oficial no GitHub. Estamos ansiosos para compartilhar o seu conteúdo no próximo mês!


 


Lembrando que você não precisa ser um especialista no Azure Static Web Apps para compartilhar o seu conteúdo. Se você está aprendendo sobre o serviço e quer compartilhar a sua jornada, fique à vontade para compartilhar o seu conteúdo!


 


Até a próxima edição! :cool:

Simplify development with Dev Container templates for Azure SQL Database

Simplify development with Dev Container templates for Azure SQL Database

This article is contributed. See the original author and article here.

What are Dev Containers?


A development container essentially packages up your project’s development environment using the Development Container Specification (devcontainer.json). This specification enriches your container with metadata and content necessary to enable development from inside a container.


Workspace files are mounted from the local file system or copied or cloned into the container. Extensions are installed and run inside the container, where they have full access to the tools, platform, and file system. This means that you can seamlessly switch your entire development environment just by connecting to a different container.


carlosrobles_0-1721240099869.png


 


Dev Container Templates are source files packaged together that encode configuration for a complete development environment, while Dev Container Features allow us to add runtimes, tools, and libraries inside a container. As a result, all this put together ensures a consistent and reproducible development environment from any tool that supports the Development Container Specification.


When you open your project in the dev container, your code will just work without downloading anything on your local machine. Furthermore, the best part is that when connected to a dev container, your developer experience is exactly the same as if you opened the project locally in VS Code.


 


Introducing Dev Container Templates for Azure SQL Database


We are excited to introduce new Dev Container templates specifically designed for Azure SQL Database. These templates support multiple programming languages, including .NET 8, .NET Aspire, Python, and Node.js, making it easier for developers to get started quickly and focus on building their applications.


Dev Containers streamline the development process by providing an out-of-the-box environment configured for Azure SQL Database. This eliminates the need for developers to spend time searching for and setting up VS Code extensions to interact with their database and preferred programming language. With these templates, you can dive straight into coding, boosting productivity and reducing setup friction.


 


carlosrobles_1-1721240099871.png


 


Included with the templates is a pre-built demo database called Library, which serves as a practical example to help developers get started quickly. While these Dev Containers use the Azure SQL Edge container image, which offers a surface area close to Azure SQL Database, using SQL Database Projects ensures that your database code remains compatible with Azure SQL Database. With this demo project, you can easily use the dacpac artifact created by SQL Database Projects and deploy it to Azure SQL Database using the Azure SQL Action for GitHub Actions. This process streamlines your workflow and ensures seamless integration with your production environment.


Whether working locally or in the cloud, dev containers ensure consistency across development environments, making it easier to collaborate and maintain high standards across your team. With the inclusion of essential tools like SQLCMD, SqlPackage, Azure Command-Line Interface (CLI) and Azure Developer CLI (AZD), these templates offer a comprehensive solution for enhancing your development workflow with Azure SQL Database.


 


Benefits of Using Dev Containers


Dev Containers ensure a consistent and seamless experience, promoting smooth collaboration across teams and workflows, and facilitating an easy transition to Azure environments. Key benefits include:



  • Preconfigured environments: These come with all necessary tools and dependencies.

  • Consistency: Maintain uniformity across different development setups.

  • Simplified setup: Reduce time spent on configuration.

  • Enhanced collaboration: Improve teamwork within development teams.

  • Seamless transition to Azure: Leverage the scalability and reliability of Azure SQL Database for production deployments.

  • Accelerated time-to-market: Streamline development workflows and integrate seamlessly with existing toolsets, giving businesses a competitive edge.

  • Cost-efficient development: Reduce dependencies on cloud resources during the development and testing phases.


By using dev containers, developers can avoid the hassle of setting up and configuring their local development environment manually.


 


Prerequisites


Before you begin, make sure you have the following tools installed on your local machine:



To set up your environment, follow these steps:



  1. First, ensure you have Git installed for version control.

  2. Then, install Docker, which is necessary for running containers.

  3. After that, download and install Visual Studio Code, as it will be your primary IDE for using Dev Containers.

  4. Lastly, add the Dev Containers extension to Visual Studio Code to enable seamless containerized development.


 


Setting up the Dev Container template for Azure SQL Database


Creating a Dev Container



Begin by either opening a local folder containing your application project or cloning an existing repository into Visual Studio Code. This initial step sets the stage for integrating your project with a development container, whether you’re starting from scratch or working on an existing application. In Visual Studio Code, open the command palette (press F1 or Ctrl+Shift+P on Windows and Cmd+Shift+P on macOS). Select the



Dev Containers: Add Dev Container Configuration Files command.


carlosrobles_2-1721240099872.png

Select the Add configuration file to workspace option if you want to add the dev container configuration file to your current local repository. Alternatively, choose the Add configuration file to user data folder option. For this qiuckstart, select the Add configuration file to workspace option.


carlosrobles_3-1721240099873.png

Visual Studio Code prompts you to select a Dev Container template. The available templates are based on the tools and dependencies required for the specific development environment. Select Show All Definitions to view all available templates.


carlosrobles_4-1721240099873.png

Next, select the desired Dev Container template for Azure SQL Database by typing Azure SQL into the command palette. This action displays a list of available templates designed for Azure SQL Database development.


carlosrobles_5-1721240099874.png


Building the Container


Upon selection, Visual Studio Code automatically generates the necessary configuration files tailored to the chosen template. These files include settings for the development environment, extensions to install, and Docker configuration details. They’re stored in a .devcontainer folder within your project directory, ensuring a consistent and reproducible development environment.


carlosrobles_6-1721240099874.png


Following the configuration file generation, Visual Studio Code prompts you to transition your project into the newly created Dev Container environment. You can do it by selecting Reopen in Container. This step is crucial as it moves your development inside the container, applying the predefined environment settings for Azure SQL development.



If you haven’t already, you can also initiate this transition manually at any time using the Dev Containers extension. Use the Reopen in Container command from the command palette or select on the blue icon at the bottom left corner of Visual Studio Code and select Reopen in Container.


carlosrobles_7-1721240099875.png

This action initiates the setup process, where Visual Studio Code generates the necessary configuration files and builds the development container based on the selected template. The process ensures that your development environment is precisely configured for Azure SQL Database development.



Visual Studio Code builds the container based on the selected configuration. The build process might take a few minutes the first time.

carlosrobles_8-1721240099875.png


carlosrobles_9-1721240099876.png


Exploring and verifying the Dev Container


After you build the dev container, start exploring and verifying the setup. Open a terminal within Visual Studio Code to check that all necessary tools are installed and working correctly.


carlosrobles_10-1721240099877.png


As an optional step, you can also run predefined tasks directly from the command palette, streamlining your development workflow and allowing you to focus on writing code.


carlosrobles_11-1721240099879.png


carlosrobles_12-1721240099879.png


For more detailed information about specific templates, visit Azure SQL Database Dev Container templates.


Conclusion


Dev Containers for Azure SQL Database offer a powerful and efficient way to streamline your development process. By providing a consistent, portable environment, they help you focus on writing code and building features rather than configuring your setup. We encourage you to explore these templates and see how they can enhance your development workflow for Azure SQL Database.


Looking ahead, we will delve into more advanced topics like integrating Azure services with Dev Containers to further optimize your development process. Stay tuned for more insights and practical guides to help you get the most out of Azure SQL Database and Dev Containers.


 


More about Dev Container templates for Azure SQL Datatabase.