Drupal hosting on Microsoft Azure

A planning guide to running self-hosted Drupal on Microsoft Azure, covering app hosting choices, managed databases, Blob storage, Entra ID sign-in and private networking.

On this page

Why teams host Drupal on Azure and what Azure hosting has to cover

Drupal runs on Apache or Nginx with MariaDB, MySQL, PostgreSQL or SQLite as the database, so an Azure design is a set of hosting, database, file storage and identity choices rather than a special platform. Organizations that already standardize on Azure usually want that Drupal platform inside their own subscriptions, under their own networking, monitoring and access controls. The Azure design is what you build around Drupal, and it is the part your team or a partner has to get right.

Drupal is licensed under GPL-2.0-or-later, and there is no paid edition of Drupal itself, so the Azure budget covers infrastructure and services, not software licenses. Contributed modules on Drupal.org carry the same licensing model according to the Drupal.org licensing page. Your recurring costs will therefore come from compute, managed database capacity, storage, network components and the people who operate them. Ask any proposal to separate these lines so you can see which costs scale with traffic and which stay fixed.

This topic covers five Azure pieces: app hosting for the PHP runtime, managed MySQL or PostgreSQL for the database, Blob storage for public and private files, Entra ID for sign-in, and private networking that connects these components. Confirm early which Drupal version and PHP version your platform must support, since the Drupal core release schedule and PHP requirements page determine which database and runtime versions are valid. Decisions on these five pieces shape everything that follows, so settle them before infrastructure is provisioned.

Which Azure hosting option fits which Drupal platform

This table compares Azure app hosting options and database choices for a self-managed Drupal site. Read each row against your Drupal version, PHP requirement and the skills your team already has, then check the operating load on the right. The main takeaway is that managed platform services reduce what your team patches, but they do not remove the need to confirm Drupal and PHP compatibility before you choose.

OptionWhen it fitsWhat the team operatesWhat to confirm for Drupal and PHP
App Service (Linux, PHP runtime)A single site or small set of sites with standard contributed modules and no custom system packagesApplication code deployment, app settings, scaling rules, TLS settings and the build pipelineConfirm the PHP runtime offered in your region covers the PHP version your Drupal release requires, and that Composer builds run in your pipeline
Containers on Azure Kubernetes ServiceTeams already running Kubernetes, or sites that need custom PHP extensions, sidecars or per-environment imagesCluster upgrades, node pools, ingress, image builds, secrets and rolling deploys with database updatesConfirm the base image PHP version matches the Drupal release, and rebuild images after each security release
Virtual machines (Linux with Apache or Nginx and PHP-FPM)Teams that need full control of the web server, PHP extensions or operating system packages, or that must match an existing on-premises buildOS patching, web server and PHP-FPM configuration, Composer deployments, cron and backupsConfirm the OS distribution still receives security updates and that its packaged PHP version meets your target Drupal version
Azure Database for MySQL or PostgreSQL (managed)Teams that want the vendor to handle database patching, backups and failover options for a supported engine versionDatabase users, schema changes through Drupal updates, network rules, parameter settings and restore testsConfirm the engine version is supported for your Drupal release and that contributed modules you use have no engine-specific code
Self-managed database on virtual machinesTeams that need a database version or extension not offered as a managed service, or that already run database operationsEngine patching, replication, backups, point-in-time recovery and monitoringConfirm the engine and minimum version against the Drupal system requirements before you build, and plan restore testing
Blob storage for public and private filesAny site that stores user uploads or generated files across more than one web nodeStorage account, container layout, access keys or managed identity, and backup or lifecycle rulesConfirm which contributed file system module your Drupal version supports and how private file paths are served

How to set up a Drupal site on Azure in sequence

