October 18, 2018
Due to the web application builds up with a rather complex architecture, the CD/CI configuration is not included, please refer to Module 2 tutorial. This article mainly focuses on implementing the features of app with AWS-CLI commands.
The Mythical Mysfits website serves its static content directly from Amazon S3, provides a microservice API backend deployed as a container through AWS Fargate on Amazon ECS, stores data in a managed NoSQL database provided by Amazon DynamoDB, with authentication and authorization for the application enabled through AWS API Gateway and its integration with AWS Cognito. The user website clicks will be sent as records to an Amazon Kinesis Firehose Delivery stream where those records will be processed by serverless AWS Lambda functions and then stored in Amazon S3.
Several aws-cli commands
Create S3 bucket
aws s3 mb s3://REPLACE_ME_BUCKET_NAME
Set website homepage in bucket
aws s3 website s3://REPLACE_ME_BUCKET_NAME --index-document index.html
Set bucket access policy to public
aws s3api put-bucket-policy
--bucket REPLACE_ME_BUCKET_NAME
--policy file://~/environment/aws-modern-application-workshop/module-1/aws-cli/website-bucket-policy.json
Publish website on S3
aws s3 cp
~/environment/aws-modern-application-workshop/module-1/web/index.html
s3://REPLACE_ME_BUCKET_NAME/index.html
Visit static website s3 index
AWS Fargate is a deployment option in Amazon ECS that allows you to deploy containers without having to manage any clusters or servers. For our Mythical Mysfits backend, we will use Python and create a Flask app in a Docker container behind a Network Load Balancer. These will form the microservice backend for the frontend website to integrate with.
Create the Core Infrastructure stack on cloud using AWS CloudFormation in 10 minutes, including
aws cloudformation create-stack --stack-name MythicalMysfitsCoreStack --capabilities CAPABILITY_NAMED_IAM
--template-body file://~/environment/aws-modern-application-workshop/module-2/cfn/core.yml
Stack components are specified in core.yml.
aws cloudformation describe-stacks --stack-name MythicalMysfitsCoreStack >
~/environment/cloudformation-core-output.json
Dockerize backend Flask webservice
Change directory, where Dockerfile that tells Docker all of the instructions that should take place when the build command is executed.
cd ~/environment/aws-modern-application-workshop/module-2/app
Build Docker image
docker build . -t REPLACE_ME_ACCOUNT_ID.dkr.ecr.REPLACE_ME_REGION.amazonaws.com/mythicalmysfits/service:latest
Run image locally
docker run -p 8080:8080 REPLACE_ME_WITH_DOCKER_IMAGE_TAG
Push the Docker Image to Amazon ECR (Amazon Elastic Container Registry)
aws ecr create-repository --repository-name mythicalmysfits/service
$(aws ecr get-login --no-include-email)
docker push REPLACE_ME_WITH_DOCKER_IMAGE_TAG
Deploy container on Cluster in the Amazon Elastic Container Service (ECS)
Create cluster
aws ecs create-cluster --cluster-name MythicalMysfits-Cluster
Create an AWS CloudWatch Logs Group
aws logs create-log-group --log-group-name mythicalmysfits-logs
AWS Fargate allows you to specify that your containers be deployed to a cluster without having to actually provision or manage any servers yourself.
Enabling a Load Balanced Fargate Service
Create a Network Load Balancer
aws elbv2 create-load-balancer --name mysfits-nlb --scheme internet-facing --type network
--subnets REPLACE_ME_PUBLIC_SUBNET_ONE REPLACE_ME_PUBLIC_SUBNET_TWO > ~/environment/nlb-output.json
Create a Load Balancer Target Group
A target group allows AWS resources to register themselves as targets for requests that the load balancer receives to forward.
aws elbv2 create-target-group --name MythicalMysfits-TargetGroup --port 8080 --protocol TCP --target-type ip
--vpc-id REPLACE_ME_VPC_ID --health-check-interval-seconds 10 --health-check-path /
--health-check-protocol HTTP --healthy-threshold-count 3 --unhealthy-threshold-count 3 >
~/environment/target-group-output.json
This informs that load balancer that for requests received on a specific port, they should be forwarded to targets that have registered to the above target group.
aws elbv2 create-listener --default-actions TargetGroupArn=REPLACE_ME_NLB_TARGET_GROUP_ARN,
Type=forward --load-balancer-arn REPLACE_ME_NLB_ARN --port 80 --protocol TCP
Visit website s3 index again, website is accessing load balancer to retrieve data
Rather than have all of the Mysfits be stored in a static JSON file, we will store them in a database to make the websites future more extensible and scalable.
aws dynamodb create-table --cli-input-json
file://~/environment/aws-modern-application-workshop/module-3/aws-cli/dynamodb-table.json
aws dynamodb batch-write-item
--request-items file://~/environment/aws-modern-application-workshop/module-3/aws-cli/populate-dynamodb.json
Update Flask code to read data from DynamoDB
Visit website s3 index again, website now displays data from DynamoDB.
To make sure that only registered users are authorized to like or adopt mysfits on the website, we will deploy an REST API with Amazon API Gateway to sit in front of our NLB.
Adding a User Pool for Website Users
Create the Cognito User Pool
aws cognito-idp create-user-pool --pool-name MysfitsUserPool --auto-verified-attributes email
Create a Cognito User Pool Client
aws cognito-idp create-user-pool-client --user-pool-id REPLACE_ME --client-name MysfitsUserPoolClient
Adding a new REST API with Amazon API Gateway
Create an API Gateway VPC Link
aws apigateway create-vpc-link --name MysfitsApiVpcLink --target-arns REPLACE_ME_NLB_ARN >
~/environment/api-gateway-link-output.json
In order for API Gateway to privately integrate with our NLB, we will configure an API Gateway VPC Link that enables API Gateway APIs to directly integrate with backend web services that are privately hosted inside a VPC.
Create the REST API using Swagger REST API and all of its resources, methods, and configuration are defined within a JSON file.
Deploy the API A stage is a named reference to a deployment, which is a snapshot of the API. You can use a Stage to manage and optimize a particular deployment.
Updating the Mythical Mysfits Website
Provide new Flask service to keep up with the newly defined API in Gateway
Switch API endpoint to API Gateway from NLB, see API gateway health check
To help us gather more insights of user activity, we will implement the ability for the website frontend to submit a tiny request, each time a mysfit profile is clicked by a user, to a new microservice API we’ll create. Those records will be processed in real-time by a serverless code function, aggregated, and stored for any future analysis that you may want to perform.
Creating the Streaming Service Stack
Sending Mysfit Profile Clicks to the Service
Login and click on website items, check user behavior data gathered in bucket
Workshop Clean-Up
Clean up the workshop to avoid additional charging
aws cloudformation delete-stack --stack-name STACK-NAME-HERE
Written by Warren who studies distributed systems at George Washington University. You might wanna follow him on Github