Skip to content

Commit 21d14f6

Browse files
committed
[ActiveDirectory] In AD 1-click template fail faster in case of issues.
In particular: 1. Make the Ad admin node signal the failure, not only the success; in this way the wait condition handle can fail faster. 2. reduced the number of retries made by adcli from 5 to 3 because in case of issues is not necessary to do that many retries; especially considering that adcli has a 2min retry delay. 3. reduced the condition handle timeout from 900s to 600s as 10min are enough to include AD admin node bootstrap and 3 adcli retries. 4. Execute the post processing lambda only if the AD admin node was able to setup the directory
1 parent 3156e9b commit 21d14f6

File tree

1 file changed

+60
-47
lines changed

1 file changed

+60
-47
lines changed

cloudformation/ad/ad-integration.yaml

Lines changed: 60 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ Resources:
402402
Properties:
403403
Count: 1
404404
Handle: !Ref AdDomainAdminNodeWaitConditionHandle
405-
Timeout: 900
405+
Timeout: 600
406406

407407
AdDomainAdminNode:
408408
Type: AWS::EC2::Instance
@@ -446,55 +446,66 @@ Resources:
446446
#!/bin/bash -e
447447
set -o pipefail
448448
exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
449-
yum update -y aws-cfn-bootstrap
450-
/opt/aws/bin/cfn-init -v --stack "${AWS::StackName}" --resource AdDomainAdminNode --configsets setup --region "${AWS::Region}"
451-
echo "Directory Id: ${DirectoryId}"
452-
echo "Domain Name: ${DirectoryDomain}"
453-
echo "Domain DNS IP 1: ${DnsIp1}"
454-
echo "Domain DNS IP 2: ${DnsIp2}"
455-
echo "Domain Certificate Secret: ${DomainCertificateSecretArn}"
456-
echo "Domain Private Key Secret: ${DomainPrivateKeySecretArn}"
449+
function main() {
450+
yum update -y aws-cfn-bootstrap
451+
/opt/aws/bin/cfn-init -v --stack "${AWS::StackName}" --resource AdDomainAdminNode --configsets setup --region "${AWS::Region}"
452+
echo "Directory Id: ${DirectoryId}"
453+
echo "Domain Name: ${DirectoryDomain}"
454+
echo "Domain DNS IP 1: ${DnsIp1}"
455+
echo "Domain DNS IP 2: ${DnsIp2}"
456+
echo "Domain Certificate Secret: ${DomainCertificateSecretArn}"
457+
echo "Domain Private Key Secret: ${DomainPrivateKeySecretArn}"
458+
459+
echo "Describing directory..."
460+
aws ds describe-directories --directory-id "${DirectoryId}" --region "${AWS::Region}"
461+
echo "Describing domain controllers..."
462+
aws ds describe-domain-controllers --directory-id "${DirectoryId}" --region "${AWS::Region}"
463+
464+
ADMIN_PW="${AdminPassword}"
465+
466+
USERNAMES="ReadOnlyUser,${UserNames}"
467+
echo "Registering Users: $USERNAMES ..."
468+
for username in $(echo $USERNAMES | sed "s/,/ /g")
469+
do
470+
attempt=0
471+
max_attempts=3
472+
until [ $attempt -ge $max_attempts ]; do
473+
attempt=$((attempt+1))
474+
echo "Registering user $username (attempt $attempt/$max_attempts) ..."
475+
echo "$ADMIN_PW" | adcli create-user -v -x -U "${Admin}" --domain-controller="${DnsIp1}" --display-name="$username" "$username" && echo "User registered: $username" && break
476+
echo "$ADMIN_PW" | adcli create-user -v -x -U "${Admin}" --domain-controller="${DnsIp2}" --display-name="$username" "$username" && echo "User registered: $username" && break
477+
echo "User creation failed, describing directory and controllers for troubleshooting..."
478+
aws ds describe-directories --directory-id "${DirectoryId}" --region "${AWS::Region}"
479+
aws ds describe-domain-controllers --directory-id "${DirectoryId}" --region "${AWS::Region}"
480+
sleep 10
481+
done
482+
done
483+
484+
echo "Creating domain certificate..."
485+
PRIVATE_KEY="${DirectoryDomain}.key"
486+
CERTIFICATE="${DirectoryDomain}.crt"
487+
printf '.\n.\n.\n.\n.\n%s\n.\n' "${DirectoryDomain}" | openssl req -x509 -sha256 -nodes -newkey rsa:2048 -keyout "$PRIVATE_KEY" -days 365 -out "$CERTIFICATE"
488+
489+
echo "Storing domain private key to Secrets Manager..."
490+
aws secretsmanager put-secret-value --secret-id "${DomainPrivateKeySecretArn}" --secret-string "file://$PRIVATE_KEY" --region "${AWS::Region}"
491+
492+
echo "Storing domain certificate to Secrets Manager..."
493+
aws secretsmanager put-secret-value --secret-id "${DomainCertificateSecretArn}" --secret-string "file://$CERTIFICATE" --region "${AWS::Region}"
494+
495+
echo "Deleting private key and certificate from local file system..."
496+
rm -rf "$PRIVATE_KEY" "$CERTIFICATE"
497+
}
457498

