Are you looking to deploy a Django app on Elastic Container Service at scale? This comprehensive guide is designed to help you do just that. With step-by-step instructions, you’ll learn how to create an Elastic Container Registry, set up an Elastic Load Balancer, create an Elastic Container Service, and configure auto-scaling.
In addition, this guide covers important security considerations, such as updating security groups and ensuring a secure AWS environment.
Let’s start without wasting time.
Index
Part 1: Coding the XKCD Django App
Coding the XKCD Django App
- Creating and activating a virtual environment
- Installing Django
- Creating database models
- Adding models to the Django admin page
- Creating the homepage view
- Adding homepage view to URLs
- Creating homepage.html
- Creating requirements.txt file
- Dockerizing our Django App
- Testing the Docker Image
Part 2: AWS: Configuring RDS, Parameter Store, ElastiCache
Configuring AWS
- AWS RDS – Relational Database Service
- Configuring RDS Security Group
- Creating a Postgresql Database on RDS
- Updating Django settings to use the PostgreSQL Database Backend
- Install the PostgreSQL library
- Update the settings.py
- AWS Systems Manager Parameter Store
- Adding our secrets to Parameter Store
- Configuring Django App to use AWS Parameter Store
- Install AWS SDK for Python: boto3
- Update the settings.py file
- Migrating Django models to RDS instance
- Build & run the docker image with the aws credentials
- Creating Parameter Store IAM Role
- Creating a super user
- ElastiCache Redis
- Creating the Security Group: XKCDAppElastiCacheSecurityGroup
- Creating the ElastiCache Redis Instance
- Adding ElastiCache endpoint to Parameter Store
- Installing django-redis package
- Updating Django settings to use Redis as Session Storage
Part 3: AWS: Deploying XKCD App to Elastic Container Service
- Elastic Container Registry
- Uploading XKCD Apps Docker Image to ECR
- Elastic Load Balancing
- ELB Security Group Creation
- ELB Creation
- Step 1: Configure Load Balancer
- Step 2: Security Settings
- Step 3: Security Groups
- Step 4: Routing: Target Group Creation
- Step 5: Registering Targets to Target Group
- Step 6: Review
- Step 7: Forward traffic from port 80 to port 8000
- Elastic Container Service
- Creating an ECS Task Execution Role: XKCDAppECSTaskExecutionRole
- Creating ECS security group: XKCDAppECSSecurityGroup
- Creating Task Definition: XKCDAppTaskDefinition
- Adding a container to XKCDAppTaskDefinition
- Creating Cluster Service
- Step 1: Configure Service
- Step 2: Configure Network
- Step 3: Set Auto Scaling
- Step 4: Review
- Load Testing our App with Hey
- Creating Auto Scaling for XKCDAppClusterService
- Testing the Auto Scaling Policy
- Updating Security Groups
- Updating XKCDAppElasticLoadBalancerSecurityGroup
- Updating XKCDAppECSSecurityGroup
- Updating XKCDAppElastiCacheSecurityGroup
- Updating XKCDAppRDSSecurityGroup
1. Elastic Container Registry
Go to Repositories
under Elastic Container Registry
and click on the Create Repository button. Give your ECR repository a name and click “create”.
Elastic Container Registry Creation
1.1 Uploading XKCD Apps Docker Image to ECR
Go to the detail page of your repository and click View Push Commands
on the upper right. This will give you login
, build
, tag
and push
commands specific to your repository.
# get credentials to ECR Repo
aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin 12345678912.dkr.ecr.eu-west-2.amazonaws.com
#build your image
docker build -t xckdapp .
# tag it as the latest
docker tag xckdapp:latest 12345678912.dkr.ecr.eu-west-2.amazonaws.com/xckdapp:latest
# push to ECR
docker push 12345678912.dkr.ecr.eu-west-2.amazonaws.com/xckdapp:latest
2. Elastic Load Balancing
We are going to access our Elastic Container Service container instances through an AWS Elastic Load Balancer. We are going to create the ELB first in order to add it to Elastic Container Service upon creation.
2.1 ELB Security Group Creation
Go to Security Groups
under VPC
and create one.
ELB Security Group Creation
Setting | Option |
---|---|
Name | XKCDAppElasticLoadBalancerSecurityGroup |
Description | XKCDApps Elastic Load Balancer Security Group. |
VPC | Select your VPC, or use the default one. |
Inbound Rules | Type: HTTP , Source: Anywhere |
Inbound Rules | Type: HTTPS Source: Anywhere |
Inbound Rules | Type: CustomTCP , Port Range: 8000 , Source: Anywhere |
Outbound Rules | Type: All Trafic , Destination: Anywhere |
2.2 ELB Creation
Go to Load Balancers
under EC2
and click on Create Load Balancer button and select Application Load Balancer
.
2.2.1 – Step 1: Configure Load Balancer
ELB Creation: Configuring the Load Balancer
For Availability Zones, you should remember your AZ choices, as you will need to use the same configuration for Elastic Container Service creation.
ELB Creation: Configuring availability zones
Setting | Option |
---|---|
Load Balancer Type | Application Load Balancer |
Name | XKCDAppELB |
Scheme | internet-facing |
IP address type | ipv4 |
Listeners | HTTP: 80 |
Listeners | HTTP: 8000 |
Availability Zones | 2a, 2b, 2c |
2.2.2 – Step 2: Security Settings
ELB Creation: Target Group Creation
We are not going to use HTTPS for this demo, feel free to skip this step.
2.2.3 – Step 3: Security Groups
ELB Creation: Security Group Selection
2.2.4 – Step 4: Routing: Target Group Creation
ELB Creation: Target Group Creation
Setting | Option |
---|---|
Target Group | New target group |
Name | XKCDAppClusterServiceTargetGroup |
Target Type | IP |
Protocol | HTTP |
Port | 8000 |
Protocol version | HTTP1 |
Health Checks: Protocol | HTTP |
Health Checks: Path | / |
2.2.5 – Step 5: Registering Targets to Target Group
Feel free to skip this step, ECS will go to manage target groups.
2.2.6 – Step 6: Review
Click on the create button. And when you go back to the Load Balancers console, you should see something like this.
Name | DNS name | state |
---|---|---|
XKCDAppELB | XKCDAppELB-123456789.eu-west-2.elb.amazonaws.com | provisioning |
We will be using the DNS name to connect to our ECS instances, take note of it.
2.2.7 – Step 7: Forward traffic from port 80 to port 8000
Go to Listeners
tab on XKCDAppELB’s detail view under Load balancers
. On listener HTTP: 80
click on view/edit rules
.
ELB Port Forwarding: Target Group Creation
Add a rule to forward HTTP:80 traffic to HTTP:8000.
Setting | Option |
---|---|
Path | * |
Redirect to | HTTP 8000 |
HTTP Code | 301 – Permanently Moved |
Port Forwarding: Adding a Rule Group Creation
3. Elastic Container Service
3.1 Creating an ECS Task Execution Role: XKCDAppECSTaskExecutionRole
Go to Role
under IAM
and click on the create role button. Attach policies below:
- AmazonECSTaskExecutionRolePolicy (aws managed)
- SystemManagerParameterStoreFullAccess (custom)
ECS Task Role Creation
3.2 Creating ECS security group: XKCDAppECSSecurityGroup
Creating ECS security group: XKCDAppECSSecurityGroup
Setting | Option |
---|---|
Name | XKCDAppECSSecurityGroup |
Description | XKCD Apps security group, allows container ports |
VPC | Select your VPC, or use the default one. |
Inbound Rules | Type: CustomTCP , Port Range: 80 , Source: Anywhere |
Inbound Rules | Type: CustomTCP , Port Range: 8000 , Source: Anywhere |
Outbound Rules | Type: All Trafic , Destination: Anywhere |
3.3 Creating Task Definition: XKCDAppTaskDefinition
Go to Task Definitions
under Elastic Container Service
and create a task definition.
Configure task and container definitions
Setting | Option |
---|---|
Launch Type | Fargate |
Name | XKCDAppTaskDefinition |
Task Role | XKCDAppECSTaskExecutionRole |
Network mode | awsvpc |
Task Execution Role | ecsTaskExecutionRole |
Task Memory | 2 GiB |
Task CPU | 1vCPU |
3.3.1 Adding a container to XKCDAppTaskDefinition
Click on Add container
button under the section Container Definitions
Remember to append :latest
tag to your Elastic Container Registry URI.
Setting | Option |
---|---|
Container name | XKCDAppContainer |
Image | 12345678912.dkr.ecr.eu-west-2.amazonaws.com/xkcdapp:latest |
Port Mappings | 8000 TCP |
Port Mappings | 80 TCP |
3.4 Creating Cluster Service
Click on the default cluster on Clusters
page under Elastic Container Service
.
AWS ECS default cluster
Click on Create
button under Services
.
3.4.1 – Step 1: Configure Service
Setting | Option |
---|---|
Launch Type | Fargate |
Task Definition | XKCDAppTaskDefinition |
Task Revision | 1(latest) |
Platform Version | Latest |
Cluster | default |
Service name | XKCDAppClusterService |
Service Type | Replica |
Number of tasks | 1 |
Min healthy percent | 100 |
Max percent | 200 |
3.4.2 – Step 2: Configure Network
VPC & Security Group
Setting | Option |
---|---|
Cluster VPC | default |
Subnets | 2a, 2b, 2c |
Security Group | Select existing: XKCDAppECSSecurityGroup |
Auto-assign public IP | ENABLED |
Load Balancing
Setting | Option |
---|---|
Load Balancer Type | Application Load Balancer |
Load Balancer Name | XKCDAppELB |
Container to load balance
Setting | Option |
---|---|
Production Listener Port | 80:HTTP |
Production Listener Protocol | HTTP |
Target group name | Select existing: XKCDAppClusterServiceTargetGroup |
Target group protocol | HTTP |
Target type | IP |
Path Pattern | / |
Evaluation Order | default |
Health check path | / |
3.4.3 – Step 3: Set Auto Scaling
We will configure auto-scaling later. Skip this step for now.
3.4.4 – Step 4: Review
Make sure your changes are correct and click on Create Service
button.
Go to Tasks
tab under Service: XKCDAppClusterService
, and wait for your task’s status to be RUNNING
.
Now you can go to your Elastic Load Balancer’s DNS name which is something like this: http://xkcdappelb-12346578.eu-west-2.elb.amazonaws.com:8000/
If you haven’t done the ELB port forwarding remember to append the port :8000
to DNS name.
3.5 Load Testing our App with Hey
Hey is an open-sourced load testing tool. We will be using it to test how well a single container of the XKCD App does under load. And with the information we get out of load-testing, we can decide on a good Auto Scaling Policy.
Let’s run hey with 100 requests, 1 concurrent request at a time.
❯ hey -n 100 -c 1 http://xkcdappelb-123456789.eu-west-2.elb.amazonaws.com:8000/
Summary:
Total: 64.8392 secs
Slowest: 1.6920 secs
Fastest: 0.1304 secs
Average: 0.6484 secs
Requests/sec: 1.5423
Total data: 109851 bytes
Size/request: 1098 bytes
Response time histogram:
0.130 [1] |■
0.287 [6] |■■■■■■
0.443 [22] |■■■■■■■■■■■■■■■■■■■■
0.599 [7] |■■■■■■■
0.755 [43] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.911 [1] |■
1.067 [16] |■■■■■■■■■■■■■■■
1.224 [2] |■■
1.380 [0] |
1.536 [1] |■
1.692 [1] |■
Latency distribution:
10% in 0.3377 secs
25% in 0.3638 secs
50% in 0.6604 secs
75% in 0.7351 secs
90% in 1.0325 secs
95% in 1.0596 secs
99% in 1.6920 secs
Details (average, fastest, slowest):
DNS+dialup: 0.0065 secs, 0.1304 secs, 1.6920 secs
DNS-lookup: 0.0058 secs, 0.0000 secs, 0.5765 secs
req write: 0.0000 secs, 0.0000 secs, 0.0001 secs
resp wait: 0.6418 secs, 0.1302 secs, 1.5321 secs
resp read: 0.0001 secs, 0.0000 secs, 0.0003 secs
Status code distribution:
[200] 100 responses
In almost a minute, our application responded to 100 requests and it responded in an average of 0.64 seconds. You can try to experiment with hey, change the request count, update your Task Definition’s RAM or vCPU, etc.
That’s the ideal situation for XKCD App, so we will configure the Auto Scaling condition to be 100 requests per minute per instance.
3.6 Creating Auto Scaling for XKCDAppClusterService
Go to XKCDAppClusterService
under default cluster and click update.
Configuring AWS ECS Auto Scaling
Set up a reasonable Auto Scaling Policy.
Configuring AWS ECS Auto Scaling Policy
3.6.1 Testing the Auto Scaling Policy
Normally, XKCDAppClusterService’s desired count of instances is 1.
But when I load-test it again with Hey,
❯ hey -n 400 -c 10 http://xkcdappelb-123456798.eu-west-2.elb.amazonaws.com:8000/
I could see that my instance count increased after cool-down time.
4. Updating Security Groups
Our XKCD App runs on the security group configuration of the below diagram.
If we follow the access through the security groups, we can come up with an inbound/outbound access table:
inbound | outbound |
---|---|
Public Internet | XKCDAppElasticLoadBalancerSecurityGroup |
XKCDAppElasticLoadBalancerSecurityGroup | XKCDAppECSSecurityGroup |
XKCDAppECSSecurityGroup | XKCDAppElastiCacheSecurityGroup |
XKCDAppECSSecurityGroup | XKCDAppRDSSecurityGroup |
Let’s update our security groups. Go to Security Groups
under VPC
.
4.1 Updating XKCDAppElasticLoadBalancerSecurityGroup
Select XKCDAppElasticLoadBalancerSecurityGroup
and edit the rules.
Rule Type | Type | Destination Type | Destination |
---|---|---|---|
Inbound | HTTP:80 | Anywhere | |
Inbound | Custom TCP: 8000 | Custom | Anywhere |
Outbound | All Traffic | Custom | XKCDAppECSSecurityGroup |
4.2 Updating XKCDAppECSSecurityGroup
Select XKCDAppECSSecurityGroup
and edit the rules.
Rule Type | Type | Destination Type | Destination |
---|---|---|---|
Inbound | HTTP:80 | Custom | XKCDAppElasticLoadBalancerSecurityGroup |
Inbound | Custom TCP: 8000 | Custom | XKCDAppElasticLoadBalancerSecurityGroup |
Outbound | All Traffic | Anywhere | |
Outbound | Custom TCP: 6379 | Custom | XKCDAppElastiCacheSecurityGroup |
Outbound | Custom TCP: 5432 | Custom | XKCDAppRDSSecurityGroup |
4.3 Updating XKCDAppElastiCacheSecurityGroup
Select XKCDAppElastiCacheSecurityGroup
and edit the rules.
Rule Type | Type | Destination Type | Destination |
---|---|---|---|
Inbound | TCP: 6379 | Custom | XKCDAppECSSecurityGroup |
4.4 Updating XKCDAppRDSSecurityGroup
Select XKCDAppRDSSecurityGroup
and edit the rules.
Rule Type | Type | Destination Type | Destination |
---|---|---|---|
Inbound | TCP: 5432 | Custom | XKCDAppECSSecurityGroup |
Conclusion
If you’ve followed this blog post to the end, you should have a secure AWS environment where a Django app is served on Elastic Container Service at scale. We created multiple services for our application’s needs and configured their network settings to accept traffic from where they’re supposed to. And also, our application secrets are located securely in the AWS Parameter Store.
If you would like to tighten the security of your AWS environment, please consider configuring your VPC securely. You can read more about secure VPC design in our previous blog post Secure AWS VPC Design and Configuration Guide.
Check out our DevOps services to stay secure!