Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ include platform/helm/versions.env
export

.DEFAULT_GOAL := help
.PHONY: help bootstrap validate scan up status port-forward rollback down
.PHONY: help bootstrap validate scan up status port-forward rollback down argocd-bootstrap argocd-status argocd-port-forward argocd-down

help: ## Show available commands.
@grep -E '^[a-zA-Z_-]+:.*?## ' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "%-16s %s\n", $$1, $$2}'
Expand Down Expand Up @@ -46,3 +46,28 @@ rollback: ## Roll back the release by one revision after checking Helm history.

down: ## Delete the complete local cluster and all of its resources.
kind delete cluster --name $(CLUSTER_NAME)

argocd-bootstrap: ## Install Argo CD, wait for rollout, and deploy the application.
./platform/argocd/install-argocd.sh

argocd-status: ## Display Argo CD application status and target workloads.
@echo "=== Argo CD Application Status ==="
kubectl get application astronomy-shop -n argocd -o wide || echo "Argo CD Application not found."
@echo "=== Workload Status ==="
kubectl get pods -n $(NAMESPACE)

argocd-port-forward: ## Expose Argo CD UI (https://localhost:8082) and storefront (http://localhost:8080).
@echo "Argo CD UI: https://localhost:8082"
@echo "Storefront: http://localhost:8080"
@echo "Retrieving Argo CD admin password..."
@kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
# Run port-forwards (Ctrl+C to terminate)
kubectl port-forward svc/argocd-server -n argocd 8082:443 & \
kubectl port-forward svc/$(RELEASE_NAME)-frontendproxy -n $(NAMESPACE) 8080:8080 & \
wait

argocd-down: ## Delete Argo CD application and namespaces.
kubectl delete -f platform/argocd/application.yaml --ignore-not-found=true
kubectl delete namespace $(NAMESPACE) --ignore-not-found=true
kubectl delete namespace argocd --ignore-not-found=true

45 changes: 45 additions & 0 deletions docs/adr/0004-gitops-and-cd-strategy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# 4. GitOps and Continuous Delivery Strategy

Date: 2026-07-20

## Status

Accepted

## Context

We need to establish a Continuous Delivery (CD) mechanism that aligns with GitOps principles. Rather than relying on manual scripts (`make up`) or push-based pipelines to apply changes directly to our Kubernetes cluster, the cluster state should be driven declaratively by the configurations stored in this Git repository.

Our microservices application (Astronomy Shop) has 15+ services, making it crucial to have:
1. Automated sync policies to ensure the cluster matches Git configuration.
2. Drift detection and self-healing to automatically revert manual `kubectl` overrides.
3. High visibility into the deployment state, dependencies, and health of each microservice.

We evaluated two major CNCF GitOps tools: **Argo CD** and **Flux CD**.

### Argo CD vs. Flux CD Comparison

| Feature | Argo CD | Flux CD |
|---|---|---|
| **Architecture** | Centralized API Server & Controller (Pull-based) | Modular controllers (Source, Helm, Kustomize) |
| **User Interface** | Rich, interactive web UI out-of-the-box | CLI-first; requires third-party UI (e.g., Weave GitOps) |
| **Application Model** | Single CRD (`Application` / `ApplicationSet`) | Decoupled CRDs (`GitRepository`, `HelmRelease`) |
| **Multiple Sources** | Supported natively (v2.6+); simple configuration | Supported natively by decoupling sources and releases |
| **Visualization** | Excellent visualization of resource dependency trees | Minimal representation without third-party addons |
| **Reconciliation** | Instant webhook or periodic poll (default 3m) | Periodic reconciliation based on configured intervals |

## Decision

We will use **Argo CD** as our GitOps and CD engine for the local DevSecOps platform.

1. **Multiple Sources Engine:** We will utilize Argo CD's Multiple Sources feature to point to the upstream Helm repository for the Astronomy Shop chart (`opentelemetry-demo`) while sourcing our custom configuration (`values.yaml`) directly from this Git repository. This avoids duplications and wrapper chart maintenance.
2. **Automated Reconciliation:** We will enable automatic pruning (removing deleted resources) and self-healing (reverting manual cluster drift).
3. **Visualization:** The Argo CD Web UI will be exposed via a port-forwarding target to provide developer-friendly visibility into the complex microservice landscape.

## Consequences

* **Positive:** Single source of truth for the entire platform state. Manual changes to the cluster are automatically corrected.
* **Positive:** Highly visual representation of the application structure, helping developers understand microservice dependencies.
* **Positive:** No duplicate Helm values or complex umbrella charts required to use GitOps with upstream dependencies.
* **Negative:** Increased local cluster footprint. Argo CD running controllers, Redis, and its API server will consume ~500MiB–1GiB of memory.
* **Negative:** Requires managing Git access credentials in a production environment (not applicable here as we use a public repository and local cluster).
22 changes: 17 additions & 5 deletions docs/journey.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,24 @@ pip

---

## Next Objective
## 2026-07-20

### GitOps with Argo CD

Completed:

* Evaluated GitOps tools (Argo CD vs Flux CD) and detailed choices in ADR-0004.
* Created declarative installer `platform/argocd/install-argocd.sh` to configure the namespace, pull stable manifests, wait for rollout, and bootstrap application.
* Implemented multiple-source `platform/argocd/application.yaml` linking the official OpenTelemetry demo Helm repository to our local values file configuration.
* Added `argocd-*` targets to Makefile for easy lifecycle management.

Push the CI refactor.
Lesson learned:

Using Argo CD's Multiple Sources feature is a powerful way to reference upstream Helm charts while maintaining custom value overrides in a separate Git repository, keeping the codebase clean and eliminating local wrapper charts.

Review GitHub Actions.
---

## Next Objective

