Hosting Kiwi TCMS in our ECS cluster with RDS

Sharath AV
3 min readJul 9, 2021

We needed to host Kiwi TCMS for use by our QA team at Sequoia. We use AWS ECS service for hosting our applications. Kiwi TCMS already has a docker image available and a docker-compose file is provided as well in their repository for hosting. However, we wanted to use RDS for the database, and use Parameter Store for storing the respective database credentials.

First I tried to find out if there’s anyone who made a similar setup using ECS. Sure enough, we found this post, which describes how they had set it up. However, it did not cover some of the details with respect to ECS task definition. And since that post is a little old, we had to make some fixes to get it working for us with the new version of Kiwi TCMS. In this post, I’d be sharing the details on how we got things working.

Our Dockerfile:

FROM kiwitcms/kiwi:latest
COPY --chown=1001 tcms/settings/ /venv/lib64/python3.8/site-packages/tcms/settings/
RUN pip install django_ses
RUN pip install boto3

Here, we’re installing django_ses for email, and boto3 to fetch RDS configuration parameters from SSM Parameter Store service. One thing we need to be careful of here is to make sure that the path is pointing to the correct Python version (here, python3.8) that the current Kiwi TCMS docker image uses. Things did not work initially as we were trying with python3.6.

And below is our - which over-rides the default settings that comes with the docker image:

import os
import boto3
boto_session = boto3.Session()
ssm_client = boto_session.client('ssm')
db_parameter = ssm_client.get_parameter(Name="/kiwi/KIWI_DB_NAME", WithDecryption=True)
username_parameter = ssm_client.get_parameter(Name="/kiwi/KIWI_DB_USER", WithDecryption=True)
password_parameter = ssm_client.get_parameter(Name="/kiwi/KIWI_DB_PASSWORD", WithDecryption=True)
host_parameter = ssm_client.get_parameter(Name="/kiwi/KIWI_DB_HOST", WithDecryption=True)
# Database settings
"default": {
"ENGINE": os.environ.get("KIWI_DB_ENGINE", "django.db.backends.mysql"),
"NAME": db_parameter['Parameter']['Value'],
"USER": username_parameter['Parameter']['Value'],
"PASSWORD": password_parameter['Parameter']['Value'],
"HOST": host_parameter['Parameter']['Value'],
"PORT": 3306,
"OPTIONS": {},
# Email settings
# DEFAULT_FROM_EMAIL must be defined if you want Kiwi TCMS to send emails.
# You also need to configure the email backend. For more information see:
# SERVER_EMAIL is used by the logging backend to send exceptions to ADMINS
EMAIL_BACKEND = 'django_ses.SESBackend'
AWS_SES_REGION_NAME = 'us-west-2'

The SES service access is provided through IAM role of the ECS service, so we need not set AWS_SES_ACCESS_KEY_ID and AWS_SES_SECRET_ACCESS_KEY here.

After this, when we tried to build the docker image and launch the service in ECS, the task was failing to register successfully with the load-balancer target group. This was because the health-check path was ‘/’, which returned 302 response-code instead of 200. Also, it was resulting in ERR_TOO_MANY_REDIRECTS when trying to access in browser. To fix this, we had to make two additional changes:

  1. Change the health-check path to ‘“/static/images/favicon.ico” to fix the health check issue ( this is a small static file from Kiwi/Django, which returns a 200 response).
  2. Add KIWI_DONT_ENFORCE_HTTPS environment variable in ECS task definition, as SSL is handled at the load-balancer itself:
environment: [
{ name : "KIWI_DONT_ENFORCE_HTTPS", value : "true" }

After these final changes, things started to work fine for us. If you’d like to know any additional details on this, please let us know in the comments.