This sequence takes a team from empty Azure subscription to a Drupal site with managed database, file storage, PHP hosting, configured secrets and working sign-in. Each step closes with a check so problems surface before content is loaded.

  1. Confirm the Drupal version and PHP constraint

    Before creating any Azure resources, the architect confirms which Drupal core release the site will run and the PHP version that release requires. Drupal 10 requires PHP 8.1 or later, Drupal 11 requires PHP 8.3 or later and Drupal 12 requires PHP 8.5 or later, so the app hosting choice depends on this decision. Confirm the current requirements with the Drupal.org PHP requirements page before committing. The output is a written version record covering Drupal core, PHP, the database engine and every contributed module that must be compatible. Done when the owner signs off on that record.

  2. Create the resource group and network layout

    The platform engineer creates a resource group per environment and a virtual network with separate subnets for the web tier, the database and any private endpoints. Keep development, staging and production in separate resource groups so access, tags and cost reporting stay distinct. Decide now whether the database and storage will be reachable only through private networking, because that choice shapes every later step. Done when the network diagram matches the approved design and each subnet has a documented purpose and address range.

  3. Provision the database with a supported engine

    The platform engineer provisions Azure Database for MySQL or Azure Database for PostgreSQL in the database subnet, selecting a major version that the Drupal system requirements list for the chosen core release. Drupal also supports MariaDB, but confirm the managed option and version against Drupal.org before selecting it. Restrict network access to the app subnet, enable automated backups and record the retention setting. Done when a test connection from a machine in the app subnet succeeds and a connection from outside the network is refused.

  4. Configure Blob storage for public and private files

    The platform engineer creates a storage account and separate containers for public and private files, with access restricted to the app identity or private endpoint. Drupal needs a public files path for served assets and a private path that is never directly reachable, so the two containers must not share an access policy. The team confirms which contributed file system module will map Drupal's file paths to Blob storage and tests that module against the chosen core release. Done when an uploaded test image appears in the public container, a test private file cannot be fetched by anonymous URL, and both paths resolve inside Drupal.

  5. Deploy the app host with the required PHP version

    The platform engineer deploys the Drupal codebase to the app hosting service selected in the architecture, setting the runtime to the PHP version confirmed in step one and enabling only the PHP extensions the Composer build requires. The application is built from a Composer-managed codebase so that the same artifact moves between environments. Set the web root to the Drupal web directory and confirm the web server handles clean URLs. Done when the Drupal installer or a health page loads over HTTPS and the PHP version reported by the runtime matches the approved record.

  6. Load secrets and environment settings from Azure

    The platform engineer moves database credentials, the hash salt, the file system paths and trusted host patterns out of the repository and into Azure configuration, such as app settings or a key vault reference, then has settings.php read them at runtime. The team sets trusted_host_patterns per environment so that only the expected hostnames are accepted. No secret should appear in the Git history or in a configuration export. Done when the site starts with secrets supplied only by Azure, a deliberate request with an unexpected Host header is rejected, and a review of the repository finds no credentials.

  7. Configure Entra ID or SAML/OIDC sign-in

    The identity administrator registers the Drupal site as an application in Microsoft Entra ID and records the redirect URI for the environment. The Drupal team then installs and configures the chosen contributed module, either the OpenID Connect client module for OIDC or the SAML Authentication module for SAML, and confirms the module supports the Drupal version in use. Decide whether accounts are created on first sign-in and which roles Entra group membership maps to. Done when a test user signs in through Entra ID, lands with the expected role, and a user outside the permitted group is refused.

  8. Run smoke tests before loading content

    The QA lead runs a short, scripted set of checks covering anonymous page loads, login and logout, content creation, a file upload to Blob storage, cron execution, cache clearing, and a Drupal status report with no errors. The team also verifies that the database connection survives an app restart and that logs reach the chosen monitoring destination. Record each result against the approved design. Done when every check passes in staging and the results are filed so the same tests can be repeated before production launch.

How Azure services connect to Drupal's request path

A request to a Drupal site on Azure enters through the Azure front door layer you choose (Azure Front Door, Application Gateway or a CDN in front of it), passes TLS termination and web application firewall rules, and reaches the web tier that serves the Drupal codebase. The web tier hands PHP requests to PHP-FPM, which bootstraps Drupal, reads settings.php, and queries the managed database for content, configuration and cache entries that have not been stored elsewhere. Each step should be confirmed against your own topology. Ask the platform team to draw the actual path, including every health probe and any rewrite rule that changes the host header, because Drupal's trusted_host_patterns setting will reject requests whose host does not match.

