A cloud-based system diagram shows secure user access, three Windows servers, backend storage, and automated software deployment.
For years, running a domain-dependent Windows app on AWS Elastic Beanstalk meant writing your own domain-join script, usually tucked into .ebextensions. AWS has now built that join into the platform. Every Windows Server instance in an Elastic Beanstalk environment can join an Active Directory domain at launch, before your application is deployed to it, and the domain join itself doesn't need stored domain credentials.

The feature first appeared in late summer. AWS's release notes say that on August 31, 2026, AWS Elastic Beanstalk began supporting automatic joining of Windows Server instances to an Active Directory domain managed with AWS Directory Service. AWS has since published a hands-on DevOps blog walkthrough. This guide combines that walkthrough with the official Developer Guide: what you need, how to turn it on, how to tell whether it worked, and how to fix it when it didn't.

A cloud-based system diagram shows secure user access, three Windows servers, backend storage, and automated software deployment. Why this matters: a long-standing gap is closed​

AWS once stated plainly that this wasn't possible. An older AWS DevOps blog post about migrating ASP.NET apps noted that Elastic Beanstalk did not support web servers being joined to an AD domain. It told customers to either alter the application to eliminate the dependency, or use other approaches to migrate onto Amazon EC2 instances without using Elastic Beanstalk. Customers kept asking for it, and "Native Active Directory Domain join support" appeared on the wish list in an RFC on the public Elastic Beanstalk roadmap about improved Windows workload support.

Domain membership matters for some very common Windows patterns:

  • Intranet sites that sign users in with Windows Integrated Authentication
  • Services that connect to SQL Server with Windows authentication instead of a password in the connection string
  • Apps that read from SMB file shares
  • Server fleets configured through Group Policy

AWS's launch announcement makes the same point: domain-joined instances can use Windows-integrated authentication, apply group policy, and reach domain resources such as file shares and SQL Server databases that use Windows authentication.

The old do-it-yourself scripts had a lot to handle. They had to fetch domain credentials from a safe place, rename the instance to avoid name collisions, join the domain, survive the reboot, and do all of it again every time Auto Scaling added an instance. That code wasn't part of the application, but teams still had to maintain it.

Section summary: Elastic Beanstalk now does natively what Windows shops used to script themselves, and it removes the need to store domain-join credentials.

Supported directories and platform versions​

You can join three kinds of directory:

Directory typeSupportedNotes
AWS Managed Microsoft ADYesUsed in AWS's walkthrough (Standard Edition)
Simple ADYesSame options; AWS notes Simple AD isn't offered in every Region
Self-managed AD via AD ConnectorYesYour on-premises or EC2-hosted AD, connected through AD Connector

The Developer Guide confirms that instances can join an AWS Managed Microsoft AD directory or a Simple AD directory, or a self-managed Active Directory through AD Connector.

The version requirement: Active Directory domain join is available on Windows Server platform versions released on or after August 18, 2026. Earlier platform versions don't support the aws:elasticbeanstalk:windows:activedirectory namespace and reject its options during validation. On an older platform version, your configuration won't silently do nothing. It will be rejected during validation. Update the platform first.

On Regions, AWS's announcement says the feature is available in all AWS Commercial Regions and the AWS GovCloud (US) Regions where Elastic Beanstalk is available.

Three settings turn it on​

Everything lives in the aws:elasticbeanstalk:windows:activedirectory namespace:

  • DirectoryId: the AWS Directory Service directory ID, such as d-1234567890. Setting this option turns the feature on. Without it, nothing about your environment changes.
  • DirectoryName: the directory's fully qualified DNS name, such as corp.example.com. Required whenever DirectoryId is set.
  • DirectoryOU (optional): the distinguished name of an organizational unit for the computer objects, such as OU=WebServers,DC=corp,DC=example,DC=com. The OU must already exist. If you leave this out, computer objects go into the directory's default container.

You can set these in a configuration file in your source bundle, in the console, or with the AWS CLI. The Developer Guide's CLI example for a running environment looks like this:

Code:
aws elasticbeanstalk update-environment \
  --environment-name my-env \
  --option-settings '[
    {"Namespace": "aws:elasticbeanstalk:windows:activedirectory", "OptionName": "DirectoryId", "Value": "d-1234567890"},
    {"Namespace": "aws:elasticbeanstalk:windows:activedirectory", "OptionName": "DirectoryName", "Value": "corp.example.com"},
    {"Namespace": "aws:elasticbeanstalk:windows:activedirectory", "OptionName": "DirectoryOU", "Value": "OU=WebServers,DC=corp,DC=example,DC=com"}
  ]'

