{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "(0004) - This template creates and installs a Windows Server 2012 based application server for testing purposes into a subnet inside a VPC. **WARNING** This template creates Amazon EC2 Windows instance and related resources. You will be billed for the AWS resources used if you create a stack from this template.", "Parameters": { "KeyPairName": { "Description": "Public/private key pairs allow you to securely connect to your instance after it launches", "Type": "AWS::EC2::KeyPair::KeyName" }, "AppServerInstanceType": { "Description": "Amazon EC2 instance type for the 1st WSFC Node", "Type": "String", "Default": "m3.xlarge", "AllowedValues": [ "m1.large", "m3.xlarge", "m2.4xlarge" ], "ConstraintDescription": "Only EBS Optimized instance types m1.large, m3.xlarge, m2.4xlarge allowed" }, "DomainDNSName": { "Description": "Fully qualified domain name (FQDN) of the forest root domain e.g. example.com", "Type": "String", "Default": "example.com", "MinLength": "3", "MaxLength": "25", "AllowedPattern": "[a-zA-Z0-9\\-]+\\..+" }, "DomainNetBIOSName": { "Description": "NetBIOS name of the domain (upto 15 characters) for users of earlier versions of Windows e.g. CORP", "Type": "String", "Default": "example", "MinLength": "1", "MaxLength": "15", "AllowedPattern": "[a-zA-Z0-9\\-]+" }, "AppServerNetBIOSName": { "Description": "NetBIOS name of the 1st WSFC Node (up to 15 characters)", "Type": "String", "Default": "SQLClient", "MinLength": "1", "MaxLength": "15", "AllowedPattern": "[a-zA-Z0-9\\-]+" }, "DomainAdminUser": { "Description": "User name for an existing domain admin account in Active Directory.", "Type": "String", "Default": "StackAdmin", "MinLength": "5", "MaxLength": "25", "AllowedPattern": "[a-zA-Z0-9]*" }, "DomainAdminPassword": { "Description": "Password for the domain admin user.", "Type": "String", "MinLength": "8", "MaxLength": "32", "NoEcho": "true" }, "ADServer1PrivateIp": { "Description": "Fixed private IP for the first Active Directory server located in AZ1", "Type": "String", "Default": "10.0.0.10" }, "ADServer2PrivateIp": { "Description": "Fixed private IP for the second Active Directory serverr located in AZ2", "Type": "String", "Default": "10.0.64.10" }, "DomainMemberSGID": { "Description": "ID of the Domain Member Security Group (e.g., sg-7f16e910)", "Type": "String" }, "VPC": { "Description": "ID of the VPC (e.g., vpc-0343606e)", "Type": "AWS::EC2::VPC::Id" }, "PrivateSubnet": { "Description": "ID of the Subnet you want to provision the App Server into (e.g., subnet-a0246dcd)", "Type": "AWS::EC2::Subnet::Id" } }, "Mappings": { "AWSAMIRegionMap": { "AMI": { "WS2012R2": "Windows_Server-2012-R2_RTM-English-64Bit-Base-2019.07.12" }, "ap-northeast-1": { "WS2012R2": "ami-0eee9047b95b1f74c" }, "ap-northeast-2": { "WS2012R2": "ami-03e603f10c77a5463" }, "ap-northeast-3": { "WS2012R2": "ami-00a2d6fa816579509" }, "ap-south-1": { "WS2012R2": "ami-0ed889b4a59795a32" }, "ap-southeast-1": { "WS2012R2": "ami-0331be4a84b3b2e75" }, "ap-southeast-2": { "WS2012R2": "ami-087682590b598bde5" }, "ca-central-1": { "WS2012R2": "ami-05b0f7544383bc098" }, "eu-central-1": { "WS2012R2": "ami-02bafaa0e5f273fe6" }, "eu-west-1": { "WS2012R2": "ami-0c12af89247c70572" }, "eu-west-2": { "WS2012R2": "ami-040d07b284d8ded6b" }, "eu-west-3": { "WS2012R2": "ami-098e42db816ef64a8" }, "sa-east-1": { "WS2012R2": "ami-0b3e238c9181e2d52" }, "us-east-1": { "WS2012R2": "ami-0b7fbf81b6d5e4ac5" }, "us-east-2": { "WS2012R2": "ami-002c8e8f81577a96c" }, "us-west-1": { "WS2012R2": "ami-073e71ca7a28f7de4" }, "us-west-2": { "WS2012R2": "ami-07872c9dbb86b69ed" } } }, "Resources": { "AppServerWaitCondition": { "Type": "AWS::CloudFormation::WaitCondition", "DependsOn": "AppServer", "Properties": { "Handle": { "Ref": "AppServerWaitHandle" }, "Timeout": "3500" } }, "AppServerWaitHandle": { "Type": "AWS::CloudFormation::WaitConditionHandle" }, "AppServer": { "Type": "AWS::EC2::Instance", "Metadata": { "AWS::CloudFormation::Init": { "configSets": { "config": [ "CFNsetup", "renameandjoin", "finalize" ] }, "CFNsetup": { "files": { "c:\\cfn\\cfn-hup.conf": { "content": { "Fn::Join": [ "", [ "[main]\n", "stack=", { "Ref": "AWS::StackId" }, "\n", "region=", { "Ref": "AWS::Region" }, "\n" ] ] } }, "c:\\cfn\\hooks.d\\cfn-auto-reloader.conf": { "content": { "Fn::Join": [ "", [ "[cfn-auto-reloader-hook]\n", "triggers=post.update\n", "path=Resources.AppServer.Metadata.AWS::CloudFormation::Init\n", "action=cfn-init.exe -v -s ", { "Ref": "AWS::StackId" }, " -r AppServer", " --region ", { "Ref": "AWS::Region" }, "\n" ] ] } } }, "services": { "windows": { "cfn-hup": { "enabled": "true", "ensureRunning": "true", "files": [ "c:\\cfn\\cfn-hup.conf", "c:\\cfn\\hooks.d\\cfn-auto-reloader.conf" ] } } } }, "renameandjoin": { "files": { "C:\\cfn\\scripts\\RenameComputer.ps1": { "content": { "Fn::Join": [ "", [ "param ($name)", "\n", "Rename-Computer $name", "\n", "Restart-Computer" ] ] } }, "C:\\cfn\\scripts\\JoinComputer.ps1": { "content": { "Fn::Join": [ "", [ "$admin_pwd = convertto-securestring ", { "Ref": "DomainAdminPassword" }, " -asplaintext -force ", "\n", "$admincreds = New-Object System.Management.Automation.PSCredential (\"", { "Ref": "DomainNetBIOSName" }, "\\", { "Ref": "DomainAdminUser" }, "\"", ",$admin_pwd)", "\n", "Set-DnsClientServerAddress -InterfaceAlias \"Ethernet\" -ServerAddresses (\"", { "Ref": "ADServer1PrivateIp" }, "\",\"", { "Ref": "ADServer2PrivateIp" }, "\")", "\n", "Add-Computer -Credential $admincreds -DomainName ", { "Ref": "DomainDNSName" }, "\n", "Restart-Computer", "\n" ] ] } } }, "commands": { "1-execute-powershell-script-RenameComputer": { "command": { "Fn::Join": [ "", [ "powershell.exe ", "-ExecutionPolicy", " RemoteSigned", " C:\\cfn\\scripts\\RenameComputer.ps1 ", { "Ref": "AppServerNetBIOSName" } ] ] }, "waitAfterCompletion": "forever" }, "2-execute-powershell-script-JoinComputer": { "command": { "Fn::Join": [ "", [ "powershell.exe ", "-ExecutionPolicy", " RemoteSigned", " C:\\cfn\\scripts\\JoinComputer.ps1" ] ] }, "waitAfterCompletion": "forever" } } }, "finalize": { "files": { "C:\\cfn\\scripts\\DownloadBlasterApp.ps1": { "content": { "Fn::Join": [ "", [ "$zipfilename = \"C:\\cfn\\scripts\\SQLBlaster_Demo.zip\"", "\n", "$destination = \"C:\\Users\\Default\\Desktop\"", "\n", "import-module BitsTransfer ", "\n", "Start-BitsTransfer ", "-Source https://s3.amazonaws.com/aws-quickstart/quickstart-microsoft-sql/scripts/SQLBlaster_Demo.zip -Destination \"$zipfilename\"", "\n", "if(test-path($zipfilename))", "\n", "{", "\n", "[Reflection.Assembly]::LoadWithPartialName( \"System.IO.Compression.FileSystem\" )", "\n", "[System.IO.Compression.ZipFile]::ExtractToDirectory($zipfilename, $destination)", "\n", "}", "\n" ] ] } }, "C:\\cfn\\scripts\\AddUserToGroup.ps1": { "content": { "Fn::Join": [ "", [ "Param(", "\n", "[Parameter(Mandatory=$True)]", "\n", "[string]$ServerName,", "\n", "[Parameter(Mandatory=$True)]", "\n", "[string]$GroupName,", "\n", "[Parameter(Mandatory=$True)]", "\n", "[string]$DomainNetBIOSName,", "\n", "[Parameter(Mandatory=$True)]", "\n", "[string]$UserName", "\n", ")", "$de = [ADSI]\"WinNT://$ServerName/$GroupName,group\"", "\n", "$de.psbase.Invoke(\"Add\",([ADSI]\"WinNT://$DomainNetBIOSName/$UserName\").path)", "\n" ] ] } } }, "commands": { "1-execute-powershell-script-DownloadBlasterApp": { "command": { "Fn::Join": [ "", [ "powershell.exe ", "-ExecutionPolicy", " RemoteSigned", " C:\\cfn\\scripts\\DownloadBlasterApp.ps1" ] ] }, "waitAfterCompletion": "0" }, "2-execute-powershell-script-AddUserToGroup": { "command": { "Fn::Join": [ "", [ "powershell.exe ", "-ExecutionPolicy", " RemoteSigned", " C:\\cfn\\scripts\\AddUserToGroup.ps1 -UserName ", { "Ref": "DomainAdminUser" }, " -ServerName ", { "Ref": "AppServerNetBIOSName" }, " -DomainNetBIOSName ", { "Ref": "DomainNetBIOSName" }, " -GroupName \"Administrators\"", "\n" ] ] }, "waitAfterCompletion": "0" }, "3-signal-success": { "command": { "Fn::Join": [ "", [ "cfn-signal.exe -e 0 \"", { "Ref": "AppServerWaitHandle" }, "\"" ] ] } } } } } }, "Properties": { "ImageId": { "Fn::FindInMap": [ "AWSAMIRegionMap", { "Ref": "AWS::Region" }, "WS2012R2" ] }, "InstanceType": { "Ref": "AppServerInstanceType" }, "SubnetId": { "Ref": "PrivateSubnet" }, "EbsOptimized": "true", "Tags": [ { "Key": "Name", "Value": { "Ref": "AppServerNetBIOSName" } } ], "BlockDeviceMappings": [ { "DeviceName": "/dev/sda1", "Ebs": { "VolumeSize": "100", "VolumeType": "gp2" } } ], "SecurityGroupIds": [ { "Ref": "DomainMemberSGID" } ], "KeyName": { "Ref": "KeyPairName" }, "UserData": { "Fn::Base64": { "Fn::Join": [ "", [ "" ] ] } } } } }, "Outputs": { "DomainAdmin": { "Value": { "Fn::Join": [ "", [ { "Ref": "DomainNetBIOSName" }, "\\", { "Ref": "DomainAdminUser" } ] ] }, "Description": "Domain administrator account" }, "LocalAdmin": { "Value": "Administrator", "Description": "Please retrieve Administrator password of the instance" }, "AppServerNetBIOSName": { "Value": { "Ref": "AppServerNetBIOSName" }, "Description": "NetBIOS name of the App Server" } } }