Joining an EC2 instance to a self-managed AD to launch with user-data

My latest project is a bit of a return to my old life with Microsoft. The majority of my AWS work has been with Linux workloads, so it’s been nice to brush off my old skills and return to PowerShell 😃. After manually joining a couple of instances to a self-managed AD (not an AWS Managed AD instance) via an SSM session and PowerShell, I decided to script the process. A quick search of the web and I found very little on the topic, so I cobbled together a process.

THE SETUP

1. Create an “AD Joiner” user and delegate the “Join a computer to the domain” at the root of the domain.

2. Create a secret in AWS Secrets Manager with username and password as keys and values of the user and password created in AD.

3. Create an IAM policy to allow access to secret. Then assign policy to EC2 IAM Role.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue",
                "secretsmanager:DescribeSecret"
            ],
            "Resource": [
                "arn:aws:secretsmanager:us-east-1:0123456789:secret:adjoin-joiner"
            ]
        }
    ]
}

4. Update the VPC’s DHCP setting to assign the self-managed AD’s DCs as DNS servers.

5. Add code user-data and assign a Name tag and value

THE CODE

The code will use EC2’s metadata to pull the Name tag and use that as the computer name or if none is provided the instance’s randomly generated name is used. Also the code will install the NuGet and AWSPowerShell modules. The NuGet module is needed to be able to install the AWSPowerShell module and the AWSPowerShell module is required to call the AWS Secret values.

<powershell>
#Variables
$secretArn = "arn:aws:secretsmanager:us-east-1:0123456789:secret:adjoin-xxxx"
$domain = "thenewtonlab.com"
$OUPath = "OU=AWS,OU=Lab,DC=thenewtonlab,DC=com"

#Install AWSPowerShell module
Start-Transcript -Path "C:\Programdata\Amazon\EC2Launch\log\user-data.log"
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
Install-Module AWSPowerShell -SkipPublisherCheck -Force -Scope AllUsers
Import-Module -Name AWSPowershell

#Get instance Name Tag
[string]$token = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"} -Method PUT -Uri http://169.254.169.254/latest/api/token
$instanceId = (invoke-webrequest -Headers @{"X-aws-ec2-metadata-token" = $token} -uri http://169.254.169.254/latest/meta-data/instance-id -UseBasicParsing).content
$compname = (get-ec2tag -filter @{Name="resource-id";Value=$instanceid},@{Name="key";Value="Name"}).Value
Write-host $compname

#Get Password
$user1 = ((Get-SECSecretValue -SecretId $secretArn).SecretString| ConvertFrom-Json).username
$pwd1 = ((Get-SECSecretValue -SecretId $secretArn).SecretString|ConvertFrom-Json).password | ConvertTo-SecureString -AsPlainText -Force 
$cred = New-Object -TypeName System.Management.Automation.PSCredential ($User1, $pwd1)

#Join to domain and rename instance
if($compname){
    Add-Computer -ComputerName $env:COMPUTERNAME -NewName $compname -DomainName $domain -OUPath $OUPath -Credential $cred -restart -ErrorAction Continue
}
else {
    Add-Computer -ComputerName $env:COMPUTERNAME -DomainName $domain -OUPath $OUPath -Credential $cred -ErrorAction Continue
}
</powershell>

Happy building,

D

Joining an EC2 instance to a self-managed AD to launch with user-data

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top