├── .gitignore ├── .gitmodules ├── .metadata ├── .nojekyll ├── .taskcat.yml ├── CODEOWNERS ├── LICENSE.txt ├── NOTICE.txt ├── README.md ├── ci ├── exchange2019.json └── taskcat.yml ├── docs ├── generated │ ├── parameters │ │ ├── exchange-master.adoc │ │ ├── exchange.adoc │ │ └── index.adoc │ ├── regions │ │ └── index.adoc │ └── services │ │ ├── index.adoc │ │ └── metadata.adoc ├── images │ ├── Exchange Architecture.pptx │ ├── architecture_diagram.png │ ├── aws-quickstart-graphic.png │ ├── cfn_outputs.png │ ├── image1.png │ ├── image10.png │ ├── image2.png │ ├── image3.png │ ├── image4.png │ ├── image5.png │ ├── image6.png │ ├── image7.png │ ├── image8.png │ ├── image9.png │ └── microsoft-exchange-architecture-diagram.pptx └── partner_editable │ ├── _settings.adoc │ ├── additional_info.adoc │ ├── architecture.adoc │ ├── deploy_steps.adoc │ ├── deployment_options.adoc │ ├── faq_troubleshooting.adoc │ ├── licenses.adoc │ ├── overview_target_and_usage.adoc │ ├── pre-reqs.adoc │ ├── product_description.adoc │ ├── regions.adoc │ ├── service_limits.adoc │ └── specialized_knowledge.adoc ├── manifests └── app-manager │ └── app-manager-manifest.yaml ├── scripts ├── Add-ExchangeGroup.ps1 ├── Configure-EdgeDnsRecord.ps1 ├── Configure-ExchangeDAG.ps1 ├── Configure-UAC.ps1 ├── Download-Prerequisites.ps1 ├── Expand-Exchange.ps1 ├── Initialize-Disks.ps1 ├── Install-EdgePrerequisites.ps1 ├── Install-ExchPrerequisites.ps1 ├── Install-ExchangeEdgeServer.ps1 ├── Install-ExchangeOrg.ps1 ├── Install-ExchangeServer.ps1 ├── Install-NetFramework.ps1 ├── Install-SecurityUpdates.ps1 ├── Install-UcmaRuntime.ps1 ├── Install-UrlRewrite.ps1 ├── Install-VisualCRuntime.ps1 ├── Install-WindowsFailoverClustering.ps1 ├── Invoke-ADReplication.ps1 ├── Join-Domain.ps1 └── Reset-LocalAdminPassword.ps1 └── templates ├── exchange-main.template.yaml └── exchange.template.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "submodules/quickstart-aws-vpc"] 2 | path = submodules/quickstart-aws-vpc 3 | url = ../../aws-quickstart/quickstart-aws-vpc.git 4 | branch = main 5 | [submodule "submodules/quickstart-microsoft-utilities"] 6 | path = submodules/quickstart-microsoft-utilities 7 | url = ../../aws-quickstart/quickstart-microsoft-utilities.git 8 | branch = main 9 | [submodule "submodules/quickstart-microsoft-rdgateway"] 10 | path = submodules/quickstart-microsoft-rdgateway 11 | url = ../../aws-quickstart/quickstart-microsoft-rdgateway.git 12 | branch = main 13 | [submodule "submodules/quickstart-microsoft-activedirectory"] 14 | path = submodules/quickstart-microsoft-activedirectory 15 | url = ../../aws-quickstart/quickstart-microsoft-activedirectory.git 16 | branch = main 17 | [submodule "docs/boilerplate"] 18 | path = docs/boilerplate 19 | url = https://github.com/aws-quickstart/quickstart-documentation-base-common.git 20 | branch = main 21 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | language_type: cloudformation 2 | -------------------------------------------------------------------------------- /.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-quickstart/quickstart-microsoft-exchange/f4f19f90f6331372766f426dbc47f62a86038882/.nojekyll -------------------------------------------------------------------------------- /.taskcat.yml: -------------------------------------------------------------------------------- 1 | project: 2 | name: quickstart-microsoft-exchange 3 | owner: quickstart-eng@amazon.com 4 | package_lambda: false 5 | regions: 6 | - ap-northeast-1 7 | - ap-northeast-2 8 | - ap-south-1 9 | - ap-southeast-1 10 | - ap-southeast-2 11 | - eu-central-1 12 | - eu-west-1 13 | - sa-east-1 14 | - us-east-1 15 | - us-east-2 16 | - us-west-1 17 | - us-west-2 18 | s3_bucket: '' 19 | tests: 20 | exchange2016: 21 | parameters: 22 | AvailabilityZones: $[taskcat_getaz_2] 23 | NumberOfRDGWHosts: '0' 24 | DomainAdminPassword: $[taskcat_genpass_16] 25 | KeyPairName: $[taskcat_getkeypair] 26 | RDGWCIDR: 10.0.0.0/16 27 | IncludeEdgeTransportRole: 'yes' 28 | EncryptDataVolumes: 'true' 29 | DeployLoadBalancer: 'false' 30 | ThirdAZ: 'no' 31 | ExchangeServerVersion: '2016' 32 | QSS3BucketName: $[taskcat_autobucket] 33 | QSS3BucketRegion: $[taskcat_current_region] 34 | regions: 35 | # - ap-northeast-1 36 | # - ap-southeast-2 37 | # - ap-northeast-2 38 | # - ap-south-1 39 | # - us-east-1 40 | - eu-west-1 41 | # - us-west-2 42 | template: templates/exchange-main.template.yaml 43 | exchange2019: 44 | parameters: 45 | AvailabilityZones: $[taskcat_getaz_2] 46 | DomainAdminPassword: $[taskcat_genpass_16] 47 | NumberOfRDGWHosts: '0' 48 | KeyPairName: $[taskcat_getkeypair] 49 | RDGWCIDR: 10.0.0.0/16 50 | IncludeEdgeTransportRole: 'yes' 51 | EncryptDataVolumes: 'true' 52 | DeployLoadBalancer: 'false' 53 | ExchangeServerVersion: '2019' 54 | ThirdAZ: 'no' 55 | QSS3BucketName: $[taskcat_autobucket] 56 | QSS3BucketRegion: $[taskcat_current_region] 57 | # Exchange2019Source: 'override' 58 | regions: 59 | # - ap-northeast-1 60 | # - ap-southeast-2 61 | # - ap-northeast-2 62 | # - ap-south-1 63 | - us-east-1 64 | # - us-west-2 65 | # - eu-west-1 66 | template: templates/exchange-main.template.yaml 67 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @davmayd @vsnyc @aws-quickstart/aws_quickstart_team 2 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2016-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at 4 | 5 | http://aws.amazon.com/apache2.0/ 6 | 7 | or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # quickstart-microsoft-exchange 2 | ## Deprecation Notice 3 | 4 | :x: This repository is subject to deprecation in Q4 2024. For more details, [please review this announcement](https://github.com/aws-ia/.announcements/issues/1). 5 | 6 | ## This repository has been deprecated in favor of https://github.com/aws-ia/cfn-ps-microsoft-exchange. 7 | ***We will archive this repository and keep it publicly available until May 1, 2024.*** 8 | -------------------------------------------------------------------------------- /ci/exchange2019.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ParameterKey": "KeyPairName", 4 | "ParameterValue": "$[taskcat_getkeypair]" 5 | }, 6 | { 7 | "ParameterKey": "AvailabilityZones", 8 | "ParameterValue": "$[taskcat_getaz_2]" 9 | }, 10 | { 11 | "ParameterKey": "DomainAdminPassword", 12 | "ParameterValue": "$[taskcat_genpass_16]" 13 | }, 14 | { 15 | "ParameterKey": "RDGWCIDR", 16 | "ParameterValue": "10.0.0.0/16" 17 | }, 18 | { 19 | "ParameterKey": "IncludeEdgeTransportRole", 20 | "ParameterValue": "yes" 21 | }, 22 | { 23 | "ParameterKey": "EncryptDataVolumes", 24 | "ParameterValue": "true" 25 | }, 26 | { 27 | "ParameterKey": "DeployLoadBalancer", 28 | "ParameterValue": "false" 29 | }, 30 | { 31 | "ParameterKey": "ExchangeServerVersion", 32 | "ParameterValue": "2019" 33 | }, 34 | { 35 | "ParameterKey": "ThirdAZ", 36 | "ParameterValue": "no" 37 | }, 38 | { 39 | "ParameterKey": "QSS3BucketName", 40 | "ParameterValue": "$[taskcat_autobucket]" 41 | }, 42 | { 43 | "ParameterKey": "Exchange2019Source", 44 | "ParameterValue": "override" 45 | } 46 | ] 47 | -------------------------------------------------------------------------------- /ci/taskcat.yml: -------------------------------------------------------------------------------- 1 | global: 2 | marketplace-ami: false 3 | owner: quickstart-eng@amazon.com 4 | qsname: quickstart-microsoft-exchange 5 | regions: 6 | - ap-northeast-1 7 | - ap-northeast-2 8 | - ap-south-1 9 | - ap-southeast-1 10 | - ap-southeast-2 11 | - eu-central-1 12 | - eu-west-1 13 | - sa-east-1 14 | - us-east-1 15 | - us-east-2 16 | - us-west-1 17 | - us-west-2 18 | reporting: true 19 | tests: 20 | exchange2019: 21 | parameter_input: exchange2019.json 22 | regions: 23 | # - ap-northeast-1 24 | # - ap-southeast-2 25 | # - ap-northeast-2 26 | # - ap-south-1 27 | - us-east-1 28 | - eu-west-1 29 | - us-west-2 30 | template_file: exchange-master.template 31 | -------------------------------------------------------------------------------- /docs/generated/parameters/exchange-master.adoc: -------------------------------------------------------------------------------- 1 | 2 | .Network Configuration 3 | [width="100%",cols="16%,11%,73%",options="header",] 4 | |=== 5 | |Parameter label (name) |Default value|Description|Availability Zones 6 | (`AvailabilityZones`)|`**__Requires input__**`|List of Availability Zones to use for the subnets in the VPC. Note: You must specify two Availability Zones, unless you specify the Third AZ parameter. In this case, you must specify three Availability Zones. The Quick Start preserves the logical order you specify.|Number of Availability Zones 7 | (`NumberOfAZs`)|`2`|Number of Availability Zones to use in the VPC. This must match your selections in the list of Availability Zones parameter.|Third Availability Zone 8 | (`ThirdAZ`)|`no`|Enable a 3 AZ deployment, the 3rd AZ can either be used just for the witness, or can be a full Exchange node. Note that if witness is chosen, the WFC File Server Private IP Address parameter must be set to an IP in the 3rd subnet range.|VPC CIDR 9 | (`VPCCIDR`)|`10.0.0.0/16`|CIDR Block for the VPC.|Public Subnet 1 CIDR 10 | (`PublicSubnet1CIDR`)|`10.0.128.0/20`|CIDR Block for the public DMZ subnet 1 located in Availability Zone 1.|Public Subnet 2 CIDR 11 | (`PublicSubnet2CIDR`)|`10.0.144.0/20`|CIDR Block for the public DMZ subnet 2 located in Availability Zone 2.|Public Subnet 3 CIDR 12 | (`PublicSubnet3CIDR`)|`10.0.160.0/20`|(Optional) CIDR Block for the public DMZ subnet 3 located in Availability Zone 3.|Private Subnet 1 CIDR 13 | (`PrivateSubnet1CIDR`)|`10.0.0.0/19`|CIDR Block for private subnet 1 located in Availability Zone 1.|Private Subnet 2 CIDR 14 | (`PrivateSubnet2CIDR`)|`10.0.32.0/19`|CIDR Block for private subnet 2 located in Availability Zone 2.|Private Subnet 3 CIDR 15 | (`PrivateSubnet3CIDR`)|`10.0.64.0/19`|(Optional) CIDR Block for private subnet 3 located in Availability Zone 3. 16 | |=== 17 | .Amazon EC2 Configuration 18 | [width="100%",cols="16%,11%,73%",options="header",] 19 | |=== 20 | |Parameter label (name) |Default value|Description|Key pair name 21 | (`KeyPairName`)|`**__Requires input__**`|Public/private key pairs allow you to securely connect to your instance after it launches. 22 | |=== 23 | .Microsoft Active Directory Configuration 24 | [width="100%",cols="16%,11%,73%",options="header",] 25 | |=== 26 | |Parameter label (name) |Default value|Description|Domain DNS name 27 | (`DomainDNSName`)|`example.com`|The fully qualified domain name (FQDN) of the forest root domain e.g. example.com.|Domain NetBIOS name 28 | (`DomainNetBIOSName`)|`example`|The NetBIOS name of the domain (up to 15 characters) for users of earlier versions of Windows e.g. EXAMPLE.|Domain Admin user name 29 | (`DomainAdminUser`)|`StackAdmin`|The user name for the account that will be added as Domain Administrator. This is separate from the default Administrator account.|Domain Admin password 30 | (`DomainAdminPassword`)|`**__Requires input__**`|The password for the domain admin user. Must be at least 8 characters containing letters, numbers and symbols.|Domain Controller 1 instance type 31 | (`ADServer1InstanceType`)|`m5.xlarge`|The Amazon EC2 instance type for the first Active Directory instance.|Domain Controller 1 NetBIOS name 32 | (`ADServer1NetBIOSName`)|`DC1`|The NetBIOS name of the first Active Directory server (up to 15 characters).|Domain Controller 1 private IP address 33 | (`ADServer1PrivateIP`)|`10.0.0.10`|The private IP for the first Active Directory server located in Availability Zone 1.|Domain Controller 2 instance type 34 | (`ADServer2InstanceType`)|`m5.xlarge`|The Amazon EC2 instance type for the second Active Directory instance.|Domain Controller 2 NetBIOS name 35 | (`ADServer2NetBIOSName`)|`DC2`|The NetBIOS name of the second Active Directory server (up to 15 characters).|Domain Controller 2 private IP address 36 | (`ADServer2PrivateIP`)|`10.0.32.10`|The private IP for the second Active Directory server located in Availability Zone 2. 37 | |=== 38 | .Remote Desktop Gateway Configuration 39 | [width="100%",cols="16%,11%,73%",options="header",] 40 | |=== 41 | |Parameter label (name) |Default value|Description|Allowed Remote Desktop Gateway external access CIDR 42 | (`RDGWCIDR`)|`**__Requires input__**`|The allowed CIDR Block for external access to the Remote Desktop Gateways.|Remote Desktop Gateway instance type 43 | (`RDGWInstanceType`)|`t2.large`|The Amazon EC2 instance type for the Remote Desktop Gateway instances.|Number of RDGW Hosts 44 | (`NumberOfRDGWHosts`)|`1`|The number of Remote Desktop Gateway hosts to create. 45 | |=== 46 | .Exchange Server Configuration 47 | [width="100%",cols="16%,11%,73%",options="header",] 48 | |=== 49 | |Parameter label (name) |Default value|Description|Enable AWS Backups 50 | (`EnableBackups`)|`yes`|Creates a default daily/weekly backup schedule using AWS Backup|Exchange Server version 51 | (`ExchangeServerVersion`)|`2016`|Version of Exchange Server to install. Options include either "2016" or "2019".|Exchange Server 2019 source (ISO) 52 | (`Exchange2019Source`)|`https://`|(Optional) Full URL (including https://) for Exchange 2019 ISO.|Deploy Edge servers 53 | (`IncludeEdgeTransportRole`)|`no`|Choose yes to deploy Exchange Edge Transport servers in the public subnets.|Edge Role instance type 54 | (`EdgeInstanceType`)|`m5.large`|The Amazon EC2 instance type for the Exchange Edge Transport servers.|Edge Node 1 NetBIOS name 55 | (`EdgeNode1NetBIOSName`)|`EdgeNode1`|The NetBIOS name of the first Edge server (up to 15 characters).|Edge Node 1 private IP address 56 | (`EdgeNode1PrivateIP1`)|`10.0.128.12`|The primary private IP for the first Edge server located in Availability Zone 1.|Edge Node 2 NetBIOS name 57 | (`EdgeNode2NetBIOSName`)|`EdgeNode2`|The NetBIOS name of the second Edge server (up to 15 characters).|Edge Node 2 private IP address 58 | (`EdgeNode2PrivateIP1`)|`10.0.144.12`|The primary private IP for the second Edge server located in Availability Zone 1.|Enable or disable ReFS 59 | (`EnableReFSVolumes`)|`true`|Choose false to format the data and log volumes on Exchange nodes using NTFS instead of ReFS.|Encrypt data volumes 60 | (`EncryptDataVolumes`)|`false`|Choose true to encrypt the data and log volumes on Exchange nodes.|KMS key to encrypt volumes 61 | (`EncryptionKmsKey`)|`**__Blank string__**`|(Optional) Specify the KMS encryption arn in format arn:aws:kms:[REGION]:[ACCOUNTNUMBER]:key/[GUID]. Leave blank to use default EBS encryption key.|Exchange Server volume IOPS 62 | (`VolumeIops`)|`1000`|The provisioned IOPS for the Exchange Data and Logs volumes. This parameter is only applicable when Exchange Server Volume Type is set to "io2".|Exchange Server volume size (GiB) 63 | (`VolumeSize`)|`500`|The volume size for the Exchange Data and Logs volumes.|Exchange Server volume type 64 | (`VolumeType`)|`gp2`|The volume type for the Exchange Data and Logs volumes. 65 | |=== 66 | .Load Balancer Configuration 67 | [width="100%",cols="16%,11%,73%",options="header",] 68 | |=== 69 | |Parameter label (name) |Default value|Description|Deploy Network Load Balancer 70 | (`DeployLoadBalancer`)|`false`|Choose true to deploy a Network Load Balancer (NLB).|Network Load Balancer Certificate 71 | (`CertificateArn`)|`**__Blank string__**`|(Conditional) If 'true' was chosen in Deploy Network Load Balancer option, specify the Certificate arn to be used by load balancer in arn:aws:acm:[REGION]:[ACCOUNTNUMBER]:certificate/[GUID] format. 72 | |=== 73 | .Failover Cluster Configuration 74 | [width="100%",cols="16%,11%,73%",options="header",] 75 | |=== 76 | |Parameter label (name) |Default value|Description|Instance type for Exchange nodes 77 | (`ExchangeNodeInstanceType`)|`r5.xlarge`|The Amazon EC2 instance type for the Exchange nodes.|Exchange Node 1 NetBIOS name 78 | (`ExchangeNode1NetBIOSName`)|`ExchangeNode1`|The NetBIOS name of the first Exchange node (up to 15 characters).|Exchange Node 1 private IP address 1 79 | (`ExchangeNode1PrivateIP1`)|`10.0.0.100`|The primary private IP for Exchange node 1.|Exchange Node 1 private IP address 2 80 | (`ExchangeNode1PrivateIP2`)|`10.0.0.101`|The secondary private IP for Exchange node 1.|Exchange Node 2 NetBIOS name 81 | (`ExchangeNode2NetBIOSName`)|`ExchangeNode2`|The NetBIOS name of the second Exchange node (up to 15 characters).|Exchange Node 2 private IP address 1 82 | (`ExchangeNode2PrivateIP1`)|`10.0.32.100`|The primary private IP for Exchange node 2.|Exchange Node 2 private IP address 2 83 | (`ExchangeNode2PrivateIP2`)|`10.0.32.101`|The secondary private IP for Exchange node 2.|Exchange Node 3 NetBIOS name 84 | (`ExchangeNode3NetBIOSName`)|`ExchangeNode3`|(Optional) The NetBIOS name of the third Exchange node (up to 15 characters).|Exchange Node 3 private IP address 1 85 | (`ExchangeNode3PrivateIP1`)|`10.0.64.100`|(Optional) The primary private IP for the Exchange node 3.|Exchange Node 3 private IP address 2 86 | (`ExchangeNode3PrivateIP2`)|`10.0.64.101`|(Optional) The secondary private IP for the Exchange node 3.|File Server instance type 87 | (`FileServerInstanceType`)|`t3.small`|The Amazon EC2 instance type for the file-share witness server.|File Server NetBIOS name 88 | (`FileServerNetBIOSName`)|`FileServer`|The NetBIOS name of the file-share witness server (up to 15 characters).|File Server private IP address 89 | (`FileServerPrivateIP`)|`10.0.0.200`|The primary private IP for the file-share witness server. 90 | |=== 91 | .AWS Quick Start Configuration 92 | [width="100%",cols="16%,11%,73%",options="header",] 93 | |=== 94 | |Parameter label (name) |Default value|Description|Quick Start S3 bucket name 95 | (`QSS3BucketName`)|`aws-quickstart`|The S3 bucket you’ve created for your copy of Quick Start assets, if you decide to customize or extend the Quick Start for your own use. The bucket name can include numbers, lowercase letters, uppercase letters, and hyphens, but should not start or end with a hyphen.|Quick Start S3 key prefix 96 | (`QSS3KeyPrefix`)|`quickstart-microsoft-exchange/`|The S3 key name prefix used to simulate a folder for your copy of Quick Start assets, if you decide to customize or extend the Quick Start for your own use. This prefix can include numbers, lowercase letters, uppercase letters, hyphens, and forward slashes, but should not start or end with a forward slash (which is automatically added).|Quick Start S3 bucket region 97 | (`QSS3BucketRegion`)|`us-east-1`|The AWS Region where the Quick Start S3 bucket (QSS3BucketName) is hosted. When using your own bucket, you must specify this value. 98 | |=== -------------------------------------------------------------------------------- /docs/generated/parameters/exchange.adoc: -------------------------------------------------------------------------------- 1 | 2 | .Network Configuration 3 | [width="100%",cols="16%,11%,73%",options="header",] 4 | |=== 5 | |Parameter label (name) |Default value|Description|Third Availability Zone 6 | (`ThirdAZ`)|`no`|Enables you to deploy three Availability Zones. The third Availability Zone can either be used just for the witness, or can be a full Exchange node. If you use the Availability Zone for the witness, you must set the File Server Private IP Address parameter to an IP in the third subnet range.|VPC for Exchange deployment 7 | (`VPCID`)|`**__Requires input__**`|The ID of the VPC (e.g., vpc-0343606e).|CIDR block of VPC 8 | (`VPCCidrBlock`)|`10.0.0.0/16`|The CIDR block for the VPC.|Private Subnet 1 ID 9 | (`PrivateSubnet1ID`)|`**__Requires input__**`|The ID of the private subnet 1 in Availability Zone 1 (e.g., subnet-a0246dcd).|Private Subnet 1 CIDR 10 | (`PrivateSubnet1CIDR`)|`10.0.0.0/19`|The CIDR block for the private subnet 1 located in Availability Zone 1.|Private Subnet 2 ID 11 | (`PrivateSubnet2ID`)|`**__Requires input__**`|The ID of the private subnet 2 in Availability Zone 2 (e.g., subnet-a0246dcd).|Private Subnet 2 CIDR 12 | (`PrivateSubnet2CIDR`)|`10.0.32.0/19`|The CIDR block for the private subnet 2 located in Availability Zone 2.|Private Subnet 3 ID 13 | (`PrivateSubnet3ID`)|`**__Blank string__**`|(Optional) The ID of the private subnet 3 in Availability Zone 3 (e.g., subnet-a0246dcd)|Private Subnet 3 CIDR 14 | (`PrivateSubnet3CIDR`)|`10.0.64.0/19`|(Optional) The CIDR block for private subnet 3 located in Availability Zone 3.|Public Subnet 1 ID 15 | (`PublicSubnet1ID`)|`**__Requires input__**`|(Optional) The ID of the public subnet 1 in Availability Zone 1 (e.g., subnet-a0246dcd).|Public Subnet 2 ID 16 | (`PublicSubnet2ID`)|`**__Requires input__**`|(Optional) The ID of the public subnet 2 in Availability Zone 2 (e.g., subnet-a0246dcd). 17 | |=== 18 | .Amazon EC2 Configuration 19 | [width="100%",cols="16%,11%,73%",options="header",] 20 | |=== 21 | |Parameter label (name) |Default value|Description|Key Pair Name 22 | (`KeyPairName`)|`**__Requires input__**`|The public/private key pair, which allows you to connect securely to your instance after it launches. When you created an AWS account, this is the key pair you created in your preferred region.|Windows Server 2016 AMI name 23 | (`WS2016FULLBASE`)|`/aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base`|The image name for the AWS Systems Manager Windows Server 2016 AMI ID lookup|Windows Server 2019 AMI name 24 | (`WS2019FULLBASE`)|`/aws/service/ami-windows-latest/Windows_Server-2019-English-Full-Base`|The image name for the AWS Systems Manager Windows Server 2019 AMI ID lookup 25 | |=== 26 | .Microsoft Active Directory Configuration 27 | [width="100%",cols="16%,11%,73%",options="header",] 28 | |=== 29 | |Parameter label (name) |Default value|Description|Domain DNS name 30 | (`DomainDNSName`)|`example.com`|The fully qualified domain name (FQDN) of the forest root domain (e.g. example.com).|Domain NetBIOS name 31 | (`DomainNetBIOSName`)|`EXAMPLE`|The NetBIOS name of the domain (up to 15 characters) for users of earlier versions of Windows (e.g. EXAMPLE).|Domain Admin user name 32 | (`DomainAdminUser`)|`StackAdmin`|The user name for the account that will be used as Domain Administrator. This is separate from the default "Administrator" account.|Domain Admin password 33 | (`DomainAdminPassword`)|`**__Requires input__**`|The password for the domain admin user. Must be at least 8 characters containing letters, numbers and symbols.|Domain Controller 1 NetBIOS name 34 | (`ADServer1NetBIOSName`)|`DC1`|The NetBIOS name of the first Active Directory server (up to 15 characters).|Domain Controller 1 private IP address 35 | (`ADServer1PrivateIP`)|`10.0.0.10`|The private IP for the first Active Directory server located in Availability Zone 1.|Domain Controller 2 NetBIOS name 36 | (`ADServer2NetBIOSName`)|`DC2`|The NetBIOS name of the second Active Directory server (up to 15 characters).|Security Group ID for AD domain members 37 | (`DomainMemberSGID`)|`**__Requires input__**`|The ID of the Domain Member Security Group (e.g., sg-7f16e910). 38 | |=== 39 | .Microsoft Exchange Server Configuration 40 | [width="100%",cols="16%,11%,73%",options="header",] 41 | |=== 42 | |Parameter label (name) |Default value|Description|Exchange Server version 43 | (`ExchangeServerVersion`)|`2016`|Version of Exchange Server to install. Options include either "2016" or "2019"|Deploy Edge servers 44 | (`IncludeEdgeTransportRole`)|`no`|Choose yes to deploy Exchange Edge Transport servers in the public subnets.|Instance type for Edge server 45 | (`EdgeInstanceType`)|`t3.large`|The Amazon EC2 instance type for the Exchange Edge Transport servers.|Edge Node 1 NetBIOS Name 46 | (`EdgeNode1NetBIOSName`)|`EdgeNode1`|The NetBIOS name of the first Edge Server (up to 15 characters).|Edge Node 1 private IP address 47 | (`EdgeNode1PrivateIP1`)|`10.0.128.12`|The primary private IP for the first Edge Server located in Availability Zone 1.|Edge Node 2 NetBIOS name 48 | (`EdgeNode2NetBIOSName`)|`EdgeNode2`|The NetBIOS name of the second Edge Server (up to 15 characters).|Edge Node 2 private IP address 49 | (`EdgeNode2PrivateIP1`)|`10.0.144.12`|The primary private IP for the second Edge Server located in Availability Zone 2.|Enable or disable ReFS 50 | (`EnableReFSVolumes`)|`true`|Choose false to format the data and log volumes on Exchange nodes using NTFS instead of ReFS.|Encrypt Data volumes 51 | (`EncryptDataVolumes`)|`false`|Choose true to encrypt the data and log volumes on Exchange nodes.|KMS key to encrypt volumes 52 | (`EncryptionKmsKey`)|`**__Blank string__**`|(Optional) Specify the KMS encryption arn in format arn:aws:kms:[REGION]:[ACCOUNTNUMBER]:key/[GUID]. Leave blank to use default EBS encryption key.|Data Volume size (GiB) 53 | (`VolumeSize`)|`500`|The volume size for the Exchange data drive.|Data Volume type 54 | (`VolumeType`)|`gp2`|The volume type for the Exchange data drive.|Data Volume IOPS 55 | (`VolumeIops`)|`1000`|The Iops for the Exchange Data drive (Only used when volume type is io2).|Path to Exchange 2016 ISO 56 | (`Exchange2016Source`)|`https://download.microsoft.com/download/d/2/3/d23b113b-9634-4456-acba-1f7b0ce22b0e/ExchangeServer2016-x64-cu18.iso`|Full URL (including https://) for Exchange 2016 ISO.|Path to Exchange 2019 ISO 57 | (`Exchange2019Source`)|`https://`|Full URL (including https://) for Exchange 2019 ISO.|Enable AWS Backups 58 | (`EnableBackups`)|`yes`|Creates a default daily/weekly backup schedule using AWS Backup 59 | |=== 60 | .Load Balancer Configuration 61 | [width="100%",cols="16%,11%,73%",options="header",] 62 | |=== 63 | |Parameter label (name) |Default value|Description|Deploy Network Load Balancer 64 | (`DeployLoadBalancer`)|`false`|Choose true to deploy an Network Load Balancer (NLB).|Network Load Balancer Certificate 65 | (`CertificateArn`)|`**__Blank string__**`|(Conditional) If 'true' was chosen in Deploy Network Load Balancer option, specify the Certificate arn to be used by load balancer in arn:aws:acm:[REGION]:[ACCOUNTNUMBER]:certificate/[GUID] format. 66 | |=== 67 | .Failover Cluster Configuration 68 | [width="100%",cols="16%,11%,73%",options="header",] 69 | |=== 70 | |Parameter label (name) |Default value|Description|File Server instance type 71 | (`FileServerInstanceType`)|`t3.small`|The Amazon EC2 instance type for the file-share witness server.|File Server NetBIOS name 72 | (`FileServerNetBIOSName`)|`FileServer`|The NetBIOS name of the file-share witness server (up to 15 characters).|File Server private IP address 73 | (`FileServerPrivateIP`)|`10.0.0.200`|The primary private IP for the file-share witness server.|Instance type for Exchange nodes 74 | (`ExchangeNodeInstanceType`)|`r5.xlarge`|The Amazon EC2 instance type for the Exchange nodes.|Exchange Node 1 NetBIOS name 75 | (`ExchangeNode1NetBIOSName`)|`ExchangeNode1`|The NetBIOS name of the first Exchange Node (up to 15 characters).|Exchange Node 1 private IP address 1 76 | (`ExchangeNode1PrivateIP1`)|`10.0.0.100`|The primary private IP for Exchange node 1.|Exchange Node 1 private IP address 2 77 | (`ExchangeNode1PrivateIP2`)|`10.0.0.101`|The secondary private IP for Exchange node 1.|Exchange Node 2 NetBIOS name 78 | (`ExchangeNode2NetBIOSName`)|`ExchangeNode2`|The NetBIOS name of the second Exchange Node (up to 15 characters).|Exchange Node 2 private IP address 1 79 | (`ExchangeNode2PrivateIP1`)|`10.0.32.100`|The primary private IP for Exchange node 2.|Exchange Node 2 private IP address 2 80 | (`ExchangeNode2PrivateIP2`)|`10.0.32.101`|The secondary private IP for Exchange node 2.|Exchange Node 3 NetBIOS Name 81 | (`ExchangeNode3NetBIOSName`)|`ExchangeNode3`|(Optional) The NetBIOS name of the third Exchange node (up to 15 characters).|Exchange Node 3 private IP address 1 82 | (`ExchangeNode3PrivateIP1`)|`10.0.64.100`|(Optional) The primary private IP for the Exchange node 3.|Exchange Node 3 private IP address 2 83 | (`ExchangeNode3PrivateIP2`)|`10.0.64.101`|(Optional) The secondary private IP for the Exchange node 3. 84 | |=== 85 | .AWS Quick Start Configuration 86 | [width="100%",cols="16%,11%,73%",options="header",] 87 | |=== 88 | |Parameter label (name) |Default value|Description|Quick Start S3 Bucket Name 89 | (`QSS3BucketName`)|`aws-quickstart`|S3 bucket name for the Quick Start assets. Quick Start bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-).|Quick Start S3 bucket region 90 | (`QSS3BucketRegion`)|`us-east-1`|The AWS Region where the Quick Start S3 bucket (QSS3BucketName) is hosted. When using your own bucket, you must specify this value.|Quick Start S3 Key Prefix 91 | (`QSS3KeyPrefix`)|`quickstart-microsoft-exchange/`|S3 key prefix for the Quick Start assets. Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slash (/). 92 | |=== -------------------------------------------------------------------------------- /docs/generated/parameters/index.adoc: -------------------------------------------------------------------------------- 1 | 2 | === Launch into a new VPC 3 | include::exchange-master.adoc[] 4 | 5 | === Launch into an existing VPC 6 | include::exchange.adoc[] 7 | -------------------------------------------------------------------------------- /docs/generated/regions/index.adoc: -------------------------------------------------------------------------------- 1 | // placeholder 2 | -------------------------------------------------------------------------------- /docs/generated/services/index.adoc: -------------------------------------------------------------------------------- 1 | // placeholder 2 | -------------------------------------------------------------------------------- /docs/generated/services/metadata.adoc: -------------------------------------------------------------------------------- 1 | // placeholder 2 | -------------------------------------------------------------------------------- /docs/images/Exchange Architecture.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-quickstart/quickstart-microsoft-exchange/f4f19f90f6331372766f426dbc47f62a86038882/docs/images/Exchange Architecture.pptx -------------------------------------------------------------------------------- /docs/images/architecture_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-quickstart/quickstart-microsoft-exchange/f4f19f90f6331372766f426dbc47f62a86038882/docs/images/architecture_diagram.png -------------------------------------------------------------------------------- /docs/images/aws-quickstart-graphic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-quickstart/quickstart-microsoft-exchange/f4f19f90f6331372766f426dbc47f62a86038882/docs/images/aws-quickstart-graphic.png -------------------------------------------------------------------------------- /docs/images/cfn_outputs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-quickstart/quickstart-microsoft-exchange/f4f19f90f6331372766f426dbc47f62a86038882/docs/images/cfn_outputs.png -------------------------------------------------------------------------------- /docs/images/image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-quickstart/quickstart-microsoft-exchange/f4f19f90f6331372766f426dbc47f62a86038882/docs/images/image1.png -------------------------------------------------------------------------------- /docs/images/image10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-quickstart/quickstart-microsoft-exchange/f4f19f90f6331372766f426dbc47f62a86038882/docs/images/image10.png -------------------------------------------------------------------------------- /docs/images/image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-quickstart/quickstart-microsoft-exchange/f4f19f90f6331372766f426dbc47f62a86038882/docs/images/image2.png -------------------------------------------------------------------------------- /docs/images/image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-quickstart/quickstart-microsoft-exchange/f4f19f90f6331372766f426dbc47f62a86038882/docs/images/image3.png -------------------------------------------------------------------------------- /docs/images/image4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-quickstart/quickstart-microsoft-exchange/f4f19f90f6331372766f426dbc47f62a86038882/docs/images/image4.png -------------------------------------------------------------------------------- /docs/images/image5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-quickstart/quickstart-microsoft-exchange/f4f19f90f6331372766f426dbc47f62a86038882/docs/images/image5.png -------------------------------------------------------------------------------- /docs/images/image6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-quickstart/quickstart-microsoft-exchange/f4f19f90f6331372766f426dbc47f62a86038882/docs/images/image6.png -------------------------------------------------------------------------------- /docs/images/image7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-quickstart/quickstart-microsoft-exchange/f4f19f90f6331372766f426dbc47f62a86038882/docs/images/image7.png -------------------------------------------------------------------------------- /docs/images/image8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-quickstart/quickstart-microsoft-exchange/f4f19f90f6331372766f426dbc47f62a86038882/docs/images/image8.png -------------------------------------------------------------------------------- /docs/images/image9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-quickstart/quickstart-microsoft-exchange/f4f19f90f6331372766f426dbc47f62a86038882/docs/images/image9.png -------------------------------------------------------------------------------- /docs/images/microsoft-exchange-architecture-diagram.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-quickstart/quickstart-microsoft-exchange/f4f19f90f6331372766f426dbc47f62a86038882/docs/images/microsoft-exchange-architecture-diagram.pptx -------------------------------------------------------------------------------- /docs/partner_editable/_settings.adoc: -------------------------------------------------------------------------------- 1 | // Do not change this first attribute. Do change the others. 2 | :quickstart-team-name: AWS Quick Start team 3 | :quickstart-project-name: quickstart-microsoft-exchange 4 | :partner-product-name: Microsoft Exchange 5 | // For the following attribute, if you have no short name, enter the same name as partner-product-name. 6 | :partner-product-short-name: Exchange 7 | // If there's no partner, comment partner-company-name and partner-contributors. 8 | // :partner-company-name: Example Company Name, Ltd. 9 | :doc-month: November 10 | :doc-year: 2020 11 | // For the following two "contributor" attributes, if the partner agrees to include names in the byline, 12 | // enter names for both partner-contributors and quickstart-contributors. 13 | // Otherwise, delete all placeholder names: everything preceding "{partner-company-name}" 14 | // and "{quickstart-team-name}". Use commas as shown in the placeholder text. 15 | // Use the comma before "and" only when three or more names. 16 | //:partner-contributors: Shuai Ye, Michael McConnell, and John Smith, {partner-company-name} 17 | :quickstart-contributors: Dragos Madarasan and Aaron Lima, AWS Quick Start team 18 | // For deployment_time, use minutes if deployment takes an hour or less, 19 | // for example, 30 minutes or 60 minutes. 20 | // Use hours for deployment times greater than 60 minutes (rounded to a quarter hour), 21 | // for example, 1.25 hours, 2 hours, 2.5 hours. 22 | :deployment_time: 3 hours 23 | :default_deployment_region: us-east-1 24 | :parameters_as_appendix: 25 | // Uncomment the following two attributes if you are using an AWS Marketplace listing. 26 | // Additional content will be generated automatically based on these attributes. 27 | // :marketplace_subscription: 28 | // :marketplace_listing_url: https://example.com/ 29 | -------------------------------------------------------------------------------- /docs/partner_editable/additional_info.adoc: -------------------------------------------------------------------------------- 1 | // Add steps as necessary for accessing the software, post-configuration, and testing. Don’t include full usage instructions for your software, but add links to your product documentation for that information. 2 | //Should any sections not be applicable, remove them 3 | 4 | == Post-deployment steps 5 | // If post-deployment steps are required, add them here. If not, remove the heading 6 | 7 | === Run Windows Updates 8 | 9 | In order to ensure the deployed servers' operating systems and installed applications have the latest Microsoft updates, run Windows Update on each server. 10 | 11 | 1. Create an RDP session from the Remote Desktop Gateway server to each deployed server. 12 | 2. Open the *Settings* application. 13 | 3. Open *Update & Security*. 14 | 4. Click *Check for updates*. 15 | 5. Install any updates and reboot if necessary. 16 | 17 | === (Optional) Create database copies 18 | 19 | The Quick Start creates a database availability group (DAG) and adds the Exchange nodes to the DAG. As part of the Exchange installation, each Exchange node contains a mailbox database. The first node contains a database called DB1, and the second node contains a database called DB2. 20 | 21 | As part of configuring high availability for the mailbox roles, you can add mailbox database copies on the other Exchange nodes. Alternatively, you can create entirely new databases and only then create additional copies. 22 | 23 | To create a second copy for the initial databases, use the following commands: 24 | 25 | ---- 26 | Add-MailboxDatabaseCopy -Identity DB1 –MailboxServer ExchangeNode2 -ActivationPreference 2 27 | 28 | Add-MailboxDatabaseCopy -Identity DB2 –MailboxServer ExchangeNode1 -ActivationPreference 2 29 | ---- 30 | 31 | === (Optional) Create a DNS entry for the load balancer 32 | 33 | 1. If you chose the option to deploy a load balancer, the Network Load Balancer (NLB) will have an endpoint address such as [elb.amazonaws.com]. 34 | 2. To use the load balancer with your Exchange namespace, create a CNAME record in Active Directory that points to the ALB. 35 | 3. Before proceeding, go to the https://console.aws.amazon.com/ec2/v2/home[Amazon EC2 console] and, under *Load balancer*, select the load balancer that the Quick Start created. 36 | 4. Copy the value listed under the DNS name, as shown in Figure 7. 37 | 38 | [#architecture7] 39 | .Creating a DNS entry for the load balancer 40 | image::../images/image7.png[Architecture,width=646,height=275] 41 | 42 | [start=5] 43 | 5. To create the DNS record, connect using Remote Desktop to one of the domain controllers using domain credentials, and open the DNS console by going to the Start menu and typing “DNS”. 44 | 6. In the DNS console, navigate to the Active Directory zone, right-click, and select *New Alias (CNAME)*, as shown in Figure 8. 45 | 46 | [#architecture8] 47 | .Selecting New Alias (CNAME) 48 | image::../images/image8.png[Architecture,width=355,height=557] 49 | 50 | [start=7] 51 | 7. Create the DNS entry such as “mail” and in *fully qualified domain name (FQDN) for target host*, paste the value of the Application Load Balancer endpoint, as shown in Figure 9. 52 | 53 | [#architecture9] 54 | .Creating the DNS entry (“mail”) 55 | image::../images/image9.png[Architecture,width=422,height=480] 56 | 57 | [start=8] 58 | 9. Verify that the DNS entry is resolved successfully by performing an nslookup. Go to Start and type “cmd”. In the command line window, type the following: 59 | 60 | Nslookup *mail*._example.com_ 61 | 62 | _______________________________________________________________________________________________________________ 63 | Where mail is the name of the CNAME record you created, and “example.com” is your Active Directory domain name. 64 | _______________________________________________________________________________________________________________ 65 | 66 | [start=10] 67 | 10. Ensure that the record resolves to the load balancer DNS record, such as shown in Figure 10. 68 | 69 | [#architecture10] 70 | .Verifying the DNS record 71 | image::../images/image10.png[Architecture,width=647,height=278] 72 | 73 | == Best practices for using {partner-product-short-name} on AWS 74 | // Provide post-deployment best practices for using the technology on AWS, including considerations such as migrating data, backups, ensuring high performance, high availability, etc. Link to software documentation for detailed information. 75 | 76 | The architecture built by this Quick Start supports AWS best practices for high availability and security. 77 | 78 | [[high-availability-and-disaster-recovery]] 79 | === High availability and disaster recovery 80 | 81 | Amazon EC2 provides the ability to place instances in multiple locations composed of AWS Regions and Availability Zones. Regions are dispersed and located in separate geographic areas. Availability Zones are distinct locations within a Region that are engineered to be isolated from failures in other Availability Zones and that provide inexpensive, low-latency network connectivity to other Availability Zones in the same Region. 82 | 83 | By launching your instances in separate Regions, you can design your application to be closer to specific customers or to meet legal or other requirements. By launching your instances in separate Availability Zones, you can protect your applications from the failure of a single location. Exchange provides infrastructure features that complement the high availability and disaster recovery scenarios supported in the AWS Cloud. 84 | 85 | [[automatic-failover]] 86 | === Automatic failover 87 | 88 | Deploying the Quick Start with the *default parameters* configures a two-node database availability group (DAG) with a file share witness. The DAG uses Windows Server Failover Clustering for automatic failover. 89 | 90 | The Quick Start implementation supports the following scenarios: 91 | 92 | * Protection from the failure of a single instance 93 | * Automatic failover between the cluster nodes 94 | * Automatic failover between Availability Zones 95 | 96 | However, the Quick Start default implementation doesn’t provide automatic failover in every case. For example, the loss of Availability Zone 1, which contains the primary node and file share witness, would prevent automatic failover to Availability Zone 2. This is because the cluster would fail as it loses quorum. In this scenario, you could follow manual disaster recovery steps that include restarting the cluster service and forcing quorum on the second cluster node (e.g., ExchangeNode2) to restore application availability. 97 | 98 | The Quick Start also provides an option to deploy into three Availability Zones. This deployment option can mitigate the loss of quorum in the case of a failure of a single node. However, you can select this option only in AWS Regions that include three or more Availability Zones; for a current list, see https://aws.amazon.com/about-aws/global-infrastructure/[AWS Global Infrastructure]. 99 | 100 | We recommend that you consult the https://docs.microsoft.com/en-us/Exchange/exchange-server?view=exchserver-2019[Microsoft Exchange Server documentation] and customize some of the steps described in this guide or add ones (e.g., deploy additional cluster nodes and configure mailbox database copies) to deploy a solution that best meets your business, IT, and security requirements. 101 | 102 | [[security-groups-and-firewalls]] 103 | === Security groups and firewalls 104 | 105 | When the EC2 instances are launched, they must be associated with a security group, which acts as a stateful firewall. You have complete control over the network traffic entering or leaving the security group, and you can build granular rules that are scoped by protocol, port number, and source or destination IP address or subnet. By default, all traffic egressing a security group is permitted. Ingress traffic, on the other hand, must be configured to allow the appropriate traffic to reach your instances. 106 | 107 | The https://d0.awsstatic.com/whitepapers/aws-microsoft-platform-security.pdf[Securing the Microsoft Platform on Amazon Web Services] whitepaper discusses the different methods for securing your AWS infrastructure. Recommendations include providing isolation between application tiers using security groups. We recommend that you tightly control ingress traffic, so that you reduce the attack surface of your EC2 instances. 108 | 109 | Domain controllers and member servers require several security group rules to allow traffic for services such as AD DS replication, user authentication, https://docs.microsoft.com/en-us/windows-server/networking/windows-time-service/windows-time-service-top[Windows Time service], and Distributed File System (DFS), among others. The nodes running Exchange Server permit full communication between each other, as recommended by Microsoft best practices. For more information, see https://blogs.technet.microsoft.com/exchange/2013/02/18/exchange-firewalls-and-support-oh-my[Exchange, Firewalls, and Support]. 110 | 111 | Edge node servers (if configured to be deployed) allow port 25 TCP (SMTP) from the entire internet. 112 | 113 | The Quick Start creates certain security groups and rules for you. For a detailed list of port mappings, see the https://docs.aws.amazon.com/quickstart/latest/active-directory-ds/security.html[Security section] of the Active Directory Domain Services Quick Start deployment guide, and the link:#security[Security section] of this guide. 114 | 115 | == Security 116 | // Provide post-deployment best practices for using the technology on AWS, including considerations such as migrating data, backups, ensuring high performance, high availability, etc. Link to software documentation for detailed information. 117 | 118 | AWS provides a set of building blocks (for example, Amazon EC2 and Amazon VPC) that you can use to provision infrastructure for your applications. In this model, some security capabilities, such as physical security, are the responsibility of AWS and are highlighted in the https://d0.awsstatic.com/whitepapers/aws-security-best-practices.pdf[AWS security whitepaper]. Other areas, such as controlling access to applications, fall on the application developer and the tools provided in the Microsoft platform. 119 | 120 | This Quick Start configures the following security groups for Exchange Server: 121 | 122 | [cols=",,,",options="header",] 123 | |======================================================================= 124 | |Security group |Associated with |Inbound source |Ports 125 | |DomainMemberSGID |Exchange nodes, FileServer, RD Gateway, Domain controllers |VPC CIDR |Standard AD ports 126 | |EXCHClientSecurityGroup |Exchange nodes, FileServer |VPC CIDR |25, 80, 443, 143, 993, 110, 995, 587 127 | |ExchangeSecurityGroup |Exchange nodes |ExchangeSecurityGroup |All ports 128 | |EXCHEdgeSecurityGroup |EXCHEdgeSecurityGroup |Private subnets CIDR, 0.0.0.0/0 |50636, 25 129 | |LoadBalancerSecurityGroup |Load balancer |0.0.0.0/0 |0.0.0.0/0 130 | |======================================================================= 131 | -------------------------------------------------------------------------------- /docs/partner_editable/architecture.adoc: -------------------------------------------------------------------------------- 1 | Before you deploy the template in this Quick Start, decide whether to use two Availability Zones or three, and whether to use a https://docs.microsoft.com/en-us/windows-server/failover-clustering/manage-cluster-quorum[file share witness] or a full node. 2 | 3 | By default, the Exchange Server Quick Start uses two Availability Zones, with one Exchange node in each zone. The file share witness is launched in the same Availability Zone as the first Exchange node. 4 | 5 | *Note*: Where possible, we recommend deploying the Exchange Server Quick Start using three Availability Zones. This enables automatic failover of database availability groups (DAGs), without the need for manual intervention. 6 | 7 | You can deploy a full Exchange node instead of a file share witness. In addition, you can specify whether to deploy the full node or the file share witness in a third Availability Zone. 8 | 9 | To learn more about Exchange DAGs and quorum models, see https://technet.microsoft.com/en-us/library/dd979799[TechNet – database availability groups]. 10 | 11 | In addition, you can deploy an internal Application Load Balancer (ALB) to provide high availability and distribute traffic to the Exchange nodes. In this configuration, you need to import a Secure Sockets Layer (SSL) certificate into AWS Certificate Manager (ACM) before you launch the template. 12 | 13 | AWS Secrets Manager is used to securely store the Exchange administrative account credentials. AWS Systems Manager Parameter Store is used to retrieve the credentials. 14 | 15 | Deploying this Quick Start for a new virtual private cloud (VPC) with default parameters builds the following {partner-product-short-name} environment in the AWS Cloud. 16 | 17 | // Replace this example diagram with your own. Send us your source PowerPoint file. Be sure to follow our guidelines here : http://(we should include these points on our contributors giude) 18 | :xrefstyle: short 19 | [#architecture1] 20 | .Quick Start architecture for {partner-product-short-name} on AWS 21 | image::../images/image1.png[Architecture,width=100%,height=100%] 22 | 23 | You can also choose to build an architecture with three Availability Zones, as shown in the following figure: 24 | 25 | [#architecture2] 26 | .Quick Start architecture for {partner-product-short-name} across three Availability Zones on AWS 27 | image::../images/image2.png[Architecture,width=100%,height=100%] 28 | 29 | As shown in <>, the Quick Start sets up the following: 30 | 31 | * A highly available architecture that spans two or three Availability Zones.* 32 | * A VPC configured with public and private subnets, according to AWS best practices, to provide you with your own virtual network on AWS.* 33 | * In the public subnets: 34 | ** Managed network address translation (NAT) gateways to allow outbound internet access for resources in the private subnets.* 35 | ** A Remote Desktop Gateway in an Auto Scaling group to allow inbound Remote Desktop Protocol (RDP) access to EC2 instances in public and private subnets.* 36 | * In the private subnets: 37 | ** Active Directory domain controllers. 38 | ** Windows Server EC2 instances as Exchange nodes. 39 | ** (Optional) In the public subnets, Exchange Edge Transport servers for routing internet email in and out of your environment. 40 | // Add bullet points for any additional components that are included in the deployment. Make sure that the additional components are also represented in the architecture diagram. End each bullet with a period. 41 | 42 | [.small]#*The template that deploys the Quick Start into an existing VPC skips the components marked by asterisks and prompts you for your existing VPC configuration.# 43 | 44 | [[implementation-details]] 45 | === Implementation Details 46 | 47 | [[storage-on-the-exchange-nodes]] 48 | ==== Storage on the Exchange Nodes 49 | 50 | Storage capacity and performance are key aspects of any production installation. Although capacity and performance vary from one deployment to the next, this Quick Start provides a reference configuration that you can use as a starting point. The AWS CloudFormation template deploys the Exchange nodes using the memory-optimized r5.xlarge instance type by default. 51 | 52 | To provide highly performant and durable storage, we’ve also included Amazon EBS volumes in this reference architecture. EBS volumes are network-attached disk storage, which you can create and attach to EC2 instances. Once these are attached, you can create a file system on top of these volumes, run a mailbox database, or use them in any other way you would use a block device. EBS volumes are placed in a specific Availability Zone, where they are automatically replicated to protect you from the failure of a single component. 53 | 54 | Provisioned IOPS EBS volumes offer storage with consistent and low-latency performance. They are backed by solid state drives (SSDs) and are designed for applications with I/O-intensive workloads such as databases. 55 | 56 | Amazon EBS-optimized instances, such as the R5 instance type, deliver dedicated throughput between Amazon EC2 and Amazon EBS. The dedicated throughput minimizes contention between Amazon EBS I/O and other traffic from your Amazon EC2 instance, and provides the best performance for your EBS volumes. 57 | 58 | By default, on each Exchange node, the Quick Start deploys three 500-GiB General Purpose (GP2) SSD volumes to store mailbox databases and transaction logs. The database and log partitions are formatted using GUID Partition Table ( GPT). 59 | 60 | By default, partitions are created using Resilient File System (ReFS), which is the Preferred Architecture (PA) choice for Exchange Server 2016 and Exchange Server 2019. If you set the Enable or disable ReFS parameter to *false*, the partitions are formatted using NTFS. 61 | 62 | The GP2 volume type delivers a consistent baseline of 3 IOPS/GiB, which provides a total of 1,500 IOPS per volume for Exchange database and transaction log volumes. You can customize the volume size, and you can switch to using dedicated IOPS volumes. 63 | 64 | If you need more IOPS per volume, consider using Provisioned IOPS SSD volumes by changing the *Exchange Server Volume Type* and *Exchange Server Volume IOPS* parameters, or use disk striping within Windows. 65 | 66 | The default disk layout in this Quick Start uses the following EBS volumes: 67 | 68 | * One General Purpose SSD volume (100 GiB) for the operating system (C:) 69 | * One General Purpose SSD volume (500 GiB) to host the Exchange Server database files (D:) 70 | * One General Purpose SSD volume (500 GiB) to host the Exchange Server transaction log files (E:) 71 | 72 | The following figure shows the disk layout on each Exchange Server node: 73 | 74 | [#architecture3] 75 | .Disk layout on Exchange Server node 76 | image::../images/image3.png[Architecture,width=521,height=172] 77 | 78 | *Note* You’ll find the installation software on each node in the *C:\Exchangeinstall* folder. 79 | 80 | Depending on the instance type selected, you might see additional drives for instance store (ephemeral) volumes such as (Z:). Data on instance storage will be lost when you stop your EC2 instance. 81 | 82 | [[ip-addresses-on-the-exchange-nodes]] 83 | ==== IP Addresses on the Exchange nodes 84 | 85 | By default, the Microsoft Exchange Quick Start template deploys two Exchange nodes with two IP addresses each: 86 | 87 | * One IP address is used as the primary IP address for the instance. 88 | * A second IP address acts as the Failover Cluster IP resource. 89 | 90 | When you launch the AWS CloudFormation template, you can specify the addresses for each node, as shown in Figure 4. By default, the 10.0.0.0/19, 10.0.32.0/19, and 10.0.64.0/19 CIDR blocks are used for the private subnets. 91 | 92 | [#architecture4] 93 | .Configuring IP addresses on the Exchange node 94 | image::../images/image4.png[Architecture,width=639,height=146] 95 | 96 | [[database-availability-group]] 97 | ==== Database Availability Group 98 | 99 | A failover cluster is automatically created for the database availability group (DAG). The AWS CloudFormation templates carry out this task when deploying the second node. If you use the default parameter settings in the template, the Quick Start runs the following Windows PowerShell commands to complete this task: 100 | 101 | ---- 102 | Install-WindowsFeature failover-clustering –IncludeManagementTools 103 | 104 | New-DatabaseAvailabilityGroup -Name DAG -WitnessServer FileServer 105 | 106 | -WitnessDirectory C:\DAG 107 | 108 | Add-DatabaseAvailabilityGroupServer -Identity DAG 109 | 110 | -MailboxServer ExchangeNode1 111 | 112 | Add-DatabaseAvailabilityGroupServer -Identity DAG 113 | 114 | -MailboxServer ExchangeNode2 115 | ---- 116 | 117 | *Note*: By default, the database availability group is created with the name DAG. To change this value, modify the DAGName default parameter value in the Configure-ExchangeDAG.ps1 file. 118 | 119 | The first command runs on each instance during the bootstrapping process. It installs the required components and management tools for the failover clustering services. The rest of the commands run near the end of the bootstrapping process on the second node and are responsible for creating the cluster and for defining the server nodes and IP addresses. 120 | 121 | By default, the Quick Start configures an even number of servers in the cluster. You need a third resource to maintain a majority vote to keep the cluster online if an individual server fails. For this, the Quick Start uses a dedicated file share witness instance, which can be either a domain-joined server or a third Exchange node (which cannot be part of the DAG itself). By default, the Quick Start creates a Dedicated Instance in the first Availability Zone to act as the file share witness. For production environments, you can also set the *Third AZ* parameter to *witness* to create a Dedicated Instance with a file share in a third Availability Zone. 122 | 123 | Alternatively, you can use any domain-joined server for this task. (This isn’t included in the Quick Start.) If you set the *Third AZ* parameter to *full*, the Quick Start keeps the quorum settings to the default node majority and creates a third Exchange Server node in the third Availability Zone. Note that some AWS Regions support only two Availability Zones; for a current list, see https://aws.amazon.com/about-aws/global-infrastructure/[AWS Global Infrastructure]. 124 | 125 | The Quick Start automated solution ends after creating the DAG and adding the two Exchange nodes to the DAG. When the deployment is complete, you can create additional databases and make them highly available by creating copies on the second nodes. This process is covered in link:#step-3.-optional-create-database-copies[step 3] of the deployment instructions. 126 | 127 | [[edge-transport-nodes]] 128 | ==== Edge Transport Nodes 129 | 130 | Edge Transport nodes relay inbound and outbound emails and provide smart host services within the Exchange organization. The Edge nodes are installed in the public subnets and aren’t domain-joined. However, they do require information from Active Directory, and configuring an Edge sync subscription is needed. 131 | 132 | Because Edge Transport role nodes aren’t required for end-to-end mail flow, by default, Edge nodes aren’t deployed. For this to occur, you must select *yes* on the *Deploy Edge servers* launch option, as shown in the following figure: 133 | 134 | [#architecture5] 135 | .Deploying Edge servers 136 | image::../images/image5.png[Architecture,width=648,height=89] 137 | 138 | A pair of Edge servers is deployed in the public subnets (which must be defined), and the Exchange Server Edge Transport role is installed using default settings. The EC2 instances aren’t domain-joined, but the DNS suffix that corresponds to the domain name is configured on the network interface cards (NICs). Also, DNS records are created in Active Directory corresponding to their hostname. 139 | 140 | The Local Administrator password is reset to the Domain Admin password, and an Edge subscription file is created, which can be found in C:\EdgeServerSubscription.xml. 141 | 142 | Copy the subscription file to a *mailbox* server, and import the subscription by running the following command: 143 | 144 | New-EdgeSubscription -FileData ([byte[]]$(Get-Content -Path "C:\EdgeServerSubscription.xml" -Encoding Byte -ReadCount 0)) -Site "AZ1" 145 | 146 | [[load-balancer]] 147 | ==== Load balancer 148 | 149 | Exchange servers running with the Client Access/Transport roles are usually situated behind a network load balancer (NLB) with a unified Exchange namespace such as “mail.example.com.” The namespace resolves to the load balancer, which in turns distributes traffic to the Exchange servers. 150 | 151 | The Exchange Server Quick Start contains an option to deploy an Application Load Balancer that distributes the traffic to the Exchange nodes. 152 | 153 | By default, the load balancer isn’t deployed because it requires an existing SSL certificate to be imported in AWS Certificate Manager. 154 | 155 | For a load balancer to be deployed, you must: 156 | 157 | 1. Import or generate a certificate in AWS Certificate Manager. 158 | 2. Specify the full Amazon Resource Name (ARN) in the CertificateARN option. 159 | 3. Select *true* in *Deploy Load Balancer*, when you launch the Quick Start. 160 | 161 | [[volume-encryption]] 162 | ==== Volume Encryption 163 | 164 | As part of the default setup, the Exchange Server Quick Start creates and attaches two EBS volumes to each Exchange node. One EBS volume (corresponding to the D:\ drive) holds the Exchange mailbox databases, while the other EBS volume (E:\) holds the Exchange transaction logs. 165 | 166 | Optionally, the Quick Start provides an option to encrypt the EBS volumes with either the default AWS Key Management Service (AWS KMS) encryption key or a custom KMS key, as shown in the following figure: 167 | 168 | [#architecture6] 169 | .Encrypting the EBS volumes 170 | image::../images/image5.png[Architecture,width=648,height=83] 171 | 172 | *Note* The root volume of the Exchange nodes (C:\) isn’t encrypted, if *Encrypt data volumes* is selected. 173 | -------------------------------------------------------------------------------- /docs/partner_editable/deploy_steps.adoc: -------------------------------------------------------------------------------- 1 | // We need to work around Step numbers here if we are going to potentially exclude the AMI subscription 2 | === Sign in to your AWS account 3 | 4 | . Sign in to your AWS account at https://aws.amazon.com with an IAM user role that has the necessary permissions. For details, see link:#_planning_the_deployment[Planning the deployment] earlier in this guide. 5 | . Make sure that your AWS account is configured correctly, as discussed in the link:#_technical_requirements[Technical requirements] section. 6 | 7 | // Optional based on Marketplace listing. Not to be edited 8 | ifdef::marketplace_subscription[] 9 | === Subscribe to the {partner-product-short-name} AMI 10 | 11 | This Quick Start requires a subscription to the AMI for {partner-product-short-name} in AWS Marketplace. 12 | 13 | . Sign in to your AWS account. 14 | . {marketplace_listing_url}[Open the page for the {partner-product-short-name} AMI in AWS Marketplace], and then choose *Continue to Subscribe*. 15 | . Review the terms and conditions for software usage, and then choose *Accept Terms*. + 16 | A confirmation page loads, and an email confirmation is sent to the account owner. For detailed subscription instructions, see the https://aws.amazon.com/marketplace/help/200799470[AWS Marketplace documentation^]. 17 | 18 | . When the subscription process is complete, exit out of AWS Marketplace without further action. *Do not* provision the software from AWS Marketplace—the Quick Start deploys the AMI for you. 19 | endif::marketplace_subscription[] 20 | // \Not to be edited 21 | 22 | === Launch the Quick Start 23 | // Adapt the following warning to your Quick Start. 24 | WARNING: If you're deploying {partner-product-short-name} into an existing VPC, make sure that your VPC has two private subnets in different Availability Zones for the workload instances and that the subnets aren't shared. This Quick Start doesn't support https://docs.aws.amazon.com/vpc/latest/userguide/vpc-sharing.html[shared subnets^]. These subnets require https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html[NAT gateways^] in their route tables to allow the instances to download packages and software without exposing them to the internet. Also make sure that the domain name option in the DHCP options is configured as explained in http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_DHCP_Options.html[DHCP options sets^]. You provide your VPC settings when you launch the Quick Start. 25 | 26 | NOTE: You are responsible for the cost of the AWS services used while running this Quick Start reference deployment. There is no additional cost for using this Quick Start. For full details, see the pricing pages for each AWS service used by this Quick Start. Prices are subject to change. 27 | 28 | Each deployment takes about {deployment_time} to complete. 29 | 30 | . Sign in to your AWS account, and choose one of the following options to launch the AWS CloudFormation template. For help with choosing an option, see link:#_deployment_options[Deployment options] earlier in this guide. 31 | 32 | [cols=2*] 33 | |=== 34 | ^|https://fwd.aws/MqvGy[Deploy {partner-product-short-name} into a new VPC on AWS^] 35 | ^|https://github.com/aws-quickstart/quickstart-microsoft-exchange/blob/main/templates/exchange-master.template[View template^] 36 | 37 | ^|https://fwd.aws/xq5Mx[Deploy {partner-product-short-name} into an existing VPC on AWS^] 38 | ^|https://github.com/aws-quickstart/quickstart-microsoft-exchange/blob/main/templates/exchange.template[View template^] 39 | |=== 40 | 41 | [start=2] 42 | . Check the AWS Region that's displayed in the upper-right corner of the navigation bar, and change it if necessary. This Region is where the network infrastructure for {partner-product-short-name} is built. The template is launched in the {default_deployment_region} Region by default. 43 | 44 | // *Note:* This deployment includes Amazon EFS, which isn't currently supported in all AWS Regions. For a current list of supported Regions, see the https://docs.aws.amazon.com/general/latest/gr/elasticfilesystem.html[endpoints and quotas webpage]. 45 | 46 | [start=3] 47 | . On the *Create stack* page, keep the default setting for the template URL, and then choose *Next*. 48 | . On the *Specify stack details* page, change the stack name if needed. Review the parameters for the template. Provide values for the parameters that require input. For all other parameters, review the default settings and customize them as necessary. For details on each parameter, see the link:#_parameter_reference[Parameter reference] section of this guide. When you finish reviewing and customizing the parameters, choose *Next*. 49 | -------------------------------------------------------------------------------- /docs/partner_editable/deployment_options.adoc: -------------------------------------------------------------------------------- 1 | // Edit this placeholder text to accurately describe your architecture. 2 | 3 | This Quick Start provides two deployment options: 4 | 5 | * *Deploy {partner-product-short-name} into a new VPC*. This option builds a new AWS environment consisting of the VPC, subnets, NAT gateways, security groups, bastion hosts, and other infrastructure components. It then deploys {partner-product-short-name} into this new VPC. 6 | * *Deploy {partner-product-short-name} into an existing VPC*. This option provisions {partner-product-short-name} in your existing AWS infrastructure. 7 | 8 | The Quick Start provides separate templates for these options. It also lets you configure Classless Inter-Domain Routing (CIDR) blocks, instance types, and {partner-product-short-name} settings, as discussed later in this guide. 9 | -------------------------------------------------------------------------------- /docs/partner_editable/faq_troubleshooting.adoc: -------------------------------------------------------------------------------- 1 | // Add any tips or answers to anticipated questions. This could include the following troubleshooting information. If you don’t have any other Q&A to add, change “FAQ” to “Troubleshooting.” 2 | 3 | == FAQ 4 | 5 | *Q.* I encountered a *CREATE_FAILED* error when I launched the Quick Start. 6 | 7 | *A.* If AWS CloudFormation fails to create the stack, relaunch the template with *Rollback on failure* set to *Disabled*. This setting is under *Advanced* in the AWS CloudFormation console on the *Configure stack options* page. With this setting, the stack’s state is retained and the instance is left running, so you can troubleshoot the issue. (For Windows, look at the log files in `%ProgramFiles%\Amazon\EC2ConfigService` and `C:\cfn\log`.) 8 | // If you’re deploying on Linux instances, provide the location for log files on Linux, or omit this sentence. 9 | 10 | WARNING: When you set *Rollback on failure* to *Disabled*, you continue to incur AWS charges for this stack. Delete the stack when you finish troubleshooting. 11 | 12 | For more information, see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/troubleshooting.html[Troubleshooting AWS CloudFormation^]. 13 | 14 | *Q.* I encountered a size limitation error when I deployed the AWS CloudFormation templates. 15 | 16 | *A.* Launch the Quick Start templates from the links in this guide or from another S3 bucket. If you deploy the templates from a local copy on your computer or from a location other than an S3 bucket, you might encounter template size limitations. For more information, see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html[AWS CloudFormation quotas^]. 17 | -------------------------------------------------------------------------------- /docs/partner_editable/licenses.adoc: -------------------------------------------------------------------------------- 1 | // Include details about the license and how they can sign up. If no license is required, clarify that. 2 | 3 | Exchange Server can be deployed and licensed through the https://aws.amazon.com/windows/mslicensemobility/[Microsoft License Mobility through Software Assurance] program. For development and test environments, you can use your existing MSDN licenses for Exchange Server using Amazon Elastic Compute Cloud (Amazon EC2) Dedicated Instances. For details, see the https://aws.amazon.com/windows/msdn/[MSDN on AWS] page. 4 | 5 | This Quick Start deployment uses an evaluation copy of Exchange Server. To upgrade your version, see the Microsoft Exchange Server website. 6 | 7 | This Quick Start launches the Amazon Machine Image (AMI) for Microsoft Windows Server 2016 and Windows Server 2019, and includes the license for the Windows Server operating system. The AMI is updated on a regular basis with the latest service pack for the operating system, so you don’t have to install any updates. The Windows Server AMI doesn’t require client access licenses (CALs) and includes two Microsoft Remote Desktop Services licenses. For details, see https://aws.amazon.com/windows/resources/licensing/[Microsoft Licensing on AWS]. 8 | -------------------------------------------------------------------------------- /docs/partner_editable/overview_target_and_usage.adoc: -------------------------------------------------------------------------------- 1 | // Replace the content in <> 2 | // Identify your target audience and explain how/why they would use this Quick Start. 3 | //Avoid borrowing text from third-party websites (copying text from AWS service documentation is fine). Also, avoid marketing-speak, focusing instead on the technical aspect. 4 | 5 | This Quick Start reference deployment guide includes infrastructure information, architectural considerations, and configuration steps for planning and deploying a Microsoft Exchange Server environment on the AWS Cloud. It uses https://aws.amazon.com/cloudformation/[AWS CloudFormation] templates to automate the deployment. 6 | 7 | *Note* This Quick Start supports Exchange Server 2016 and Exchange Server 2019. 8 | 9 | This Quick Start is for IT infrastructure architects, administrators, and DevOps professionals who are planning to implement or extend their Exchange Server workloads on the AWS Cloud. 10 | 11 | Included are best practices for configuring a highly available, fault-tolerant, and secure Exchange environment. This guide doesn’t cover general installation and software configuration tasks for Exchange Server. For general guidance and best practices, consult the https://docs.microsoft.com/en-us/Exchange/exchange-server?view=exchserver-2019[Microsoft Exchange Server documentation]. 12 | -------------------------------------------------------------------------------- /docs/partner_editable/pre-reqs.adoc: -------------------------------------------------------------------------------- 1 | // If no preperation is required, remove all content from here 2 | 3 | ==== Prepare for the deployment 4 | 5 | Microsoft has released Exchange Server 2019 only via https://www.microsoft.com/Licensing/servicecenter/default.aspx[Volume Licensing Service Center], so if you are deploying Exchange 2019 you need to provide your own installation media. The *Exchange2019Source* parameter takes as an input the full URL to the installation media (ISO file). 6 | 7 | The *Exchange2019Source* parameter value should always end in an ISO file extension, although the file name itself is not important as the scripts have built-in logic to determine it from the URL. 8 | 9 | Acceptable paths: 10 | 11 | https://[yourbucket].s3-us-east-1.amazonaws.com/SW_DVD9_Exchange_Svr_2019.ISO 12 | 13 | http://media.example.com/Exchange2019.ISO 14 | 15 | Improper path: 16 | 17 | https://[yourbucket].s3-us-east-1.amazonaws.com/SW_DVD9_Exchange_Svr_2019.zip 18 | 19 | *Note*: Upload the Exchange 2019 installation media to an S3 bucket and temporarily make the installation media public. This will ensure that the file is quickly downloaded to the EC2 instances. 20 | -------------------------------------------------------------------------------- /docs/partner_editable/product_description.adoc: -------------------------------------------------------------------------------- 1 | // Replace the content in <> 2 | // Briefly describe the software. Use consistent and clear branding. 3 | // Include the benefits of using the software on AWS, and provide details on usage scenarios. 4 | 5 | Exchange Server is a messaging and collaboration solution that Microsoft developed, with support for mailboxes, calendars, compliance, and e-archival. In an Exchange Server environment, your users can collaborate and—when you deploy the environment in AWS—you can scale your environment based on demand. 6 | 7 | The AWS Cloud provides infrastructure services that enable you to deploy Exchange Server in a highly available, fault-tolerant, and affordable way. By deploying on AWS, you get the functionality of Exchange Server and the flexibility and security of AWS. 8 | 9 | In addition to this Quick Start, we’ve published a set of Microsoft-based Quick Starts that you can use to deploy other common Microsoft workloads on AWS, including: 10 | 11 | * Microsoft Active Directory 12 | * Remote Desktop Gateway (RD Gateway) 13 | * Microsoft SharePoint Server 14 | * Microsoft Web Application Proxy with Active Directory Federation Services (ADFS) 15 | * Microsoft SQL Server 16 | * Windows Server Update Services 17 | 18 | Each of those Quick Starts includes a virtual private cloud (VPC) environment, which is deployed based on AWS best practices. To read more about deploying Microsoft workloads by using our Quick Starts, see the https://aws.amazon.com/quickstart/#microsoft_technologies[Quick Starts in the Microsoft Technologies category]. 19 | -------------------------------------------------------------------------------- /docs/partner_editable/regions.adoc: -------------------------------------------------------------------------------- 1 | This Quick Start supports deployment in either two or three Availability Zones, however some AWS Regions support only two Availability Zones; for a current list, see https://aws.amazon.com/about-aws/global-infrastructure/[AWS Global Infrastructure]. 2 | 3 | //Full list: https://docs.aws.amazon.com/general/latest/gr/rande.html 4 | -------------------------------------------------------------------------------- /docs/partner_editable/service_limits.adoc: -------------------------------------------------------------------------------- 1 | // Replace the in each row to specify the number of resources used in this deployment. Remove the rows for resources that aren’t used. 2 | |=== 3 | |Resource |This deployment uses 4 | 5 | // Space needed to maintain table headers 6 | |VPCs |1 7 | |Elastic IP addresses |1 8 | |Security groups |5 9 | |AWS Identity and Access Management (IAM) roles |3 10 | |Auto Scaling groups |1 11 | |Network Load Balancers |1 12 | |EC2 instances |7 13 | |=== 14 | -------------------------------------------------------------------------------- /docs/partner_editable/specialized_knowledge.adoc: -------------------------------------------------------------------------------- 1 | // Replace the content in <> 2 | // For example: “familiarity with basic concepts in networking, database operations, and data encryption” or “familiarity with .” 3 | // Include links if helpful. 4 | // You don't need to list AWS services or point to general info about AWS; the boilerplate already covers this. 5 | 6 | Before you deploy this Quick Start, we recommend that you become familiar with the following AWS services. (If you are new to AWS, see https://aws.amazon.com/getting-started/[Getting Started with AWS].) 7 | 8 | * https://aws.amazon.com/documentation/ec2/[Amazon Elastic Compute Cloud (Amazon EC2)] 9 | * https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEBS.html[Amazon Elastic Block Store (Amazon EBS)] 10 | * https://aws.amazon.com/documentation/vpc/[Amazon Virtual Private Cloud (Amazon VPC)] 11 | * https://aws.amazon.com/documentation/cloudformation/[AWS CloudFormation] 12 | * http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-nat-gateway.html[NAT gateway] 13 | * http://aws.amazon.com/documentation/iam/[AWS Identity and Access Management (IAM)] 14 | * https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/what-is-load-balancing.html[Elastic Load Balancing (ELB)] 15 | * https://aws.amazon.com/documentation/acm/[AWS Certificate Manager (ACM)] 16 | 17 | In addition, you should be familiar with the following: 18 | 19 | * Windows Server 2016 or Windows Server 2019 20 | * Microsoft Active Directory and Domain Name System (DNS) 21 | * Windows Server Failover Clustering (WSFC) 22 | * Exchange database availability groups (DAGs) 23 | 24 | For information, see the Microsoft product documentation for these technologies. 25 | -------------------------------------------------------------------------------- /manifests/app-manager/app-manager-manifest.yaml: -------------------------------------------------------------------------------- 1 | ssm_app_manager: 2 | should_upload: true 3 | documents_list: 4 | - document_name: AWSQuickStarts-Microsoft-Exchange 5 | template_name: exchange-main.template.yaml 6 | has_nested_stacks: true 7 | nested_documents: 8 | - resource_name: VPCStack 9 | document_name: AWSQuickStarts-AWS-VPC 10 | -------------------------------------------------------------------------------- /scripts/Add-ExchangeGroup.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | 4 | [Parameter(Mandatory=$true)] 5 | [string] 6 | $DomainNetBIOSName, 7 | 8 | [Parameter(Mandatory=$true)] 9 | [string] 10 | $DomainAdminUser, 11 | 12 | [Parameter(Mandatory=$true)] 13 | [string] 14 | $ExUserSecParam, 15 | 16 | [Parameter(Mandatory=$false)] 17 | [string] 18 | $ExchangeGroupName="Exchange Trusted Subsystem", 19 | 20 | [Parameter(Mandatory=$True)] 21 | [string] 22 | $ServerName, 23 | 24 | [Parameter(Mandatory=$false)] 25 | [string] 26 | $LocalGroupName="Administrators" 27 | ) 28 | 29 | 30 | try { 31 | Start-Transcript -Path C:\cfn\log\Add-ExchangeGroup.ps1.txt -Append 32 | $ErrorActionPreference = "Stop" 33 | 34 | $DomainAdminFullUser = $DomainNetBIOSName + '\' + $DomainAdminUser 35 | $DomainAdminPassword = ConvertFrom-Json -InputObject (Get-SECSecretValue -SecretId $ExUserSecParam).SecretString 36 | $DomainAdminCreds = (New-Object PSCredential($DomainAdminFullUser,(ConvertTo-SecureString $DomainAdminPassword.Password -AsPlainText -Force))) 37 | 38 | $ExchangeGroupPS={ 39 | $ErrorActionPreference = "Stop" 40 | $ExchangeGroup = [ADSI]"WinNT://$Using:DomainNetBIOSName/$Using:ExchangeGroupName,group" 41 | $LocalGroup = [ADSI]"WinNT://$Using:ServerName/$Using:LocalGroupName,group" 42 | $LocalGroup.PSBase.Invoke("Add",$ExchangeGroup.PSBase.Path) 43 | } 44 | 45 | $Retries = 0 46 | $Installed = $false 47 | while (($Retries -lt 4) -and (!$Installed)) { 48 | try { 49 | 50 | Invoke-Command -Scriptblock $ExchangeGroupPS -ComputerName $ServerName -Credential $DomainAdminCreds 51 | $Installed = $true 52 | } 53 | catch { 54 | $Exception = $_ 55 | $Retries++ 56 | if ($Retries -lt 4) { 57 | Start-Sleep ($Retries * 60) 58 | } 59 | } 60 | } 61 | if (!$Installed) { 62 | throw $Exception 63 | } 64 | 65 | } 66 | catch { 67 | Write-Verbose "$($_.exception.message)@ $(Get-Date)" 68 | $_ | Write-AWSQuickStartException 69 | } -------------------------------------------------------------------------------- /scripts/Configure-EdgeDnsRecord.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | [string] 4 | [Parameter(Mandatory=$true)] 5 | $EdgeNodeNetBIOSName, 6 | 7 | [string] 8 | [Parameter(Mandatory=$true)] 9 | $EdgeNodePrivateIP, 10 | 11 | [string] 12 | [Parameter(Mandatory=$true)] 13 | $DnsServer, 14 | 15 | [Parameter(Mandatory=$true)] 16 | [string] 17 | $DomainNetBIOSName, 18 | 19 | [Parameter(Mandatory=$true)] 20 | [string] 21 | $DomainAdminUser, 22 | 23 | [Parameter(Mandatory=$true)] 24 | [string] 25 | $ExUserSecParam 26 | ) 27 | 28 | 29 | 30 | try { 31 | Start-Transcript -Path C:\cfn\log\Configure-EdgeDNSRecord.ps1.txt -Append 32 | $ErrorActionPreference = "Stop" 33 | 34 | $DomainAdminFullUser = $DomainNetBIOSName + '\' + $DomainAdminUser 35 | $DomainAdminPassword = ConvertFrom-Json -InputObject (Get-SECSecretValue -SecretId $ExUserSecParam).SecretString 36 | $DomainAdminCreds = (New-Object PSCredential($DomainAdminFullUser,(ConvertTo-SecureString $DomainAdminPassword.Password -AsPlainText -Force))) 37 | 38 | $EdgeRecordPs={ 39 | $ErrorActionPreference = "Stop" 40 | Add-DnsServerResourceRecordA -Name $Using:EdgeNodeNetBIOSName -IPv4Address $Using:EdgeNodePrivateIP -ZoneName $Using:DomainNetBIOSName 41 | } 42 | 43 | $Retries = 0 44 | $Installed = $false 45 | while (($Retries -lt 4) -and (!$Installed)) { 46 | try { 47 | 48 | Invoke-Command -Scriptblock $EdgeRecordPs -ComputerName $DnsServer -Credential $DomainAdminCreds 49 | $Installed = $true 50 | } 51 | catch { 52 | $Exception = $_ 53 | $Retries++ 54 | if ($Retries -lt 4) { 55 | Start-Sleep ($Retries * 60) 56 | } 57 | } 58 | } 59 | if (!$Installed) { 60 | throw $Exception 61 | } 62 | } 63 | catch { 64 | Write-Verbose "$($_.exception.message)@ $(Get-Date)" 65 | $_ | Write-AWSQuickStartException 66 | } -------------------------------------------------------------------------------- /scripts/Configure-ExchangeDAG.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | 4 | [Parameter(Mandatory=$true)] 5 | [string] 6 | $DomainNetBIOSName, 7 | 8 | [Parameter(Mandatory=$true)] 9 | [string] 10 | $DomainAdminUser, 11 | 12 | [Parameter(Mandatory=$true)] 13 | [string] 14 | $ExUserSecParam, 15 | 16 | [Parameter(Mandatory=$true)] 17 | [string] 18 | $ExchangeNode1NetBIOSName, 19 | 20 | [Parameter(Mandatory=$true)] 21 | [string] 22 | $ExchangeNode2NetBIOSName, 23 | 24 | [Parameter(Mandatory=$false)] 25 | [string] 26 | $ExchangeNode3NetBIOSName=$null, 27 | 28 | [Parameter(Mandatory=$false)] 29 | [string] 30 | $ExchangeNode1PrivateIP2, 31 | 32 | [Parameter(Mandatory=$false)] 33 | [string] 34 | $ExchangeNode2PrivateIP2, 35 | 36 | [Parameter(Mandatory=$false)] 37 | [string] 38 | $ExchangeNode3PrivateIP2=$null, 39 | 40 | [Parameter(Mandatory=$false)] 41 | [string] 42 | $FileServerNetBIOSName, 43 | 44 | [Parameter(Mandatory=$false)] 45 | [string] 46 | $DAGName="DAG" 47 | ) 48 | try { 49 | Start-Transcript -Path C:\cfn\log\Configure-ExchangeDAG.ps1.txt -Append 50 | $ErrorActionPreference = "Stop" 51 | 52 | $DomainAdminFullUser = $DomainNetBIOSName + '\' + $DomainAdminUser 53 | $DomainAdminPassword = ConvertFrom-Json -InputObject (Get-SECSecretValue -SecretId $ExUserSecParam).SecretString 54 | $DomainAdminCreds = (New-Object PSCredential($DomainAdminFullUser,(ConvertTo-SecureString $DomainAdminPassword.Password -AsPlainText -Force))) 55 | 56 | $ConfigDAG={ 57 | $ErrorActionPreference = "Stop" 58 | 59 | Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn 60 | New-DatabaseAvailabilityGroup -Name $Using:DAGName -WitnessServer $Using:FileServerNetBIOSName -WitnessDirectory C:\$Using:DAGName -DatabaseAvailabilityGroupIpAddresses '255.255.255.255' 61 | 62 | Start-Sleep -s 60 63 | 64 | Add-DatabaseAvailabilityGroupServer -Identity $Using:DAGName -MailboxServer $Using:ExchangeNode1NetBIOSName 65 | Add-DatabaseAvailabilityGroupServer -Identity $Using:DAGName -MailboxServer $Using:ExchangeNode2NetBIOSName 66 | 67 | # Manuall run 68 | #Add-MailboxDatabaseCopy -Identity DB1 -MailboxServer $Using:ExchangeNode2NetBIOSName -ActivationPreference 2 69 | #Add-MailboxDatabaseCopy -Identity DB2 -MailboxServer $Using:ExchangeNode1NetBIOSName -ActivationPreference 2 70 | 71 | #There should also be a restart of the IS service (restart-service MSExchangeIS on each node) 72 | #Get-MailboxDatabaseCopyStatus * | where {$_.ContentIndexState -eq "Failed"} | Update-MailboxDatabaseCopy -CatalogOnly 73 | 74 | } 75 | if ($ExchangeNode3NetBIOSName) { 76 | $ConfigDAG={ 77 | $ErrorActionPreference = "Stop" 78 | 79 | Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn 80 | New-DatabaseAvailabilityGroup -Name $Using:DAGName -WitnessServer $Using:ExchangeNode3NetBIOSName -WitnessDirectory C:\$Using:DAGName 81 | 82 | Start-Sleep -s 60 83 | 84 | Add-DatabaseAvailabilityGroupServer -Identity $Using:DAGName -MailboxServer $Using:ExchangeNode1NetBIOSName 85 | Add-DatabaseAvailabilityGroupServer -Identity $Using:DAGName -MailboxServer $Using:ExchangeNode2NetBIOSName 86 | } 87 | } 88 | 89 | 90 | Invoke-Command -Authentication Credssp -Scriptblock $ConfigDAG -ComputerName localhost -Credential $DomainAdminCreds 91 | } 92 | catch { 93 | $_ | Write-AWSQuickStartException 94 | } 95 | -------------------------------------------------------------------------------- /scripts/Configure-UAC.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | [string] 4 | [Parameter(Mandatory=$true)] 5 | $Status 6 | ) 7 | 8 | 9 | try { 10 | Start-Transcript -Path C:\cfn\log\Configure-UAC.ps1.txt -Append 11 | $ErrorActionPreference = "Stop" 12 | 13 | if($Status -eq "Disable") { 14 | Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableLUA" -Value "0" 15 | } 16 | 17 | elseif($Status -eq "Enable") { 18 | Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableLUA" -Value "1" 19 | } 20 | } 21 | catch { 22 | Write-Verbose "$($_.exception.message)@ $(Get-Date)" 23 | $_ | Write-AWSQuickStartException 24 | } -------------------------------------------------------------------------------- /scripts/Download-Prerequisites.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | 4 | [Parameter(Mandatory=$true)] 5 | [string] 6 | $source 7 | ) 8 | 9 | try { 10 | Start-Transcript -Path C:\cfn\log\Download-PreRequisites.ps1.txt -Append 11 | 12 | $ErrorActionPreference = "Stop" 13 | 14 | $DestPath = "C:\Exchangeinstall" 15 | New-Item "$DestPath" -Type directory -Force 16 | 17 | $tries = 5 18 | while ($tries -ge 1) { 19 | try { 20 | Start-BitsTransfer -Source $source -Destination "$DestPath" -ErrorAction Stop 21 | break 22 | } 23 | catch { 24 | $tries-- 25 | Write-Verbose "Exception:" 26 | Write-Verbose "$_" 27 | if ($tries -lt 1) { 28 | throw $_ 29 | } 30 | else { 31 | Write-Verbose "Failed download. Retrying again in 5 seconds" 32 | Start-Sleep 5 33 | } 34 | } 35 | } 36 | } 37 | catch { 38 | Write-Verbose "$($_.exception.message)@ $(Get-Date)" 39 | $_ | Write-AWSQuickStartException 40 | } 41 | -------------------------------------------------------------------------------- /scripts/Expand-Exchange.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | 4 | [Parameter(Mandatory=$true)] 5 | [string] 6 | $ExchangeServerVersion, 7 | 8 | [Parameter(Mandatory=$true)] 9 | [string] 10 | $ExchangeDownloadLink 11 | 12 | ) 13 | 14 | try { 15 | Start-Transcript -Path C:\cfn\log\Expand-Exchange.ps1.txt -Append 16 | $ErrorActionPreference = "Stop" 17 | $Path = "C:\Exchangeinstall" 18 | $filename = $ExchangeDownloadLink.Substring($ExchangeDownloadLink.LastIndexOf("/") + 1) 19 | 20 | if($ExchangeServerVersion -eq "2016") { 21 | $isoPath = $Path + "\" + $filename 22 | Mount-DiskImage -ImagePath $isoPath 23 | $driveLetter = (Get-DiskImage $isoPath | Get-Volume).DriveLetter 24 | Copy-Item -Path "${driveLetter}:\*" -Destination $Path -Recurse 25 | } 26 | elseif ($ExchangeServerVersion -eq "2019") { 27 | $isoPath = $Path + "\" + $filename 28 | Mount-DiskImage -ImagePath $isoPath 29 | $driveLetter = (Get-DiskImage $isoPath | Get-Volume).DriveLetter 30 | Copy-Item -Path "${driveLetter}:\*" -Destination $Path -Recurse 31 | } 32 | } 33 | catch { 34 | # $_ | Write-AWSQuickStartException 35 | } 36 | -------------------------------------------------------------------------------- /scripts/Initialize-Disks.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | 3 | param( 4 | 5 | [Parameter(Mandatory=$false)] 6 | [string] 7 | $EnableReFSVolumes 8 | 9 | ) 10 | 11 | try { 12 | Start-Transcript -Path C:\cfn\log\Initialize-Disks.ps1.txt -Append 13 | $ErrorActionPreference = "Stop" 14 | 15 | $newdisk = get-disk | where partitionstyle -eq 'raw' 16 | 17 | foreach ($d in $newdisk){ 18 | $disknum = $d.Number 19 | Initialize-Disk -Number $disknum -PartitionStyle GPT 20 | Set-Disk -Number $disknum -IsReadOnly $False 21 | $partition = New-Partition -DiskNumber $disknum -UseMaximumSize -AssignDriveLetter 22 | 23 | if($EnableReFSVolumes -eq $true) { 24 | Format-Volume -Partition $partition -FileSystem ReFS -SetIntegrityStreams $false -Confirm:$false 25 | } 26 | 27 | elseif($EnableReFSVolumes -eq $false) { 28 | Format-Volume -Partition $partition -FileSystem NTFS -Confirm:$false 29 | } 30 | } 31 | } 32 | catch { 33 | $_ | Write-AWSQuickStartException 34 | } -------------------------------------------------------------------------------- /scripts/Install-EdgePrerequisites.ps1: -------------------------------------------------------------------------------- 1 |  2 | [CmdletBinding()] 3 | 4 | param( 5 | 6 | [Parameter(Mandatory=$true)] 7 | [string] 8 | $ExchangeServerVersion 9 | 10 | ) 11 | 12 | try { 13 | Start-Transcript -Path C:\cfn\log\Install-EdgePrerequisites.ps1.txt -Append 14 | $ErrorActionPreference = "Stop" 15 | $Retries = 0 16 | $Installed = $false 17 | 18 | do { 19 | try { 20 | if($ExchangeServerVersion -eq "2016") { 21 | Install-WindowsFeature ADLDS -ErrorAction Stop 22 | $Installed = $true 23 | } 24 | 25 | elseif ($ExchangeServerVersion -eq "2019") { 26 | Install-WindowsFeature ADLDS -ErrorAction Stop 27 | $Installed = $true 28 | } 29 | } 30 | catch { 31 | $exception = $_ 32 | $retries++ 33 | if ($retries -lt 6) { 34 | Write-Host $exception 35 | $linearBackoff = $retries * 60 36 | Write-Host "Edge prerequisites installation failed. Retrying in $linearBackoff seconds." 37 | Start-Sleep -Seconds $linearBackoff 38 | } 39 | } 40 | } while (($retries -lt 6) -and (-not $installed)) 41 | if (-not $installed) { 42 | throw $exception 43 | } 44 | } 45 | catch { 46 | $_ | Write-AWSQuickStartException 47 | } -------------------------------------------------------------------------------- /scripts/Install-ExchPrerequisites.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | 3 | param( 4 | 5 | [Parameter(Mandatory=$true)] 6 | [string] 7 | $ExchangeServerVersion 8 | 9 | ) 10 | 11 | try { 12 | Start-Transcript -Path C:\cfn\log\Install-ExchPrerequisites.ps1.txt -Append 13 | $ErrorActionPreference = "Stop" 14 | 15 | $Retries = 0 16 | $Installed = $false 17 | 18 | do { 19 | try { 20 | if($ExchangeServerVersion -eq "2016") { 21 | Install-WindowsFeature Server-Media-Foundation 22 | Install-WindowsFeature NET-Framework-45-Features, RPC-over-HTTP-proxy, RSAT-Clustering, RSAT-Clustering-CmdInterface, RSAT-Clustering-Mgmt, RSAT-Clustering-PowerShell, Web-Mgmt-Console, WAS-Process-Model, Web-Asp-Net45, Web-Basic-Auth, Web-Client-Auth, Web-Digest-Auth, Web-Dir-Browsing, Web-Dyn-Compression, Web-Http-Errors, Web-Http-Logging, Web-Http-Redirect, Web-Http-Tracing, Web-ISAPI-Ext, Web-ISAPI-Filter, Web-Lgcy-Mgmt-Console, Web-Metabase, Web-Mgmt-Console, Web-Mgmt-Service, Web-Net-Ext45, Web-Request-Monitor, Web-Server, Web-Stat-Compression, Web-Static-Content, Web-Windows-Auth, Web-WMI, Windows-Identity-Foundation, RSAT-ADDS -Restart -ErrorAction Stop 23 | $Installed = $true 24 | } 25 | 26 | elseif ($ExchangeServerVersion -eq "2019") { 27 | Install-WindowsFeature Server-Media-Foundation 28 | Install-WindowsFeature NET-Framework-45-Features, RPC-over-HTTP-proxy, RSAT-Clustering, RSAT-Clustering-CmdInterface, RSAT-Clustering-PowerShell, WAS-Process-Model, Web-Asp-Net45, Web-Basic-Auth, Web-Client-Auth, Web-Digest-Auth, Web-Dir-Browsing, Web-Dyn-Compression, Web-Http-Errors, Web-Http-Logging, Web-Http-Redirect, Web-Http-Tracing, Web-ISAPI-Ext, Web-ISAPI-Filter, Web-Metabase, Web-Mgmt-Service, Web-Net-Ext45, Web-Request-Monitor, Web-Server, Web-Stat-Compression, Web-Static-Content, Web-Windows-Auth, Web-WMI, RSAT-ADDS -Restart -ErrorAction Stop 29 | $Installed = $true 30 | } 31 | } 32 | catch { 33 | $exception = $_ 34 | $retries++ 35 | if ($retries -lt 6) { 36 | Write-Host $exception 37 | $linearBackoff = $retries * 60 38 | Write-Host "Prerequisites installation failed. Retrying in $linearBackoff seconds." 39 | Start-Sleep -Seconds $linearBackoff 40 | } 41 | } 42 | } while (($retries -lt 6) -and (-not $installed)) 43 | if (-not $installed) { 44 | throw $exception 45 | } 46 | } 47 | catch { 48 | $_ | Write-AWSQuickStartException 49 | } -------------------------------------------------------------------------------- /scripts/Install-ExchangeEdgeServer.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | 4 | [Parameter(Mandatory=$true)] 5 | [string] 6 | $EdgeNodeNetBIOSName, 7 | 8 | [Parameter(Mandatory=$true)] 9 | [string] 10 | $ExchangeServerVersion, 11 | 12 | [Parameter(Mandatory=$true)] 13 | [string] 14 | $ExUserSecParam 15 | ) 16 | 17 | try { 18 | Start-Transcript -Path C:\cfn\log\Install-ExchangeEdgeServer.ps1.txt -Append 19 | $ErrorActionPreference = "Stop" 20 | 21 | $LocalAdminFullUser = $EdgeNodeNetBIOSName + '\Administrator' 22 | $DomainAdminPassword = ConvertFrom-Json -InputObject (Get-SECSecretValue -SecretId $ExUserSecParam).SecretString 23 | $LocalAdminCreds = (New-Object PSCredential($LocalAdminFullUser,(ConvertTo-SecureString $DomainAdminPassword.Password -AsPlainText -Force))) 24 | 25 | $InstallExchPs={ 26 | $ErrorActionPreference = "Stop" 27 | $InstallPath = "C:\Exchangeinstall\setup.exe" 28 | 29 | if($Using:ExchangeServerVersion -eq "2016") { 30 | $ExchangeArgs = "/mode:Install /role:EdgeTransport /InstallWindowsComponents /IAcceptExchangeServerLicenseTerms_DiagnosticDataOFF" 31 | } 32 | elseif ($Using:ExchangeServerVersion -eq "2019") { 33 | $ExchangeArgs = "/mode:Install /role:EdgeTransport /InstallWindowsComponents /IAcceptExchangeServerLicenseTerms_DiagnosticDataOFF" 34 | } 35 | 36 | Start-Process $InstallPath -args $ExchangeArgs -Wait -ErrorAction Stop -RedirectStandardOutput "C:\cfn\log\ExchangeEdgeInstallerOutput.txt" -RedirectStandardError "C:\cfn\log\ExchangeEdgeInstallerErrors.txt" 37 | } 38 | 39 | $Retries = 0 40 | $Installed = $false 41 | 42 | do { 43 | try { 44 | Invoke-Command -Authentication Credssp -Scriptblock $InstallExchPs -ComputerName $env:COMPUTERNAME -Credential $LocalAdminCreds 45 | $installed = $true 46 | } 47 | catch { 48 | $exception = $_ 49 | $retries++ 50 | if ($retries -lt 6) { 51 | Write-Host $exception 52 | $linearBackoff = $retries * 60 53 | Write-Host "Edge role installation failed. Retrying in $linearBackoff seconds." 54 | Start-Sleep -Seconds $linearBackoff 55 | } 56 | } 57 | } while (($retries -lt 6) -and (-not $installed)) 58 | if (-not $installed) { 59 | throw $exception 60 | } 61 | } 62 | catch { 63 | Write-Verbose "$($_.exception.message)@ $(Get-Date)" 64 | $_ | Write-AWSQuickStartException 65 | } 66 | -------------------------------------------------------------------------------- /scripts/Install-ExchangeOrg.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | 4 | [Parameter(Mandatory=$true)] 5 | [string] 6 | $DomainNetBIOSName, 7 | 8 | [Parameter(Mandatory=$true)] 9 | [string] 10 | $DomainAdminUser, 11 | 12 | [Parameter(Mandatory=$false)] 13 | [string] 14 | $ExchangeServerVersion, 15 | 16 | [Parameter(Mandatory=$true)] 17 | [string] 18 | $ExUserSecParam 19 | ) 20 | 21 | 22 | try { 23 | Start-Transcript -Path C:\cfn\log\Install-ExchangeOrg.ps1.txt -Append 24 | $ErrorActionPreference = "Stop" 25 | 26 | $DomainAdminFullUser = $DomainNetBIOSName + '\' + $DomainAdminUser 27 | $DomainAdminPassword = ConvertFrom-Json -InputObject (Get-SECSecretValue -SecretId $ExUserSecParam).SecretString 28 | $DomainAdminCreds = (New-Object PSCredential($DomainAdminFullUser,(ConvertTo-SecureString $DomainAdminPassword.Password -AsPlainText -Force))) 29 | 30 | $InstallExchPs={ 31 | param($username) 32 | $ErrorActionPreference = "Stop" 33 | $InstallPath = "C:\Exchangeinstall\setup.exe" 34 | $ExchangeArgs = "/PrepareAD /OrganizationName:Exchange /IAcceptExchangeServerLicenseTerms_DiagnosticDataOFF" 35 | 36 | Add-AdGroupMember -Identity 'Schema Admins' -Members $username 37 | Add-AdGroupMember -Identity 'Enterprise Admins' -Members $username 38 | Start-Process $InstallPath -args $ExchangeArgs -Wait -ErrorAction Stop -RedirectStandardOutput "C:\cfn\log\ExchangeOrgInstallerOutput.txt" -RedirectStandardError "C:\cfn\log\ExchangeOrgInstallerErrors.txt" 39 | } 40 | 41 | $Retries = 0 42 | $Installed = $false 43 | 44 | do { 45 | try { 46 | Invoke-Command -Authentication Credssp -Scriptblock $InstallExchPs -ComputerName $env:COMPUTERNAME -Credential $DomainAdminCreds -ArgumentList $DomainAdminUser 47 | $installed = $true 48 | } 49 | catch { 50 | $exception = $_ 51 | $retries++ 52 | if ($retries -lt 6) { 53 | Write-Host $exception 54 | $linearBackoff = $retries * 60 55 | Write-Host "Exchange organization configuration failed. Retrying in $linearBackoff seconds." 56 | Start-Sleep -Seconds $linearBackoff 57 | } 58 | } 59 | } while (($retries -lt 6) -and (-not $installed)) 60 | if (-not $installed) { 61 | throw $exception 62 | } 63 | } 64 | catch { 65 | $_ | Write-AWSQuickStartException 66 | } 67 | -------------------------------------------------------------------------------- /scripts/Install-ExchangeServer.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | [Parameter(Mandatory=$true)] 4 | [string] 5 | $DomainNetBIOSName, 6 | 7 | [Parameter(Mandatory=$true)] 8 | [string] 9 | $DomainAdminUser, 10 | 11 | [Parameter(Mandatory=$true)] 12 | [string] 13 | $ExUserSecParam, 14 | 15 | [Parameter(Mandatory=$true)] 16 | [string] 17 | $ExchangeServerVersion, 18 | 19 | [string] 20 | [Parameter(Mandatory=$true)] 21 | $ServerIndex 22 | ) 23 | 24 | try { 25 | Start-Transcript -Path C:\cfn\log\Install-Exchange.ps1.txt -Append 26 | $ErrorActionPreference = "Stop" 27 | 28 | $DomainAdminFullUser = $DomainNetBIOSName + '\' + $DomainAdminUser 29 | $DomainAdminPassword = ConvertFrom-Json -InputObject (Get-SECSecretValue -SecretId $ExUserSecParam).SecretString 30 | $DomainAdminCreds = (New-Object PSCredential($DomainAdminFullUser,(ConvertTo-SecureString $DomainAdminPassword.Password -AsPlainText -Force))) 31 | 32 | $InstallExchPs={ 33 | $ErrorActionPreference = "Stop" 34 | $InstallPath = "C:\Exchangeinstall\setup.exe" 35 | 36 | if($Using:ExchangeServerVersion -eq "2016") { 37 | $ExchangeArgs = "/mode:Install /OrganizationName:Exchange /role:Mailbox /MdbName:DB$Using:ServerIndex /DbFilePath:D:\Databases\DB$Using:ServerIndex\DB$Using:ServerIndex.edb /LogFolderPath:E:\Databases\DB$Using:ServerIndex /InstallWindowsComponents /IAcceptExchangeServerLicenseTerms_DiagnosticDataOFF" 38 | } 39 | elseif ($Using:ExchangeServerVersion -eq "2019") { 40 | $ExchangeArgs = "/mode:Install /OrganizationName:Exchange /role:Mailbox /MdbName:DB$Using:ServerIndex /DbFilePath:D:\Databases\DB$Using:ServerIndex\DB$Using:ServerIndex.edb /LogFolderPath:E:\Databases\DB$Using:ServerIndex /InstallWindowsComponents /IAcceptExchangeServerLicenseTerms_DiagnosticDataOFF" 41 | } 42 | 43 | Start-Process $InstallPath -args $ExchangeArgs -Wait -ErrorAction Stop -RedirectStandardOutput "C:\cfn\log\ExchangeServerInstallerOutput.txt" -RedirectStandardError "C:\cfn\log\ExchangeServerInstallerErrors.txt" 44 | } 45 | 46 | $Retries = 0 47 | $Installed = $false 48 | 49 | do { 50 | try { 51 | Invoke-Command -Authentication Credssp -Scriptblock $InstallExchPs -ComputerName $env:COMPUTERNAME -Credential $DomainAdminCreds 52 | $installed = $true 53 | } 54 | catch { 55 | $exception = $_ 56 | $retries++ 57 | if ($retries -lt 6) { 58 | Write-Host $exception 59 | $linearBackoff = $retries * 60 60 | Write-Host "Exchange Installation failed. Retrying in $linearBackoff seconds." 61 | Start-Sleep -Seconds $linearBackoff 62 | } 63 | } 64 | } while (($retries -lt 6) -and (-not $installed)) 65 | if (-not $installed) { 66 | throw $exception 67 | } 68 | } 69 | catch { 70 | Write-Verbose "$($_.exception.message)@ $(Get-Date)" 71 | $_ | Write-AWSQuickStartException 72 | } 73 | -------------------------------------------------------------------------------- /scripts/Install-NetFramework.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | 4 | [Parameter(Mandatory=$true)] 5 | [string] 6 | $DomainNetBIOSName, 7 | 8 | [Parameter(Mandatory=$true)] 9 | [string] 10 | $DomainAdminUser, 11 | 12 | [Parameter(Mandatory=$true)] 13 | [string] 14 | $NetFrameworkDownloadLink, 15 | 16 | [Parameter(Mandatory=$true)] 17 | [string] 18 | $ExUserSecParam 19 | ) 20 | 21 | 22 | try { 23 | Start-Transcript -Path C:\cfn\log\Install-NetFramework.ps1.txt -Append 24 | $ErrorActionPreference = "Stop" 25 | 26 | $DomainAdminFullUser = $DomainNetBIOSName + '\' + $DomainAdminUser 27 | $DomainAdminPassword = ConvertFrom-Json -InputObject (Get-SECSecretValue -SecretId $ExUserSecParam).SecretString 28 | $DomainAdminCreds = (New-Object PSCredential($DomainAdminFullUser,(ConvertTo-SecureString $DomainAdminPassword.Password -AsPlainText -Force))) 29 | 30 | $InstallNetfwPs={ 31 | $ErrorActionPreference = "Stop" 32 | $temp = $Using:NetFrameworkDownloadLink 33 | $filename = $temp.Substring($temp.LastIndexOf("/") + 1) 34 | $InstallPath = "C:\Exchangeinstall" + "\" + $filename 35 | $Args = "/q /norestart /log C:\cfn\log\NetFramework_Installer.htm" 36 | 37 | Start-Process $InstallPath -args $Args -Wait -ErrorAction Stop -RedirectStandardOutput "C:\cfn\log\NetFrameworkInstallerOutput.txt" -RedirectStandardError "C:\cfn\log\NetFrameworkInstallerErrors.txt" 38 | } 39 | 40 | $Retries = 0 41 | $Installed = $false 42 | while (($Retries -lt 4) -and (!$Installed)) { 43 | try { 44 | 45 | Invoke-Command -Authentication Credssp -Scriptblock $InstallNetfwPs -ComputerName localhost -Credential $DomainAdminCreds 46 | $Installed = $true 47 | } 48 | catch { 49 | $Exception = $_ 50 | $Retries++ 51 | if ($Retries -lt 4) { 52 | Start-Sleep ($Retries * 60) 53 | } 54 | } 55 | } 56 | if (!$Installed) { 57 | throw $Exception 58 | } 59 | 60 | } 61 | catch { 62 | Write-Verbose "$($_.exception.message)@ $(Get-Date)" 63 | $_ | Write-AWSQuickStartException 64 | } -------------------------------------------------------------------------------- /scripts/Install-SecurityUpdates.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | # [Parameter(Mandatory=$true)] 3 | # [string] 4 | # $ExchangeServerVersion, 5 | 6 | [Parameter(Mandatory=$true)] 7 | [string] 8 | $SecurityPatchDownloadLink 9 | ) 10 | 11 | 12 | try { 13 | $ErrorActionPreference = "Stop" 14 | $filename = $SecurityPatchDownloadLink.Substring($SecurityPatchDownloadLink.LastIndexOf("/") + 1) 15 | 16 | $InstallPath = "C:\Exchangeinstall" + "\" + $filename 17 | $InstallArgs = "/silent" 18 | 19 | Start-Process $InstallPath -args $InstallArgs -Wait -ErrorAction Stop -RedirectStandardOutput "C:\cfn\log\SecurityUpdate.txt" -RedirectStandardError "C:\cfn\log\SecurityUpdate.txt" 20 | 21 | # if($ExchangeServerVersion -eq "2016") { 22 | # $isoPath = $Path + "\" + $filename 23 | 24 | # } 25 | # elseif ($ExchangeServerVersion -eq "2019") { 26 | # $isoPath = $Path + "\" + $filename 27 | 28 | # } 29 | } 30 | catch { 31 | # $_ | Write-AWSQuickStartException 32 | } -------------------------------------------------------------------------------- /scripts/Install-UcmaRuntime.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param() 3 | 4 | try { 5 | Start-Transcript -Path C:\cfn\log\Install-UCmaRuntime.ps1.txt -Append 6 | $ErrorActionPreference = "Stop" 7 | 8 | $Retries = 0 9 | $Installed = $false 10 | 11 | do { 12 | try { 13 | Invoke-Expression "C:\Exchangeinstall\UcmaRuntimeSetup.exe /passive /norestart" -ErrorAction Stop 14 | $installed = $true 15 | } 16 | catch { 17 | $exception = $_ 18 | $retries++ 19 | if ($retries -lt 6) { 20 | Write-Host $exception 21 | $linearBackoff = $retries * 60 22 | Write-Host "UcmaRuntime installation failed. Retrying in $linearBackoff seconds." 23 | Start-Sleep -Seconds $linearBackoff 24 | } 25 | } 26 | } while (($retries -lt 6) -and (-not $installed)) 27 | if (-not $installed) { 28 | throw $exception 29 | } 30 | } 31 | catch { 32 | $_ | Write-AWSQuickStartException 33 | } -------------------------------------------------------------------------------- /scripts/Install-UrlRewrite.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | 4 | [Parameter(Mandatory=$true)] 5 | [string] 6 | $DomainNetBIOSName, 7 | 8 | [Parameter(Mandatory=$true)] 9 | [string] 10 | $DomainAdminUser, 11 | 12 | [Parameter(Mandatory=$true)] 13 | [string] 14 | $UrlRewriteLink, 15 | 16 | [Parameter(Mandatory=$true)] 17 | [string] 18 | $ExUserSecParam 19 | ) 20 | 21 | 22 | try { 23 | Start-Transcript -Path C:\cfn\log\Install-UrlRewrite.ps1.txt -Append 24 | $ErrorActionPreference = "Stop" 25 | 26 | $DomainAdminFullUser = $DomainNetBIOSName + '\' + $DomainAdminUser 27 | $DomainAdminPassword = ConvertFrom-Json -InputObject (Get-SECSecretValue -SecretId $ExUserSecParam).SecretString 28 | $DomainAdminCreds = (New-Object PSCredential($DomainAdminFullUser,(ConvertTo-SecureString $DomainAdminPassword.Password -AsPlainText -Force))) 29 | 30 | 31 | $InstallUrlRewritePs={ 32 | $ErrorActionPreference = "Stop" 33 | $temp = $Using:UrlRewriteLink 34 | $filename = $temp.Substring($temp.LastIndexOf("/") + 1) 35 | $InstallPath = "C:\Exchangeinstall" + "\" + $filename 36 | $InstallArgs = "/i $InstallPath /qn /L*v C:\cfn\log\UrlRewrite_Installer.log" 37 | 38 | Start-Process msiexec.exe -args $InstallArgs -Wait -ErrorAction Stop -RedirectStandardOutput "C:\cfn\log\UrlRewriteInstallerOutput.txt" -RedirectStandardError "C:\cfn\log\UrlRewriteInstallerErrors.txt" 39 | 40 | } 41 | 42 | $Retries = 0 43 | $Installed = $false 44 | while (($Retries -lt 4) -and (!$Installed)) { 45 | try { 46 | 47 | Invoke-Command -Authentication Credssp -Scriptblock $InstallUrlRewritePs -ComputerName localhost -Credential $DomainAdminCreds 48 | $Installed = $true 49 | } 50 | catch { 51 | $Exception = $_ 52 | $Retries++ 53 | if ($Retries -lt 4) { 54 | Start-Sleep ($Retries * 60) 55 | } 56 | } 57 | } 58 | if (!$Installed) { 59 | throw $Exception 60 | } 61 | 62 | } 63 | catch { 64 | Write-Verbose "$($_.exception.message)@ $(Get-Date)" 65 | $_ | Write-AWSQuickStartException 66 | } -------------------------------------------------------------------------------- /scripts/Install-VisualCRuntime.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | 4 | [Parameter(Mandatory=$true)] 5 | [string] 6 | $DomainNetBIOSName, 7 | 8 | [Parameter(Mandatory=$true)] 9 | [string] 10 | $DomainAdminUser, 11 | 12 | [Parameter(Mandatory=$true)] 13 | [string] 14 | $VisualCRuntimeLink, 15 | 16 | [Parameter(Mandatory=$true)] 17 | [string] 18 | $ExUserSecParam 19 | ) 20 | 21 | 22 | try { 23 | Start-Transcript -Path C:\cfn\log\Install-VisualCRuntime.ps1.txt -Append 24 | $ErrorActionPreference = "Stop" 25 | 26 | $DomainAdminFullUser = $DomainNetBIOSName + '\' + $DomainAdminUser 27 | $DomainAdminPassword = ConvertFrom-Json -InputObject (Get-SECSecretValue -SecretId $ExUserSecParam).SecretString 28 | $DomainAdminCreds = (New-Object PSCredential($DomainAdminFullUser,(ConvertTo-SecureString $DomainAdminPassword.Password -AsPlainText -Force))) 29 | 30 | 31 | $InstallNetfwPs={ 32 | $ErrorActionPreference = "Stop" 33 | $temp = $Using:VisualCRuntimeLink 34 | $filename = $temp.Substring($temp.LastIndexOf("/") + 1) 35 | $InstallPath = "C:\Exchangeinstall" + "\" + $filename 36 | $Args = "/install /quiet /norestart /log C:\cfn\log\VisualCRuntime_Installer.log" 37 | 38 | Start-Process $InstallPath -args $Args -Wait -ErrorAction Stop -RedirectStandardOutput "C:\cfn\log\VisualCRuntimeInstallerOutput.txt" -RedirectStandardError "C:\cfn\log\VisualCRuntimeInstallerErrors.txt" 39 | 40 | } 41 | 42 | $Retries = 0 43 | $Installed = $false 44 | while (($Retries -lt 4) -and (!$Installed)) { 45 | try { 46 | 47 | Invoke-Command -Authentication Credssp -Scriptblock $InstallNetfwPs -ComputerName localhost -Credential $DomainAdminCreds 48 | $Installed = $true 49 | } 50 | catch { 51 | $Exception = $_ 52 | $Retries++ 53 | if ($Retries -lt 4) { 54 | Start-Sleep ($Retries * 60) 55 | } 56 | } 57 | } 58 | if (!$Installed) { 59 | throw $Exception 60 | } 61 | 62 | } 63 | catch { 64 | Write-Verbose "$($_.exception.message)@ $(Get-Date)" 65 | $_ | Write-AWSQuickStartException 66 | } -------------------------------------------------------------------------------- /scripts/Install-WindowsFailoverClustering.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | 4 | ) 5 | 6 | try { 7 | Start-Transcript -Path C:\cfn\log\Install-WindowsFailoverClustering.ps1.txt -Append 8 | $ErrorActionPreference = "Stop" 9 | 10 | Install-WindowsFeature failover-clustering -IncludeManagementTools 11 | } 12 | catch { 13 | $_ | Write-AWSQuickStartException 14 | } -------------------------------------------------------------------------------- /scripts/Invoke-ADReplication.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | [string] 4 | $ADAdminSecParam, 5 | 6 | [string] 7 | $DomainController 8 | ) 9 | 10 | try { 11 | $AdminSecret = Get-SECSecretValue -SecretId $ADAdminSecParam -ErrorAction Stop | Select-Object -ExpandProperty 'SecretString' 12 | $ADAdminPassword = ConvertFrom-Json -InputObject $AdminSecret -ErrorAction Stop 13 | 14 | Write-Output 'Creating Credential Object for Administrator' 15 | $AdminUserName = $ADAdminPassword.UserName 16 | $AdminUserPW = ConvertTo-SecureString ($ADAdminPassword.Password) -AsPlainText -Force 17 | $cred = New-Object -TypeName 'System.Management.Automation.PSCredential' ($AdminUserName, $AdminUserPW) 18 | 19 | $sb = { 20 | repadmin /syncall /A /e /P 21 | } 22 | 23 | Write-Verbose "Invoking repadmin on $DomainController" 24 | Invoke-Command -ScriptBlock $sb -ComputerName $DomainController -Credential $cred -ErrorAction Stop 25 | } 26 | catch { 27 | $_ | Write-AWSQuickStartException 28 | } -------------------------------------------------------------------------------- /scripts/Join-Domain.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | [string] 4 | $DomainName, 5 | 6 | [string] 7 | $ADAdminSecParam 8 | ) 9 | 10 | try { 11 | $ErrorActionPreference = "Stop" 12 | 13 | $AdminSecret = Get-SECSecretValue -SecretId $ADAdminSecParam -ErrorAction Stop | Select-Object -ExpandProperty 'SecretString' 14 | $ADAdminPassword = ConvertFrom-Json -InputObject $AdminSecret -ErrorAction Stop 15 | 16 | Write-Output 'Creating Credential Object for Administrator' 17 | $AdminUserName = $DomainName + "\" + $ADAdminPassword.UserName 18 | $AdminUserPW = ConvertTo-SecureString ($ADAdminPassword.Password) -AsPlainText -Force 19 | 20 | $cred = New-Object -TypeName 'System.Management.Automation.PSCredential' ($AdminUserName, $AdminUserPW) 21 | 22 | Add-Computer -DomainName $DomainName -Credential $cred -ErrorAction Stop 23 | 24 | # Execute restart after script exit and allow time for external services 25 | $shutdown = Start-Process -FilePath "shutdown.exe" -ArgumentList @("/r", "/t 10") -Wait -NoNewWindow -PassThru 26 | if ($shutdown.ExitCode -ne 0) { 27 | throw "[ERROR] shutdown.exe exit code was not 0. It was actually $($shutdown.ExitCode)." 28 | } 29 | } 30 | catch { 31 | $_ | Write-AWSQuickStartException 32 | } 33 | -------------------------------------------------------------------------------- /scripts/Reset-LocalAdminPassword.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | [string] 4 | $ADAdminSecParam 5 | ) 6 | 7 | try { 8 | $AdminSecret = Get-SECSecretValue -SecretId $ADAdminSecParam -ErrorAction Stop | Select-Object -ExpandProperty 'SecretString' 9 | $ADAdminPassword = ConvertFrom-Json -InputObject $AdminSecret -ErrorAction Stop 10 | 11 | Write-Output 'Creating Credential Object for Administrator' 12 | # $AdminUserName = $ADAdminPassword.UserName 13 | # $AdminUserPW = ConvertTo-SecureString ($ADAdminPassword.Password) -AsPlainText -Force 14 | 15 | Write-Verbose "Resetting local admin password" 16 | ([adsi]"WinNT://$env:computername/Administrator,user").SetPassword($ADAdminPassword.Password) 17 | } 18 | catch { 19 | $_ | Write-AWSQuickStartException 20 | } -------------------------------------------------------------------------------- /templates/exchange-main.template.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | AWSTemplateFormatVersion: '2010-09-09' 3 | Description: This template deploys two Windows Server Failover Clustering (Exchange) and 4 | Exchange Server 2016 or 2019. This template also deploys the required AD architecture 5 | outlined in "Implementing Active Directory Domain Services in the AWS Cloud" **WARNING** 6 | This template creates Amazon EC2 Windows instance and related resources. You will 7 | be billed for the AWS resources used if you create a stack from this template. (qs-1qup6raep) 8 | Metadata: 9 | cfn-lint: 10 | config: 11 | ignore_checks: 12 | - W9006 13 | - W9901 14 | QuickStartDocumentation: 15 | EntrypointName: "Launch into a new VPC" 16 | Order: "1" 17 | AWS::CloudFormation::Interface: 18 | ParameterGroups: 19 | - Label: 20 | default: Network Configuration 21 | Parameters: 22 | - AvailabilityZones 23 | - NumberOfAZs 24 | - ThirdAZ 25 | - VPCCIDR 26 | - PublicSubnet1CIDR 27 | - PublicSubnet2CIDR 28 | - PublicSubnet3CIDR 29 | - PrivateSubnet1CIDR 30 | - PrivateSubnet2CIDR 31 | - PrivateSubnet3CIDR 32 | - Label: 33 | default: Amazon EC2 Configuration 34 | Parameters: 35 | - KeyPairName 36 | - Label: 37 | default: Microsoft Active Directory Configuration 38 | Parameters: 39 | - DomainDNSName 40 | - DomainNetBIOSName 41 | - DomainAdminUser 42 | - DomainAdminPassword 43 | - ADServer1InstanceType 44 | - ADServer1NetBIOSName 45 | - ADServer1PrivateIP 46 | - ADServer2InstanceType 47 | - ADServer2NetBIOSName 48 | - ADServer2PrivateIP 49 | - Label: 50 | default: Remote Desktop Gateway Configuration 51 | Parameters: 52 | - RDGWCIDR 53 | - RDGWInstanceType 54 | - NumberOfRDGWHosts 55 | - Label: 56 | default: Exchange Server Configuration 57 | Parameters: 58 | - EnableBackups 59 | - ExchangeServerVersion 60 | - IncludeEdgeTransportRole 61 | - EdgeInstanceType 62 | - EdgeNode1NetBIOSName 63 | - EdgeNode1PrivateIP1 64 | - EdgeNode2NetBIOSName 65 | - EdgeNode2PrivateIP1 66 | - EnableReFSVolumes 67 | - EncryptDataVolumes 68 | - EncryptionKmsKey 69 | - SetupAppInsightsMonitoring 70 | - VolumeIops 71 | - VolumeSize 72 | - VolumeType 73 | - Label: 74 | default: Load Balancer Configuration 75 | Parameters: 76 | - DeployLoadBalancer 77 | - CertificateArn 78 | - Label: 79 | default: Failover Cluster Configuration 80 | Parameters: 81 | - ExchangeNodeInstanceType 82 | - ExchangeNode1NetBIOSName 83 | - ExchangeNode1PrivateIP1 84 | - ExchangeNode1PrivateIP2 85 | - ExchangeNode2NetBIOSName 86 | - ExchangeNode2PrivateIP1 87 | - ExchangeNode2PrivateIP2 88 | - ExchangeNode3NetBIOSName 89 | - ExchangeNode3PrivateIP1 90 | - ExchangeNode3PrivateIP2 91 | - FileServerInstanceType 92 | - FileServerNetBIOSName 93 | - FileServerPrivateIP 94 | - Label: 95 | default: AWS Quick Start Configuration 96 | Parameters: 97 | - QSS3BucketName 98 | - QSS3KeyPrefix 99 | - QSS3BucketRegion 100 | ParameterLabels: 101 | ADServer1InstanceType: 102 | default: Domain Controller 1 instance type 103 | ADServer1NetBIOSName: 104 | default: Domain Controller 1 NetBIOS name 105 | ADServer1PrivateIP: 106 | default: Domain Controller 1 private IP address 107 | ADServer2InstanceType: 108 | default: Domain Controller 2 instance type 109 | ADServer2NetBIOSName: 110 | default: Domain Controller 2 NetBIOS name 111 | ADServer2PrivateIP: 112 | default: Domain Controller 2 private IP address 113 | AvailabilityZones: 114 | default: Availability Zones 115 | CertificateArn: 116 | default: Network Load Balancer Certificate 117 | DeployLoadBalancer: 118 | default: Deploy Network Load Balancer 119 | DomainAdminPassword: 120 | default: Domain Admin password 121 | DomainAdminUser: 122 | default: Domain Admin user name 123 | DomainDNSName: 124 | default: Domain DNS name 125 | DomainNetBIOSName: 126 | default: Domain NetBIOS name 127 | EnableBackups: 128 | default: Enable AWS Backups 129 | EdgeInstanceType: 130 | default: Edge Role instance type 131 | EdgeNode1NetBIOSName: 132 | default: Edge Node 1 NetBIOS name 133 | EdgeNode1PrivateIP1: 134 | default: Edge Node 1 private IP address 135 | EdgeNode2NetBIOSName: 136 | default: Edge Node 2 NetBIOS name 137 | EdgeNode2PrivateIP1: 138 | default: Edge Node 2 private IP address 139 | EnableReFSVolumes: 140 | default: Enable or disable ReFS 141 | EncryptDataVolumes: 142 | default: Encrypt data volumes 143 | EncryptionKmsKey: 144 | default: KMS key to encrypt volumes 145 | ExchangeServerVersion: 146 | default: Exchange Server version 147 | ExchangeNode1NetBIOSName: 148 | default: Exchange Node 1 NetBIOS name 149 | ExchangeNode1PrivateIP1: 150 | default: Exchange Node 1 private IP address 1 151 | ExchangeNode1PrivateIP2: 152 | default: Exchange Node 1 private IP address 2 153 | ExchangeNode2NetBIOSName: 154 | default: Exchange Node 2 NetBIOS name 155 | ExchangeNode2PrivateIP1: 156 | default: Exchange Node 2 private IP address 1 157 | ExchangeNode2PrivateIP2: 158 | default: Exchange Node 2 private IP address 2 159 | ExchangeNode3NetBIOSName: 160 | default: Exchange Node 3 NetBIOS name 161 | ExchangeNode3PrivateIP1: 162 | default: Exchange Node 3 private IP address 1 163 | ExchangeNode3PrivateIP2: 164 | default: Exchange Node 3 private IP address 2 165 | ExchangeNodeInstanceType: 166 | default: Instance type for Exchange nodes 167 | FileServerInstanceType: 168 | default: File Server instance type 169 | FileServerNetBIOSName: 170 | default: File Server NetBIOS name 171 | FileServerPrivateIP: 172 | default: File Server private IP address 173 | IncludeEdgeTransportRole: 174 | default: Deploy Edge servers 175 | KeyPairName: 176 | default: Key pair name 177 | NumberOfRDGWHosts: 178 | default: Number of RDGW Hosts 179 | NumberOfAZs: 180 | default: Number of Availability Zones 181 | PrivateSubnet1CIDR: 182 | default: Private Subnet 1 CIDR 183 | PrivateSubnet2CIDR: 184 | default: Private Subnet 2 CIDR 185 | PrivateSubnet3CIDR: 186 | default: Private Subnet 3 CIDR 187 | PublicSubnet1CIDR: 188 | default: Public Subnet 1 CIDR 189 | PublicSubnet2CIDR: 190 | default: Public Subnet 2 CIDR 191 | PublicSubnet3CIDR: 192 | default: Public Subnet 3 CIDR 193 | QSS3BucketName: 194 | default: Quick Start S3 bucket name 195 | QSS3BucketRegion: 196 | default: Quick Start S3 bucket region 197 | QSS3KeyPrefix: 198 | default: Quick Start S3 key prefix 199 | RDGWInstanceType: 200 | default: Remote Desktop Gateway instance type 201 | RDGWCIDR: 202 | default: Allowed Remote Desktop Gateway external access CIDR 203 | SetupAppInsightsMonitoring: 204 | default: Setup Application Insights Monitoring 205 | ThirdAZ: 206 | default: Third Availability Zone 207 | VolumeIops: 208 | default: Exchange Server volume IOPS 209 | VolumeSize: 210 | default: Exchange Server volume size (GiB) 211 | VolumeType: 212 | default: Exchange Server volume type 213 | VPCCIDR: 214 | default: VPC CIDR 215 | Parameters: 216 | ADServer1InstanceType: 217 | AllowedValues: 218 | - t3.medium 219 | - t3.large 220 | - t3.xlarge 221 | - t3.2xlarge 222 | - m5.large 223 | - m5.xlarge 224 | - m5.2xlarge 225 | - m5.4xlarge 226 | Default: m5.xlarge 227 | Description: The Amazon EC2 instance type for the first Active Directory instance. 228 | Type: String 229 | ADServer1NetBIOSName: 230 | AllowedPattern: '^[a-zA-Z0-9]+$' 231 | Default: DC1 232 | Description: The NetBIOS name of the first Active Directory server (up to 15 characters). 233 | MaxLength: '15' 234 | MinLength: '1' 235 | Type: String 236 | ADServer1PrivateIP: 237 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' 238 | Default: 10.0.0.10 239 | Description: The private IP for the first Active Directory server located in Availability Zone 1. 240 | Type: String 241 | ADServer2InstanceType: 242 | AllowedValues: 243 | - t3.medium 244 | - t3.large 245 | - t3.xlarge 246 | - t3.2xlarge 247 | - m5.large 248 | - m5.xlarge 249 | - m5.2xlarge 250 | - m5.4xlarge 251 | Default: m5.xlarge 252 | Description: The Amazon EC2 instance type for the second Active Directory instance. 253 | Type: String 254 | ADServer2NetBIOSName: 255 | AllowedPattern: '^[a-zA-Z0-9]+$' 256 | Default: DC2 257 | Description: The NetBIOS name of the second Active Directory server (up to 15 characters). 258 | MaxLength: '15' 259 | MinLength: '1' 260 | Type: String 261 | ADServer2PrivateIP: 262 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' 263 | Default: 10.0.32.10 264 | Description: The private IP for the second Active Directory server located in Availability Zone 2. 265 | Type: String 266 | AvailabilityZones: 267 | Description: 'List of Availability Zones to use for the subnets in the VPC. Note: 268 | You must specify two Availability Zones, unless you specify the Third AZ parameter. In this case, you must specify three Availability Zones. 269 | The Quick Start preserves the logical order you specify.' 270 | Type: List 271 | CertificateArn: 272 | AllowedPattern: '^(arn:[\w+=\/,.@-]+:[\w+=\/,.@-]+:[\w+=\/,.@-]*:[0-9]+:[\w+=,.@-]+(\/[\w+=,.@-]+)*)?$' 273 | Default: '' 274 | Description: (Conditional) If 'true' was chosen in Deploy Network Load Balancer option, specify the Certificate arn to be used by load balancer in arn:aws:acm:[REGION]:[ACCOUNTNUMBER]:certificate/[GUID] format. 275 | MaxLength: '90' 276 | Type: String 277 | DomainAdminPassword: 278 | AllowedPattern: '(?=^.{8,32}$)((?=.*\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])|(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]))^.*' 279 | Description: The password for the domain admin user. Must be at least 8 characters containing letters, numbers and symbols. 280 | MaxLength: '32' 281 | MinLength: '8' 282 | NoEcho: 'true' 283 | Type: String 284 | DomainAdminUser: 285 | AllowedPattern: '^[a-zA-Z0-9]+$' 286 | Default: StackAdmin 287 | Description: The user name for the account that will be added as Domain Administrator. 288 | This is separate from the default Administrator account. 289 | MaxLength: '25' 290 | MinLength: '5' 291 | Type: String 292 | DomainDNSName: 293 | AllowedPattern: '^[a-zA-Z0-9]+[a-zA-Z0-9\-]*\.[a-zA-Z0-9]+$' 294 | Default: example.com 295 | Description: The fully qualified domain name (FQDN) of the forest root domain e.g. example.com. 296 | MaxLength: '25' 297 | MinLength: '3' 298 | Type: String 299 | DomainNetBIOSName: 300 | AllowedPattern: '^[a-zA-Z0-9]+$' 301 | Default: example 302 | Description: The NetBIOS name of the domain (up to 15 characters) for users of earlier versions of Windows e.g. EXAMPLE. 303 | MaxLength: '15' 304 | MinLength: '1' 305 | Type: String 306 | DeployLoadBalancer: 307 | AllowedValues: 308 | - 'false' 309 | - 'true' 310 | Default: 'false' 311 | Description: Choose true to deploy a Network Load Balancer (NLB). 312 | Type: String 313 | EdgeInstanceType: 314 | Description: The Amazon EC2 instance type for the Exchange Edge Transport servers. 315 | Type: String 316 | Default: m5.large 317 | AllowedValues: 318 | - t3.large 319 | - m5.large 320 | - m5.xlarge 321 | - m5.2xlarge 322 | - m5.4xlarge 323 | ConstraintDescription: Select a general purpose instance type 324 | EdgeNode1NetBIOSName: 325 | AllowedPattern: '^[a-zA-Z0-9]+$' 326 | Default: EdgeNode1 327 | Description: The NetBIOS name of the first Edge server (up to 15 characters). 328 | MaxLength: '15' 329 | MinLength: '1' 330 | Type: String 331 | EdgeNode1PrivateIP1: 332 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' 333 | Default: 10.0.128.12 334 | Description: The primary private IP for the first Edge server located in Availability Zone 1. 335 | Type: String 336 | EdgeNode2NetBIOSName: 337 | AllowedPattern: '^[a-zA-Z0-9]+$' 338 | Default: EdgeNode2 339 | Description: The NetBIOS name of the second Edge server (up to 15 characters). 340 | MaxLength: '15' 341 | MinLength: '1' 342 | Type: String 343 | EdgeNode2PrivateIP1: 344 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' 345 | Default: 10.0.144.12 346 | Description: The primary private IP for the second Edge server located in Availability Zone 1. 347 | Type: String 348 | EncryptDataVolumes: 349 | AllowedValues: 350 | - 'false' 351 | - 'true' 352 | Default: 'false' 353 | Description: Choose true to encrypt the data and log volumes on Exchange nodes. 354 | Type: String 355 | EnableReFSVolumes: 356 | AllowedValues: 357 | - 'false' 358 | - 'true' 359 | Default: 'true' 360 | Description: Choose false to format the data and log volumes on Exchange nodes using NTFS instead of ReFS. 361 | Type: String 362 | EnableBackups: 363 | AllowedValues: 364 | - 'yes' 365 | - 'no' 366 | Default: 'yes' 367 | Description: Creates a default daily/weekly backup schedule using AWS Backup 368 | Type: String 369 | EncryptionKmsKey: 370 | AllowedPattern: '^(arn:[\w+=\/,.@-]+:[\w+=\/,.@-]+:[\w+=\/,.@-]*:[0-9]+:[\w+=,.@-]+(\/[\w+=,.@-]+)*)?$' 371 | Default: '' 372 | Description: (Optional) Specify the KMS encryption arn in format arn:aws:kms:[REGION]:[ACCOUNTNUMBER]:key/[GUID]. Leave blank to use default EBS encryption key. 373 | MaxLength: '90' 374 | Type: String 375 | ExchangeNode1NetBIOSName: 376 | AllowedPattern: '^[a-zA-Z0-9]+$' 377 | Default: ExchangeNode1 378 | Description: The NetBIOS name of the first Exchange node (up to 15 characters). 379 | MaxLength: '15' 380 | MinLength: '1' 381 | Type: String 382 | ExchangeNode1PrivateIP1: 383 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' 384 | Default: 10.0.0.100 385 | Description: The primary private IP for Exchange node 1. 386 | Type: String 387 | ExchangeNode1PrivateIP2: 388 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' 389 | Default: 10.0.0.101 390 | Description: The secondary private IP for Exchange node 1. 391 | Type: String 392 | ExchangeNode2NetBIOSName: 393 | AllowedPattern: '^[a-zA-Z0-9]+$' 394 | Default: ExchangeNode2 395 | Description: The NetBIOS name of the second Exchange node (up to 15 characters). 396 | MaxLength: '15' 397 | MinLength: '1' 398 | Type: String 399 | ExchangeNode2PrivateIP1: 400 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' 401 | Default: 10.0.32.100 402 | Description: The primary private IP for Exchange node 2. 403 | Type: String 404 | ExchangeNode2PrivateIP2: 405 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' 406 | Default: 10.0.32.101 407 | Description: The secondary private IP for Exchange node 2. 408 | Type: String 409 | ExchangeNode3NetBIOSName: 410 | AllowedPattern: '^[a-zA-Z0-9]+$' 411 | Default: ExchangeNode3 412 | Description: (Optional) The NetBIOS name of the third Exchange node (up to 15 characters). 413 | MaxLength: '15' 414 | MinLength: '1' 415 | Type: String 416 | ExchangeNode3PrivateIP1: 417 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' 418 | Default: 10.0.64.100 419 | Description: (Optional) The primary private IP for the Exchange node 3. 420 | Type: String 421 | ExchangeNode3PrivateIP2: 422 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' 423 | Default: 10.0.64.101 424 | Description: (Optional) The secondary private IP for the Exchange node 3. 425 | Type: String 426 | ExchangeNodeInstanceType: 427 | AllowedValues: 428 | - m5.xlarge 429 | - r4.xlarge 430 | - r4.2xlarge 431 | - r4.4xlarge 432 | - r4.8xlarge 433 | - r5.xlarge 434 | - r5.2xlarge 435 | - r5.4xlarge 436 | - r5.8xlarge 437 | ConstraintDescription: Only EBS Optimized instance types r4.*, r5.* allowed 438 | Default: r5.xlarge 439 | Description: The Amazon EC2 instance type for the Exchange nodes. 440 | Type: String 441 | ExchangeServerVersion: 442 | AllowedValues: 443 | - '2016' 444 | - '2019' 445 | Default: '2019' 446 | Description: Version of Exchange Server to install. Options include 447 | either "2016" or "2019". 448 | Type: String 449 | FileServerInstanceType: 450 | Default: t3.small 451 | AllowedValues: 452 | - t3.small 453 | - t3.large 454 | - m5.xlarge 455 | Description: The Amazon EC2 instance type for the file-share witness server. 456 | Type: String 457 | FileServerNetBIOSName: 458 | AllowedPattern: '^[a-zA-Z0-9]+$' 459 | Default: FileServer 460 | Description: The NetBIOS name of the file-share witness server (up to 15 characters). 461 | MaxLength: '15' 462 | MinLength: '1' 463 | Type: String 464 | FileServerPrivateIP: 465 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' 466 | Default: 10.0.0.200 467 | Description: The primary private IP for the file-share witness server. 468 | Type: String 469 | IncludeEdgeTransportRole: 470 | AllowedValues: 471 | - 'yes' 472 | - 'no' 473 | Default: 'no' 474 | Description: Choose yes to deploy Exchange Edge Transport servers 475 | in the public subnets. 476 | Type: String 477 | KeyPairName: 478 | Description: Public/private key pairs allow you to securely connect to your instance 479 | after it launches. 480 | Type: AWS::EC2::KeyPair::KeyName 481 | NumberOfRDGWHosts: 482 | AllowedValues: 483 | - '0' 484 | - '1' 485 | - '2' 486 | - '3' 487 | - '4' 488 | Default: '0' 489 | Description: The number of Remote Desktop Gateway hosts to create. 490 | Type: String 491 | NumberOfAZs: 492 | AllowedValues: 493 | - "2" 494 | - "3" 495 | Default: "2" 496 | Description: Number of Availability Zones to use in the VPC. This must match your selections in the list of Availability Zones parameter. 497 | Type: String 498 | PrivateSubnet1CIDR: 499 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$' 500 | Default: 10.0.0.0/19 501 | Description: CIDR Block for private subnet 1 located in Availability Zone 1. 502 | Type: String 503 | PrivateSubnet2CIDR: 504 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$' 505 | Default: 10.0.32.0/19 506 | Description: CIDR Block for private subnet 2 located in Availability Zone 2. 507 | Type: String 508 | PrivateSubnet3CIDR: 509 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$' 510 | Default: 10.0.64.0/19 511 | Description: (Optional) CIDR Block for private subnet 3 located in Availability Zone 3. 512 | Type: String 513 | PublicSubnet1CIDR: 514 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$' 515 | Default: 10.0.128.0/20 516 | Description: CIDR Block for the public DMZ subnet 1 located in Availability Zone 1. 517 | Type: String 518 | PublicSubnet2CIDR: 519 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$' 520 | Default: 10.0.144.0/20 521 | Description: CIDR Block for the public DMZ subnet 2 located in Availability Zone 2. 522 | Type: String 523 | PublicSubnet3CIDR: 524 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$' 525 | Default: 10.0.160.0/20 526 | Description: (Optional) CIDR Block for the public DMZ subnet 3 located in Availability Zone 3. 527 | Type: String 528 | QSS3BucketName: 529 | AllowedPattern: '^[a-z0-9]+[a-z0-9\.\-]*[a-z0-9]+$' 530 | ConstraintDescription: Quick Start bucket name can include numbers, lowercase 531 | letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen 532 | (-). 533 | Default: aws-quickstart 534 | Description: The S3 bucket you’ve created for your copy of Quick Start assets, if you decide to customize or extend the Quick Start for your own use. 535 | The bucket name can include numbers, lowercase letters, uppercase letters, and hyphens, 536 | but should not start or end with a hyphen. 537 | Type: String 538 | QSS3BucketRegion: 539 | AllowedPattern: '^[a-z]+\-[a-z\-]+\-[0-9]{1}$' 540 | Default: us-east-1 541 | Description: The AWS Region where the Quick Start S3 bucket (QSS3BucketName) is hosted. When using your own bucket, you must specify this value. 542 | Type: String 543 | QSS3KeyPrefix: 544 | AllowedPattern: '^[a-zA-Z0-9\-\/]+$' 545 | ConstraintDescription: Quick Start key prefix can include numbers, lowercase letters, 546 | uppercase letters, hyphens (-), and forward slash (/). 547 | Default: quickstart-microsoft-exchange/ 548 | Description: The S3 key name prefix used to simulate a folder for your copy of Quick Start assets, if you decide to customize or extend the Quick Start for your own use. 549 | This prefix can include numbers, lowercase letters, uppercase letters, hyphens, and forward slashes, but should not start or end with a forward slash (which is automatically added). 550 | Type: String 551 | RDGWCIDR: 552 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$' 553 | ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/x 554 | Description: The allowed CIDR Block for external access to the Remote Desktop Gateways. 555 | Type: String 556 | RDGWInstanceType: 557 | AllowedValues: 558 | - t2.small 559 | - t2.medium 560 | - t2.large 561 | - t3.micro 562 | - t3.small 563 | - t3.medium 564 | - t3.large 565 | - t3.xlarge 566 | - t3.2xlarge 567 | - t3a.micro 568 | - t3a.small 569 | - t3a.medium 570 | - t3a.large 571 | - t3a.xlarge 572 | - t3a.2xlarge 573 | - m5.large 574 | - m5.xlarge 575 | - m5.2xlarge 576 | - m5.4xlarge 577 | - m5a.large 578 | - m5a.xlarge 579 | - m5a.2xlarge 580 | Default: t3.large 581 | Description: The Amazon EC2 instance type for the Remote Desktop Gateway instances. 582 | Type: String 583 | SetupAppInsightsMonitoring: 584 | AllowedValues: 585 | - 'true' 586 | - 'false' 587 | Default: 'false' 588 | Description: Setup Application Insights monitoring for Exchange resources. 589 | Type: String 590 | ThirdAZ: 591 | AllowedValues: 592 | - 'no' 593 | - witness 594 | - full 595 | Default: 'no' 596 | Description: Enable a 3 AZ deployment, the 3rd AZ can either be used just for 597 | the witness, or can be a full Exchange node. Note that if witness is 598 | chosen, the WFC File Server Private IP Address parameter must be set to an IP 599 | in the 3rd subnet range. 600 | Type: String 601 | VPCCIDR: 602 | AllowedPattern: '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$' 603 | ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 604 | Default: 10.0.0.0/16 605 | Description: CIDR Block for the VPC. 606 | Type: String 607 | VolumeIops: 608 | Default: '3000' 609 | Description: The provisioned IOPS for the Exchange Data and Logs volumes. 610 | This parameter is only applicable when Exchange Server Volume Type is set to "gp3". 611 | MaxValue: '16000' 612 | MinValue: '3000' 613 | Type: Number 614 | VolumeSize: 615 | Default: '500' 616 | Description: The volume size for the Exchange Data and Logs volumes. 617 | MaxValue: '16000' 618 | MinValue: '125' 619 | Type: Number 620 | VolumeType: 621 | AllowedValues: 622 | - gp3 623 | - st1 624 | Default: gp3 625 | Description: The volume type for the Exchange Data and Logs volumes. 626 | Type: String 627 | Conditions: 628 | IsTwoAz: !Equals 629 | - !Ref 'ThirdAZ' 630 | - 'no' 631 | IncludeRDGW: !Not 632 | - !Equals 633 | - !Ref NumberOfRDGWHosts 634 | - '0' 635 | UsingDefaultBucket: !Equals [!Ref QSS3BucketName, 'aws-quickstart'] 636 | AppInsightsEnabled: !Equals [!Ref SetupAppInsightsMonitoring, true] 637 | Resources: 638 | VPCStack: 639 | Type: AWS::CloudFormation::Stack 640 | Properties: 641 | TemplateURL: 642 | Fn::Sub: 643 | - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-aws-vpc/templates/aws-vpc.template.yaml' 644 | - S3Region: !If 645 | - UsingDefaultBucket 646 | - !Ref AWS::Region 647 | - !Ref QSS3BucketRegion 648 | S3Bucket: !If 649 | - UsingDefaultBucket 650 | - !Sub '${QSS3BucketName}-${AWS::Region}' 651 | - !Ref QSS3BucketName 652 | Parameters: 653 | AvailabilityZones: !Join 654 | - ',' 655 | - !Ref 'AvailabilityZones' 656 | NumberOfAZs: !Ref NumberOfAZs 657 | PrivateSubnet1ACIDR: !Ref 'PrivateSubnet1CIDR' 658 | PrivateSubnet2ACIDR: !Ref 'PrivateSubnet2CIDR' 659 | PrivateSubnet3ACIDR: !If 660 | - IsTwoAz 661 | - !Ref 'AWS::NoValue' 662 | - !Ref 'PrivateSubnet3CIDR' 663 | PublicSubnet1CIDR: !Ref 'PublicSubnet1CIDR' 664 | PublicSubnet2CIDR: !Ref 'PublicSubnet2CIDR' 665 | PublicSubnet3CIDR: !If 666 | - IsTwoAz 667 | - !Ref 'AWS::NoValue' 668 | - !Ref 'PublicSubnet3CIDR' 669 | VPCCIDR: !Ref 'VPCCIDR' 670 | ADStack: 671 | Type: AWS::CloudFormation::Stack 672 | Properties: 673 | TemplateURL: 674 | Fn::Sub: 675 | - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-microsoft-activedirectory/templates/ad-1.template' 676 | - S3Region: !If 677 | - UsingDefaultBucket 678 | - !Ref AWS::Region 679 | - !Ref QSS3BucketRegion 680 | S3Bucket: !If 681 | - UsingDefaultBucket 682 | - !Sub '${QSS3BucketName}-${AWS::Region}' 683 | - !Ref QSS3BucketName 684 | Parameters: 685 | ADServer1InstanceType: !Ref 'ADServer1InstanceType' 686 | ADServer1NetBIOSName: !Ref 'ADServer1NetBIOSName' 687 | ADServer1PrivateIP: !Ref 'ADServer1PrivateIP' 688 | ADServer2InstanceType: !Ref 'ADServer2InstanceType' 689 | ADServer2NetBIOSName: !Ref 'ADServer2NetBIOSName' 690 | ADServer2PrivateIP: !Ref 'ADServer2PrivateIP' 691 | DomainAdminPassword: !Ref 'DomainAdminPassword' 692 | DomainAdminUser: !Ref 'DomainAdminUser' 693 | DomainDNSName: !Ref 'DomainDNSName' 694 | DomainNetBIOSName: !Ref 'DomainNetBIOSName' 695 | KeyPairName: !Ref 'KeyPairName' 696 | PrivateSubnet1ID: !GetAtt 'VPCStack.Outputs.PrivateSubnet1AID' 697 | PrivateSubnet2ID: !GetAtt 'VPCStack.Outputs.PrivateSubnet2AID' 698 | QSS3BucketName: !Ref 'QSS3BucketName' 699 | QSS3BucketRegion: !Ref 'QSS3BucketRegion' 700 | QSS3KeyPrefix: !Sub '${QSS3KeyPrefix}submodules/quickstart-microsoft-activedirectory/' 701 | VPCCIDR: !Ref 'VPCCIDR' 702 | VPCID: !GetAtt 'VPCStack.Outputs.VPCID' 703 | RDGWStack: 704 | Type: AWS::CloudFormation::Stack 705 | Condition: IncludeRDGW 706 | Properties: 707 | TemplateURL: 708 | Fn::Sub: 709 | - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-microsoft-rdgateway/templates/rdgw-domain.template' 710 | - S3Region: !If 711 | - UsingDefaultBucket 712 | - !Ref AWS::Region 713 | - !Ref QSS3BucketRegion 714 | S3Bucket: !If 715 | - UsingDefaultBucket 716 | - !Sub '${QSS3BucketName}-${AWS::Region}' 717 | - !Ref QSS3BucketName 718 | Parameters: 719 | DomainAdminPassword: !Ref 'DomainAdminPassword' 720 | DomainAdminUser: !Ref 'DomainAdminUser' 721 | DomainDNSName: !Ref 'DomainDNSName' 722 | DomainMemberSGID: !GetAtt 'ADStack.Outputs.DomainMemberSGID' 723 | DomainNetBIOSName: !Ref 'DomainNetBIOSName' 724 | KeyPairName: !Ref 'KeyPairName' 725 | NumberOfRDGWHosts: !Ref 'NumberOfRDGWHosts' 726 | PublicSubnet1ID: !GetAtt 'VPCStack.Outputs.PublicSubnet1ID' 727 | PublicSubnet2ID: !GetAtt 'VPCStack.Outputs.PublicSubnet2ID' 728 | QSS3BucketName: !Ref 'QSS3BucketName' 729 | QSS3BucketRegion: !Ref 'QSS3BucketRegion' 730 | QSS3KeyPrefix: !Sub '${QSS3KeyPrefix}submodules/quickstart-microsoft-rdgateway/' 731 | RDGWInstanceType: !Ref 'RDGWInstanceType' 732 | RDGWCIDR: !Ref 'RDGWCIDR' 733 | VPCID: !GetAtt 'VPCStack.Outputs.VPCID' 734 | ExchangeStack: 735 | Type: AWS::CloudFormation::Stack 736 | Properties: 737 | TemplateURL: 738 | Fn::Sub: 739 | - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/exchange.template.yaml' 740 | - S3Region: !If 741 | - UsingDefaultBucket 742 | - !Ref AWS::Region 743 | - !Ref QSS3BucketRegion 744 | S3Bucket: !If 745 | - UsingDefaultBucket 746 | - !Sub '${QSS3BucketName}-${AWS::Region}' 747 | - !Ref QSS3BucketName 748 | Parameters: 749 | ADServer1NetBIOSName: !Ref 'ADServer1NetBIOSName' 750 | ADServer1PrivateIP: !Ref 'ADServer1PrivateIP' 751 | ADServer2NetBIOSName: !Ref 'ADServer2NetBIOSName' 752 | AppInsightsApplicationName: !If [AppInsightsEnabled, !Sub "ApplicationInsights-${AWS::StackName}", !Ref AWS::NoValue] 753 | CertificateArn: !Ref 'CertificateArn' 754 | DeployLoadBalancer: !Ref 'DeployLoadBalancer' 755 | DomainAdminPassword: !Ref 'DomainAdminPassword' 756 | DomainAdminUser: !Ref 'DomainAdminUser' 757 | DomainDNSName: !Ref 'DomainDNSName' 758 | DomainMemberSGID: !GetAtt 'ADStack.Outputs.DomainMemberSGID' 759 | DomainNetBIOSName: !Ref 'DomainNetBIOSName' 760 | EdgeInstanceType: !Ref 'EdgeInstanceType' 761 | EdgeNode1NetBIOSName: !Ref 'EdgeNode1NetBIOSName' 762 | EdgeNode1PrivateIP1: !Ref 'EdgeNode1PrivateIP1' 763 | EdgeNode2NetBIOSName: !Ref 'EdgeNode2NetBIOSName' 764 | EdgeNode2PrivateIP1: !Ref 'EdgeNode2PrivateIP1' 765 | EnableBackups: !Ref 'EnableBackups' 766 | EncryptionKmsKey: !Ref 'EncryptionKmsKey' 767 | ExchangeServerVersion: !Ref 'ExchangeServerVersion' 768 | EnableReFSVolumes: !Ref 'EnableReFSVolumes' 769 | EncryptDataVolumes: !Ref 'EncryptDataVolumes' 770 | FileServerInstanceType: !Ref 'FileServerInstanceType' 771 | FileServerPrivateIP: !Ref 'FileServerPrivateIP' 772 | FileServerNetBIOSName: !Ref 'FileServerNetBIOSName' 773 | IncludeEdgeTransportRole: !Ref 'IncludeEdgeTransportRole' 774 | KeyPairName: !Ref 'KeyPairName' 775 | PrivateSubnet1ID: !GetAtt 'VPCStack.Outputs.PrivateSubnet1AID' 776 | PrivateSubnet1CIDR: !Ref 'PrivateSubnet1CIDR' 777 | PrivateSubnet2ID: !GetAtt 'VPCStack.Outputs.PrivateSubnet2AID' 778 | PrivateSubnet2CIDR: !Ref 'PrivateSubnet2CIDR' 779 | PrivateSubnet3ID: !If 780 | - IsTwoAz 781 | - !Ref 'AWS::NoValue' 782 | - !GetAtt 'VPCStack.Outputs.PrivateSubnet3AID' 783 | PrivateSubnet3CIDR: !Ref 'PrivateSubnet3CIDR' 784 | PublicSubnet1ID: !GetAtt 'VPCStack.Outputs.PublicSubnet1ID' 785 | PublicSubnet2ID: !GetAtt 'VPCStack.Outputs.PublicSubnet2ID' 786 | QSS3BucketName: !Ref 'QSS3BucketName' 787 | QSS3BucketRegion: !Ref 'QSS3BucketRegion' 788 | QSS3KeyPrefix: !Ref 'QSS3KeyPrefix' 789 | ThirdAZ: !Ref 'ThirdAZ' 790 | SetupAppInsightsMonitoring: !Ref SetupAppInsightsMonitoring 791 | VPCID: !GetAtt 'VPCStack.Outputs.VPCID' 792 | VPCCidrBlock: !GetAtt 'VPCStack.Outputs.VPCCIDR' 793 | VolumeSize: !Ref 'VolumeSize' 794 | VolumeType: !Ref 'VolumeType' 795 | VolumeIops: !Ref 'VolumeIops' 796 | ExchangeNodeInstanceType: !Ref 'ExchangeNodeInstanceType' 797 | ExchangeNode1NetBIOSName: !Ref 'ExchangeNode1NetBIOSName' 798 | ExchangeNode1PrivateIP1: !Ref 'ExchangeNode1PrivateIP1' 799 | ExchangeNode1PrivateIP2: !Ref 'ExchangeNode1PrivateIP2' 800 | ExchangeNode2NetBIOSName: !Ref 'ExchangeNode2NetBIOSName' 801 | ExchangeNode2PrivateIP1: !Ref 'ExchangeNode2PrivateIP1' 802 | ExchangeNode2PrivateIP2: !Ref 'ExchangeNode2PrivateIP2' 803 | ExchangeNode3NetBIOSName: !Ref 'ExchangeNode3NetBIOSName' 804 | ExchangeNode3PrivateIP1: !If 805 | - IsTwoAz 806 | - !Ref 'AWS::NoValue' 807 | - !Ref 'ExchangeNode3PrivateIP1' 808 | ExchangeNode3PrivateIP2: !If 809 | - IsTwoAz 810 | - !Ref 'AWS::NoValue' 811 | - !Ref 'ExchangeNode3PrivateIP2' 812 | --------------------------------------------------------------------------------