Deploying a .NET Web Application to AWS Elastic Beanstalk through TeamCity

Deploying to Elastic Beanstalk can be pretty simple if we prepare our AWS environment first.
I'm using the Visual Studio AWS Toolkit which you can find in Extensions in Visual Studio.

AWS Visual Studio ToolKit

Deploy Using the ToolKit###

First we can deploy our application to Beanstalk provided we have the right permissions to do so through IAM.

When using the ToolKit wizard, it will prompt you with an option to save the configuration. Save it in the solution and remember the filename.
Let's say we called it beanstalk_config.txt. We'll need this later.

AWS Standalone Deployment Tool###

AWS Provides a standalone deployment tool that looks at a configuration file and uses it to deploy to Beanstalk.

It's usually located somewhere like C:\Program Files (x86)\AWS Tools\Deployment Tool. In the subfolder Samples, you can find a Beanstalk example configuration file. Take a gander to see some of the options available.

In TeamCity we can either add the API keys into the file and version control it or supply it as a parameter.

The awsdeploy.exe allows you to override any parameter by supplying the argument /D<key>=<value> or -D<key>=<value>. This is where we pass in the deployment package and optionally the API key and Secret Key through TeamCity's parameters.

Your configuration file should look something similar to this:

# For detailed explanation of how these config files should be used and created please see the developer guide here:

# Edit the parameter line below to set the path to the deployment archive or use
#     /DDeploymentPackage=value
# on the awsdeploy.exe command line for more flexibility.
# DeploymentPackage = <-- path to web deployment archive -->

# Profile name is used to look up AWS access key and secret key
# from either the SDK credentials store, or the credentials file found at
# <userhome-directroy>\.aws\credentials. Alternatively the access key and 
# secret key can be set using the command line parameters /DAWSAccessKey and /DAWSSecretKey.
AWSProfileName = AppProfileName
KeyPair = myKeyPair
Region = ap-southeast-2
SolutionStack = 64bit Windows Server 2012 R2 running IIS 8.5
Template = ElasticBeanstalk
UploadBucket = elasticbeanstalk-ap-southeast-2-xxxxxxxxxxx

Application.Name = MyApp

aws:autoscaling:launchconfiguration.EC2KeyName = recommendation-syd
aws:autoscaling:launchconfiguration.InstanceType = t2.small
aws:autoscaling:launchconfiguration.SecurityGroups = sg-xxxxxxxx,sg-yyyyyyyy

aws:ec2:vpc.Subnets = subnet-xxxxxxxx
aws:ec2:vpc.VPCId = vpc-xxxxxxxx

aws:elasticbeanstalk:container:dotnet:apppool.Enable 32-bit Applications = False
aws:elasticbeanstalk:container:dotnet:apppool.Target Runtime = 4.0

aws:elasticbeanstalk:environment.EnvironmentType = SingleInstance

Container.ApplicationHealthcheckPath = /
Container.Enable32BitApplications = False
Container.InstanceType = t2.small
Container.TargetRuntime = 4.0

Environment.CNAME = MyApp-dev
Environment.Name = MyApp-dev

A key thing to note is that although the Container.TargetRuntime is set to 4.0, it actually runs .NET 4.6 because the solution stack is running on 64bit Windows Server 2012 R2 running IIS 8.5.

You can confirm this by RDP-ing into the EC2 instance that is created for the app on the first deploy:

64bit Windows Server 2012 R2 running IIS 8.5 .NET version

TeamCity MSBuild The Deployment Package###

Make sure MSBuild.exe and awsdeploy.exe are in installed and in the build agent's PATH variable.

Create an MSBuild step and add in the following command line options:
/T:Package /P:Configuration=Release or optionally
/T:Package /P:Configuration=Release;PackageLocation=/desiredPath/

Point the Build file path to the MyApp.csproj file.

This should package the application up in a .zip file and use the Release configuration.
The file will sit somewhere in obj/Release/Package/

If you run into problems with MSBuild that says something like "target Package doesn't exist" make sure you have the IIS Web Deploy Tool tool installed on the agent. This will package the application into an IIS package. It also includes the Package.targets file.

If Visual Studio isn't installed on the build agent you'll also need to copy the folders (based on version):
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web and
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\WebApplications from the dev machine to the agent.

TeamCity AWS Deploy Tool Step###

This is a command line step that should look similar to:
awsdeploy.exe -DDeploymentPackage=MyApp\obj\Release\Package\ -r beanstalk_config.txt

That tells awsdeploy.exe to use the package we just compiled and push it to Beanstalk. This assumes that both VCS sources go into the same directory.
the -r tells the tool to redeploy the package.

That should be it. Check your Application Versions in Beanstalk and you should see a new timestamp and app get deployed.

You can run the MSBuild and awsdeploy.exe commands locally to test the functionality in a command console before completing the TeamCity build configuration.