Skip to content

Commit

Permalink
Merge pull request #166 from muskanlalit18/dev
Browse files Browse the repository at this point in the history
simplify e2e test, add error handling and cleanup
  • Loading branch information
muskanlalit18 authored Jan 21, 2025
2 parents 799e0fb + 3a5c0aa commit c994168
Show file tree
Hide file tree
Showing 9 changed files with 525 additions and 356 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ def modify_task_definition(task_definition, ecs_cluster_arn, bucket_arn, s3_key)
task_definition["compatibilities"].append("FARGATE")

for container_def in task_definition['containerDefinitions']:
container_def['credentialSpecs']=[]
credspec = container_def['credentialSpecs']
credspec = [d for d in credspec if 'credentialspecdomainless' not in d]
credspec.append(f"credentialspecdomainless:{bucket_arn}/{s3_key}")
Expand Down
47 changes: 23 additions & 24 deletions cdk/cdk-domainless-mode/tests/create_secrets.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,28 @@ def create_secrets():
client = boto3.client('secretsmanager')

# Base path for the secrets
base_path = "aws/directoryservice/contoso/gmsa"
secret_name = "aws/directoryservice/contoso/gmsa"

for i in range(1, number_of_gmsa_accounts + 1):
# Create the secret name
secret_name = f"{base_path}/WebApp0{i}"
# Create the secret value
secret_value = {
"username": username,
"password": password,
"domainName": directory_name,
# "distinguishedName": f"CN=WebApp0{i},OU=MYOU,OU=Users,OU={netbios_name},DC={netbios_name},DC=com"
}

# Create the secret value
secret_value = {
"username": username,
"password": password,
"domainName": directory_name,
"distinguishedName": f"CN=WebApp0{i},OU=MYOU,OU=Users,OU={netbios_name},DC={netbios_name},DC=com"
}

try:
# Create the secret
response = client.create_secret(
Name=secret_name,
Description=f"Secret for WebApp0{i}",
SecretString=json.dumps(secret_value)
)
print(f"Created secret: {secret_name}")
except client.exceptions.ResourceExistsException:
print(f"Secret already exists: {secret_name}")
except Exception as e:
print(f"Error creating secret {secret_name}: {str(e)}")
try:
# Create the secret
response = client.create_secret(
Name=secret_name,
Description=f"Secret for WebApp01",
SecretString=json.dumps(secret_value)
)
print(f"Created secret: {secret_name}")

except client.exceptions.ResourceExistsException:
print(f"Secret already exists: {secret_name}")
except Exception as e:
print(f"Error creating secret {secret_name}: {str(e)}")
return False
return True
24 changes: 0 additions & 24 deletions cdk/cdk-domainless-mode/tests/delete_secrets.py

This file was deleted.

206 changes: 103 additions & 103 deletions cdk/cdk-domainless-mode/tests/gmsa.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,116 +7,109 @@
# 5) Add members to the security group that is allowed to retrieve gMSA password
# 6) Create gMSA accounts with PrincipalsAllowedToRetrievePassword set to the security group created in 4)