Drupal's state has to live outside any single instance. Sessions should move to the database or to a shared cache service such as Azure Cache for Redis, configured through a contributed Redis module, so that a user who lands on a different instance stays signed in. Public and private files should go to Blob storage through a contributed file storage module (s3fs has an Azure-compatible equivalent in the ecosystem, so confirm the exact module and its Azure support before choosing). Uploads written to local disk on one instance would be invisible to the others and lost on redeploy. Private file paths and the temporary directory need the same treatment, and the module's stream wrapper must be tested for image styles, which generate derivative files on demand.

Cron and queue workers should not run on every web instance. Run them as a separate job, such as an Azure Container Apps job, a scheduled AKS CronJob or a dedicated worker VM, and make sure only one scheduler triggers drush cron at a time. Confirm how long-running queues behave during scale-in, because a worker stopped mid-item can leave work half done. Decide who owns the Entra ID sign-in path, since the SAML Authentication module (samlauth) and the OpenID Connect module both create or map accounts, and their callback URLs must match the public hostname exactly, not the internal one behind the front door.

Security controls for Drupal on Azure

Each control below is something your team must configure, verify and keep current after launch, not a feature Azure enables by default. Together they cover how the database, secrets, storage access, host validation, transport and patching are protected. Review them as one set, because a gap in one (for example, a public database endpoint) undermines the others.

Private database connectivity

Place Azure Database for MySQL or PostgreSQL behind a private endpoint or VNet integration so the database has no public network path. Confirm that the App Service or container environment resolves the database hostname to a private address, and that firewall rules allowing public access are removed. Test name resolution from every subnet that runs Drupal, including cron and queue workers. Ask your platform team to document which subnets can reach the database and why.

Secrets held in Key Vault

Store the database password, hash salt, API keys and SMTP credentials in Azure Key Vault rather than in settings.php or the repository. Reference them from application settings or the container runtime, and keep environment-specific values separate from code. Confirm who can read each secret, set an expiry and rotation schedule, and check that secret values never appear in logs or exported configuration.

Managed identities for storage access

Grant the Drupal runtime a managed identity with only the Blob storage role it needs, and avoid storing account keys in site configuration. Scope the role to the specific container that holds public and private files. Verify that private files are served only through Drupal's access checks, not through direct blob URLs. Review role assignments whenever the hosting resource changes.

Trusted host patterns per environment

Set trusted_host_patterns in settings.php for each environment so Drupal rejects requests whose Host header does not match the expected hostname. Use the production domain in production and the staging hostname in staging, and avoid wildcard patterns that accept any host. Keep the list in environment-specific configuration, and test that the Azure default hostname and custom domains behave as you intend before go-live.

TLS and transport settings

Terminate HTTPS at the Azure edge with certificates you manage, redirect HTTP to HTTPS, and enforce a minimum TLS version on the app and database connections. Confirm that Drupal generates HTTPS URLs when running behind a load balancer, and that the reverse proxy forwards the protocol header correctly. Check cookie flags on the session and login paths, and rerun these checks after any certificate or gateway change.

Patching against security advisories

Subscribe your team to Drupal Security Team advisories and plan rebuilds around the third-Wednesday security release window. Drupal's bugfix releases arrive on the first Wednesday of each month, so schedule staging deployments in the days after each release. Keep the Composer lockfile current, rebuild and redeploy the application image, and record the date each advisory was applied. Confirm an owner and an out-of-cycle process for critical advisories.

Questions teams ask before hiring help for Azure hosting

What drives the cost and effort of hosting Drupal on Azure?

