This is a sample to showcase a simple way of deploying a dotnet core web application to AWS.
- Stand up the entire AWS stack using Terraform.
- Execute zero-downtime rolling deployments to AWS using codedeploy + ELB/ASG.
- Deploy multiple dev/test/prod stacks to AWS side by side.
- Scale up/down the web EC2 instance count and automatically deploy the latest version of the code.
- Cross compile from windows so that we can deploy on a linux Ubuntu 14.04 AMI.
- NGINX reverse proxies to a Kestral ASP.NET web server, which is managed by supervisor.
- SSH access to the instances for debugging purposes. todo: Better security for production using VPN.
- Persist data using RDS Postgres instance.
- Custom domain name using Route53 DNS.
- Continuous integration and Continuous deploy using AWS Codebuild which is Docker based and CodePipeline.
- Support other languages and frameworks (Java, Go, Node.js, Python)
- Multi-AZ RDS instance for disaster recovery and high availablity.
- NGINX config security hardening.
- Support newer versions of Ubuntu that are systemd based and removing supervisor.
- Log collection agent using https://www.scalyr.com
- Metrics statsd agent using https://www.datadoghq.com
Install aws by downloading from here: https://aws.amazon.com/cli/
Create a user in AWS IAM called seaside-infra
which has temporary administrator access so that we can setup our infrastructure.
Configure aws cli:
$ aws configure --profile seaside-infra
Install terraform by downloading from here: https://www.terraform.io/downloads.html
Add the terraform executable into your PATH environment variable.
Rename terraform
to tf
to save typing.
In the AWS Console in EC2 create a key pair called seaside-keypair
so that you can ssh to the bastion EC2 instance.
$ cd infra/terraform
Edit the terraform.tfvars
file for your environment. I've included a sample dev
environment config.
name = "seaside"
environment = "dev-east-1"
aws-profile-name = "seaside-infra"
aws-region-id = "us-east-1"
aws-rds-db-name = "seaside"
aws-rds-db-username = "seaside"
aws-rds-db-password = "aj8^54sd9$92Kla"
aws-rds-engine = "postgres"
aws-rds-engine-version = "9.6"
Load the terraform modules:
$ tf get
Validate the terraform template:
$ tf validate
Plan the terraform template:
$ tf plan
Apply the terraform template:
$ tf apply
To destroy the stack:
$ tf destroy
$ cd infra/deploy
Switch into powershell:
$ powershell
Package web for codedeploy:
$ ./package.ps1
Edit the ./deploy.ps1
file for your environment. I've included a sample dev
environment.
$name = "seaside"
$environment = "dev-east-1"
$aws_region_id = "us-east-1"
$aws_profile_name = "seaside-infra"
$aws_codedeploy_app = "$name-$environment-codedeploy-app"
$aws_codedeploy_bucket = "$name-$environment-codedeploy-bucket"
$aws_codedeploy_group_web = "$name-$environment-aws-codedeploy-group-web"
$aws_codedeploy_deploy_config = "CodeDeployDefault.OneAtATime"
Deploy web via codedeploy:
$ ./deploy.ps1
Once codedeploy has rolled out the deploy, grab the elb dns url and ping the web site!
$ cd infra/terraform
Edit the web\main.tf
terraform file, under the "aws-web-autoscaling-group"
resource.
To scale up from 3 instances to 4 set max_size = 5
and desired_capacity = 4
Plan the change:
$ tf plan
You should see the following plan in the terraform output:
~ module.web.aws_autoscaling_group.aws-web-autoscaling-group
desired_capacity: "3" => "4"
max_size: "4" => "5"
Apply the change:
$ tf apply
To scale back down change max_size = 4
and desired_capacity = 3
then plan and apply terraform once again.