458-
echo "Describing directory..."
459-
aws ds describe-directories --directory-id "${DirectoryId}" --region "${AWS::Region}"
460-
echo "Describing domain controllers..."
461-
aws ds describe-domain-controllers --directory-id "${DirectoryId}" --region "${AWS::Region}"
499+
function signal_success() {
500+
/opt/aws/bin/cfn-signal -e 0 --stack "${AWS::StackName}" --resource "${AdDomainAdminNodeWaitConditionHandle}" --region "${AWS::Region}"
501+
}
462502

463-
ADMIN_PW="${AdminPassword}"
503+
function signal_failure() {
504+
/opt/aws/bin/cfn-signal -e 0 --stack "${AWS::StackName}" --resource "${AdDomainAdminNodeWaitConditionHandle}" --region "${AWS::Region}"
505+
exit 1
506+
}
464507

465-
USERNAMES="ReadOnlyUser,${UserNames}"
466-
echo "Registering Users: $USERNAMES ..."
467-
for username in $(echo $USERNAMES | sed "s/,/ /g")
468-
do
469-
attempt=0
470-
max_attempts=5
471-
until [ $attempt -ge $max_attempts ]; do
472-
attempt=$((attempt+1))
473-
echo "Registering user $username (attempt $attempt/$max_attempts) ..."
474-
echo "$ADMIN_PW" | adcli create-user -v -x -U "${Admin}" --domain-controller="${DnsIp1}" --display-name="$username" "$username" && echo "User registered: $username" && break
475-
echo "$ADMIN_PW" | adcli create-user -v -x -U "${Admin}" --domain-controller="${DnsIp2}" --display-name="$username" "$username" && echo "User registered: $username" && break
476-
echo "User creation failed, describing directory and controllers for troubleshooting..."
477-
aws ds describe-directories --directory-id "${DirectoryId}" --region "${AWS::Region}"
478-
aws ds describe-domain-controllers --directory-id "${DirectoryId}" --region "${AWS::Region}"
479-
sleep 10
480-
done
481-
done
482-
483-
echo "Creating domain certificate..."
484-
PRIVATE_KEY="${DirectoryDomain}.key"
485-
CERTIFICATE="${DirectoryDomain}.crt"
486-
printf '.\n.\n.\n.\n.\n%s\n.\n' "${DirectoryDomain}" | openssl req -x509 -sha256 -nodes -newkey rsa:2048 -keyout "$PRIVATE_KEY" -days 365 -out "$CERTIFICATE"
487-
488-
echo "Storing domain private key to Secrets Manager..."
489-
aws secretsmanager put-secret-value --secret-id "${DomainPrivateKeySecretArn}" --secret-string "file://$PRIVATE_KEY" --region "${AWS::Region}"
490-
491-
echo "Storing domain certificate to Secrets Manager..."
492-
aws secretsmanager put-secret-value --secret-id "${DomainCertificateSecretArn}" --secret-string "file://$CERTIFICATE" --region "${AWS::Region}"
493-
494-
echo "Deleting private key and certificate from local file system..."
495-
rm -rf "$PRIVATE_KEY" "$CERTIFICATE"
496-
497-
/opt/aws/bin/cfn-signal -e "$?" --stack "${AWS::StackName}" --region "${AWS::Region}" "${AdDomainAdminNodeWaitConditionHandle}"
508+
main && signal_success || signal_failure
498509

499510
- { DirectoryId: !GetAtt Prep.DirectoryId,
500511
DirectoryDomain: !GetAtt Prep.DomainName,
@@ -622,6 +633,8 @@ Resources:
622633
623634
Post:
624635
Type: Custom::PostLambda
636+
DependsOn:
637+
- AdDomainAdminNodeWaitCondition
625638
Properties:
626639
ServiceToken: !GetAtt PostLambda.Arn
627640
AdminNodeInstanceId: !Ref AdDomainAdminNode

0 commit comments

Comments
 (0)