# 1) Install SSM agent
function Test-SSMAgentUpdate {
$ssm = Get-Service -Name "AmazonSSMAgent" -ErrorAction SilentlyContinue
if (-not $ssm) { return $false }
# Add additional version checking logic if needed
return $true
# Create a temporary directory for downloads
$tempDir = "C:\temp"
if (-not (Test-Path $tempDir)) {
New-Item -ItemType Directory -Path $tempDir
}

# 1) Install SSM agent
Write-Output "Updating SSM agent..."
[System.Net.ServicePointManager]::SecurityProtocol = 'TLS12'
$progressPreference = 'silentlyContinue'
Invoke-WebRequest https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/windows_amd64/AmazonSSMAgentSetup.exe -OutFile $env:USERPROFILE\Desktop\SSMAgent_latest.exe
Start-Process -FilePath $env:USERPROFILE\Desktop\SSMAgent_latest.exe -ArgumentList "/S"

# To install the AD module on Windows Server, run Install-WindowsFeature RSAT-AD-PowerShell
# To install the AD module on Windows 10 version 1809 or later, run Add-WindowsCapability -Online -Name 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0'
# To install the AD module on older versions of Windows 10, see https://aka.ms/rsat
try {
# 1) Check and Update SSM agent if needed
if (-not (Test-SSMAgentUpdate)) {
Write-Output "Updating SSM agent..."
[System.Net.ServicePointManager]::SecurityProtocol = 'TLS12'
$progressPreference = 'silentlyContinue'
Invoke-WebRequest https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/windows_amd64/AmazonSSMAgentSetup.exe -OutFile $env:USERPROFILE\Desktop\SSMAgent_latest.exe
Start-Process -FilePath $env:USERPROFILE\Desktop\SSMAgent_latest.exe -ArgumentList "/S"
}
Write-Output "Installing Active Directory management tools..."
Install-WindowsFeature -Name "RSAT-AD-Tools" -IncludeAllSubFeature
Install-WindowsFeature RSAT-AD-PowerShell
Install-Module CredentialSpec
Install-Module -Name SqlServer -AllowClobber -Force

# Check if AD tools are installed
if (-not (Get-WindowsFeature -Name "RSAT-AD-Tools").Installed) {
Write-Output "Installing Active Directory management tools..."
Install-WindowsFeature -Name "RSAT-AD-Tools" -IncludeAllSubFeature
Install-WindowsFeature RSAT-AD-PowerShell
Install-Module CredentialSpec -Force
Install-Module -Name SqlServer -AllowClobber -Force
}
$username = "admin@DOMAINNAME"
$password = "INPUTPASSWORD" | ConvertTo-SecureString -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($username, $password)
$groupAllowedToRetrievePassword = "WebAppAccounts_OU"
# This is the basedn path that needs to be in secrets manager as "distinguishedName" : "OU=MYOU,OU=Users,OU=ActiveDirectory,DC=contoso,DC=com"
$path = "OU=MYOU,OU=Users,OU=contoso,DC=NETBIOS_NAME,DC=com"
$supath = "OU=Users,OU=contoso,DC=contoso,DC=com"

$username = "admin@DOMAINNAME"
$password = "INPUTPASSWORD" | ConvertTo-SecureString -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($username, $password)
$groupAllowedToRetrievePassword = "WebAppAccounts_OU"
# This is the basedn path that needs to be in secrets manager as "distinguishedName" : "OU=MYOU,OU=Users,OU=ActiveDirectory,DC=contoso,DC=com"
$path = "OU=MYOU,OU=Users,OU=contoso,DC=NETBIOS_NAME,DC=com"

# 2) Create OU if it doesn't exist
if (-not (Get-ADOrganizationalUnit -Filter "Name -eq 'MYOU'" -ErrorAction SilentlyContinue)) {
New-ADOrganizationalUnit -Name "MYOU" -Path "OU=Users,OU=contoso,DC=NETBIOS_NAME,DC=com" -Credential $credential
}
# 2) Create OU
New-ADOrganizationalUnit -Name "MYOU" -Path "OU=Users,OU=contoso,DC=NETBIOS_NAME,DC=com" -Credential $credential

# 3) Create security group if it doesn't exist
if (-not (Get-ADGroup -Filter "SamAccountName -eq '$groupAllowedToRetrievePassword'" -ErrorAction SilentlyContinue)) {
New-ADGroup -Name "WebApp Authorized Accounts in OU" -SamAccountName $groupAllowedToRetrievePassword -Credential $credential -GroupScope DomainLocal -Server DOMAINNAME
}

# 4) Create standard user if it doesn't exist
if (-not (Get-ADUser -Filter "SamAccountName -eq 'StandardUser01'" -ErrorAction SilentlyContinue)) {
New-ADUser -Name "StandardUser01" -AccountPassword (ConvertTo-SecureString -AsPlainText "********" -Force) -Enabled 1 -Credential $credential -Path $path -Server DOMAINNAME
}

# 5) Add members to security group if not already members
$group = Get-ADGroup $groupAllowedToRetrievePassword
$members = Get-ADGroupMember $group | Select-Object -ExpandProperty SamAccountName
# 3) Create the security group
try {
New-ADGroup -Name "WebApp Authorized Accounts in OU" -SamAccountName $groupAllowedToRetrievePassword -Credential $credential -GroupScope DomainLocal -Server DOMAINNAME
} catch {
Write-Output "Security Group created"
}

foreach ($member in @("StandardUser01", "admin")) {
if ($member -notin $members) {
Add-ADGroupMember -Identity $groupAllowedToRetrievePassword -Members $member -Credential $credential -Server DOMAINNAME
}
}
# 4) Create a new standard user account, this account's username and password needs to be stored in a secret store like AWS secrets manager.
try {
New-ADUser -Name "StandardUser01" -AccountPassword (ConvertTo-SecureString -AsPlainText "p@ssw0rd" -Force) -Enabled 1 -Credential $credential -Path $supath -Server DOMAINNAME
} catch {
Write-Output "Created StandardUser01"
}

# 6) Create gMSA accounts if they don't exist
for (($i = 1); $i -le $NUMBER_OF_GMSA_ACCOUNTS; $i++) {
$gmsa_account_name = "WebApp0" + $i
$gmsa_account_with_domain = $gmsa_account_name + ".DOMAINNAME"
$gmsa_account_with_host = "host/" + $gmsa_account_name
$gmsa_account_with_host_and_domain = $gmsa_account_with_host + ".DOMAINNAME"
# 5) Add members to the security group that is allowed to retrieve gMSA password
try {
Add-ADGroupMember -Identity $groupAllowedToRetrievePassword -Members "StandardUser01" -Credential $credential -Server DOMAINNAME
Add-ADGroupMember -Identity $groupAllowedToRetrievePassword -Members "admin" -Credential $credential -Server DOMAINNAME
} catch {
Write-Output "Created AD Group $groupAllowedToRetrievePassword"
}

if (-not (Get-ADServiceAccount -Filter "Name -eq '$gmsa_account_name'" -ErrorAction SilentlyContinue)) {
# 6) Create gMSA accounts with PrincipalsAllowedToRetrievePassword set to the security group created in 4)
$string_err = ""
for (($i = 1); $i -le NUMBER_OF_GMSA_ACCOUNTS; $i++)
{
# Create the gMSA account
$gmsa_account_name = "WebApp0" + $i
$gmsa_account_with_domain = $gmsa_account_name + ".DOMAINNAME"
$gmsa_account_with_host = "host/" + $gmsa_account_name
$gmsa_account_with_host_and_domain = $gmsa_account_with_host + ".DOMAINNAME"

try {
# Check if the service account already exists
if (-not (Get-ADServiceAccount -Filter {Name -eq $gmsa_account_name} -ErrorAction SilentlyContinue)) {
New-ADServiceAccount -Name $gmsa_account_name `
-DnsHostName $gmsa_account_with_domain `
-ServicePrincipalNames $gmsa_account_with_host, $gmsa_account_with_host_and_domain `
-PrincipalsAllowedToRetrieveManagedPassword $groupAllowedToRetrievePassword `
-Path $path `
-Credential $credential `
-Server DOMAINNAME
-DnsHostName $gmsa_account_with_domain `
-ServicePrincipalNames $gmsa_account_with_host, $gmsa_account_with_host_and_domain `
-PrincipalsAllowedToRetrieveManagedPassword $groupAllowedToRetrievePassword `
-Path $path `
-Credential $credential `
-Server DOMAINNAME
Write-Output "Created new gMSA account: $gmsa_account_name"
} else {
Write-Output "gMSA account $gmsa_account_name already exists - skipping creation"
}
} catch {
$string_err = $_ | Out-String
Write-Output "Error while processing gMSA account $gmsa_account_name : $string_err"
}
}

# SQL Server Configuration
$sqlInstance = $env:computername

# Create firewall rules if they don't exist
$firewallRules = Get-NetFirewallRule | Select-Object -ExpandProperty DisplayName
# Set the SQL Server instance name
$sqlInstance = $env:computername

if ("SQLServer default instance" -notin $firewallRules) {
New-NetFirewallRule -DisplayName "SQLServer default instance" -Direction Inbound -LocalPort 1433 -Protocol TCP -Action Allow
}
if ("SQLServer Browser service" -notin $firewallRules) {
New-NetFirewallRule -DisplayName "SQLServer Browser service" -Direction Inbound -LocalPort 1434 -Protocol UDP -Action Allow
}
if ("AllowRDP" -notin $firewallRules) {
New-NetFirewallRule -DisplayName "AllowRDP" -Direction Inbound -Protocol TCP -LocalPort 3389 -Action Allow
}
if ("AllowSQLServer" -notin $firewallRules) {
New-NetFirewallRule -DisplayName "AllowSQLServer" -Direction Inbound -Protocol TCP -LocalPort 1433 -Action Allow
}
New-NetFirewallRule -DisplayName "SQLServer default instance" -Direction Inbound -LocalPort 1433 -Protocol TCP -Action Allow
New-NetFirewallRule -DisplayName "SQLServer Browser service" -Direction Inbound -LocalPort 1434 -Protocol UDP -Action Allow
netsh advfirewall firewall add rule name = SQLPort dir = in protocol = tcp action = allow localport = 1433 remoteip = localsubnet profile = DOMAIN
New-NetFirewallRule -DisplayName AllowRDP -Direction Inbound -Protocol TCP –LocalPort 3389 -Action Allow
New-NetFirewallRule -DisplayName "AllowSQLServer" -Direction Inbound -Protocol TCP -LocalPort 1433 -Action Allow

# SQL Database creation and configuration
$connectionString0 = "Server=$sqlInstance;Integrated Security=True;"
$connectionString1 = "Server=$sqlInstance;Database=EmployeesDB;Integrated Security=True;"

# Check if database exists
$dbExists = Invoke-Sqlcmd -ConnectionString $connectionString0 -Query "SELECT name FROM sys.databases WHERE name = 'EmployeesDB'"
# Create a connection string
$connectionString0 = "Server=$sqlInstance;Integrated Security=True;"
$connectionString1 = "Server=$sqlInstance;Database=EmployeesDB;Integrated Security=True;"

if (-not $dbExists) {
Invoke-Sqlcmd -ConnectionString $connectionString0 -Query "CREATE DATABASE EmployeesDB"
$createDatabaseQuery = "CREATE DATABASE EmployeesDB"

$query = @"
$query = @"
CREATE TABLE dbo.EmployeesTable (
EmpID INT IDENTITY(1,1) PRIMARY KEY,
EmpName VARCHAR(50) NOT NULL,
Expand All @@ -133,21 +126,28 @@ VALUES
('DEWANE PAUL', 'PROGRAMMER', 'IT', '2022-03-05 03:57:09.967'),
('MATTS', 'SR. PROGRAMMER', 'IT', '2022-03-05 03:57:09.967'),
('PLANK OTO', 'ACCOUNTANT', 'ACCOUNTS', '2022-03-05 03:57:09.967');
alter authorization on database::[EmployeesDB] to [WebApp01$]
"@

Invoke-Sqlcmd -ConnectionString $connectionString1 -Query $query
}

# Check if login exists before creating
$loginExists = Invoke-Sqlcmd -ConnectionString $connectionString0 -Query "SELECT name FROM sys.server_principals WHERE name = 'NETBIOS_NAME\webapp01$'"
Invoke-Sqlcmd -ConnectionString $connectionString0 -Query $createDatabaseQuery -QueryTimeout 60
Invoke-Sqlcmd -ConnectionString $connectionString1 -Query $query

# Sleep for 10 seconds
Start-Sleep -Seconds 10

# Loop through WebApp01$ to WebApp010$
for ($i = 1; $i -le NUMBER_OF_GMSA_ACCOUNTS; $i++) {
$webAppName = "WebApp0$i`$"

$createLoginQuery = @"
CREATE LOGIN [NETBIOS_NAME\$webAppName] FROM WINDOWS WITH DEFAULT_DATABASE = [master], DEFAULT_LANGUAGE = [us_english];
USE [EmployeesDB];
CREATE USER [$webAppName] FOR LOGIN [NETBIOS_NAME\$webAppName];
ALTER ROLE [db_owner] ADD MEMBER [$webAppName];
ALTER AUTHORIZATION ON DATABASE::[EmployeesDB] TO [$webAppName];
"@

if (-not $loginExists) {
$createLoginQuery = "CREATE LOGIN [NETBIOS_NAME\webapp01$] FROM WINDOWS WITH DEFAULT_DATABASE = [master], DEFAULT_LANGUAGE = [us_english]; EXEC sp_addrolemember 'db_owner', 'NETBIOS_NAME\webapp01$';"
Invoke-Sqlcmd -ConnectionString $connectionString0 -Query $createLoginQuery
}
Write-Host "Creating login and granting permissions for $webAppName"
Invoke-Sqlcmd -ConnectionString $connectionString0 -Query $createLoginQuery
}

} catch {
Write-Error "An error occurred: $_"
throw
}

1 change: 1 addition & 0 deletions cdk/cdk-domainless-mode/tests/parse_data_from_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def get_value(key):
password = data["password"]
windows_instance_tag = data["windows_instance_tag"]
domain_admin_password = data["domain_admin_password"]
containers_per_instance = data["max_tasks_per_instance"] * 10 # maximum number of container definitions per task is 10 (ref: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-quotas.html)

if "XXX" in bucket_name:
print("S3_PREFIX is not setup correctly, please set it and retry")
Expand Down
Loading

0 comments on commit c994168

Please sign in to comment.