The biggest drivers are the architecture you choose, the database sizing, the network design, whether you are migrating from Drupal 7, and how many environments you need. A single production site with one staging copy is a very different job from a multisite estate with development, test, staging and production in separate subscriptions. Ask any partner to break the quote into discovery, infrastructure build, Drupal configuration, migration, hardening, testing and handover, so you can see which parts scale with your scope. Ask which Azure services are included, who creates and owns the subscriptions, and what happens if the requirements change during the build.

Can our own team host Drupal on Azure without a partner?

Often yes, if you already run Linux servers, managed databases and infrastructure as code in Azure. The skills that matter most are network design with private endpoints, identity configuration with Entra ID, secrets handling, backups and a repeatable Composer-based release process. Teams without that experience usually underestimate the work around the Drupal application itself, such as file storage, cron, cache layers and security update routines. A useful test is whether your engineers can rebuild the environment from code, restore a backup into a clean subscription and apply a security release without an outage.

What do we need to provide before the work starts?

Expect to provide access to the Azure subscriptions or management groups where the platform will run, including the role assignments needed to create resources and networks. You will also need identity administrators who can register the application in Entra ID, configure redirect URIs and approve group claims. Network approvals matter early: address ranges, DNS zones, firewall rules, private DNS links to on-premises networks and any inbound traffic from a CDN or web application firewall. Ask the partner to list these dependencies in writing, with the person responsible for each one and the date it is needed.

How long does an Azure hosting project take?

Duration depends on scope, not on a fixed template. The main variables are the number of environments, whether a Drupal 7 migration is included, how many integrations need network access and how many approvals your network and identity teams must give. Approval cycles inside large organizations often set the pace more than the build itself. Ask for a timeline that separates discovery, approvals, build, migration, load testing and go-live readiness, and confirm which of those steps depend on your teams.

Which parts of Azure hosting still cost money after launch?

Recurring costs typically include compute for the application tier, the managed database, storage for files and backups, network components such as gateways or private endpoints, monitoring and log retention, and licensing for any Azure or third-party tooling you choose. Drupal itself is free software under GPL-2.0-or-later, so the recurring spend is infrastructure and the people who maintain it. Ask the quote to show monthly running costs at the sizing you chose, plus the cost of security updates, Drupal core upgrades and contributed module maintenance across the year.

Do we need to plan a Drupal 7 migration before moving to Azure?

Yes. Drupal 7 security support ended on January 5, 2025, according to Drupal.org, so a site still on Drupal 7 should not stay exposed on new infrastructure. Drupal 6 and 7 sites cannot simply be updated to Drupal 10 or later; they are migrated into a new site using the core Migrate modules or Drush, and themes must be rebuilt. If you cannot migrate yet, the Drupal Association lists certified Extended Security Support Provider vendors. Ask the partner whether the quote covers the migration itself or only the hosting, and what happens to content that needs cleanup.

Which Drupal version and PHP runtime should we plan for on Azure?

Plan the platform around a supported Drupal version and the PHP version it requires. According to the Drupal.org PHP requirements page, Drupal 10 requires PHP 8.1 or later, Drupal 11 requires PHP 8.3 or later and Drupal 12 requires PHP 8.5 or later. Drupal 11 is the current major version, and Drupal 10 reaches end of life on December 9, 2026, according to the core release schedule. Confirm with your partner which PHP runtime the chosen Azure app hosting option supports, and whether the platform can move to the next major version without rebuilding the network and identity layers.

Operating Drupal on Azure after launch

The recurring work on a Drupal site on Azure falls into three rhythms: monthly bugfix releases, security releases and planned major-version moves. According to the Drupal core release schedule, bugfix releases arrive on the first Wednesday of each month and security releases on the third Wednesday, so your operations calendar should hold a slot in each of those weeks. Assign a named owner for each release, and rehearse the update on a staging slot in your Azure App Service or container environment before it reaches production. Keep the Composer lock file and the container image tag under version control so that every deployed release can be traced and rolled back. Confirm with your Azure team how long your planned maintenance windows allow for the database update step, because drush updatedb runs against Azure Database for MySQL or PostgreSQL and can be the slowest part of a release.