Notice that the example uses JSON syntax. AWS chose it on purpose: DirectoryOU values contain commas, and the CLI's shorthand syntax treats commas as separators. AWS's own walkthrough goes a step further and writes the option settings to a file passed with --option-settings file://options.json, which avoids shell quoting problems altogether.

Expect instance replacement. Adding, changing or removing any option in this namespace makes Elastic Beanstalk reprovision the environment's EC2 instances, which triggers a rolling update. Don't treat it as a casual change in the middle of the day.

What happens at launch​

When an instance launches with these options set, it does the following before your application arrives:

  1. Creates its own computer object. It calls the Directory Service CreateComputer API using the environment's instance profile credentials. That's why no domain password is involved.
  2. Renames itself to EC2-XXXXXXXX, where the Xs are the last eight characters of the instance ID in uppercase.
  3. Joins the domain and reboots. This is the same one-time reboot every Windows Server instance in Elastic Beanstalk already does during provisioning, so the join adds no extra reboot.

This applies to every instance, including ones Auto Scaling adds later. As AWS's announcement puts it, every instance in the environment — including instances launched later by auto scaling — joins the domain at boot, before your application deploys, with no custom scripts.

Why the hostname changes​

Without AD options, Elastic Beanstalk names Windows instances after their private IPv4 address, such as IP-0A010203. IP addresses get reused, so those names can collide with stale computer objects in a directory. The Developer Guide mentions disaster-recovery setups that reuse IP ranges across Regions, and long-lived environments, as places where this happens. Instance IDs are globally unique, so AWS describes the chance of a collision as negligible. The ID-based naming applies only when AD options are set.

Prerequisites checklist​

Check these before you flip the switch:

  • A reachable directory and working DNS. The environment must run in a VPC that can reach the directory, and instances must be able to resolve the directory's DNS name. The join finds domain controllers through DNS SRV records. The usual setup is a VPC DHCP options set that points at the directory's DNS servers. AWS says missing DNS resolution is a common cause of failed joins. In its walkthrough, AWS notes that the directory's DNS servers forward queries they can't answer to the VPC resolver, so instances can still reach AWS endpoints and the internet.
  • IAM permission for ds:CreateComputer. The instance profile (for example, aws-elasticbeanstalk-ec2-role) needs this permission. The least-privilege approach scopes it to the directory's ARN:
Code:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ds:CreateComputer",
      "Resource": "arn:aws:ds:us-east-2:123456789012:directory/d-1234567890"
    }
  ]
}

You can attach the AmazonSSMDirectoryServiceAccess managed policy instead, but it grants ds:CreateComputer for every directory in the account. In an account with several directories, the scoped policy is the better choice.

  • A supported platform version (released on or after August 18, 2026).
  • A pre-created OU, if you use DirectoryOU. Elastic Beanstalk doesn't create OUs.

How to tell whether it worked​

An environment showing Ready does not prove the domain join succeeded. A failed join deliberately doesn't block deployment. The Developer Guide states that if an instance can't join, it falls back to the standard IP-address-derived hostname (IP-XXXXXXXX), the deployment continues, and the environment can still reach the Ready state and report healthy.

That design keeps your app online, but a green health status can hide the fact that Windows authentication is broken. Check the join directly in one of these ways:

  • Hostname: a joined instance is named EC2-XXXXXXXX. An IP-XXXXXXXX name means the instance fell back to the default naming.
  • Directory: look for the EC2-XXXXXXXX computer object in your OU or the default container.
  • Deployment log: look for the line Active Directory: joined to <directory-name>. In the console, open the environment's Deployments tab, open the Environment Creation deployment, then select Deployment Logs.

For instances that Auto Scaling launches or replaces, the console's Deployments tab doesn't show the log. Download it from the environment's S3 bucket. In AWS's walkthrough, it was the newest object under resources/environments/logs/deployments/<environment-id>/selfstartup/, with the instance ID in the file name.

Troubleshooting failed joins​

When membership doesn't match the configured directory, Elastic Beanstalk logs it. For instances launched while the environment is being created, it also raises an ERROR event like this:

