Skip to content

Repository files navigation

Azure Bastion Project

This document provides a guide to deploying and demonstrating Azure Bastion and it's capabilities.

Architecture

Read more about the architecture on my project blogs titled Azure Bastion Capabilities.

Prerequisites

  • Azure Subscription with sufficient permissions.
  • Terraform installed locally.
    You'll need a CI/CD pipeline like Jenkins, GitHub Actions or ArgoCD in the real world environment
  • Basic knowledge of Azure networking and RBAC.
  • Azure CLI installed.
  • Optional capabilities, Highly recommended in production
    • Entra ID with Premium license for Conditional Access and PIM.
    • Privileged Identity Management (PIM) enabled in Entra ID.
    • Just-In-Time (JIT) access configured.
    • Access Packages configured in Entra ID.

Resource Creation

  • Checkout the repository locally.

    • In the root directory, login to your Azure account. az login. Note this is not needed if running via a CI tool.

    • Run the below command and take note of the id value

      az account show
  • If deploying a Public endpoint architecture, then skip next step

  • If deploying a Private endpoint architecture

    • Update the following variables in the tfvars file
      • bastion_sku set this to Premium
      • bastion_is_private set to true
      • bastion_session_recording_enabled set to true if you want to see this in action
      • If you dont have a VPN you will need one. Set use_vpn_gateway to true
  • Execute the below command in the terminal you logged in from via the cli

    terraform plan -var-file=dev.tfvars -var subscription_id=<your_subscription_id>
  • Review the plan. This is very good practice with terraform, done assume always double check.

  • When done with reviews run the below command

    terraform apply -auto-approve -var-file=dev.tfvars -var subscription_id=<your_subscription_id>

    The -auto-approve is like the Linux -y, it signals to terraform to proceed without prompting you for approvals. You'd find this mostly with CI configurations

  • While you wait, go to you Azure portal, look for the new resource group and follow the creation of the resources.

  • After deployment, verify the vms are all ready

  • Follow the verification steps below to test this out

Considerations

  • IP Overlaps, you may need to consider this. Change them to what suits if errors in the apply on this.
  • VM SKUs and SKU limits, especially or personal accounts. Change to whats applicable in you environment
  • location yours may not be UK South update as per your requirements
  • Naming conventions. As it's mostly driven via the tfvars file, make any necessary adjustments to suit your needs or policy

Access Packages set up - Optional

Step 1: Create Entra ID Groups

You’ll need at least these groups: Bastion-Connect → Engineers who can connect to VMs via Bastion.

Bastion-UploadDownload → Engineers allowed to upload and download files.

Bastion-UploadOnly → Engineers allowed to upload files only.

There are a couple ways to create these groups:

  1. Using Access Packages (Recommended for JIT):
    • Go to Entra ID → Identity Governance → Access Packages → New access package.
    • Create an access package for each role, linking to the respective group.
    • Configure policies for approval, expiration, and JIT access.
    • Publish the access packages.
    • Engineers can request access via the Access Package portal.
    • Approvals and expirations are managed automatically.
    • This method provides better governance and auditing.
  2. Manually Creating Groups:
    • If the creation of the groups failed or you don't have the permissions to create groups, you can get someone with the required permissions to assist. See below for manual group creation steps.
  3. Via Scripts:
    • Execute the cli commands in the setup-bastion-rbac.sh script file to assign the roles to the groups. Groups should have been created by Terraform, this us an addition just incase

How to create groups manually:

  • Go to Microsoft Entra admin center → Groups → New group.
  • Choose Security as the group type.
  • Name the group (e.g., Bastion-Connect).
  • Add members (or leave empty if you’ll use JIT later).
  • Repeat for the other two groups.

Step 2: Assign Roles to Groups

Azure Bastion uses Azure RBAC roles for permissions. Assign these roles at the Bastion resource scope:

Virtual Machine User Login

  • Required for SSH/RDP access to VMs.
  • Assign to Bastion-Connect group.

Reader

  • Allows viewing Bastion resource.
  • Assign to all groups.

Custom Roles for File Transfer

Upload & Download: Action → Microsoft.Network/bastionHosts/fileTransfer/action

Upload Only: Action → Microsoft.Network/bastionHosts/fileUpload/action

Assign these custom roles to Bastion-UploadDownload and Bastion-UploadOnly respectively.

Step 3: Conditional Access

Apply Conditional Access policies to these groups:

  • Require MFA.
  • Require compliant device.
  • Restrict access to VPN IP ranges.

Step 4: Optional JIT Access

If you want engineers to request access dynamically (similar to Access Packages), you can use:

  • Privileged Identity Management (PIM) for group membership.
  • Configure eligible assignments for these groups.

Validation Checklist

There are some verification steps in the Verification Step Scripts document. Follow the example to validate you can access resources via the newly deployed Azure bastion

Essentially we want to validate

  • VPN connectivity verified (either the p2s or own VPN)
  • Conditional Access enforced (If configured, requires P1 and above license)
  • Bastion deployed in management VNet
  • Session recording enabled and tested (if using premium)
  • File transfer tested for both roles
  • Native client and browser access verified
  • Tunneling tested
  • Logs flowing to Log Analytics

These would cover most use cases where an IaaS VM is deployed as a JumpBox and should validate that Azure bastion can provide same capabilities.

🧨 Clean Up - Important

If testing things out in your personal account or using your organisations provided "sandbox", ensure you delete what you have created as it will cost you or your organisation money by the hour.

To remove all resources run the below command

terraform destroy -auto-approve -var-file=dev.tfvars -var subscription_id=<your_subscription_id>

Documentation

About

Project exploring Azure bastion capabilities

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages