As Quoin reimagines our website, we are also reimagining the infrastructure on which it runs. Our original website uses two Amazon Elastic Compute Cloud (EC2) server instances - one each for the development and production environments, along with storage services and attendant Identity and Access Management (IAM) roles and policies. While this collection of services is functional, it is more than strictly necessary to run a containerized website. In the interest of greater efficiency, enabled by the latest technologies, we are therefore transitioning to AWS Fargate, which allows containerized applications to run without maintaining an underlying server instance.
Fargate is a launch type within Amazon Elastic Container Service (ECS) that runs containerized applications without requiring maintenance of an underlying operating system or other supporting infrastructure. The arrangement of Fargate tasks follows many of the conventions that are used during local development through docker-compose, although the Amazon documentation often gives links to the Docker Remote API and the corresponding options to the 'docker run' command.
We initially planned to use a Cloudformation template to automate the deployment of all components needed to run the containerized website. However, as some necessary features are not yet supported by Cloudformation, we created an automated deployment strategy using the AWS boto3 Python SDK to circumvent Cloudformation’s limitations. This simplified deployment was a welcome improvement from a more manual approach that used the AWS Command Line Interface (CLI). Logging data from the containers using AWS Cloudwatch was similarly simple to integrate to the Fargate deployment.
The main feature to which we at Quoin are looking forward is the ability to use Cloudformation to create Elastic File System (EFS) access points. But as the Fargate launch type is a recent addition to ECS, some interconnections to other AWS technologies have not yet been added.
Fortunately, this should only be a temporary inconvenience. Amazon announced the ability to use EFS with Fargate on April 8, 2020, and an issue in the Cloudformation GitHub repository has been made for the creation of EFS access points through Cloudformation.
We will use a two step deployment until we can unify the process creating the EFS access points for the Fargate tasks with the deployment of the tasks themselves. The first step of our deployment uses Cloudformation to create the necessary file systems, IAM roles and policies, and Fargate tasks and services that do not rely upon EFS for persistent storage. The second step then uses a Python script with boto3 to create the access points for the file systems, the Fargate tasks using the access points, and the Fargate services corresponding to the tasks.
An unexpected benefit has been the simplified Cloudwatch logging afforded by ECS with Fargate. We created a log group in the Cloudformation template and then used that log group within the parameters for creation of the tasks through boto3 with a dedicated stream prefix for each of the tasks. The log group then appears in the AWS on-line console, and the output from each container is found using the stream prefix.
Our experience so far with the Fargate launch type has been positive. We have learned more of the functionality available from the boto3 SDK and simplified the setup of logging from our containers. The deployment process for the access points, tasks, and services is now a single command to run the Python script. Above all else, the transition to Fargate has granted us freedom from concern about the steps required to configure a supporting server instance.
Our infrastructure for running the original website was created and deployed with Cloudformation and configured with Ansible. The Cloudformation template creates the EC2 instance with the Debian Buster AMI available in the deployment region. The Cloudformation template also creates components such as an IAM role for interacting with the S3 buckets for data backups and a security group for the EC2 instance. Components analogous to these are also created in the new Cloudformation template. The Ansible configuration steps that were required for the EC2 instance, however, have so far been avoided through our new method. These configuration steps included setting up the EBS file system, creating the directories needed for Docker, installing Docker, setting up the environment files for the containers, pulling the Docker images from ECR, and finally building and starting the containers. It is noteworthy that this process does allow one to log in to the instance and examine the state of the running container using the 'docker exec' command, which the move to Fargate prohibits. We have not yet felt any negative impacts from this, and we believe that freedom from configuring the instance outweighs the absence of this ability.
Developers can work with local docker images for the reverse proxy, CMS, and website. When they are ready to see them running remotely, they can push the images to ECR and restart the necessary Fargate services to pull the new image. The Cloudformation deployment is currently stable, but future additions will be deployed by a single command using the AWS CLI. The creation of the EFS access points, Fargate tasks, and Fargate services is similarly simple thanks to the new Python based deployment. If it is necessary to tear down the Fargate services, tasks, and optionally the EFS access points, then that can also be accomplished by passing arguments to the same Python script that is used for deployment.
There are a few tasks remaining before the new infrastructure is finished. We are planning to help developers move faster and replicate the remote environment more closely by splitting the development processes into two phases:
The current infrastructure is using S3 buckets for backup and Cloudwatch alarms to alert when things are not going as planned, and we plan to duplicate those features for the new infrastructure. We also plan to investigate the addition of automated steps within the remote containers to verify their ability to communicate with one another prior to running their main activities. Fargate supports container dependencies within a task, but our containers do not share a task as we are currently profiling the resource usage of the individual containers. We may either consolidate the containers into fewer tasks or create these automated steps to verify container communication. We are also planning to simplify the process of restarting the Fargate services when new images are available in ECR.
The deployment process for Quoin's new website is continuing to use Cloudformation to create the necessary AWS components. So far with the transition to Fargate, we have not needed Ansible configuration steps to run the containerized components for the site. We have also learned to use more functionality of the boto3 SDK, and we are using it to deploy the ECS Fargate tasks and services that will run our new website. We no longer need to configure and maintain an underlying server instance in order to run these containerized components, and bringing in the latest changes to the docker images is as simple as restarting the related Fargate services. Our next steps are to configure Cloudwatch alarms and backups to S3, as well as determine how we would like to verify inter-container dependencies and communication. We also hope to unify the deployment through Cloudformation when creation of EFS access points is added, but in the meantime our reimagined deployment strategy shows great promise. By using the latest technologies, Quoin’s website will be able to go serverless, thus simplifying the process of configuration and optimizing functionality.