Fighting COVID-19 with AWS CDK
Folding@Home recently announced that they are supporting the simulation of protein folding to help study COVID-19.
In this post I'll show you how easy it is to start Folding on Amazon Fargate using AWS CDK. It was inspired by a small project k8s-fah by richstokes where he setup a method for running the folding client on Kubernetes clusters.
You should read this post if you are any of the following:
- Interested in Infrastructure as Code
- Interested in Simulating Protein Folding
- Have a lot of Money or AWS Credits that you need to use
NOTE: I don't recommend actually running this unless you're mad rich and feel generous. It is meant as a way to practically learn how easy it is to spin up resources with AWS CDK.
What is Folding
Protein folding simulations done through Folding@Home are done in a distributed fashion leveraging peoples computers all over the world to solve a one big problem together.
Think of it like a big cake that is cut up into small pieces, and it is your responsibility to eat your part of that cake... Okay maybe this isn't the best analogy, but you get what I mean.
Proteins are not stagnant—they wiggle and fold and unfold to take on numerous shapes. We need to study not only one shape of the viral spike protein, but all the ways the protein wiggles and folds into alternative shapes in order to best understand how it interacts with the ACE2 receptor, so that an antibody can be designed - From Folding@Home Takes up the fight against COVID-19
I want to get involved but I'm lazy
That's perfect! So am I! That's why I use AWS CDK for most of my projects. CDK lets you define AWS Resources as code and quickly deploy a lot of infrastructure with very little code.
I'll give you a spoiler now, the only code you are going to need to deploy everything to AWS is the following.
const cluster = new ecs.Cluster(this, 'cluster');
const taskDefinition = new ecs.FargateTaskDefinition(this, 'task', {
memoryLimitMiB: 8192,
cpu: 4096
});
taskDefinition.addContainer('container', {
image: ecs.ContainerImage.fromAsset(path.join(__dirname, '../docker/')),
logging: new ecs.AwsLogDriver({ streamPrefix: 'covid19' })
});
new ecs.FargateService(this, 'service', {
cluster,
taskDefinition
});
You're probably thinking, "wow that's amazing". And you've be correct in that thinking. Now lets move on to learning how to deploy it.
Deploying Folding@Home
Start by installing some basic dependencies on your computer, you'll need the following as a bare minimum in order to deploy the resources to.
- NodeJS - The newer the better
- AWS Profile - Although you don't need the full AWS CLI, it's worth installing and configuring your access keys.
For deploying, you have two options depending on how hands on or off you want to be:
- Build from Scratch - Go through how to create a new CDK project and add all the resources you need to deploy.
- Just Deploy - Pull down the existing repository and deploy it.
Building from Scratch
You've taken the approach to build the entire project from scratch! Good for you, I'm proud. Start off by running the following commands to setup a new AWS CDK project
# Install aws-cdk package globally
npm install -g aws-cdk
# Create a new CDK typescript project
mkdir cdk-fah-covid19 && cd cdk-fah-covid19
cdk init --language typescript
# Install the aws-ecs CDK constructs
npm install @aws-cdk/aws-ecs
With the project setup and all the dependencies we'll need installed, it's time to start setting up the code. Open up the lib/cdk-fah-covid19-stack.ts
file and add the following content (might look familiar).
import * as cdk from '@aws-cdk/core';
import ecs = require('@aws-cdk/aws-ecs');
import path = require('path');
export class CdkFahCovid19Stack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// 1. Create a Fargate cluster
const cluster = new ecs.Cluster(this, 'cluster');
// 2. Define resource limits for task
const taskDefinition = new ecs.FargateTaskDefinition(this, 'task', {
memoryLimitMiB: 8192,
cpu: 4096
});
// 3. Add a container to the Task definition
taskDefinition.addContainer('container', {
image: ecs.ContainerImage.fromAsset(path.join(__dirname, '../docker/')),
logging: new ecs.AwsLogDriver({ streamPrefix: 'covid19' })
});
// 4. Create the service in our Fargate Cluster
new ecs.FargateService(this, 'service', {
cluster,
taskDefinition
});
}
}
There are four steps that are taken to configure the Amazon Fargate service to run our folding at home container.
- Amazon Fargate cluster is create - by default this also included ALL the networking required as well
- Task Definition - Specifies the resources allocated to a task, tasks can include 1 or more containers
- Add a container to the Task - Along with setting up a container image, we also define some logging so we can monitor how the Folding is going.
- Register the task with the Fargate Cluster - The final step connecting the task definition and the cluster together.
Dockerfile
You might have noticed a random reference to ../docker/
in the previous code. This is where we will need to put our Folding@Home docker container that will automatically be uploaded for us to Amazon ECR.
Go ahead and create the file docker/Dockerfile
in your project and add the following contents to it
FROM ubuntu:16.04
ENV DEBIAN_FRONTEND noninteractive
RUN apt update
RUN apt install wget -y
# Download/Install latest FAH client
# See here for latest - https://foldingathome.org/alternative-downloads/
RUN wget https://download.foldingathome.org/releases/public/release/fahclient/debian-stable-64bit/v7.5/fahclient_7.5.1_amd64.deb
RUN dpkg -i --force-depends fahclient_7.5.1_amd64.deb
EXPOSE 7396 36396
WORKDIR /var/lib/fahclient
CMD ["/usr/bin/FAHClient", \
"--config", "/etc/fahclient/config.xml", \
"--run-as", "fahclient", \
"--pid-file=/var/run/fahclient.pid"]
And that's it! Move onto the next step to learn how to deploy it.
Just Deploy
If you are at this point then you've either completed the Build from Scratch section or you've decided to pull down the existing repository and just want to deploy it. Either way you're in the right place.
If you don't already have the repository, pull it down from the github and install the dependencies
# Clone repository
git clone https://github.com/t04glovern/cdk-fah-covid19.git
# Install dependencies
cd cdk-fah-covid19
npm install -g aws-cdk
npm install
Now we've got to transpile the typescript and prepare it for deploy. It's usually recommended to run this command in the background while you're working on typescript. However for this example run it then ctrl+c
to exit once it's done
npm run watch
Finally, you're ready to deploy the stack. It's as easy as running the following command
cdk deploy
# CdkFahCovid19Stack: deploying...
# aws-cdk/assets:bb9ebb84d6a5d2887a7406685ff3ccb2178b47cb9ee4f1e54db1a84cb899a104: image already exists, skipping build and push
# CdkFahCovid19Stack: creating CloudFormation changeset...
# 0/60 | 9:31:46 pm | UPDATE_IN_PROGRESS | AWS::ECS::TaskDefinition | task (task117DF50A)
# 0/60 | 9:31:47 pm | UPDATE_IN_PROGRESS | AWS::ECS::TaskDefinition | task (task117DF50A) Resource creation Initiated
# 59/60 | 9:31:47 pm | UPDATE_COMPLETE | AWS::ECS::TaskDefinition | task (task117DF50A)
# 59/60 | 9:31:49 pm | UPDATE_IN_PROGRESS | AWS::ECS::Service | service/Service (serviceService7DDC3B7C)
# 59/60 Currently in progress: serviceService7DDC3B7C
# 59/60 | 9:33:51 pm | UPDATE_COMPLETE | AWS::ECS::Service | service/Service (serviceService7DDC3B7C)
# 59/60 | 9:33:53 pm | UPDATE_COMPLETE_CLEA | AWS::CloudFormation::Stack | CdkFahCovid19Stack
# ✅ CdkFahCovid19Stack
Note: the deploy can take up to 10-15 minutes as it needs to setup a whole bunch of networking services.
Checking Status
If you want to check in the status of the Folding, navigate to the ECS cluster portal and click on your cluster.
It will have a random name starting with
CdkFahCovid19Stack
.
Next open up the service by clicking on its name
You then want to click on the Logs
tab and you should be able to view the logs coming out of the container currently Folding for you
Destroying Resources
This is important!, the configuration I've put in the repo will cost you a pretty penny to run long term.
To completely remove all the resources associated with this project, run the following
cdk destroy
# Are you sure you want to delete: CdkFahCovid19Stack (y/n)? y
# CdkFahCovid19Stack: destroying...
Summary
AWS CDK is a great way to deploy a lot of resources really fast, and putting it to the use of running Folding@Home containers is a fun little experiment.
Have you used Fargate for something interesting? Or maybe you're an avid Folding@Home contributor? Reach out to me on Twitter @nathangloverAUS and let me know!