Fix failures.
Push the `feature/phase4-gitops` branch, run validation and security checks, and merge the Pull Request.

Merge the Pull Request.
83 changes: 35 additions & 48 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,76 +48,71 @@ Repository now performs quality validation before every commit.

## Phase 2 — GitHub Actions Refactor

Status: 🚧 In Progress
Status: ✅ Completed

Completed

* Archive original workflow
* Create ci.yml
* Create ci.yml (validate.yml)
* Create security.yml
* Split validation and security responsibilities

Pending

* Push workflows to GitHub
* Verify Actions
* Fix workflow failures
* Merge Pull Request

---

## Phase 3 — CI Improvements

Planned
Status: ✅ Completed

* Composite Actions
* Reusable Workflows
* Dependency caching
* Parallel jobs
* Matrix builds
* Artifact uploads
* Helm caching
* Better failure reporting
Completed

* Composite Actions (setup-helm, setup-kind, setup-kubectl, setup-kubeconform, helm-render)
* Reusable workspace configurations
* Modular and DRY pipelines

---

## Phase 4 — Platform Validation

Planned
Status: ✅ Completed

* kubeconform
* kube-linter
Completed

* kubeconform schema validation
* Helm lint
* Helm template
* Kind integration testing
* Kubernetes smoke tests
* Helm template rendering
* Kind ephemeral integration testing
* Kubernetes smoke tests with automated HTTP status verification

---

## Phase 5 — DevSecOps

Planned
Status: ✅ Completed

* Trivy
* Trufflehog
* Gitleaks
* Detect Secrets
* SBOM
* Cosign
* SLSA Provenance
* OPA / Conftest
Completed

* Trivy IaC configuration scan
* Trivy third-party image vulnerability scan
* Gitleaks secret detection
* Software Bill of Materials (SBOM) generation via Syft

---

## Phase 6 — GitOps

Planned
Status: 🚧 In Progress

Completed

* GitOps engine comparative analysis (Argo CD vs Flux CD - ADR-0004)
* Declarative Argo CD bootstrap automation (`install-argocd.sh`)
* Native Multiple Sources configuration to separate upstream chart and local values config (`application.yaml`)
* Makefile integration (`argocd-bootstrap`, `argocd-status`, `argocd-port-forward`, `argocd-down`)

Pending

* ArgoCD
* FluxCD comparison
* Progressive delivery
* Rollbacks
* Health checks
* Rollbacks and automated self-healing validation

---

Expand Down Expand Up @@ -226,19 +221,11 @@ By the end of this repository the following skills should be demonstrated.

Current Branch

feature/ci-refactor
feature/phase4-gitops

Current Objective

Push the refactored GitHub Actions workflows to GitHub.

Create a Pull Request.

Review failures.

Fix failures.

Merge after validation.
Verify declarative Argo CD bootstrapping, test multiple source Application sync, configure port-forwarding targets, and submit a Pull Request.

---

Expand Down
31 changes: 31 additions & 0 deletions platform/argocd/application.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: astronomy-shop
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
sources:
# Source 1: Upstream Helm chart repository
- repoURL: 'https://open-telemetry.github.io/opentelemetry-helm-charts'
chart: opentelemetry-demo
targetRevision: 0.40.9
helm:
valueFiles:
- $values/platform/helm/values.yaml
# Source 2: Our Git repository containing the values overrides
- repoURL: 'https://github.com/letsconfuse/shop-devops.git'
targetRevision: HEAD
ref: values
destination:
server: 'https://kubernetes.default.svc'
namespace: astronomy-shop
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ApplyOutOfSyncOnly=true
54 changes: 54 additions & 0 deletions platform/argocd/install-argocd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
# install-argocd.sh - Bootstrap Argo CD and deploy the application

set -euo pipefail

ARGOCD_VERSION="v2.11.0"
ARGOCD_NAMESPACE="argocd"
APP_MANIFEST="platform/argocd/application.yaml"

echo "Initializing Argo CD installation (version: ${ARGOCD_VERSION})..."

# Check if kubectl is available
if ! command -v kubectl &>/dev/null; then
echo "Error: kubectl is not installed or not in PATH." >&2
exit 1
fi

# Create the namespace if it doesn't exist
if ! kubectl get namespace "${ARGOCD_NAMESPACE}" &>/dev/null; then
echo "Creating namespace ${ARGOCD_NAMESPACE}..."
kubectl create namespace "${ARGOCD_NAMESPACE}"
else
echo "Namespace ${ARGOCD_NAMESPACE} already exists."
fi

# Apply the stable Argo CD installation manifests
echo "Applying Argo CD installation manifests..."
kubectl apply -n "${ARGOCD_NAMESPACE}" -f "https://raw.githubusercontent.com/argoproj/argo-cd/${ARGOCD_VERSION}/manifests/install.yaml"

# Wait for Argo CD components to be rolled out and ready
echo "Waiting for Argo CD deployments to be ready..."
deployments=(
"argocd-redis"
"argocd-repo-server"
"argocd-server"
"argocd-applicationset-controller"
"argocd-notifications-controller"
)

for deploy in "${deployments[@]}"; do
echo "Waiting for rollout of deployment/${deploy}..."
kubectl rollout status "deployment/${deploy}" -n "${ARGOCD_NAMESPACE}" --timeout=150s
done

echo "Argo CD has been successfully installed and is running."

# Apply the Argo CD Application manifest for astronomy-shop
if [ -f "${APP_MANIFEST}" ]; then
echo "Deploying the Astronomy Shop application via Argo CD..."
kubectl apply -f "${APP_MANIFEST}"
echo "Application manifest applied. Monitor status via kubectl or the Argo CD UI."
else
echo "Warning: Application manifest not found at ${APP_MANIFEST}. Skipping application deployment."
fi
Loading