Welcome to the DevOps Engineer Technical Test Solution! This is the solution to the DevOps Engineer Technical Test by Stanislaus Cristo to create automated infrastructure and CI/CD pipelines while adhering to modern DevOps methodologies.
The task is to create a CI build pipeline that deploys this Node.js web application to a load-balanced environment and can be completed by locally using tools like Docker or on a cloud provider of your choice.
-
Trigger Mechanism:
- The CI job should trigger automatically when a feature branch is pushed to GitHub.
- If working locally, implement an alternative method to trigger the pipeline.
-
Deployment Workflow:
- The CI pipeline should test and deploy the application to the target environment after a successful build.
The environment must meet the following specifications:
-
Load Balancer:
- Accessible via HTTP on port 80.
- Configured to use a round-robin strategy to distribute traffic between application servers.
-
Application Servers:
- Two instances running this web application.
- Each accessible via HTTP on port 3000.
- The application must respond with:
Hi there! I'm being served from {hostname}!
The tools used for this task are:
- CI Services: GitHub Actions
- Local Environment: Docker, Vagrant, VMWare Workstation Provider
- Machine Providers: Local machine
- Load Balancers: NGINX
- Version Control: GitHub
The execution plan for this task are as below:
- Check the Node.js web application locally without any virtual machines to ensure that the application passes the required test.
- Create and provision three virtual machines with Vagrant, with the names:
- NGINX: to serve as load balancer for the application servers
- applicationInstance1: first virtual machine for Node.js web application
- applicationInstance2: second virtual machine for Node.js web application
- Check NGINX server configurations after the virtual machines are created and provisoned
- Create two Github Actions runners to use as the CI pipeline for each virtual machine
- Created two Github Actions workflow:
- To push the docker image to Docker Hub
- To deploy the application to each Runner in a docker image
- Check web applications
- Save snapshot of virtual machines and suspend them
Before creating the solution, the following softwares are installed:
- Docker
- Vagrant
- VMWare Workstation Provider
- Vagrant VMWare Utility
- Run the command
npm test - Found fault in
Chaiused for the application due to not complying with Commonjs syntax - Reverted
Chaito version4.5.0in the package-lock.json file - Run the command
npm audit fixto fix any vulnerabilities found due to revertingChai
- Created the virtual machines Vagrant with the command
vagrant up. Vagrant will use the provided Vagrantfile in this repository and will automotically provision the virtual machines - Checked the virtual machine status with the command
vagrant statusto ensure the virtual machines have been created and are currently running
- SSH to the virtual machine named "nginx" with the command
ssh nginx - Checked NGINX server configuration with the command:
cat /etc/nginx/nginx.conf | grep "include /etc/nginx/sites-" - Checked the configuration of the load balancer by checking whether the file load_balancer.conf exists in the directory /etc/nginx/conf.d/, if not use load_balancer.conf provided in this repository
- Restarted the NGINX service, with the command
sudo systemctl restart nginx
- SSH to each virtual machine created for each application instance.
- In the Settings of this repository there is a section under "Actions" called Runners
- Selected "New self-hosted runner" and followed the instructions given by Github for each self-hosted runner for each virtual machine.
- Made sure that the status of each Github Runner status is in
idle, this will change torunningwhen there are jobs given to each Runner.
- The first workflow is push-docker-image.yml. This is a workflow run on the local machine to push a docker image to Docker Hub
- The second workflow is deploy.yml. This is to deploy the Node.js web applicaction to the created Github Actions Runners and run the web application in a docker image in each virtual machine.
- SSH to each virtual machine for the web application
- Checked whether deploy.yml successfuly deployed the docker image to each instance
docker ps -a | grep ntx-devops-test - If the container is running, checked whether the application is also running by accessing the IP for the web application defined in the Vagrantfile. This will show the Node.js web application
Hi there! I'm being served from {hostname}!
- Run the command
vagrant snasphot save devops-ntx-testas a precaution to save the snapshot of the virtual machines - Run the command
vagrant suspend [virtual-machine-name]so that the virtual machines are suspended in state, so that the Github Runners in each virtual machines are saved
- Cloud deployment was attempted in Amazon Web Services (AWS), but changed to local deployment due to storage constraints for Jenkins
- Jenkins was not used for local deployment due to local machine storage constraints also
- Manual tasks that was done for this task:
- Definining the IPs for the three virtual machines
- Creating the Github Actions Runner for each web application instance still needed to SSH to each server manually
- Activating the Github Runners for each application after booting the virtual machines