This repository contains sample code for the AWS Blog Post Using Windows Authentication with gMSA on Linux Containers on Amazon ECS.
Before running this sample, you will need:
- An AWS account.
- Complete the AWS CDK getting started guide, including installing the CDK and learning the key concepts.
- Create an Amazon EC2 key pair and record its name.
- Install the AWS CLI and set up your AWS credentials for command-line use if you are using a Bash-compatible shell.
- If you prefer to use PowerShell, install the AWS Tools for PowerShell and set up your AWS credentials for PowerShell.
- Install a Microsoft Remote Desktop (RDP) client.
- Install the latest version of the Docker runtime.
- Install the latest .NET 6 SDK.
There are two modes in which you can support Windows authentication using gMSA for your applications, non-domain-joined (domainless) mode and domain-joined mode.
In domainless mode, the Amazon ECS container instances doesn’t need to be joined to the target AD domain. This is the recommended mode for most workloads, especially when scaling is needed.
In domain-joined mode, you to have the Amazon ECS container instances joined to the target AD domain prior to deploying tasks on them. Use this mode if you don’t want to manage individual AD user accounts.
-
Clone this repository and open the terminal and run the following commands, replace
{KEY_PAIR_NAME}
with your Amazon EC2 key pair name, and run the following commands:- If you are using Bash:
export AWS_DEFAULT_REGION={YOUR REGION} export EC2_INSTANCE_KEYPAIR_NAME="{KEY_PAIR_NAME}" export MY_SG_INGRESS_IP=$(curl checkip.amazonaws.com) export DOMAIN_JOIN_ECS=0
- If you’re using PowerShell:
$Env:AWS_DEFAULT_REGION = "{YOUR REGION}" $Env:EC2_INSTANCE_KEYPAIR_NAME = "{KEY_PAIR_NAME}" $Env:MY_SG_INGRESS_IP = $(Invoke-WebRequest -URI https://checkip.amazonaws.com).ToString().Trim() $Env:DOMAIN_JOIN_ECS = 0
- If you are using Bash:
-
Based on your laguage poreference, perform one of the following tasks:
- For Typescript: Open a terminal and in the cdk-typescript folder and execute the following command:
npm install
- For C#: Open a terminal and in the cdk-dotnet folder and execute the following command:
dotnet build src
- For Typescript: Open a terminal and in the cdk-typescript folder and execute the following command:
-
Execute deploy command for cdk project:
cdk deploy "*" --require-approval "never"
Note: To use domain-joined mode, set the
DOMAIN_JOIN_ECS
variable to1
before deploying the AWS CDK solution.
Note: In domain-joined mode, you need to add the Computer principal to the AD security group allowed to retrieve gMSA passwords. You can do this manually or via automation. The script inside the AD management instance on
C:\SampleConfig\Add-ECSContainerInstancesToADGroup.ps1
inside the AD management instance, automatically adds all Amazon ECS container instance's principals to the AD security group. You need to pass as argument the name of the Amazon ECS’s ASG, which you will find in the ECSAutoScalingGroupName output of the amazon-ecs-gmsa-linux-infrastructure CloudFormation stack.
- Navigate to the AWS Secrets Manager console and copy the value of the amazon-ecs-gmsa-linux/active-directory-administrator-password secret.
This will start the deployment of three AWS CloudFormation stacks that contain the sample solution. The deployment takes around one hour to complete.
- Navigate to the Amazon EC2 console, then select the instance named amazon-ecs-gmsa-linux-bastion/active-directory-management-instance and connect to it using RDP using the following:
- Username:
directory.amazon-ecs-gmsa-linux.com\admin
- Password: Use the one you retrieved from Secrets Manager.
- Username:
If you can’t log in, the instance is still setting up the database and Active Directory. Wait 10-15 minutes and try again.
- In the Remote Desktop session, open a PowerShell window and run
C:\SampleConfig\Generate-CredSpec.ps1
Note: In domain-joined mode, append the following parameter while running the script:
-DomainlessArn ""
.
-
Open a terminal in the web-app folder and build the solution running
dotnet build web-app.sln
-
Build the Docker container running
docker build .
-
Navigate to the Amazon ECR console,select the amazon-ecs-gmsa-linux/web-site repository, then select View push commands.
-
Follow the directions to tag and push your image to the ECR repository.
If you are building the container in a computer with an ARM processor like a M1/M2 Mac, to build a x86-64 container use:
docker buildx build --platform=linux/amd64 -t amazon-ecs-gmsa-linux/web-site .
You need to update the ECS Task definition created by CDK to set the ARN for the CredSpec file using the new credentialSpec
property. This property can only be set using the AWS CLI. The sample solution has a script that does this for you. Using the same terminal where you deployed the CDK solution, run the following command if you are using Bash:
../scripts/update-ecs-task-definition-cred-spec.sh -t amazon-ecs-gmsa-linux-web-site-task
Or the following command if you are using PowerShell:
../scripts/Update-ECSTaskDefinitionCredSpec.ps1 -TaskDefinitionName amazon-ecs-gmsa-linux-web-site-task
Note: In domain-joined mode, set the
--domain-joined-mode
(-DomainJoinedMode
in PowerShell) flag when running the script.
Review the output of the script and take note of the revision number that was just created. You will use it in the next step.
-
Go back to the terminal you used to deploy the infrastructure and run the following commands:
-
If you are using Bash:
export DEPLOY_APP=1 export APP_TD_REVISION=[TASK DEFINITION REVISION] cdk deploy "*" --require-approval "never"
-
If you are using PowerShell:
$Env:DEPLOY_APP = 1 $Env:APP_TD_REVISION = [TASK DEFINITION REVISION] cdk deploy "*" --require-approval "never"
-
-
Once the deployment is complete, go to the CloudFormation console and click on the value of the output named like websiteec2serviceServiceURLXXXXXXXX to navigate to the web app. The web application will run and authenticate to the AD using the gMSA.
-
Run this command in the terminal or PowerShell window::
cdk destroy "*" --require-approval "never"
-
Manually delete the manually created revision for the amazon-ecs-gmsa-linux-web-site-task Amazon ECS task definition, the amazon-ecs-gmsa-linux/web-site Amazon ECR repository, and the amazon-ecs-gmsa-linux-infrastructure-vpcFlowLogCloudWatchLogGroupXXXXXXX-XXXXXXXXXXXX Amazon CloudWatch log group .
See CONTRIBUTING for more information.
This library is licensed under the MIT-0 License. See the LICENSE file.