Skip to main content

Command Palette

Search for a command to run...

#Handson Deploying a Secure SQL Server VM on Azure with Infrastructure as Code and Just-in-Time Access

Updated
6 min read
#Handson Deploying a Secure SQL Server VM on Azure with Infrastructure as Code and Just-in-Time Access
R

I'm technologist in love with almost all things tech from my daily job in the Cloud to my Master's in Cybersecurity and the journey all along.

Executive Brief

This deployment demonstrates a modern, secure approach to cloud infrastructure management using Infrastructure as Code (IaC) principles with Bicep. By combining Azure DevOps pipelines, Azure Key Vault for secret management, and Just-in-Time (JIT) VM access, we've created a repeatable, auditable, and highly secure deployment pattern.

Azure_Bicep_Deployment_Diagram.png

The Repo:

Key Benefits & Why This Approach Matters:

  1. Infrastructure as Code (Bicep):

    • Version-controlled infrastructure - Every change is tracked in Git

    • Consistent deployments - Eliminates configuration drift

    • Self-documenting - Bicep files serve as living documentation

    • Collaboration enabled - Team members can review and approve changes via PRs

  2. Secure Secret Management with Azure Key Vault:

    • No hardcoded credentials in code or pipelines

    • Centralized secret management - Single source of truth for passwords

    • Automatic rotation support - Easy password rotation without redeployment

    • Access auditing - Track who accessed secrets and when

  3. Azure DevOps CI/CD Pipeline:

    • Automated validation - Bicep syntax and what-if analysis

    • Controlled deployments - Approval gates and environment promotion

    • Audit trail - Complete history of who deployed what and when

    • Rollback capability - Easy to revert to previous versions

  4. Just-in-Time (JIT) VM Access:

    • Zero standing access - No open RDP/SSH ports by default

    • Time-limited access - Connections automatically expire (max 3 hours)

    • Approval workflow - Request/approve access through Defender for Cloud

    • Attack surface reduction - Eliminates 24/7 exposure to brute force attacks

    • Compliance friendly - Meets strict security requirements (NIST, CIS, etc.)

Azure_JIT_Access_Diagram.png

This approach transforms traditional VM deployment from a manual, error-prone process into a repeatable, secure, and compliant operation that scales across teams and environments.

Complete Deployment Journey: Step-by-Step

Phase 1: Initial Setup & Repository Creation

StepWhere PerformedActionCommands/Details
1. Create GitHub RepositoryGitHub.comCreated new repository for infrastructure codehttps://github.com/soyroberto/bicex
2. Clone Repository LocallyLocal TerminalSet up local working directorygit clone https://github.com/soyroberto/bicex.git
3. Create Project StructureLocal FilesystemOrganized Bicep files and pipelineCreated bicep/ directory and azure-pipelines.yml

Phase 2: Bicep Template Development

StepWhere PerformedActionCommands/Details
4. Create Main Bicep Templatebicep/main.bicepDefined VM with SQL Server 2019Parameters for VM name, size, networking, Key Vault reference
5. Create Parameter Filebicep/main.bicepparamDefined non-sensitive configurationVM name, admin username, location, subnet details
6. Implement Key Vault Integrationbicep/main.bicepAdded secure password retrievalreference() function for Key Vault secret value

Phase 3: Azure Resource Preparation

StepWhere PerformedActionCommands/Details
7. Create Resource GroupAzure Portal/CLISet up target resource groupRGAUANSDeploy in australiasoutheast
8. Create Key VaultAzure Portal/CLISet up secure secret storagekvaueansdeploy with RBAC authorization
9. Store VM PasswordAzure Key VaultCreated secret for VM admin passwordSecret name: vmAdminPassword
10. Verify Existing NetworkAzure CLIConfirmed VNet and NSG availabilityvnetausclient and nsgauejit in RGAUSNetCh

Phase 4: Azure DevOps Pipeline Setup

