Deploy WordPress on Kubernetes using Argo CD, GitHub Actions, AWS Secrets Manager, External Secrets Operator, and NGINX Ingress Controller.
This project demonstrates a modern GitOps workflow where Git serves as the single source of truth for Kubernetes deployments. Every change is validated through a CI pipeline before being automatically synchronized to the Kubernetes cluster by Argo CD.
Modern Kubernetes deployments should be secure, automated, and fully declarative.
This repository demonstrates how to deploy a production-style WordPress application on Kubernetes using GitOps principles while keeping sensitive credentials outside the Git repository.
Instead of storing Kubernetes Secrets inside Git:
- AWS Secrets Manager securely stores application credentials.
- External Secrets Operator synchronizes secrets into Kubernetes.
- Argo CD continuously reconciles the cluster with the desired state stored in Git.
- GitHub Actions validates every Kubernetes manifest before deployment.
The result is a secure, repeatable, and production-oriented deployment workflow suitable for modern DevOps environments.
- β¨ Project Highlights
- π Project Status
- π― Project Objectives
- π Key Features
- ποΈ High-Level Architecture
- π οΈ Technology Stack
- π Repository Structure
- π― Design Principles
- π Prerequisites
- βοΈ Project Configuration
- π Deploy the Application
- β Verification
- πΈ Screenshots
- π Documentation
- π£οΈ Roadmap
- π Learning Outcomes
- π€ Contributing
- π License
- π GitOps-based Continuous Deployment using Argo CD
- βΈοΈ Kubernetes-native WordPress and MySQL deployment
- π Automated synchronization with Git as the single source of truth
- π Secure secret management using AWS Secrets Manager
- π External Secrets Operator for dynamic Kubernetes Secret creation
- β‘ GitHub Actions CI pipeline
- β YAML linting with yamllint
- β Kubernetes manifest validation using kubeconform
- π‘οΈ Kubernetes security scanning with Checkov
- π NGINX Ingress for external application access
- πΎ Persistent storage for WordPress and MySQL
- β€οΈ Kubernetes readiness and liveness probes
- π Resource requests and limits
- π Modular Kubernetes manifest structure
- π Well-documented deployment process
| Property | Value |
|---|---|
| Project Name | GitOps WordPress Platform |
| Version | v1.0 |
| Status | Completed |
| Deployment Model | GitOps |
| CI | GitHub Actions |
| CD | Argo CD |
| Platform | Kubernetes |
| Cloud | AWS |
| Database | MySQL 8 |
| CMS | WordPress 6 |
| Secret Management | AWS Secrets Manager |
| Secret Synchronization | External Secrets Operator |
| Ingress | NGINX Ingress Controller |
| License | MIT |
This project demonstrates how to build a secure and automated Kubernetes application deployment pipeline using GitOps principles.
The main objectives are:
- Build a production-style GitOps workflow using Argo CD.
- Keep Kubernetes manifests under version control.
- Eliminate plaintext Kubernetes Secret manifests from Git.
- Store application secrets securely in AWS Secrets Manager.
- Automatically synchronize secrets into Kubernetes using External Secrets Operator.
- Validate Kubernetes manifests automatically through GitHub Actions.
- Perform Kubernetes security scanning during every code change.
- Demonstrate declarative application deployment using Kubernetes.
- Provide a reusable reference architecture for GitOps deployments.
- Showcase modern DevOps and Cloud Engineering practices.
- Git as the single source of truth
- Automatic synchronization using Argo CD
- Self-healing deployments
- Automatic reconciliation
- Declarative Kubernetes manifests
Every push to GitHub automatically triggers a CI pipeline.
The pipeline performs:
- YAML syntax validation
- Kubernetes manifest validation
- Security scanning
- Pull Request validation
This prevents invalid Kubernetes manifests from reaching the cluster.
Instead of storing sensitive credentials inside Git:
- AWS Secrets Manager securely stores application credentials.
- External Secrets Operator retrieves secrets dynamically.
- Kubernetes Secrets are generated automatically.
- WordPress and MySQL consume Kubernetes Secrets at runtime.
No plaintext credentials are committed to the repository.
The application uses standard Kubernetes resources including:
- Namespace
- Deployments
- Services
- PersistentVolumeClaims
- Ingress
- ExternalSecret resources
All resources are defined declaratively.
Persistent Volume Claims ensure application data survives Pod restarts.
Persistent storage is configured for:
- MySQL database
- WordPress application data
NGINX Ingress Controller provides external access to the application.
Features include:
- Host-based routing
- ClusterIP services
- Single entry point
- Kubernetes-native networking
The following diagram illustrates the complete deployment lifecycleβfrom committing code to GitHub to automatically deploying WordPress on Kubernetes while securely retrieving secrets from AWS Secrets Manager.
Developer
β
git push
β
βΌ
GitHub Repository
β
βΌ
GitHub Actions (CI Pipeline)
ββββββββββββββββββββΌβββββββββββββββββββ
β β β
βΌ βΌ βΌ
yamllint kubeconform Checkov
β β β
ββββββββββββββββββββ΄βββββββββββββββββββ
β
Validation Successful
β
βΌ
Argo CD
β
Automatic Synchronization
β
βΌ
Kubernetes API Server
β
ββββββββββββββββββββββββββΌβββββββββββββββββββββββββ
βΌ βΌ βΌ
Namespace WordPress MySQL
β β β
β ββββββββββββ¬ββββββββββββ
β βΌ
β Kubernetes Secrets
β β²
β β
βΌ External Secrets Operator
β
βΌ
AWS Secrets Manager
This project follows a GitOps deployment model, where Git is the single source of truth for the Kubernetes cluster.
Whenever a change is pushed to GitHub:
- GitHub Actions validates the Kubernetes manifests.
- The manifests are checked using:
- yamllint (YAML formatting)
- kubeconform (Kubernetes schema validation)
- Checkov (security best practices)
- If the repository passes validation, Argo CD continuously monitors the Git repository.
- Argo CD detects changes and synchronizes the Kubernetes cluster automatically.
- External Secrets Operator retrieves secrets from AWS Secrets Manager.
- WordPress and MySQL consume the generated Kubernetes Secrets.
This approach removes the need to manually run kubectl apply, ensuring the cluster always matches the desired state stored in Git.
The deployment workflow is completely Git-driven.
Developer
β
β Update Kubernetes Manifest
βΌ
Git Commit
β
βΌ
Git Push
β
βΌ
GitHub Repository
β
βΌ
Argo CD detects new commit
β
βΌ
Automatic Synchronization
β
βΌ
Kubernetes Cluster Updated
- Git becomes the single source of truth.
- No manual deployments.
- Automatic reconciliation.
- Easy rollback using Git history.
- Consistent deployments across environments.
Every code change is validated before it reaches the cluster.
Developer
β
βΌ
Git Push
β
βΌ
GitHub Actions
β
βββ Checkout Repository
βββ YAML Lint
βββ Kubernetes Validation
βββ Security Scan
β
βΌ
Validation Successful
| Tool | Purpose |
|---|---|
| GitHub Actions | Continuous Integration |
| yamllint | YAML formatting validation |
| kubeconform | Kubernetes schema validation |
| Checkov | Kubernetes security scanning |
Instead of committing Kubernetes Secret manifests to Git, this project stores secrets securely in AWS Secrets Manager.
Administrator
β
βΌ
Create Secrets
β
βΌ
AWS Secrets Manager
β
βΌ
External Secrets Operator
β
βΌ
Kubernetes Secret
β
ββββββββββββββββ
βΌ βΌ
WordPress Pod MySQL Pod
- Secrets never exist inside Git.
- Centralized secret management.
- Native Kubernetes Secret resources.
- IAM-based authentication.
- Easy secret rotation.
| Category | Technology | Purpose |
|---|---|---|
| Cloud Platform | AWS | Secret storage |
| Container Orchestration | Kubernetes | Container orchestration |
| GitOps | Argo CD | Continuous deployment |
| Version Control | Git | Source control |
| Repository Hosting | GitHub | Git repository |
| Continuous Integration | GitHub Actions | CI pipeline |
| YAML Validation | yamllint | YAML linting |
| Kubernetes Validation | kubeconform | Manifest validation |
| Security Scanning | Checkov | Kubernetes security analysis |
| Secret Management | AWS Secrets Manager | Secure credential storage |
| Secret Synchronization | External Secrets Operator | Create Kubernetes Secrets |
| Web Application | WordPress 6 | Content Management System |
| Database | MySQL 8 | Relational Database |
| Networking | NGINX Ingress Controller | External application access |
| Storage | PersistentVolumeClaims | Persistent storage |
| Configuration | YAML | Kubernetes manifests |
| Automation | Bash | AWS secret creation script |
gitops-wordpress-platform
β
βββ .github
β βββ workflows
β βββ validate-kubernetes.yml
β
βββ docs
β βββ architecture
β βββ architecture.md
β βββ deployment-guide.md
β βββ screenshots
β βββ troubleshooting.md
β
βββ kubernetes
β βββ argocd
β β βββ application.yaml
β β
β βββ ingress
β β βββ ingress.yaml
β β
β βββ mysql
β β βββ mysql-deployment.yaml
β β βββ mysql-pvc.yaml
β β βββ mysql-service.yaml
β β
β βββ namespace
β β βββ namespace.yaml
β β
β βββ secrets
β β βββ mysql-external-secret.yaml
β β βββ wordpress-external-secret.yaml
β β
β βββ wordpress
β βββ wordpress-deployment.yaml
β βββ wordpress-pvc.yaml
β βββ wordpress-service.yaml
β
βββ scripts
β βββ create-aws-secrets.sh
β
βββ .env.example
βββ .gitignore
βββ LICENSE
βββ README.md
| Directory | Description |
|---|---|
.github/workflows |
GitHub Actions CI workflow for validating Kubernetes manifests |
docs |
Project documentation, architecture diagrams, deployment guide and troubleshooting |
kubernetes/argocd |
Argo CD Application manifest |
kubernetes/namespace |
Creates the WordPress namespace |
kubernetes/mysql |
MySQL Deployment, Service and PersistentVolumeClaim |
kubernetes/wordpress |
WordPress Deployment, Service and PersistentVolumeClaim |
kubernetes/secrets |
ExternalSecret resources |
kubernetes/ingress |
NGINX Ingress configuration |
scripts |
Automation scripts for AWS Secrets Manager |
.env.example |
Example environment configuration |
README.md |
Project documentation |
This project follows several modern DevOps and cloud-native design principles.
Git is the single source of truth.
Every infrastructure or application change should be committed to Git instead of manually applying manifests with kubectl.
Benefits include:
- Version-controlled deployments
- Automatic synchronization
- Easy rollback
- Self-healing infrastructure
- Consistent environments
Sensitive credentials are never stored inside Git.
Instead:
- AWS Secrets Manager securely stores secrets.
- External Secrets Operator synchronizes secrets into Kubernetes.
- Kubernetes applications consume generated Secret resources.
This reduces the risk of accidentally exposing credentials in source control.
Every Kubernetes resource is defined as YAML.
Resources include:
- Namespace
- Deployments
- Services
- PersistentVolumeClaims
- Ingress
- ExternalSecret resources
- Argo CD Application
Declarative manifests make deployments reproducible and easy to audit.
Every push to GitHub automatically triggers a validation pipeline.
The pipeline checks:
- YAML syntax
- Kubernetes manifest correctness
- Security best practices
Only validated manifests are considered ready for deployment through GitOps.
Each Kubernetes component is organized into its own directory.
This improves:
- Readability
- Maintainability
- Reusability
- Collaboration
This project includes Checkov security scanning as part of the GitHub Actions CI pipeline.
Some Checkov recommendations (such as running containers as a non-root user, using a read-only root filesystem, or dropping all Linux capabilities) are intentionally not enforced in this project because the official WordPress and MySQL container images require elevated privileges during their initialization process.
These findings are reviewed and documented rather than ignored.
In a production environment, these recommendations can be addressed by:
- Using hardened or custom-built container images
- Running applications as non-root users
- Pinning container images by digest
- Mounting secrets as volumes instead of environment variables where supported
- Applying additional Pod Security Standards and runtime hardening
This project prioritizes demonstrating a functional GitOps workflow while documenting the security trade-offs of using the official container images.
Before deploying this project, ensure the following components are available.
A running Kubernetes cluster with:
- Kubernetes v1.30+
- Default StorageClass
- NGINX Ingress Controller
- Argo CD
- External Secrets Operator
- ClusterSecretStore configured for AWS Secrets Manager
Note
This repository only contains the application manifests. The Kubernetes infrastructure can be provisioned separately.
You need:
- AWS Account
- AWS CLI installed
- AWS CLI configured
- IAM user or role with access to AWS Secrets Manager
Verify AWS access:
aws sts get-caller-identityInstall the following tools:
| Tool | Purpose |
|---|---|
| Git | Clone the repository |
| kubectl | Kubernetes management |
| AWS CLI | Manage AWS Secrets Manager |
| Bash | Run automation scripts |
Verify installation:
git --version
kubectl version --client
aws --versiongit clone https://github.com/<YOUR_USERNAME>/gitops-wordpress-platform.git
cd gitops-wordpress-platformCreate your environment file.
cp .env.example .envExample:
AWS_REGION=us-east-1
MYSQL_ROOT_PASSWORD=root123
MYSQL_DATABASE=wordpress
MYSQL_USER=wordpress
MYSQL_PASSWORD=wordpress123
WORDPRESS_DB_HOST=mysql
WORDPRESS_DB_NAME=wordpress
WORDPRESS_DB_USER=wordpress
WORDPRESS_DB_PASSWORD=wordpress123
Run:
bash scripts/create-aws-secrets.shThe script automatically:
- Validates AWS credentials
- Creates secrets if they don't exist
- Updates existing secrets if already present
The following secrets are created:
wordpress/mysql
wordpress/app
Verify:
aws secretsmanager list-secretsOnce AWS Secrets Manager has been configured, deploy the application.
Apply the Argo CD Application:
kubectl apply -f kubernetes/argocd/application.yamlExpected output:
application.argoproj.io/wordpress-gitops created
Argo CD will automatically:
- Create the WordPress namespace
- Deploy MySQL
- Deploy WordPress
- Create Services
- Create PersistentVolumeClaims
- Synchronize External Secrets
- Generate Kubernetes Secrets
- Configure NGINX Ingress
No additional kubectl apply commands are required.
Clone Repository
β
βΌ
Configure .env
β
βΌ
Run create-aws-secrets.sh
β
βΌ
AWS Secrets Manager
β
βΌ
kubectl apply application.yaml
β
βΌ
Argo CD
β
βΌ
External Secrets Operator
β
βΌ
Kubernetes Secrets
β
βΌ
Deploy MySQL
β
βΌ
Deploy WordPress
β
βΌ
Configure Ingress
β
βΌ
Application Ready
Every push to the main branch automatically triggers GitHub Actions.
The pipeline performs:
- Checkout repository
- YAML linting
- Kubernetes manifest validation
- Kubernetes security scan
This prevents invalid manifests from reaching the GitOps repository.
Argo CD continuously monitors this repository.
Whenever a Kubernetes manifest changes:
Developer
β
git push
β
GitHub Repository
β
Argo CD detects changes
β
Automatic Synchronization
β
Kubernetes Cluster Updated
No manual deployment is required.
Git becomes the single source of truth.
After Argo CD synchronizes the application, verify each component to ensure the deployment completed successfully.
kubectl get nsExpected output:
NAME STATUS
wordpress Active
kubectl get pods -n wordpressExample:
NAME READY STATUS
mysql-xxxxxxxxxx-xxxxx 1/1 Running
wordpress-xxxxxxxxxx-xxxxx 1/1 Running
wordpress-xxxxxxxxxx-yyyyy 1/1 Running
wordpress-xxxxxxxxxx-zzzzz 1/1 Running
All Pods should eventually reach the Running state.
kubectl get svc -n wordpressExample:
NAME TYPE CLUSTER-IP
mysql ClusterIP
wordpress ClusterIP
kubectl get pvc -n wordpressExample:
NAME STATUS
mysql-pvc Bound
wordpress-pvc Bound
Both PVCs should be in the Bound state.
List ExternalSecret resources.
kubectl get externalsecret -n wordpressExample:
NAME STATUS
mysql-secret SecretSynced
wordpress-secret SecretSynced
Describe one of them:
kubectl describe externalsecret mysql-secret -n wordpressExpected:
Ready: True
Secret Synced
Repeat for the WordPress secret if required.
kubectl get secret -n wordpressExample:
mysql-secret
wordpress-secret
These Secrets should be created automatically by the External Secrets Operator.
List secrets:
aws secretsmanager list-secretsExpected:
wordpress/mysql
wordpress/app
Check the Argo CD Application.
kubectl get applications -n argocdExpected:
NAME SYNC STATUS HEALTH STATUS
wordpress-gitops Synced Healthy
Describe the application:
kubectl describe application wordpress-gitops -n argocdThe application should report:
- Healthy
- Synced
- No synchronization errors
kubectl get ingress -n wordpressExample:
NAME CLASS HOSTS
wordpress-ingress nginx wordpress
If using a local DNS entry, update your hosts file.
Linux/macOS:
/etc/hosts
Windows:
C:\Windows\System32\drivers\etc\hosts
Example:
<MASTER_PUBLIC_IP> wordpress
Open:
http://wordpress
You should see the WordPress installation page.
Open your GitHub repository.
Navigate to:
GitHub
β
Actions
The latest workflow should complete successfully.
The workflow validates:
- YAML syntax
- Kubernetes manifests
- Kubernetes security
A successful run confirms that the repository is ready for GitOps deployment.
One of the easiest ways to verify GitOps is working is to modify a deployment.
Example:
Change:
replicas: 3to:
replicas: 4Commit and push:
git add .
git commit -m "Scale WordPress deployment"
git pushArgo CD detects the new commit automatically.
Verify:
kubectl get pods -n wordpressYou should now see four WordPress Pods running.
No manual deployment command such as:
kubectl applyis required.
At this point the platform includes:
- β GitHub Actions CI
- β GitOps with Argo CD
- β WordPress
- β MySQL
- β AWS Secrets Manager
- β External Secrets Operator
- β Kubernetes Secrets
- β NGINX Ingress
- β Persistent Storage
- β Automated Kubernetes Validation
- β Security Scanning
The Kubernetes cluster is now managed declaratively through Git, with Argo CD continuously reconciling the desired state.
This walkthrough demonstrates the complete GitOps workflow of the project, from securely storing secrets in AWS Secrets Manager to automatic deployment, monitoring, and GitOps-based application scaling using Argo CD.
The GitOps repository contains Kubernetes manifests, GitHub Actions workflows, Argo CD configuration, monitoring resources, and project documentation.
Application and database credentials are securely stored in AWS Secrets Manager and synchronized into Kubernetes using External Secrets Operator.
After configuring AWS Secrets Manager, the GitOps application is deployed into the Kubernetes cluster.
Argo CD continuously watches the Git repository and keeps the Kubernetes cluster synchronized with the desired state stored in Git.
The complete application topology managed by Argo CD, including:
- Namespace
- Deployments
- ReplicaSets
- Pods
- Services
- Persistent Volume Claims
- External Secrets
- Kubernetes Secrets
- NGINX Ingress
Prometheus continuously collects Kubernetes metrics while Grafana visualizes CPU, memory, and network utilization.
Cluster-wide monitoring showing CPU usage, memory utilization, resource requests, and limits.
CPU utilization of WordPress and MySQL workloads inside the wordpress namespace.
Memory usage and resource limits for all application pods.
Real-time network bandwidth and packet metrics collected by Prometheus.
Example PromQL query showing live CPU usage metrics for WordPress pods.
One of the main objectives of this project is to demonstrate a complete GitOps workflow where Git serves as the single source of truth.
The following sequence shows how changing the desired state in Git automatically updates the Kubernetes cluster.
The replica count in the WordPress Deployment manifest is changed from 3 to 4.
replicas: 4The change is committed and pushed to GitHub.
Pushing to the repository automatically triggers the GitHub Actions workflow, which validates all Kubernetes manifests.
The CI pipeline successfully validates the Kubernetes manifests before deployment.
Argo CD detects the new Git commit, synchronizes the desired state, and Kubernetes automatically scales the deployment from 3 to 4 running WordPress pods.
Argo CD successfully synchronizes the latest Git commit, and the application topology now reflects the updated deployment with four running WordPress replicas.
After Argo CD synchronizes the latest Git commit, the WordPress application is successfully deployed and accessible through the configured NGINX Ingress.
The dashboard confirms that the application is running correctly, database connectivity is working, persistent storage is mounted, and the deployment is fully operational.
Developer
β
βΌ
Modify Kubernetes Manifest
β
βΌ
Git Commit
β
βΌ
Git Push
β
βΌ
GitHub Actions
(Validate Kubernetes YAML)
β
βΌ
Validation Success
β
βΌ
Argo CD Detects Git Change
β
βΌ
Automatic Synchronization
β
βΌ
Kubernetes Applies Changes
β
βΌ
Application Updated
β
βΌ
Prometheus Collects Metrics
β
βΌ
Grafana Visualizes Metrics
This project demonstrates a complete production-style GitOps workflow by integrating GitHub Actions, Argo CD, AWS Secrets Manager, External Secrets Operator, NGINX Ingress, Prometheus, and Grafana to automate deployment, synchronization, monitoring, and infrastructure management on Kubernetes.
This project demonstrates practical implementation of modern cloud-native technologies.
| Category | Implementation |
|---|---|
| GitOps | Argo CD |
| CI | GitHub Actions |
| Kubernetes Validation | kubeconform |
| YAML Validation | yamllint |
| Security Scanning | Checkov |
| Secret Management | AWS Secrets Manager |
| Secret Synchronization | External Secrets Operator |
| Kubernetes Networking | NGINX Ingress |
| Storage | PersistentVolumeClaims |
| Database | MySQL |
| Application | WordPress |
Additional documentation is available in the docs/ directory.
| File | Description |
|---|---|
architecture.md |
Project architecture |
deployment-guide.md |
Step-by-step deployment guide |
troubleshooting.md |
Common issues and fixes |
Future enhancements planned for this project.
- HTTPS using cert-manager
- Network Policies
- Pod Security Standards
- Image digest pinning
- Secret rotation
- Horizontal Pod Autoscaler (HPA)
- PodDisruptionBudget
- Pod Anti-Affinity
- StatefulSet for MySQL
- High Availability database deployment
- Grafana dashboards
- Prometheus alert rules
- Loki log aggregation
- Distributed tracing
- GitHub Actions
- YAML Validation
- Kubernetes Validation
- Security Scanning
- Automatic container image updates
This project demonstrates hands-on experience with:
- GitOps using Argo CD
- Kubernetes application deployment
- AWS Secrets Manager
- External Secrets Operator
- GitHub Actions CI
- Kubernetes manifest validation
- Kubernetes security scanning
- NGINX Ingress Controller
- Persistent storage
- Kubernetes Deployments and Services
- Infrastructure-independent application deployment
Contributions are welcome.
- Fork the repository.
- Create a feature branch.
git checkout -b feature/my-feature- Commit your changes.
git commit -m "feat: add new feature"- Push the branch.
git push origin feature/my-feature- Open a Pull Request.
This project is licensed under the MIT License.
See the LICENSE file for more information.
This application is designed to run on a Kubernetes platform.
Infrastructure for the cluster can be provisioned using a companion infrastructure repository or any Kubernetes cluster that includes:
- Kubernetes
- Argo CD
- External Secrets Operator
- NGINX Ingress Controller
- AWS Secrets Manager integration
Vijay VW
Cloud β’ DevOps β’ Kubernetes β’ AWS
- GitHub: https://github.com/vijayvw
- LinkedIn: (Add your LinkedIn profile here)
If you found this project helpful:
- β Star this repository
- π΄ Fork the project
- π’ Share it with others
Your support helps improve the project and encourages future development.
Made with β€οΈ by Vijay VW















