Deploying Docker in AWS
+
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

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

DNS management
DNS Record
Domain name mapping
ACM

SSL/TLS certificates
Networking
VPC

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
Lambda

Event processor
SQS

Message queue
SNS

Pub/sub messaging
EventBridge

Event routing
S3

File storage
DynamoDB

NoSQL database
Managed
EFS

Shared hard drive
EBS

Hard drive
RDS

Postgres database
EC2

Dedicated compute
Fargate

Unmanaged compute
ALB

Load balancer
ECS Service
Container deployment
Task Definition
Container configuration
Target Group
Instances to load balance
ECS

Container orchestration service
ASG

Auto scaling group
Container Registry
ECR

Image repository
Security
IAM

User
IAM Role
Service permissions
IAM Policy
Permission rules
Monitoring
CloudWatch

Monitoring and logs
End-to-end, application layers
Ingress
ALB

API Gateway

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/stageThen 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

DNS Record
Networking & Security
VPC

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

Fargate

EC2

Egress
ALB

API Gateway

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

Ingress & Egress
api

Container instance, will auto scale to maximum concurrency configuration
lambda:execute
lambda-role
The Lambda Proxy with Authentication
api-gateway-role
lambda:invokeFunction
authenticator

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

Ingress & Egress
api

Container instance, will auto scale to maximum concurrency configuration
lambda:execute
lambda-role
Simple Network
VPC

10.0.0.0/16
Availability Zone
A
public
10.0.0.0/24
main-route-table
Internet Gateway
Layered Network
VPC

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

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

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

Fargate

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! ♥️