PHP planning is the decision most often left too late. According to the Drupal.org PHP requirements page, Drupal 10 requires PHP 8.1 or later, Drupal 11 requires PHP 8.3 or later and Drupal 12 requires PHP 8.5 or later. Drupal 12 is scheduled for the week of December 7, 2026, so the runtime on your Azure hosts must support PHP 8.5 before that week, and contributed modules and custom code need to be tested against it in advance. Restore testing belongs in the same routine. Test restores of the Azure Database for MySQL or PostgreSQL point-in-time backups into a separate resource group, and confirm that the Blob storage container holding public and private files can be restored to the same point, because a database restored without its files produces broken media references. Record the time each restore takes, since that figure, not the backup retention setting, defines your real recovery time.

Drupal 10 reaches end of life on December 9, 2026, according to the Drupal core release schedule. Treat that date as a planning milestone for every existing site, not a launch deadline for the next project. Inventory which sites are still on Drupal 10, which custom modules and themes would block a move to Drupal 11, and which Entra ID or SAML integrations depend on module versions that support your target release. Monitoring should cover the application and the platform: Application Insights or your chosen error tracker for PHP errors, Azure Monitor alerts for App Service or container health and database CPU and storage, and an uptime check on the public URL. Confirm those tools and their retention settings with your own security and compliance owners before you rely on them as evidence.

Azure hosting choices by team situation

A new Drupal build on a small platform team should favor the fewest moving parts that still meet availability and security needs. Start with a current release line. Drupal 11 is the current major version, and Drupal 10 reaches end of life on December 9, 2026, so a build started now should target Drupal 11 and plan for Drupal 12, which is scheduled for the week of December 7, 2026. Drupal 11 requires PHP 8.3 or later, so the app hosting choice must support that runtime.

  • Managed PHP app hosting: A platform-as-a-service app service reduces patching of the web tier, but confirm that it supports your PHP version, custom Composer builds and the write access Drupal needs for generated files.
  • Managed database: Azure Database for MySQL or PostgreSQL removes database patching and backup tooling from the team's list. Confirm the engine version against the minimums in the Drupal system requirements before you pick one.
  • Blob storage for files: Keep public and private files off the web node so that scaling out does not copy file state. Your Drupal integration for object storage will need to be chosen and tested.
  • Single region, one environment set: A small team usually gains more from a clear dev, staging and production split than from multi-region designs.

Confirm with the team's Azure partner or support contact which managed database tier and backup retention your recovery targets require, and who owns the Drupal cron schedule.

How DeployOpen scopes and supports Drupal on Azure

DeployOpen plans, implements, hardens, documents and supports self-hosted open-source platforms inside the client's own infrastructure, including Microsoft Azure subscriptions you control. For Drupal on Azure, the work starts with a written scope that fixes what is built, tested and handed over before any build begins.

How we scope

  • Engagements are fixed-scope, with deliverables and timelines agreed in writing before work starts.
  • The written scope names the Azure subscriptions, regions, app hosting option and database service the site will run on.
  • Scope also records the Drupal version, PHP version, contributed modules and identity integration (Entra ID or another provider).

How we build

  • Infrastructure is built as code in your subscriptions, covering networking, private endpoints, Blob storage and secrets handling.
  • Drupal settings, file storage paths and trusted host patterns are configured per environment, with secrets kept outside the repository.
  • Each environment is tested before launch, including sign-in, file uploads, cron, cache behavior and restore from backup.

How we hand over

  • Handover includes architecture notes, runbooks for deployments, backups, restores and rollback, and access records.
  • Your team receives documentation of the build, configuration decisions and the upgrade path for the chosen Drupal version.
  • Knowledge transfer sessions are scheduled in the written scope so your staff can operate the platform after launch.

How we support

  • Ongoing support, upgrades and continuous testing are available as retainers, scoped separately from the build.
  • Support can cover monitoring of the Azure resources, patch application for Drupal security releases and PHP version changes.
  • Ask any support provider to confirm response expectations, change windows and who holds administrative access to your subscriptions.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.