Active Directory domain join did not complete: instance is not joined to 'corp.example.com' (PartOfDomain=False, Domain=WORKGROUP). See the deployment log for the join output.

The walkthrough adds a detail the reference docs don't cover: Elastic Beanstalk checks the join state once per launched instance. The customer-visible ERROR event appears for launches during environment creation. For instances that Auto Scaling launches or replaces, the failure shows up in the deployment log. So for a 3 a.m. scale-out, don't rely on the events stream alone. Read the logs.

On each instance, the join output is written to C:\cfn\log\eb-ad-join.log. When a join fails, it's also copied into the deployment log, so you don't have to connect to the instance. Work through these checks:

  1. Read the join log. AWS deliberately broke a join in its walkthrough by pointing DirectoryOU at an OU that didn't exist. The log showed [ERROR] AD join failed: Could not create computer. That message means Directory Service rejected the CreateComputer call. It doesn't say why, so compare it against what you changed most recently.
  2. Check DNS. From an instance in the VPC, confirm the DirectoryName value resolves. If it doesn't, fix the DHCP options set.
  3. Check IAM. Confirm the instance profile allows ds:CreateComputer on that directory.
  4. Check the OU. It must exist, and its distinguished name must match the option value exactly.
  5. Check what the instance received. C:\cfn\eb-ad.json records the DirectoryId and DirectoryName the instance launched with.

To fix AWS's demo failure, remove the bad option. This triggers yet another instance replacement:

Code:
aws elasticbeanstalk update-environment \
  --environment-name ad-join-demo-env \
  --options-to-remove Namespace=aws:elasticbeanstalk:windows:activedirectory,OptionName=DirectoryOU

Cleaning up stale computer objects​

Elastic Beanstalk never deletes computer objects. Every instance that joins leaves an EC2-XXXXXXXX object behind, and every scale-out event adds more. Terminating instances or the whole environment doesn't remove them, and neither does switching directories or removing the options. AWS says cleanup is the customer's job, using normal directory tools.

The unique names mean these leftover objects won't collide with new instances. They will still clutter your directory and make it harder to audit. A busy, autoscaling web tier can create a lot of them over a few months. A scheduled job that finds and removes computer objects that haven't logged on recently should be part of the rollout, not something you deal with later.

Analysis: worth adopting, with caveats​

For teams already running Windows workloads on Elastic Beanstalk, this is a clear improvement:

  • Less code to maintain. Your custom join scripts can go.
  • No domain-join secrets. The domain join uses the instance profile, so no domain-join password sits in Secrets Manager, Parameter Store or a config file.
  • Predictable naming. Names based on instance IDs fix a real collision problem.

A few things to weigh against that:

  • Failures are quiet by design. Keeping the app up beats a hard failure, but an IIS site that depends on Kerberos will be up and still useless if the join fails. Add a post-deployment check or alarm based on the hostname pattern or the log line.
  • You have to clean up objects yourself. See above.
  • AD changes mean instance replacements. Plan OU and directory changes as change-managed events.
  • Platform currency matters. Teams pinned to older Windows platform versions must update before they can use the feature.

The managed policy is also broader than it may look. The scoped inline policy takes a few extra lines of JSON, and it's worth writing.

If you need finer control, such as unjoining instances when they terminate, AWS Systems Manager Automation runbooks are still an option for plain EC2 fleets. AWS has published guidance on using Automation to dynamically automate domain join and unjoin activities with Microsoft Active Directory Domain Services (AD DS) for Windows instances on Amazon EC2. For Elastic Beanstalk environments, the built-in option should now be the default.

Bottom line: Update to a Windows Server platform version from August 18, 2026 or later, fix DNS first, scope the IAM permission to your directory, create any OU in advance, and verify each join in the logs rather than trusting the health status. The feature is a big improvement over custom scripts, as long as you also schedule cleanup of old computer objects.

 

References

  1. Automate Active Directory joins for Elastic Beanstalk Windows applications - Amazon Web Services (AWS) Amazon Web Services (AWS) 2026-10-19T16:07:51+00:00
  2. RFC: Improved Windows Workload Support in Elastic Beanstalk · Issue #354 · aws/elastic-beanstalk-roadmap · GitHub github.com
  3. Joining instances to an Active Directory domain - AWS Elastic Beanstalk docs.aws.amazon.com