Solution to Thoughtworks Infra-problem
- This solution is designed to keep the current situtation and future in Mind.
- Used AWS as that was a bit easy to test.
Pre-requisite:
-
AWS Account
-
Create IAM user and download Access key and Secret key
-
Following needs to be installed on the local system:
• AWS CLI • Docker • Kubectl • Helm • Terraform • Terragrunt • Java • Clojure • Leiningen
To Setup Infrastructure:
- Run pre-deploy.sh to set the variables
- Run deploy.sh, this will setup an infra in AWS
To deploy application: Run app-deploy.sh , which will build and deploy the application in EKS. Note: Creating docker image and storing it in ECR, using helm for the application deployment. This way in future if you need to migrate your application somewhere you can do it on the fly as the appplication is KNative.
Future Ready scenarios:
-
Infra and code together can be deployed using CICD pipeline.
-
Intergrate Kubernetes with the runner (if Jenkins --> we can configure clouds under manage Jenkins) with which we can let the runner assign a dynamic pod for building, testing the application, let JIB convert the code and push the docker images to registry and helm will create charts using the helm templates which inturn can be deployed to various environemnts.
-
Webhooks/actions can be configured to auto trigger the pipeline upon the successful merge of the latest changes.
-
Google's JIB can be a good candidate for the future, using which we can replace dockerfiles and docker compose files. All we need to do is to configure project.clj with below. This will help us avoid extra code as JIB takes care of converting the artifacts into docker images along with configuring the entrypoint in order for the artifacts to be choosen.
Detailed documentation is available in https://cloud.google.com/java/getting-started/jib
:plugins :jib-build/build-config {:base-image {:type :registry :image-name "ecr.io/distroless/java"} :target-image {:type :docker :image-name "helloworld"}}
:target-image {:type :registry :image-name "123456789.dkr.ecr.mordor-east-1.amazonaws.com/helloworld" :authorizer {:fn leiningen.aws-ecr-auth/ecr-auth :args {:type :access-key :access-key-id "AK1231232414" :secret-access-key "111111111111111"}}}
References:
https://docs.aws.amazon.com/eks/latest/userguide/creating-a-vpc.html - for the cloud formation template
https://registry.terraform.io/ - for terraform modules
This project contains three services:
quotes
which serves a random quote fromquotes/resources/quotes.json
newsfeed
which aggregates several RSS feeds togetherfront-end
which calls the two previous services and displays the results.
- Java
- Leiningen (can be installed using
brew install leiningen
)
You can run the tests of all apps by using make test
First you need to ensure that the common libraries are installed: run make libs
to install them to your local ~/.m2
repository. This will allow you to build the JARs.
To build all the JARs and generate the static tarball, run the make clean all
command from this directory. The JARs and tarball will appear in the build/
directory.
cd
to front-end/public
and run ./serve.py
(you need Python3 installed). This will serve the assets on port 8000.
All the apps take environment variables to configure them and expose the URL /ping
which will just return a 200 response that you can use with e.g. a load balancer to check if the app is running.
java -jar front-end.jar
Environment variables:
APP_PORT
: The port on which to run the appSTATIC_URL
: The URL on which to find the static assetsQUOTE_SERVICE_URL
: The URL on which to find the quote serviceNEWSFEED_SERVICE_URL
: The URL on which to find the newsfeed serviceNEWSFEED_SERVICE_TOKEN
: The authentication token that allows the app to talk to the newsfeed service. This should be treated as an application secret. The value should be:T1&eWbYXNWG1w1^YGKDPxAWJ@^et^&kX
java -jar quotes.jar
Environment variables
APP_PORT
: The port on which to run the app
java -jar newsfeed.jar
Environment variables
APP_PORT
: The port on which to run the app