TaskOps is a full DevOps capstone project that demonstrates how a simple full-stack application can be containerized, provisioned on AWS, deployed to Kubernetes using GitOps, and monitored using Prometheus and Grafana.
The goal of this project is not only to run an application, but to show a complete beginner-friendly DevOps workflow:
Code Push → GitHub Actions → Amazon ECR → Terraform AWS Infrastructure → EKS → Argo CD → Helm → Kubernetes → Prometheus/Grafana
Developer
|
| git push
v
GitHub Repository
|
| GitHub Actions
v
Docker Build
|
| Push images
v
Amazon ECR
|
| Images pulled by Kubernetes
v
Amazon EKS Cluster
|
| Argo CD syncs Helm chart
v
TaskOps Application
|
| /metrics endpoint
v
Prometheus
|
| Data source
v
Grafana Dashboard
| Category | Tools |
|---|---|
| Cloud Provider | AWS |
| Infrastructure as Code | Terraform |
| Container Registry | Amazon ECR |
| Containerization | Docker |
| Orchestration | Kubernetes, Amazon EKS |
| Package/Deployment | Helm |
| GitOps | Argo CD |
| CI/CD | GitHub Actions |
| Monitoring | Prometheus |
| Visualization | Grafana |
| Application | Node.js, HTML, CSS, JavaScript |
| Database | MySQL |
.
├── .github/
│ └── workflows/
│ └── docker-build.yml
├── app/
│ ├── backend/
│ └── frontend/
├── argocd/
│ └── application.yaml
├── helm/
│ └── taskops-chart/
├── monitoring/
│ └── prometheus.yaml
├── terraform/
│ ├── main.tf
│ ├── variables.tf
│ ├── outputs.tf
│ └── terraform.tfvars
├── docker-compose.yml
└── README.md
- Automated Docker image build using GitHub Actions
- Docker images pushed to Amazon ECR
- AWS infrastructure provisioned using Terraform
- EKS cluster deployment
- Kubernetes manifests managed through Helm
- GitOps deployment using Argo CD
- Frontend exposed through a Kubernetes LoadBalancer service
- Backend service monitored through Prometheus
- Grafana dashboard for visual monitoring
- MySQL database deployed inside Kubernetes
Terraform is used to create the AWS infrastructure required for the project.
The Terraform setup creates:
- Amazon ECR repository for the backend image
- Amazon ECR repository for the frontend image
- AWS VPC
- Public and private subnets
- NAT Gateway
- Amazon EKS cluster
- EKS managed node group
cd terraform
terraform init
terraform plan
terraform applyAfter Terraform completes, get the outputs:
terraform outputImportant outputs:
aws_account_id
aws_region
cluster_name
cluster_endpoint
backend_ecr_repository_url
frontend_ecr_repository_url
After the EKS cluster is created, connect your local kubectl to the cluster:
aws eks update-kubeconfig --region ap-south-1 --name taskops-eksVerify the connection:
kubectl get nodesExpected result:
NAME STATUS ROLES AGE VERSION
ip-xx-xx-xx-xx.ap-south-1.compute.internal Ready <none> ...
GitHub Actions builds and pushes Docker images to Amazon ECR.
The workflow is triggered when code is pushed to the main branch and changes are made inside the app/ directory.
The workflow builds:
- Backend Docker image
- Frontend Docker image
Each image is pushed to ECR using two tags:
latest
github commit SHA
Example image format:
AWS_ACCOUNT_ID.dkr.ecr.ap-south-1.amazonaws.com/taskops-backend:latest
AWS_ACCOUNT_ID.dkr.ecr.ap-south-1.amazonaws.com/taskops-frontend:latest
Required GitHub repository secrets:
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
The TaskOps application is deployed using a Helm chart located in:
helm/taskops-chart
The Helm chart manages:
- Frontend deployment
- Frontend service
- Backend deployment
- Backend service
- MySQL deployment
- MySQL service
- Persistent storage configuration
Before deploying, update the image repositories in:
helm/taskops-chart/values.yaml
Example:
frontend:
image:
repository: 123456789012.dkr.ecr.ap-south-1.amazonaws.com/taskops-frontend
tag: latest
pullPolicy: Always
backend:
image:
repository: 123456789012.dkr.ecr.ap-south-1.amazonaws.com/taskops-backend
tag: latest
pullPolicy: AlwaysArgo CD is used to continuously sync the Kubernetes application from GitHub into the EKS cluster.
The Argo CD application manifest is located at:
argocd/application.yaml
It points to the Helm chart path:
helm/taskops-chart
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yamlCheck Argo CD pods:
kubectl get pods -n argocdkubectl apply -f argocd/application.yamlCheck the application:
kubectl get applications -n argocdExpected result:
NAME SYNC STATUS HEALTH STATUS
taskops Synced Healthy
Port-forward the Argo CD server:
kubectl port-forward svc/argocd-server -n argocd 8080:443Open:
https://localhost:8080
Username:
admin
Get the password in Git Bash or WSL:
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -dPowerShell:
$password = kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}"
[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($password))Check TaskOps pods:
kubectl get pods -n taskopsCheck services:
kubectl get svc -n taskopsThe frontend service should expose a LoadBalancer DNS:
frontend LoadBalancer xxxx.elb.ap-south-1.amazonaws.com
Open the LoadBalancer URL in the browser:
http://LOAD_BALANCER_DNS
The monitoring configuration is located at:
monitoring/prometheus.yaml
Prometheus is configured to scrape the backend metrics endpoint:
backend.taskops.svc.cluster.local:5000/metrics
Add the Helm repository:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo updateInstall or upgrade the monitoring stack:
helm upgrade --install monitoring prometheus-community/kube-prometheus-stack \
-n monitoring \
--create-namespace \
-f monitoring/prometheus.yamlCheck monitoring pods:
kubectl get pods -n monitoringIf Grafana is exposed using LoadBalancer:
kubectl get svc -n monitoringOpen the external LoadBalancer URL for:
monitoring-grafana
If using port-forward:
kubectl port-forward svc/monitoring-grafana -n monitoring 3000:80Open:
http://localhost:3000
Grafana login:
Username: admin
Password: TaskOpsAdmin123
A simple Grafana panel was created to monitor whether the backend is reachable by Prometheus.
PromQL query:
up{job="taskops-backend"}
Panel settings:
Visualization: Stat
Title: TaskOps Backend Status
Unit: none
Value mapping:
1 = UP
0 = DOWN
This panel confirms that Prometheus is successfully scraping the TaskOps backend metrics endpoint.
The project currently uses the latest image tag in the Helm values file.
This works for basic deployment, but for a stronger GitOps workflow, GitHub Actions should update the Helm image tag to the Git commit SHA after pushing the image.
TaskOps demonstrates a complete DevOps deployment pipeline using modern cloud-native tools. The project provisions AWS infrastructure with Terraform, builds and pushes Docker images using GitHub Actions, deploys the application to Amazon EKS through Argo CD and Helm, and monitors the application using Prometheus and Grafana.









