Leo's Notebook

Deploying Docker in AWS

Docker Logo

+

AWS Logo

How to prepare applications as packages and stitch together a secure and scalable infrastructure to host them.

Lets assume we have our applications ready and dormant, stored in ECR.

ECR

ECR Logo

Repository like github, but for executable standalone code

Infrastructure

Serverless vs Managed

The key difference between these services is that managed resources needs a VPC to be deployed into, consequentially they need to have a ENI, a security group and a way to connect into and out of the VPC.

So there are three levels of hosting:

  • 1. (easy) Serverless, Lambda
  • 2. (very hard) Managed, Fargate
  • 3. (beyond insanity) Managed, EC2

Services

These are all the services that are required to deploy a containerized application in AWS and their relationships. Not all are needed simultaneously but knowing all of these different kinds of services will help you understand and build the right architecture. This also displays why some services are more complex to deploy than others given the number of arrows comming in and out.

Entrypoint

Route 53

Route 53 Logo

DNS management

DNS Record

Domain name mapping

ACM

ACM Logo

SSL/TLS certificates

Networking

VPC

VPC Logo

Virtual private cloud

Subnet

Network segment

Availability Zone

Independent infrastructure zone

Security Group

Firewall rules

Route Table

Resource links

ENI

Network connectors

NAT Gateway

Private to public gateway

Internet Gateway

Public internet access

Serverless

API Gateway

API Gateway Logo

API gateway

Lambda

Lambda Logo

Event processor

SQS

SQS Logo

Message queue

SNS

SNS Logo

Pub/sub messaging

EventBridge

EventBridge Logo

Event routing

S3

S3 Logo

File storage

DynamoDB

DynamoDB Logo

NoSQL database

Managed

EFS

EFS Logo

Shared hard drive

EBS

EBS Logo

Hard drive

RDS

RDS Logo

Postgres database

EC2

EC2 Logo

Dedicated compute

Fargate

Fargate Logo

Unmanaged compute

ALB

ALB Logo

Load balancer

ECS Service

Container deployment

Task Definition

Container configuration

Target Group

Instances to load balance

ECS

ECS Logo

Container orchestration service

ASG

ASG Logo

Auto scaling group

Container Registry

ECR

ECR Logo

Image repository

Security

IAM

IAM Logo

User

IAM Role

Service permissions

IAM Policy

Permission rules

Monitoring

CloudWatch

CloudWatch Logo

Monitoring and logs

End-to-end, application layers

Ingress

ALB

ALB Logo

API Gateway

API Gateway Logo

All inbound requests starts here, the internet facing input services. This layer is the HTTPS entrypoint, every request after this point is decrypted and routed to the specific application. These services comes with a default HTTPS endpoint and a SSL/TLS certificate.

These services provide a domain like this:

https://service.elb.us-east-2.amazonaws.comhttps://uuid.execute-api.us-east-2.amazonaws.com/stage

Then we can use the Route53 hosted zone with a DNS record to point to the load balancer, API gateway or directly to a public IP inside the VPC. This will serve as an alias for the application, redirecting traffic using subdomains.

DNS

Route 53

Route 53 Logo

DNS Record

Networking & Security

VPC

VPC Logo

Availability Zone

Security Group

IAM Role

IAM Policy

This layer we define where the app will be hosted, what traffict it will accept and with what our container can do inside our AWS. A container uses our VPC and a availability zone to be hosted.

The security group is the layer where we define what traffic it will accept, the IAM role is the layer where we define what the container can do inside our AWS and the IAM policy is the layer where we define what the container can do inside our AWS.

The compute layer is the layer where the application is running, a place to execute your Docker images stored in ECR as containers. The three main types of compute resources are Lambda, Fargate and EC2.

EC2 is a machine that you can SSH into it and directly run commands like `docker run ...`, analogous to the local machine, it can host multiple containers as long as you have the needed RAM, CPU, storage and ENI for every container.

Fargate is a “automatic” EC2 instantiator where you dont need to care about any configuration, just provide the Docker image and things like port mapping. This instance will run a single container that needs to be stateless and idempotent.

Lambda is a serverless compute service, a event processor, it will instantiate a Docker container for each individual event, process it and then terminate the container after some time. This quirk affects deeply the way you need to design your application, since you need to make it stateless and idempotent.

Compute

Lambda

Lambda Logo

Fargate

Fargate Logo

EC2

EC2 Logo

Egress

ALB

ALB Logo

API Gateway

API Gateway Logo

NAT Gateway

Internet Gateway

The reply of the service can be simply routed back as a default action to the API gateway or load balancer given that the container can be routed back to the load balancer and have the correct security group permissions.

The Internet Gateway is needed for non-serverless services in your VPC if they need to access the internet or be accessed from the internet without a load balancer or API gateway, like a direct connection to RDS or SSH connection.

The NAT Gateway is needed for a non-serverless services in a private subnet to access the internet, one way flow.

Common Architectures

The Lambda Proxy

api-gateway-role

lambda:invokeFunction

api-gateway

API Gateway Logo

Ingress & Egress

api

Lambda Logo

Container instance, will auto scale to maximum concurrency configuration

lambda:execute

lambda-role

The Lambda Proxy with Authentication

api-gateway-role

lambda:invokeFunction

authenticator

Lambda Logo

Proxy service for JWT token validation and user identity lookup, is executed once for every token as a cache with TTL

api-gateway

API Gateway Logo

Ingress & Egress

api

Lambda Logo

Container instance, will auto scale to maximum concurrency configuration

lambda:execute

lambda-role

Simple Network

VPC

VPC Logo

10.0.0.0/16

Availability Zone

A

public

10.0.0.0/24

main-route-table

Internet Gateway

Layered Network

VPC

VPC Logo

10.0.0.0/16

Availability Zone

A

public

10.0.0.0/24

public-route-table

Internet Gateway

private

10.0.1.0/24

private-route-table

NAT Gateway

Multi-AZ Network

VPC

VPC Logo

10.0.0.0/16

Availability Zone A

public-a

10.0.0.0/24

Availability Zone B

public-b

10.0.1.0/24

main-route-table

Internet Gateway

Container Task

task-role

task-policy

s3:get

execution-role

execution-policy

ecr:pull

alb

ALB Logo

Forwards HTTPS traffic from 443 to the target group HTTP 3000

alb-tg

Target group is where a service register its instances, the load balancer will distribute traffic with a round robin algorithm

service

Task definition instantiation, can be scaled to thousands of instances seemingly

task-definition

Configuration like RAM, CPU, ephemeral storage, networking, security, and image configuration

alb-sg

allow TCP 443 inbound, allow all outbound

cluster

ECS Logo

Fargate

Fargate Logo

ecs-sg

allow HTTP 3000 from alb-sg, allow all outbound

Now to the other steps

...

Last words

What about Kubernetes?

Why add another layer of abstraction on top of AWS that brings even more building blocks? Kubernetes make it easy to template a project, but ECS can do everything that Kubernetes can do, and even more since we are working directly with the cloud provider.

Next steps

  • Add more architectures
  • Create a page for every component with detailed description,terraform code, and examples
  • Improve diagrams to minimize clutter and to make them interactive
  • Add code generation for architectures

♥️ Thank you for reading! ♥️