StepWhere PerformedActionCommands/Details
11. Create Service ConnectionAzure DevOpsConnected Azure subscriptionService principal: AzureServiceConnection
12. Create Variable GroupAzure DevOps → LibraryStored non-sensitive configurationGroup: bicep-deployment-secrets with 7 variables
13. Set Secret VariablesVariable GroupAdded sensitive resource IDsVNET_RESOURCE_ID and NSG_RESOURCE_ID (marked secret)

Phase 5: Permission Configuration

StepWhere PerformedActionCommands/Details
14. Grant Key Vault AccessAzure CLIAdded RBAC roles for service principalKey Vault Secrets User role assignment
15. Grant Network PermissionsAzure CLIEnabled pipeline to modify networkNetwork Contributor on VNet resource group
16. Grant Resource Group AccessAzure CLIEnabled pipeline to create resourcesContributor on target resource group

Phase 6: Pipeline Development & Testing

StepWhere PerformedActionCommands/Details
17. Create Pipeline YAMLazure-pipelines.ymlDefined CI/CD workflowSingle stage with Bicep installation and deployment

Phase 7: Deployment Execution

StepWhere PerformedActionCommands/Details
18. Commit and Push CodeLocal TerminalTriggered pipeline via Git pushgit add . && git commit -m "Ready" && git push origin main
19. Monitor Pipeline ExecutionAzure DevOps PortalWatched real-time deployment logsValidated each step: checkout → Bicep install → VM deployment
20. Verify Deployment SuccessAzure PortalConfirmed VM creationvmausbixvm01 running in RGAUANSDeploy resource group

Phase 8: Post-Deployment Configuration

StepWhere PerformedActionCommands/Details
21. Retrieve VM PasswordAzure CLIRetrieved admin credentials from Key Vaultaz keyvault secret show --vault-name kvaueansdeploy --name vmAdminPassword
22. Get VM Public IPAzure CLIRetrieved connection endpointaz vm show -g RGAUANSDeploy -n vmausbixvm01 --query publicIps -o tsv
23. Configure JIT AccessMicrosoft Defender for CloudEnabled Just-in-Time VM accessPortal: Defender for Cloud → Just-in-time VM access → Enable on vmausbixvm01

Before Requesting access from the Remote Desktop Client:

Requesting Access

After JIT enabled

the NSG is enabled on the selected ports 3389

RDPing to the VM

Key Technical Decisions & Learnings

1. Bicep Over ARM Templates

  • Cleaner syntax - More readable than JSON ARM templates

  • Better tooling - VS Code extension with IntelliSense

  • Modular design - Can be broken into reusable modules

2. Pipeline Design Choices

  • Single-stage deployment - Simplified MVP approach

  • Inline script execution - Avoided external script dependencies

  • Variable groups - Centralized configuration management

3. Security Implementation

  • RBAC over access policies - More granular permission control

  • Secret retrieval at runtime - Never stored in pipeline variables

  • JIT-ready NSG - Pre-configured for zero-standing-access model

4. Error Resolution Process

  • Iterative debugging - Fixed issues in sequence:

    1. Pipeline script location configuration

    2. Parameter file syntax compatibility

    3. Key Vault secret retrieval method

    4. VM image patch settings compatibility

Future Enhancement Opportunities

  1. Multi-environment pipelines - Dev, Test, Prod promotion

  2. Bicep modules - Reusable network, storage, and security components

  3. Integration testing - Post-deployment validation scripts

  4. Cost optimization - Auto-shutdown schedules and sizing recommendations

  5. Monitoring integration - Azure Monitor alerts and dashboards

Conclusion

This deployment demonstrates an automated deployment for a secure Azure VM that balances, automation, and maintainability. By leveraging Infrastructure as Code, secure secret management, and Just-in-Time access, organizations can significantly reduce their attack surface while maintaining operational efficiency.

The complete solution took approximately 4 hours from initial repository creation to successful VM connection, with the majority of time spent on configuration and debugging rather than manual infrastructure provisioning. Subsequent deployments would take under 15 minutes (ideally)

Roberto

More from this blog

U

Understand. Build. Conquer the Cloud

70 posts

No time for a novel? Here are my my Cloud Architect field notes: Distilling my complex cloud adventures into digestible TL;DRs.