/seaside

Primary LanguageShell

Seaside

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

Tools Setup

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.

AWS Infrastructure Setup

$ 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

Deployment

$ 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!

Scale up/down web instance count

$ 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.