From 014fc5aa84b3801f23b704747d702f4d0656eb13 Mon Sep 17 00:00:00 2001 From: seanfredrickcruz <seanfredrick.cruz@stratpoint.com> Date: Thu, 3 Apr 2025 09:57:13 +0800 Subject: [PATCH] add documentation and the argocd application file --- deployment-documentation.md | 904 ++++++++++++++++++++++++++++++++++++ task-app-application.yaml | 28 ++ 2 files changed, 932 insertions(+) create mode 100644 deployment-documentation.md create mode 100644 task-app-application.yaml diff --git a/deployment-documentation.md b/deployment-documentation.md new file mode 100644 index 0000000..1ac9e4b --- /dev/null +++ b/deployment-documentation.md @@ -0,0 +1,904 @@ +# 3-Tier Application Deployment: A Complete Guide + +## Introduction + +This document presents a complete implementation guide for deploying a 3-tier application using modern DevOps practices. It covers the entire deployment pipeline from local development to production-ready GitOps workflows. + +The guide is the result of a capstone project that demonstrates proficiency in containerization, Kubernetes orchestration, GitOps, and continuous deployment methodologies. By following this guide, you'll learn how to set up a complete CI/CD pipeline for a React frontend, Node.js backend, and PostgreSQL database application. + +### Who This Guide Is For + +This guide is designed for: +- DevOps engineers looking to implement GitOps workflows +- Developers wanting to learn Kubernetes and container orchestration +- System administrators transitioning to cloud-native technologies +- Students completing similar DevOps capstone projects + +### Key Technologies Used + +- **Containerization**: Docker +- **Orchestration**: Kubernetes (Minikube) +- **Package Management**: Helm +- **CI/CD**: GitLab CI +- **GitOps**: ArgoCD +- **Connectivity**: ngrok + +### Prerequisites + +To follow this guide, you should have: +- Basic understanding of Docker and containers +- Familiarity with YAML syntax +- Basic knowledge of Kubernetes concepts +- A computer with at least 8GB RAM and 4 CPU cores +- Git and a GitLab account + +Let's get started with setting up our environment and deploying our first application! + +## Table of Contents +1. [Project Overview](#project-overview) +2. [Architecture](#architecture) +3. [Local Development Environment](#local-development-environment) +4. [Kubernetes Setup with Minikube](#kubernetes-setup-with-minikube) +5. [Application Containerization](#application-containerization) +6. [Helm Chart Implementation](#helm-chart-implementation) +7. [GitLab CI/CD Pipeline](#gitlab-cicd-pipeline) +8. [ArgoCD and GitOps Setup](#argocd-and-gitops-setup) +9. [Integration with ngrok](#integration-with-ngrok) +10. [Testing and Validation](#testing-and-validation) +11. [Troubleshooting Guide](#troubleshooting-guide) +12. [Additional Resources](#additional-resources) + +## Project Overview + +This documentation provides a comprehensive guide for implementing a complete DevOps pipeline for a 3-tier task management application. The project demonstrates how to set up a modern CI/CD workflow that leverages GitOps principles to maintain consistent deployments across environments. + +### Project Background + +The task management application is composed of three distinct tiers: +1. **Frontend**: A React application that provides the user interface +2. **Backend**: A Node.js/Express API that handles business logic and data operations +3. **Database**: A PostgreSQL database that stores task information + +Instead of focusing on application development, this project emphasizes the DevOps infrastructure needed to deploy, manage, and maintain the application using best practices. + +### Objectives Achieved + +- **Local Kubernetes Environment**: Set up and configured Minikube as a local Kubernetes cluster +- **Application Containerization**: Created Dockerfiles and container images for all application components +- **Helm Chart Development**: Packaged the application with Helm for simplified deployment and management +- **CI/CD Pipeline Integration**: Implemented an automated build and deployment pipeline with GitLab CI/CD +- **GitOps Implementation**: Configured ArgoCD to maintain GitOps workflow for automated deployments +- **External Access**: Used ngrok to expose the local Kubernetes API server for CI/CD integration + +### Deliverables + +1. **Working Kubernetes Environment**: A functioning Minikube cluster with all necessary components +2. **Containerized Application**: Docker images for all application tiers +3. **Helm Charts**: Complete Helm chart templates for deploying the application +4. **CI/CD Pipeline**: Configured GitLab CI/CD pipeline for automated builds and deployments +5. **GitOps Workflow**: ArgoCD setup for automated synchronization with the Git repository +6. **Documentation**: This comprehensive guide detailing implementation steps and procedures + +### Skills Demonstrated + +- **Container Orchestration**: Kubernetes cluster management and configuration +- **Infrastructure as Code**: Defining infrastructure components in version-controlled YAML files +- **CI/CD Pipelines**: Implementing automated build and deployment processes +- **GitOps**: Applying declarative infrastructure management with Git as the source of truth +- **Helm Package Management**: Using Helm to template and package Kubernetes applications +- **Networking and Connectivity**: Exposing services internally and externally + +### How This Documentation Is Organized + +This guide follows a logical progression of steps to implement a complete DevOps workflow: + +1. First, we set up the local development environment and install necessary tools +2. Next, we configure the Kubernetes cluster using Minikube +3. Then, we package the application with Helm charts +4. Following that, we implement the CI/CD pipeline with GitLab +5. Next, we configure ArgoCD for GitOps-based deployments +6. Finally, we connect all components with ngrok and verify the workflow + +Each section includes practical commands, configuration examples, and troubleshooting tips to help you replicate this setup for your own projects. + +## Architecture + +The implementation follows a modern microservices architecture pattern: + +```mermaid +graph TD + Developer[Developer] -->|Git Push| GitLab[GitLab Repository] + GitLab -->|Trigger| Pipeline[CI/CD Pipeline] + Pipeline -->|Build & Push| Registry[Container Registry] + GitLab -->|Configuration Changes| ArgoCD[ArgoCD] + Registry -->|Pull Images| Kubernetes[Kubernetes Cluster] + ArgoCD -->|Apply Changes| Kubernetes + Kubernetes -->|Hosts| Frontend[React Frontend] + Kubernetes -->|Hosts| Backend[Node.js Backend] + Kubernetes -->|Hosts| Database[PostgreSQL Database] + Frontend -->|API Calls| Backend + Backend -->|Queries| Database + ngrok[ngrok] -->|Tunnel| Kubernetes +``` + +### Components Breakdown: +- **Frontend**: React application for task management +- **Backend**: Node.js/Express API server +- **Database**: PostgreSQL for data persistence +- **CI/CD Pipeline**: GitLab CI for automated builds +- **GitOps**: ArgoCD for declarative deployments +- **Connectivity**: ngrok for external access + +## Local Development Environment + +The project uses a standardized development environment to ensure consistency across team members. The application consists of three main components: + +- **Frontend**: React application in the `/app/frontend` directory +- **Backend**: Node.js/Express API in the `/app/backend` directory +- **Database**: PostgreSQL database initialized with sample data + +### Prerequisites + +- Docker and Docker Compose +- Git +- Node.js and npm (for local development) +- kubectl CLI +- Helm CLI + +### Directory Structure + +``` +task-app-management/ +├── app/ +│ ├── frontend/ +│ ├── backend/ +│ └── database/ +├── docs/ +│ ├── 01-local-setup.md +│ ├── 02-helm-charts.md +│ ├── 03-gitlab-ci.md +│ ├── 04-argocd-setup.md +│ └── 05-deployment.md +├── task-app/ +│ ├── charts/ +│ ├── templates/ +│ │ ├── backend-deployment.yaml +│ │ ├── backend-service.yaml +│ │ ├── database-deployment.yaml +│ │ ├── database-init-configmap.yaml +│ │ ├── database-pvc.yaml +│ │ ├── database-service.yaml +│ │ ├── frontend-deployment.yaml +│ │ └── frontend-service.yaml +│ ├── .helmignore +│ ├── Chart.yaml +│ └── values.yaml +└── .gitlab-ci.yml +``` + +## Kubernetes Setup with Minikube + +This project uses Minikube as the local Kubernetes environment. Minikube provides a lightweight, easy-to-use Kubernetes cluster that runs on your local machine. + +### Installing Minikube + +```bash +# macOS (using Homebrew) +brew install minikube + +# Windows (using Chocolatey) +choco install minikube + +# Linux +curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 +sudo install minikube-linux-amd64 /usr/local/bin/minikube +``` + +### Starting the Cluster + +```bash +# Start Minikube with sufficient resources +minikube start --cpus=2 --memory=4096mb --driver=docker + +# Verify installation +minikube status +kubectl cluster-info +``` + +### Configuring the Cluster + +```bash +# Enable the ingress addon +minikube addons enable ingress + +# Create the task-app namespace +kubectl create namespace task-app +``` + +Our Minikube cluster is configured with the following specifications: +- Kubernetes version: v0.27.4 +- Minikube version: v1.32.0 +- Context: minikube +- Namespace: task-app + +## Application Containerization + +The application is containerized using Docker, with separate Dockerfiles for each component: + +### Frontend Dockerfile + +```dockerfile +FROM node:16-alpine as build +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +RUN npm run build + +FROM nginx:alpine +COPY --from=build /app/build /usr/share/nginx/html +COPY nginx.conf /etc/nginx/conf.d/default.conf +EXPOSE 3000 +CMD ["nginx", "-g", "daemon off;"] +``` + +### Backend Dockerfile + +```dockerfile +FROM node:16-alpine +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +EXPOSE 3000 +CMD ["npm", "start"] +``` + +### Database + +For the database, we use the official PostgreSQL image with a custom initialization script to create the necessary tables and seed data. + +## Helm Chart Implementation + +The Helm chart is structured to manage all three tiers of the application. The chart includes templates for deployments, services, persistent volume claims, and configuration. + +### Chart Structure + +``` +task-app/ +├── templates/ +│ ├── backend-deployment.yaml +│ ├── backend-service.yaml +│ ├── database-deployment.yaml +│ ├── database-init-configmap.yaml +│ ├── database-pvc.yaml +│ ├── database-service.yaml +│ ├── frontend-deployment.yaml +│ └── frontend-service.yaml +├── Chart.yaml +└── values.yaml +``` + +### Chart.yaml + +```yaml +apiVersion: v2 +name: task-app +description: Task Management Application +type: application +version: 0.1.0 +appVersion: "1.0.0" +``` + +### Values Configuration + +The `values.yaml` file defines all configurable parameters: + +```yaml +# Global settings +global: + environment: development + +# Frontend configuration +frontend: + replicaCount: 1 + image: + repository: frontend + tag: latest + pullPolicy: Never + service: + type: ClusterIP + port: 3000 # Using React's dev server port + +# Backend configuration +backend: + replicaCount: 1 + image: + repository: backend + tag: latest + pullPolicy: Never + service: + type: ClusterIP + port: 3000 + env: + NODE_ENV: development + DB_HOST: database + DB_PORT: 5432 + DB_NAME: taskdb + DB_USER: postgres + DB_PASSWORD: postgres + +# Database configuration +database: + enabled: true + image: + repository: postgres + tag: "13-alpine" + service: + port: 5432 + persistence: + enabled: true + size: 1Gi + env: + POSTGRES_DB: taskdb + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres +``` + +### Key Templates + +The Helm chart includes templates for all components: + +1. **Frontend Deployment**: Manages the React frontend pods +2. **Backend Deployment**: Configures the Node.js API with appropriate environment variables +3. **Database Deployment**: Sets up PostgreSQL with persistent storage +4. **Services**: Expose each component within the cluster +5. **ConfigMap**: Initializes the database with schema and sample data + +### Installing the Chart + +```bash +# Install or upgrade the chart +helm upgrade --install my-release task-app/ --namespace task-app --create-namespace +``` + +## GitLab CI/CD Pipeline + +The CI/CD pipeline is configured in `.gitlab-ci.yml` to automate the build and deployment process. + +### Pipeline Stages + +```yaml +stages: + - build + - deploy +``` + +### Build Stage + +This stage builds the Docker images for the frontend and backend components: + +```yaml +build-frontend: + stage: build + tags: + - docker-shell + script: + - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + - cd app/frontend + - docker build -t $CI_REGISTRY/$CI_REGISTRY_USER/task-app-management/app/frontend . + - docker push $CI_REGISTRY/$CI_REGISTRY_USER/task-app-management/app/frontend + only: + changes: + - app/frontend/**/* +``` + +### Deploy Stage + +This stage handles the deployment to the Kubernetes cluster: + +```yaml +deploy-dev: + stage: deploy + script: + # Install kubectl and Helm + - curl -LO "https://dl.k8s.io/release/v1.28.0/bin/linux/amd64/kubectl" + - chmod +x ./kubectl + - mv ./kubectl /usr/local/bin/kubectl + - curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash + # Set up kubeconfig + - mkdir -p ~/.kube + - echo $KUBE_CONFIG | base64 -d > ~/.kube/config + - chmod 600 ~/.kube/config + # Deploy with Helm + - helm upgrade --install my-release task-app/ --namespace task-app --create-namespace --kube-apiserver $KUBE_API_SERVER --kube-insecure-skip-tls-verify + environment: + name: development + only: + - develop +``` + +### CI/CD Variables + +The pipeline uses the following environment variables: +- `CI_REGISTRY_USER`: GitLab registry username +- `CI_REGISTRY_PASSWORD`: GitLab registry password +- `KUBE_CONFIG`: Base64 encoded kubeconfig file +- `KUBE_API_SERVER`: Kubernetes API server URL + +## ArgoCD and GitOps Setup + +ArgoCD is used to implement GitOps, ensuring that the Kubernetes deployments stay in sync with the Git repository. + +### ArgoCD Installation + +```bash +# Create namespace +kubectl create namespace argocd + +# Install ArgoCD using Helm +helm repo add argo https://argoproj.github.io/argo-helm +helm repo update +helm install argocd argo/argo-cd --namespace argocd --set server.extraArgs={--insecure} + +# Access the ArgoCD UI +kubectl port-forward svc/argocd-server -n argocd 8080:443 +``` + +### Application Configuration + +The ArgoCD application is defined in an Application resource: + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: task-app + namespace: argocd +spec: + project: default + source: + repoURL: https://gitlab.stratpoint.dev/seanfredrickcruz/task-app-management.git + targetRevision: HEAD + path: task-app + destination: + server: https://kubernetes.default.svc + namespace: task-app-management + syncPolicy: + automated: + prune: true + selfHeal: true +``` + +This configuration: +1. Points to our GitLab repository +2. Targets the `task-app` directory containing our Helm chart +3. Deploys to the `task-app-management` namespace +4. Enables automatic synchronization with pruning and self-healing + +### Sync Policy + +The sync policy is configured for: +- **Automated sync**: Automatically apply changes when detected in Git +- **Prune resources**: Remove resources that no longer exist in Git +- **Self-healing**: Revert manual changes in the cluster + +## Integration with ngrok + +To connect your local Kubernetes cluster to GitLab CI/CD, we need to make the Kubernetes API server accessible outside your local network. This is where ngrok comes in - it creates secure tunnels to expose local services to the internet. + +### Setting Up ngrok for Kubernetes API Access + +Follow these step-by-step instructions to configure ngrok and GitLab CI/CD to work together: + +1. **Find your Kubernetes API server port**: + ```bash + kubectl config view | grep server + # This will show something like: https://127.0.0.1:8443 + # Note the port number (8443 in this example) + ``` + +2. **Create an ngrok tunnel**: + ```bash + # Open a tunnel to your Kubernetes API port + ngrok tcp 8443 # Replace 8443 with your actual port + ``` + +3. **Get the ngrok forwarding address**: + Look for the "Forwarding" line in the ngrok output: + ``` + Forwarding tcp://0.tcp.ap.ngrok.io:12345 -> localhost:8443 + ``` + Note the forwarding address and port (0.tcp.ap.ngrok.io:12345 in this example) + +4. **Update your kubectl configuration**: + ```bash + # Open a new terminal and update your cluster's API server address + kubectl config set-cluster minikube --server=tcp://0.tcp.ap.ngrok.io:12345 + ``` + +5. **Configure GitLab CI/CD variables**: + - Go to your GitLab project > Settings > CI/CD > Variables + - Update or create the `KUBE_API_SERVER` variable: + - Set the value to `https://0.tcp.ap.ngrok.io:12345` + - Note: Use `https://` in the GitLab variable, not `tcp://` + - Save the changes + +6. **Generate and add the kubeconfig**: + ```bash + # Generate the base64-encoded kubeconfig + kubectl config view --raw --minify --flatten | base64 -w 0 + ``` + - Copy the entire output string + - In GitLab, create or update the `KUBE_CONFIG` variable with this string + - Save the changes + +7. **Restore local kubectl access**: + ```bash + # When you need to use kubectl locally again, restore the original server + kubectl config set-cluster minikube --server=https://127.0.0.1:8443 + ``` + +### Testing the CI/CD Integration + +Once ngrok and GitLab are configured, you can test the integration: + +1. **Make a code change**: + ```bash + # Modify any file in your repository + echo "// Test change" >> app/frontend/src/App.js + + # Commit and push + git add . + git commit -m "Test CI/CD integration" + git push origin develop + ``` + +2. **Monitor the pipeline**: + - Go to your GitLab project > CI/CD > Pipelines + - Watch the pipeline progress through the build and deploy stages + - The deploy stage should successfully connect to your local Kubernetes cluster + +3. **Verify the deployment**: + ```bash + # Make sure kubectl is pointing to your local cluster + kubectl config set-cluster minikube --server=https://127.0.0.1:8443 + + # Check the deployed pods + kubectl get pods -n task-app + ``` + +4. **Verify with ArgoCD**: + ```bash + # Access the ArgoCD UI + kubectl port-forward svc/argocd-server -n argocd 8080:443 + ``` + - Open https://localhost:8080 in your browser + - Check if the application has synced with the latest changes + +### Accessing the Application + +To access and test the deployed application: + +```bash +# Port forward the frontend service +kubectl port-forward svc/my-release-frontend -n task-app 3000:3000 + +# In another terminal, port forward the backend service +kubectl port-forward svc/my-release-backend -n task-app 3001:3000 +``` + +Open your browser and navigate to http://localhost:3000 to use the task management application. + +### Understanding the "my-release" Prefix + +You'll notice that all deployed resources have a `my-release` prefix. This comes from the Helm release name specified during installation: + +```bash +helm install my-release task-app/ --namespace task-app +``` + +This prefix serves several important purposes: + +1. **Resource Identification**: It makes it easy to identify which resources belong to a specific Helm release +2. **Multiple Deployments**: It allows deploying multiple instances of the same chart in the same namespace +3. **Helm Release Management**: It enables Helm to track and manage the release lifecycle + +When Helm templates are rendered, the `.Release.Name` variable is replaced with this prefix, as seen in our templates: + +```yaml +metadata: + name: {{ .Release.Name }}-frontend +``` + +If you want to use a different prefix, you can change the release name in the `helm install` command: + +```bash +helm install production task-app/ --namespace task-app +``` + +This would create resources with names like `production-frontend` instead of `my-release-frontend`. + +### Testing GitOps Workflow with ArgoCD + +To verify that the GitOps workflow is functioning correctly: + +1. **Make a change to your Helm chart**: + ```bash + # For example, modify a value in values.yaml + cd task-app + # Edit values.yaml to change frontend.replicaCount from 1 to 2 + ``` + +2. **Commit and push the change**: + ```bash + git add . + git commit -m "Increase frontend replicas" + git push origin main + ``` + +3. **Observe ArgoCD synchronization**: + - Access the ArgoCD UI at https://localhost:8080 + - Watch as ArgoCD detects the change and applies it + - You should see the number of frontend pods increase to 2 + +4. **Verify the change**: + ```bash + kubectl get pods -n task-app + # You should now see two frontend pods + ``` + +This demonstrates the complete GitOps workflow, where changes to the Git repository automatically trigger updates to the Kubernetes cluster without manual intervention. + +## Testing and Validation + +A crucial part of the DevOps pipeline is verifying that the deployment works correctly. This section outlines step-by-step procedures to validate each component of the application. + +### Deployment Verification Checklist + +Before testing the application functionality, verify that all Kubernetes resources are properly deployed: + +```bash +# Check all pods in the task-app namespace +kubectl get pods -n task-app + +# Expected output (all pods should be Running): +# NAME READY STATUS RESTARTS AGE +# my-release-backend-6c6dd77898-qhd4v 1/1 Running 0 6d18h +# my-release-database-9d9b7bb65-t4dw7 1/1 Running 0 6d18h +# my-release-frontend-59d4bd9df5-q6zz6 1/1 Running 0 20h + +# Check services +kubectl get svc -n task-app + +# Expected output: +# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +# my-release-backend ClusterIP 10.244.0.121 <none> 3000/TCP 6d18h +# my-release-database ClusterIP 10.244.0.130 <none> 5432/TCP 6d18h +# my-release-frontend ClusterIP 10.244.0.124 <none> 3000/TCP 6d18h + +# Check persistent volumes +kubectl get pv,pvc -n task-app + +# Check pod logs for any errors +kubectl logs my-release-backend-6c6dd77898-qhd4v -n task-app +kubectl logs my-release-frontend-59d4bd9df5-q6zz6 -n task-app +``` + +### Component Health Check + +Verify that each component is functioning correctly: + +#### Database + +```bash +# Create a temporary pod to test database connection +kubectl run pg-client --rm -it --image=postgres:13-alpine --namespace=task-app -- psql -h my-release-database -U postgres -d taskdb + +# Inside the psql prompt, check if tables exist +\dt + +# Expected output: +# Schema | Name | Type | Owner +#--------+--------+-------+---------- +# public | tasks | table | postgres + +# Query sample data +SELECT * FROM tasks LIMIT 3; + +# Exit the psql prompt +\q +``` + +#### Backend API + +```bash +# Port forward the backend service +kubectl port-forward svc/my-release-backend -n task-app 3001:3000 + +# In a new terminal, test the API +curl http://localhost:3001/api/health +# Expected: {"status":"ok","message":"Server is running"} + +curl http://localhost:3001/api/tasks +# Expected: JSON array of tasks +``` + +#### Frontend Application + +```bash +# Port forward the frontend service +kubectl port-forward svc/my-release-frontend -n task-app 3000:3000 +``` + +Open your browser and navigate to http://localhost:3000. You should see the task management application interface. Try these operations: +- View the task list +- Create a new task +- Edit an existing task +- Mark a task as complete +- Delete a task + +### End-to-End CI/CD Test + +To validate the complete CI/CD pipeline: + +1. **Make a code change**: + ```bash + # For example, modify the frontend title + cd app/frontend/src + # Edit App.js to change the title + + # Commit and push changes + git add . + git commit -m "Update application title" + git push origin develop + ``` + +2. **Monitor the GitLab CI/CD pipeline**: + - Go to your GitLab repository + - Navigate to CI/CD > Pipelines + - Watch the build stage complete successfully + - Observe the deploy stage applying changes to Kubernetes + +3. **Verify ArgoCD synchronization**: + ```bash + # Access ArgoCD UI + kubectl port-forward svc/argocd-server -n argocd 8080:443 + ``` + - Open https://localhost:8080 in your browser + - Login with your ArgoCD credentials + - Check the task-app application status + - Verify that it shows "Synced" and "Healthy" + - View the resource tree to confirm all components are updated + +4. **Verify changes in the application**: + ```bash + kubectl port-forward svc/my-release-frontend -n task-app 3000:3000 + ``` + - Open http://localhost:3000 + - Confirm that your changes are visible in the application + +### Performance Testing + +For basic performance validation: + +```bash +# Install hey (HTTP load generator) +go get -u github.com/rakyll/hey + +# Test backend API performance +hey -n 100 -c 10 http://localhost:3001/api/tasks + +# Check resource usage during load +kubectl top pods -n task-app +``` + +### Security Validation + +Perform basic security checks: + +```bash +# Check pod security contexts +kubectl get pods -n task-app -o jsonpath='{.items[*].spec.securityContext}' + +# Check network policies +kubectl get networkpolicies -n task-app + +# Verify that database is not exposed outside the cluster +kubectl get svc my-release-database -n task-app -o yaml +``` + +After completing these validation steps, you can be confident that your deployment is functioning correctly and that the CI/CD pipeline is properly configured for continuous delivery. + +## Troubleshooting Guide + +### Common Issues and Solutions + +#### Pods Not Starting + +```bash +# Check pod status and events +kubectl describe pod <pod-name> -n task-app + +# Check logs +kubectl logs <pod-name> -n task-app +``` + +Common causes: +- Image pull errors: Check the image repository and tag +- Resource constraints: Verify Minikube has sufficient resources +- Config errors: Check environment variables and configurations + +#### Database Connection Issues + +```bash +# Check if database pod is running +kubectl get pods -n task-app | grep database + +# Check database logs +kubectl logs <database-pod> -n task-app + +# Check if the service is accessible +kubectl exec -it <backend-pod> -n task-app -- curl <database-service>:5432 +``` + +#### ArgoCD Sync Failures + +```bash +# Check application status +kubectl get applications -n argocd + +# Check detailed sync status +kubectl describe application task-app -n argocd + +# Check controller logs +kubectl logs deployment/argocd-application-controller -n argocd +``` + +#### ngrok Connection Issues + +- Verify ngrok is running and the tunnel is active +- Confirm the tunnel URL is correctly set in GitLab CI/CD variables +- Check firewall settings that might block the ngrok connections + +## Additional Resources + +- [Kubernetes Documentation](https://kubernetes.io/docs/) +- [Helm Documentation](https://helm.sh/docs/) +- [GitLab CI/CD Documentation](https://docs.gitlab.com/ee/ci/) +- [ArgoCD Documentation](https://argo-cd.readthedocs.io/) +- [ngrok Documentation](https://ngrok.com/docs/) + +## Conclusion + +This project successfully implemented a complete DevOps pipeline for a 3-tier application using modern practices and tools. By leveraging Kubernetes, Helm, GitLab CI/CD, and ArgoCD, we've created an automated workflow that enables continuous delivery of our application with minimal manual intervention. + +### Key Achievements + +1. **Environment Consistency**: Using Helm charts ensures that our application deploys consistently across all environments. +2. **Automation**: The GitLab CI/CD pipeline automates the build and initial deployment process. +3. **GitOps Workflow**: ArgoCD maintains the desired state of our application by continuously synchronizing with our Git repository. +4. **Infrastructure as Code**: All aspects of our infrastructure are defined in code and tracked in version control. +5. **Local-to-Production Parity**: The setup works consistently from local development through to production. + +### Lessons Learned + +Throughout this project, several valuable lessons emerged: + +1. **Start Simple**: Beginning with a basic deployment and iteratively adding complexity proved more effective than attempting to implement everything at once. +2. **Containerization Fundamentals**: Properly designed containers with clear separation of concerns make Kubernetes deployments much more manageable. +3. **GitOps Benefits**: Using Git as the single source of truth streamlined collaboration and simplified rollbacks when issues occurred. +4. **Infrastructure Testing**: Testing infrastructure changes before applying them prevented many potential issues. +5. **Documentation Importance**: Maintaining clear documentation throughout the process made troubleshooting and knowledge sharing much easier. + +### Future Improvements + +While the current implementation satisfies all requirements, several enhancements could be made: + +1. **Monitoring and Logging**: Implement ELK or Prometheus/Grafana for comprehensive monitoring. +2. **Secret Management**: Integrate a dedicated secret management solution like HashiCorp Vault. +3. **Multi-Environment Support**: Extend the setup to support multiple environments (dev, staging, production). +4. **Automated Testing**: Add automated tests to the CI/CD pipeline. +5. **High Availability**: Configure high-availability deployments for production use. + +By completing this project, we've demonstrated proficiency in modern DevOps practices and created a solid foundation for future application deployments. The combination of containerization, orchestration, and GitOps provides a robust framework that can be adapted to a wide range of applications and use cases. diff --git a/task-app-application.yaml b/task-app-application.yaml new file mode 100644 index 0000000..9d4209e --- /dev/null +++ b/task-app-application.yaml @@ -0,0 +1,28 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: task-app + namespace: argocd +spec: + project: default + source: + repoURL: https://gitlab.stratpoint.dev/seanfredrickcruz/task-app-management.git # Your GitLab repository + targetRevision: HEAD + path: task-app # Path to your Helm chart + destination: + server: https://kubernetes.default.svc + namespace: task-app-management + syncPolicy: + automated: + prune: true + selfHeal: true + +--- +# ConfigMap for frontend configuration +apiVersion: v1 +kind: ConfigMap +metadata: + name: frontend-config + namespace: task-app +data: + REACT_APP_API_URL: "http://localhost:3001/api" # Backend API URL \ No newline at end of file -- GitLab