Skip to content

dlanger/aws-vpc-scenario-2

Repository files navigation

AWS' VPC Scenario 2, implemented in Terraform.

This builds a system containing:

  • Auto-scaled instances spanning two availability zones, behind an application load balancer, in a VPC
  • Routing set so that the instances don't have public IP addresses, and all outbound traffic is routed through a NAT gateway (either one per environment, or one per availability zone)
  • An SSH bastion host with a public IP, which you can connect to and then from there connect to the private instances
  • Properly-configured security groups
  • Consistent resource tagging & naming, designed to support easy budget management and a pleasant console experience

These are delivered using a series of Terraform modules with sensible defaults, to make it easier to expand the system.

Take a look at scenario-2.tf, and go from there.

Requirements

You'll need to create the following AWS objects manually:

Object Used later as
An S3 bucket to be used for ALB logs, configured with these permissions log_bucket_name
An ACM certificate for your external load balancer(s) external_lb_ssl_certificate_arn
An AMI, described as below service_app1.ami

Ensure all variables defined in scenario-2.tf/locals are either defined or hardcoded in the file.

You should also review the values in scenario-2.tf, and the additional possible ones in the modules' variables.tf.

You'll need your own AMI for service_app1.ami - when done booting, it should serve a 200 response on service_app1.server_port at path service_app1.healthcheck_path. Terraform is set to wait for the app servers to come up, so your stack won't finish applying if your AMI doesn't do this.

Deploying

  1. Set the appropriate values in scenario-2.tf/locals
  2. Set an AMI in service_app1.ami
  3. terraform plan
  4. terraform apply

Testing

When your stack deploys successfully, you can test it with curl:

$ curl https://<outputs.app1_lb_dns_name> --insecure

We need --insecure as this stack doesn't set up DNS for your load-balancer, and whatever domain you put on the ACM certificate you set doesn't cover *.elb.amazonaws.com.

Production Use

This stack is usable for microservice-based production use as-is.

If I were using it for a longer time, some enhancements I'd consider:

  • Automatically installing SSH keys onto all instances
  • Adding DNS for each load-balancer
  • Moving the bastion into an autoscaling group of one, and use something like this to update Route53 when the instance gets cycled
  • Modify the service module to support internal-only load balancers
  • Modify the service module to use only one ALB, and then use path-based routing to send the request to the right target group
  • Adding a script to the bastion instance that sets up the SSH hosts file with appropriate servers for the instances in the auto-scaling groups

To add a second microservice, add another service module.

Releases

No releases published

Packages

No packages published

Languages