{"id":20899196,"url":"https://github.com/geekzter/azure-vdc","last_synced_at":"2025-05-13T01:31:39.125Z","repository":{"id":43175408,"uuid":"190187734","full_name":"geekzter/azure-vdc","owner":"geekzter","description":"Automated VDC on Azure","archived":false,"fork":false,"pushed_at":"2023-05-31T20:39:11.000Z","size":8143,"stargazers_count":19,"open_issues_count":3,"forks_count":8,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-04-24T02:57:19.523Z","etag":null,"topics":["azure","azure-app-service","azure-cli","azure-pipelines","codespace","diagram","hcl","infrastructure-as-code","network","paas-services","powershell","provision","provision-infrastructure","provision-resources","terraform","terraform-azure","vdc","vdc-terraform","vpn"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/geekzter.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2019-06-04T11:26:23.000Z","updated_at":"2024-02-20T11:57:49.000Z","dependencies_parsed_at":"2022-09-10T14:01:18.444Z","dependency_job_id":"27b0edbf-3b11-4b19-80ac-3c874d57ef4e","html_url":"https://github.com/geekzter/azure-vdc","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geekzter%2Fazure-vdc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geekzter%2Fazure-vdc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geekzter%2Fazure-vdc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geekzter%2Fazure-vdc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/geekzter","download_url":"https://codeload.github.com/geekzter/azure-vdc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225165778,"owners_count":17431342,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure","azure-app-service","azure-cli","azure-pipelines","codespace","diagram","hcl","infrastructure-as-code","network","paas-services","powershell","provision","provision-infrastructure","provision-resources","terraform","terraform-azure","vdc","vdc-terraform","vpn"],"created_at":"2024-11-18T11:13:26.063Z","updated_at":"2024-11-18T11:13:26.571Z","avatar_url":"https://github.com/geekzter.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Maintenance notice\n__Note__: I stopped maintaining this repository.\nFor Virtual Data Center / Hub \u0026 Spoke guidance, check [Enterprise-scale Landing Zones](http://aka.ms/eslz).\n\n\n# Automated VDC\nThis project contains a sample starter Virtual Datacenter (VDC), which follows a Hub \u0026 Spoke network topology and includes PaaS services with private networking. Two demo applications (one IaaS, one PaaS) are deployed into it.\n\n## TL;DR - Quickstart\nIf you want to get going without reading what's below, choose either:\n- Setup [option A](#option-a-local-terraform), the fastest way to provision infrastructure if you already have Azure CLI and Terraform set up. You can use any shell.   \n- Setup [option B](#option-b-visual-studio-codespace), the fastest if you have nothing set up yet. All you need is a browser (Chrome or Edge) and an Azure subscription.\n\n## Architecture description\n### Infrastructure\n![alt text](diagram.png \"Network view\")\n\nThis repo deploys the following components:\n\n- A hub network with subnets for shared components (dmz, mgmt, etc)\n- Azure Firewall used as Internet Access Gateway (egress, outbound FQDN whitelisting)\n- Application Gateway as Web Application Firewall (WAF, HTTP ingress)\n- A Management VM that is used as jump server to connect to other VM's\n- A Managed Bastion as well\n- A Point to Site (P2S VPN), with transitive access to PaaS services\n- An IIS VM application deployed in a spoke network, with subnet segregation (app, data)\n- An App Service web application integrated into another spoke network\n  - Ingress through Private Endpoint\n  - Egress through VNet integration (delegated subnet)\n- Several PaaS services connected as Private Endpoints\n  \n\n### Identify flow\n![alt text](identity-diagram.png \"Identity View\")   \n\nPrivate networking provides some isolation from uninvited guests. However, a [zero trust](https://www.microsoft.com/security/blog/2019/10/23/perimeter-based-network-defense-transform-zero-trust-model/) 'assume breach' approach uses multiple methods of isolation. This is why identity is called the the new perimeter. With Azure Active Directory Authentication, most application level communication can be locked down and access controlled through RBAC. This is done in the following places:\n\n1. App Service uses Service Principal \u0026 RBAC to access Container Registry\n1. User AAD auth (SSO with MFA) to App Service web app\n1. App Service web app uses MSI to access SQL Database (using least privilege database roles, see [grant_database_access.ps1](./scripts/grant_database_access.ps1))\n1. User AAD auth (SSO with MFA) on Point-to-Site VPN\n1. User AAD auth to VM's (RDP, VM MSI \u0026 AADLoginForWindows extension)\n1. SQL Database tools (Azure Data Studio, SQL Server Management Studio) use AAD Autnentication with MFA\n1. Azure DevOps (inc. Terraform) access to ARM using Service Principal\n\n### Deployment automation\n![alt text](deployment-diagram.png \"Deployment View\")\n\nThe diagram conveys the release pipeline, with end-to-end orchestration by Azure Pipelines (YAML). The pipeline provisions infrastructure, and deploys 2 applications:\n\n- An [ASP.NET Core app](https://github.com/geekzter/dotnetcore-sqldb-tutorial) deployed on PaaS App Service, SQl Database \u0026 more\n- An [ASP.NET Framework application](https://github.com/geekzter/azure-vdc/tree/master/apps/IaaS-ASP.NET) deployed on IaaS VM's \n\nThe high-level pipeline steps are:\n\n1. Create [Pipeline environment](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/environments) using multi-stage YAML pipeline\n1. Infrastructure provisioning with Terraform   \nThis diagram only shows resources (App Service, SQL Database \u0026 VM's) that participate in downstream  deployments. Many more resources are created that are not displayed.\n1. Provision SQL Database\n1. Provision App Service (with SQL DB connection string)\n1. App Service pulls configured \n[ASP.NET Core app](https://github.com/geekzter/dotnetcore-sqldb-tutorial) container running offline from database\n1. Provision Virtual Machines \n1. Import database (PowerShell with Azure CLI)\n1. SQL Database pulls bacpac image\n1. Swap deployment slots (PowerShell with Azure CLI)   \n[ASP.NET Core app](https://github.com/geekzter/dotnetcore-sqldb-tutorial) now uses live database\n1. Deploy [ASP.NET Framework application](https://github.com/geekzter/azure-vdc/tree/master/apps/IaaS-ASP.NET)\n\n## Provisioning\nTo get started you need [Git](https://git-scm.com/), [Terraform](https://www.terraform.io/downloads.html) (to get that I use [tfenv](https://github.com/tfutils/tfenv) on Linux \u0026 macOS and [chocolatey](https://chocolatey.org/packages/terraform) on Windows) and [Azure CLI](http://aka.ms/azure-cli). Make sure you have the latest version of Azure CLI. This requires some tailored work on Linux (see http://aka.ms/azure-cli) e.g. for Debian/Ubuntu:   \n`curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash`    \n\nAlternatively, you can create a Visual Studio Codespace with this repo, using this [link](https://online.visualstudio.com/environments/new?name=azure-vdc\u0026repo=geekzter/azure-vdc)\n\nMake sure you clean up, this creates quite a number of resources (see [disclaimer](#disclaimer)).\n\n### Option A: Local Terraform\nUse this option if you're using bash, zsh and/or don't have PowerShell Core. \n\n1. Clone repository:  \n`git clone https://github.com/geekzter/azure-vdc.git`  \n\n1. Change to the [`terraform`](./terraform) directrory  \n`cd azure-vdc/terraform`\n\n1. Login into Azure with Azure CLI:  \n`az login`   \n\n1. This also authenticates the Terraform [azurerm](https://www.terraform.io/docs/providers/azurerm/guides/azure_cli.html) provider when working interactively. Optionally, you can select the subscription to target:  \n`az account set --subscription 00000000-0000-0000-0000-000000000000`   \n`ARM_SUBSCRIPTION_ID=$(az account show --query id -o tsv)` (bash, zsh)   \n`$env:ARM_SUBSCRIPTION_ID=$(az account show --query id -o tsv)` (pwsh)   \n\n1. You can then provision resources by first initializing Terraform:   \n`terraform init`  \n\n1. And then running:  \n`terraform apply`\n\n1. When you want to destroy resources, run:   \n`terraform destroy`\n\nThe default configuration will work with any shell. Additional [features](#feature-toggles) may require PowerShell and one of the options below.\n\n### Option B: Visual Studio Codespace\nThis will use [Visual Studio Codespaces](https://online.visualstudio.com/) as the environment to provision from. A Codespace is an online version of Visual Studio Code, with a repository cloned into a Linux container and required tools configured. This repo can create a [customized](https://docs.microsoft.com/en-us/visualstudio/online/reference/configuring) Codespace with the resources in the [.devcontainer](./.devcontainer) directory. This will install pre-requisites needed on the Codespace.   \n\nTerraform can use optional Azure backend state, and invocation is wrapped by [tf_deploy.ps1](./scripts/tf_deploy.ps1). This unlocks [features](#feature-toggles) dependent on using [PowerShell](https://github.com/PowerShell/PowerShell#get-powershell) (e.g. which use the Terraform [local-exec provisioner](https://www.terraform.io/docs/provisioners/local-exec.html)).\n\n1. Create a Codespace [plan](https://docs.microsoft.com/en-us/visualstudio/online/how-to/browser#create-an-environment) if you don't have one yet.\n\n1. Create a Codespace by following this link:    \n[https://online.visualstudio.com/environments/new?name=azure-vdc\u0026repo=geekzter/azure-vdc](https://online.visualstudio.com/environments/new?name=azure-vdc\u0026repo=geekzter/azure-vdc)    \nThis should prompt you to clone this repo when creating the Codespace.\n\n1. Once the Codespace has been created, open a terminal by typing Ctrl-` (backquote). This opens a PowerShell session.\n\n1. (Optional) A [Terraform Backend](https://www.terraform.io/docs/backends/index.html) allows multi-host, multi-user collaboration on the same Terraform configuration. To set up a [Terraform Azure Backend](https://www.terraform.io/docs/backends/types/azurerm.html), create a storage account and configure `backend.tf` (copy [`backend.tf.sample`](./terraform/backend.tf.sample)) with the details of the storage account you created. Make sure the user used for Azure CLI has the [Storage Blob Data Contributor](https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#storage-blob-data-contributor) or [Storage Blob Data Owner](https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#storage-blob-data-owner) role (it is not enough to have Owner/Contributor rights, as this doesn't grant Data Plane access). Alternatively, you can set `ARM_ACCESS_KEY` or `ARM_SAS_TOKEN` environment variables e.g.  \n`$env:ARM_ACCESS_KEY=$(az storage account keys list -n \u003cSTORAGE_ACCOUNT\u003e --query \"[0].value\" -o tsv)`   \nor   \n`$env:ARM_SAS_TOKEN=$(az storage container generate-sas -n \u003cSTORAGE_CONTAINER\u003e --permissions acdlrw --expiry 202Y-MM-DD --account-name \u003cSTORAGE_ACCOUNT\u003e -o tsv)`   \nInitialize Terraform azurerm backend by running   \n`tf_deploy.ps1 -init` \n\n1. (Optional) Customize `variables.tf` or create a `.auto.tfvars` file that contains your customized configuration (see [Features](#feature-toggles) below)\n\n1. Run  \n`tf_deploy.ps1 -apply`  \nto provision resources (this will create a plan that you will be prompted to apply).    \nYou will be prompted to select a subscription if `$env:ARM_SUBSCRIPTION_ID` is not set.\n\n1. When you want to destroy resources, run:   \n`tf_deploy.ps1 -destroy` (with Terraform, recommended)   \nor    \n`erase.ps1 -destroy` (with Azure CLI, as a last resort)   \n\n\n### Option C: Azure Pipelines\nAforementioned options only provision infrastructure, and does so interactively. There are a number of [pipelines](./pipelines) that do this end-to-end and also deploy 2 demo applications:\n\n- [vdc-terraform-apply-ci.yml](./pipelines/vdc-terraform-apply-ci.yml)   \nCI pipeline that does a full provisioning, deployment and tear down\n- [vdc-terraform-apply-release.yml](./pipelines/vdc-terraform-apply-release.yml)   \nRelease pipeline that takes artifacts published by CI pipeline\n- [vdc-terraform-apply-cd.yml](./pipelines/vdc-terraform-apply-cd.yml)   \nCD pipeline that combines both CI \u0026 release in a single multi-stage pipeline\n\nAll these pipelines share the same [template](./pipelines/templates/vdc-terraform-apply.yml).\n\n## Feature toggles ###\nThe Automated VDC has a number of features that are turned off by default. This can be because the feature has pre-requisites (e.g. certificates, or you need to own a domain). Another reason is the use of Azure preview features, or features that just simply take a long time to provision. Features are toggled by a corresponding variable in [`variables.tf`](./terraform/variables.tf).\n|Feature|Toggle|Dependencies and Pre-requisites|\n|---|---|---|\n|Azure\u0026nbsp;Bastion. Provisions the [Azure Bastion](https://azure.microsoft.com/en-us/services/azure-bastion/) service in each Virtual Network|`deploy_managed_bastion`|None|\n|Monitoring\u0026nbsp;VM\u0026nbsp;Extensions. Controls whether these extensions are provisioned: `IaaSDiagnostics`, `MicrosoftMonitoringAgent`, `DependencyAgentWindows`|`deploy_monitoring_vm_extensions`|None|\n|Non\u0026#x2011;essential\u0026nbsp;VM\u0026nbsp;Extensions. Controls whether these extensions are provisioned: `TeamServicesAgent` (for VM's that are not a deployment target for an Azure Pipeline), `BGInfo`|`deploy_non_essential_vm_extensions`|PowerShell 7|\n|[Network\u0026nbsp;Watcher](https://azure.microsoft.com/en-us/services/network-watcher/)|`deploy_network_watcher`|`deploy_non_essential_vm_extensions` also needs to be set. This requires PowerShell 7|\n|Security\u0026nbsp;VM\u0026nbsp;Extensions. Controls whether these extensions are provisioned: `AADLoginForWindows`, `AzureDiskEncryption`|`deploy_security_vm_extensions`|None|\n|VPN, provisions [Point-to-Site (P2S) VPN](https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-howto-point-to-site-rm-ps)|`deploy_vpn`|You need to have the [Azure VPN application](https://go.microsoft.com/fwlink/?linkid=2117554) [provisioned](https://docs.microsoft.com/en-us/azure/vpn-gateway/openvpn-azure-ad-tenant) in your Azure Active Directory tenant.|\n|Disable all access public ip address of SQL Database, regardless of SQL Firewall settings|`disable_public_database_access`|`enable_private_link` also needs to be set|\n|AAD\u0026nbsp;Authentication. [Configure](https://docs.microsoft.com/en-us/azure/app-service/configure-authentication-provider-aad) App Service to authenticate using Azure Active Directory|`enable_app_service_aad_auth`|SSL and a vanity domain needs to have been set up. You also need to [create](https://docs.microsoft.com/en-us/azure/app-service/configure-authentication-provider-aad) an Azure AD App registration and configure the `paas_aad_auth_client_id_map` map for at least the `default` workspace (see example in [config.auto.tfvars.sample](./terraform/config.auto.tfvars.sample))). (Note: Terraform could provision this pre-requiste as well, but I'm assuming you don't have suffiient AAD permissions as this requires a Service Principal to create Service Principals in automation)|\n|[Private Link](https://azure.microsoft.com/en-us/services/private-link/)|`enable_private_link`|None|\n|[Storage Logging]. Enables storage logging to Log Analytics workspace.(https://docs.microsoft.com/en-us/azure/storage/common/monitor-storage)|`enable_storage_diagnostic_setting`|The subscription used needs to be enabled for the private preview of the Log Analytics diagnostics setting for Azure Storage|\n|Grant access to SQL Database for App Service MSI and user/group defined by `admin_object_id`. This is required for database import and therefore application deployment|`grant_database_access`|PowerShell 7|\n|Limits access to PaaS services to essential admin IPs, Virtual Networks|`restrict_public_access`|PowerShell 7.     Scripting is required for reentrancy. The Terraform IP can change as multiple users collaborate, you simply execute from a different location, or your ISP gave you a dynamic IP address.|\n|Pipeline\u0026nbsp;agent\u0026nbsp;type. By default a [Deployment Group](https://docs.microsoft.com/en-us/azure/devops/pipelines/release/deployment-groups/) will be used. Setting this to `true` will instead use an [Environment](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/environments)|`use_pipeline_environment`|Multi-stage YAML Pipelines|\n|SSL\u0026nbsp;\u0026\u0026nbsp;Vanity\u0026nbsp;domain. Use HTTPS and Vanity domains (e.g. yourdomain.com)|`use_vanity_domain_and_ssl`|You need to own a domain, and delegate the management of the domain to [Azure DNS](https://azure.microsoft.com/en-us/services/dns/). The domain name and resource group holding the Azure DNS for it need to be configured using `vanity_domainname` and `shared_resources_group` respectively. You need a wildcard SSL certificate and configure its location by setting `vanity_certificate_*` (see example in [config.auto.tfvars.sample](./terraform/config.auto.tfvars.sample)).\n\n## Dashboard\nA portal dashboard will be generated:   \n\n![alt text](dashboard.png \"Portal Dashboard\")\n\nThis dashboard can be reverse engineered into the template that creates it by running:   \n`templatize_dashboard.ps1`   \nThis recreates `dashboard.tpl`, which in turn generates the dashboard. Hence full round-trip dashboard editing support is provided.\n\n## Resources\n- [Azure CLI](http://aka.ms/azure-cli)\n- [Azure Pipelines](https://azure.microsoft.com/en-us/services/devops/pipelines/)\n- [PowerShell Core](https://github.com/PowerShell/PowerShell)\n- [Terraform Azure Backend](https://www.terraform.io/docs/backends/types/azurerm.html)\n- [Terraform Azure Provider](https://www.terraform.io/docs/providers/azurerm/index.html)\n- [Terraform on Azure documentation](https://docs.microsoft.com/en-us/azure/developer/terraform)\n- [Terraform Learning](https://learn.hashicorp.com/terraform?track=azure#azure)\n- [Visual Studio Code](https://github.com/Microsoft/vscode)\n\n## Disclaimer\nThis project is provided as-is, and is not intended as a blueprint on how a VDC should be deployed, or Azure components and Terraform should be used. It is merely an example on how you can use the technology. The project creates a number of Azure resources, you are responsible for monitoring and managing cost. Auto shutdown on is configured on VM's only.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeekzter%2Fazure-vdc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgeekzter%2Fazure-vdc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeekzter%2Fazure-vdc/lists"}