We have two ASP.Net Core 3.1 web sites (with different domain names / host headers) deployed in Elastic Beanstalk running Windows 2019 Core server and IIS. We were able to do this by following https://aws.amazon.com/blogs/developer/multi-app-support-with-custom-domains-for-net-and-aws-elastic-beanstalk/
However, both the websites are running under 'DefaultAppPool'. ASP.Net Core does not allow more than one application per application pool (HTTP Error 500.35 - ASP.NET Core does not support multiple apps in the same app pool).
So, we added the following section to aws-windows-deployment-manifest.json
"iisConfig": {
"appPools": [
{
"name": "AppPool1",
"managedPipelineMode": "Integrated",
"managedRuntimeVersion": "v4.0"
},
{
"name": "AppPool2",
"managedPipelineMode": "Integrated",
"managedRuntimeVersion": "v4.0"
}
]
}
And, EB deployment created corresponding app pools in IIS.
Now, we are not able to assign the app pool to each web site. Ideally, we'd like to use commands from WebAdministration module (https://learn.microsoft.com/en-us/powershell/module/webadministration/?view=windowsserver2019-ps) in 'install*.ps1' powershell scripts or in a '.config' file in '.ebextensions' folder. However, WebAdministration module is not available in either place and
IMPORT-MODULE WebAdministration
doesn't work either. Only IISAdministration module (https://learn.microsoft.com/en-us/powershell/module/iisadministration/?view=windowsserver2019-ps) is available at time 'install*.ps1' scripts are executed.
So, how to assign application pools to different ASP.Net Core web sites in AWS Elastic Beanstalk?
Very lightly documented (for Windows Server) secret sauce is hiding at https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/custom-platform-hooks.html
So, for us the following strategy worked. We added the following contents in apppool.config (name doesn't matter as long as it has .config extension) file to .ebextensions
files:
"c:/Program Files/Amazon/ElasticBeanstalk/hooks/appdeploy/post/config.ps1":
content: |
Start-IISCommitDelay
$site = Get-IISSite "site1"
$site.Applications["/"].ApplicationPoolName = "AppPool1"
$site = Get-IISSite "site2"
$site.Applications["/"].ApplicationPoolName = "AppPool2"
Stop-IISCommitDelay
This created a powershell script config.ps1
in c:/Program Files/Amazon/ElasticBeanstalk/hooks/appdeploy/post/
folder. The powershell script executes after a new instance is created or a new version is deployed.
The only shortcoming is config.ps1
is created every time new version is deployed on an existing instance. It doesn't hurt as old file is renamed to config.ps1.bak
and is ignored by EB deployment process. There is definitely room for improvement here (will defer for another day).
For the sake of completion, here's entire aws-windows-deployment-manifest.json
{
"manifestVersion": 1,
"iisConfig": {
"appPools": [
{
"name": "AppPool1",
"managedPipelineMode": "Integrated",
"managedRuntimeVersion": "v4.0"
},
{
"name": "AppPool2",
"managedPipelineMode": "Integrated",
"managedRuntimeVersion": "v4.0"
}
]
},
"deployments": {
"custom": [
{
"name": "site1",
"scripts": {
"install": {
"file": "install1.ps1"
},
"restart": {
"file": "restart.ps1"
},
"uninstall": {
"file": "uninstall1.ps1"
}
}
},
{
"name": "site2",
"scripts": {
"install": {
"file": "install2.ps1"
},
"restart": {
"file": "restart.ps1"
},
"uninstall": {
"file": "uninstall2.ps1"
}
}
}
]
}
}
And Here's install1.ps1
Copy-Item -Path "C:\staging\site1" -Destination "C:\inetpub" -Recurse -Force
New-IISSite -Name "site1" -BindingInformation "*:80:*.site1.com" -PhysicalPath "C:\inetpub\site1" -Force
And uninstall1.ps1
Remove-IISSite -Name "site1" -Confirm:$False
rm -r "c:\inetpub\site1" -Force
And restart.ps1
iisreset /timeout:1
install2.ps1
and uninstall2.ps1
are similar to their site1 counterpart, as above.
We have referred to a lot of articles online and owe a Thank You
to all of them.