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
54 changes: 42 additions & 12 deletions .github/workflows/platform-validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,44 @@ jobs:
helm lint standardized-path/app -f platform/apps/app-b/stage/values.yaml
helm lint standardized-path/app -f platform/apps/app-b/prod/values.yaml

- name: Enforce immutable tags and revisions
run: |
set +e
has_error=0
for f in platform/apps/**/values.yaml argocd/**/*.yaml; do
[ -f "$f" ] || continue
if grep -qE 'tag:\s*"?latest"?' "$f" 2>/dev/null; then
echo "::error file=$f::Found 'latest' image tag — use an immutable version tag instead"
has_error=1
fi
if grep -qE 'targetRevision:\s*"?HEAD"?' "$f" 2>/dev/null; then
echo "::error file=$f::Found 'HEAD' revision — pin to an explicit branch or tag"
has_error=1
fi
done
# Also check per-environment values files explicitly
for f in platform/apps/dev/values.yaml platform/apps/stage/values.yaml platform/apps/prod/values.yaml platform/apps/app-b/dev/values.yaml platform/apps/app-b/stage/values.yaml platform/apps/app-b/prod/values.yaml; do
[ -f "$f" ] || continue
tag_val=$(grep -E '^\s+tag:' "$f" | sed 's/.*tag:\s*"\{0,1\}\([^"]*\)"\{0,1\}/\1/' | xargs)
if [ "$tag_val" = "latest" ]; then
echo "::error file=$f::Found 'latest' image tag — use an immutable version tag instead"
has_error=1
fi
done
exit $has_error

- name: Helm unit tests
run: helm unittest standardized-path/app

- name: Render manifests
run: |
helm template simple-app-dev standardized-path/app -f platform/apps/dev/values.yaml > /tmp/simple-app-dev.yaml
helm template simple-app-stage standardized-path/app -f platform/apps/stage/values.yaml > /tmp/simple-app-stage.yaml
helm template simple-app-prod standardized-path/app -f platform/apps/prod/values.yaml > /tmp/simple-app-prod.yaml
helm template app-b-dev standardized-path/app -f platform/apps/app-b/dev/values.yaml > /tmp/app-b-dev.yaml
helm template app-b-stage standardized-path/app -f platform/apps/app-b/stage/values.yaml > /tmp/app-b-stage.yaml
helm template app-b-prod standardized-path/app -f platform/apps/app-b/prod/values.yaml > /tmp/app-b-prod.yaml
IMG="--set image.repository=${{ vars.IMAGE_REPO || 'repo' }}"
helm template simple-app-dev standardized-path/app -f platform/apps/dev/values.yaml $IMG > /tmp/simple-app-dev.yaml
helm template simple-app-stage standardized-path/app -f platform/apps/stage/values.yaml $IMG > /tmp/simple-app-stage.yaml
helm template simple-app-prod standardized-path/app -f platform/apps/prod/values.yaml $IMG > /tmp/simple-app-prod.yaml
helm template app-b-dev standardized-path/app -f platform/apps/app-b/dev/values.yaml $IMG > /tmp/app-b-dev.yaml
helm template app-b-stage standardized-path/app -f platform/apps/app-b/stage/values.yaml $IMG > /tmp/app-b-stage.yaml
helm template app-b-prod standardized-path/app -f platform/apps/app-b/prod/values.yaml $IMG > /tmp/app-b-prod.yaml

- name: Validate manifests with kubeconform
run: |
Expand All @@ -128,12 +155,13 @@ jobs:

- name: Validate EKS manifests with OPA policies
run: |
helm template simple-app-dev standardized-path/app -f platform/apps/dev/values.yaml | tr -d '\r' | conftest test -p policy/eks/ --no-color -
helm template simple-app-stage standardized-path/app -f platform/apps/stage/values.yaml | tr -d '\r' | conftest test -p policy/eks/ --no-color -
helm template simple-app-prod standardized-path/app -f platform/apps/prod/values.yaml | tr -d '\r' | conftest test -p policy/eks/ --no-color -
helm template app-b-dev standardized-path/app -f platform/apps/app-b/dev/values.yaml | tr -d '\r' | conftest test -p policy/eks/ --no-color -
helm template app-b-stage standardized-path/app -f platform/apps/app-b/stage/values.yaml | tr -d '\r' | conftest test -p policy/eks/ --no-color -
helm template app-b-prod standardized-path/app -f platform/apps/app-b/prod/values.yaml | tr -d '\r' | conftest test -p policy/eks/ --no-color -
IMG="--set image.repository=${{ vars.IMAGE_REPO || 'repo' }}"
helm template simple-app-dev standardized-path/app -f platform/apps/dev/values.yaml $IMG | tr -d '\r' | conftest test -p policy/eks/ --no-color -
helm template simple-app-stage standardized-path/app -f platform/apps/stage/values.yaml $IMG | tr -d '\r' | conftest test -p policy/eks/ --no-color -
helm template simple-app-prod standardized-path/app -f platform/apps/prod/values.yaml $IMG | tr -d '\r' | conftest test -p policy/eks/ --no-color -
helm template app-b-dev standardized-path/app -f platform/apps/app-b/dev/values.yaml $IMG | tr -d '\r' | conftest test -p policy/eks/ --no-color -
helm template app-b-stage standardized-path/app -f platform/apps/app-b/stage/values.yaml $IMG | tr -d '\r' | conftest test -p policy/eks/ --no-color -
helm template app-b-prod standardized-path/app -f platform/apps/app-b/prod/values.yaml $IMG | tr -d '\r' | conftest test -p policy/eks/ --no-color -

openshift-validate:
runs-on: ubuntu-latest
Expand All @@ -148,6 +176,7 @@ jobs:
- name: Render with OpenShift flags
run: |
helm template test standardized-path/app \
--set image.repository=${{ vars.IMAGE_REPO || 'repo' }} \
--set openshift.enabled=true \
--set openshift.route.enabled=true \
--set ingress.enabled=false \
Expand All @@ -174,6 +203,7 @@ jobs:
- name: Validate OpenShift manifests with OPA policies
run: |
helm template test standardized-path/app \
--set image.repository=${{ vars.IMAGE_REPO || 'repo' }} \
--set openshift.enabled=true \
--set openshift.route.enabled=true \
--set ingress.enabled=false \
Expand Down
9 changes: 6 additions & 3 deletions .github/workflows/terraform-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@ jobs:

- name: Install Terrascan
run: |
TERRASCAN_VERSION=$(curl -s https://api.github.com/repos/tenable/terrascan/releases/latest | jq -r '.tag_name')
TERRASCAN_VERSION=${TERRASCAN_VERSION#v}
wget https://github.com/tenable/terrascan/releases/download/v${TERRASCAN_VERSION}/terrascan_${TERRASCAN_VERSION}_Linux_x86_64.tar.gz -O terrascan.tar.gz
TERRASCAN_VERSION=$(curl -s https://api.github.com/repos/tenable/terrascan/releases/latest | jq -r '.tag_name' 2>/dev/null | sed 's/^v//' || true)
if [ -z "$TERRASCAN_VERSION" ] || [ "$TERRASCAN_VERSION" = "null" ]; then
TERRASCAN_VERSION="1.18.0"
echo "API rate limited; falling back to Terrascan v${TERRASCAN_VERSION}"
fi
wget "https://github.com/tenable/terrascan/releases/download/v${TERRASCAN_VERSION}/terrascan_${TERRASCAN_VERSION}_Linux_x86_64.tar.gz" -O terrascan.tar.gz
tar -xf terrascan.tar.gz terrascan
rm terrascan.tar.gz
sudo install terrascan /usr/local/bin
Expand Down
67 changes: 40 additions & 27 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ help:
@echo ' kind-up Create Kind cluster'
@echo ' kind-down Delete Kind cluster'
@echo ' argocd-install Install Argo CD and apply AppProjects'
@echo ' deploy Apply platform bootstrap + add-ons + demo app'
@echo ' deploy Apply platform bootstrap (Argo CD reconciles add-ons and apps via GitOps)'
@echo ' test Run Helm unit tests'
@echo ' validate Run CI checks locally (Helm lint + test + conftest)'
@echo ' clean kind-down + remove tmp files'
Expand All @@ -43,13 +43,8 @@ argocd-install: kind-up

.PHONY: deploy
deploy:
@echo "=== Applying platform bootstrap ==="
kubectl apply -f platform/bootstrap/namespaces.yaml
kubectl apply -f platform/bootstrap/resource-quota.yaml
kubectl apply -f platform/bootstrap/limit-range.yaml
kubectl apply -f platform/bootstrap/network-policy.yaml
kubectl apply -f platform/bootstrap/rbac-readonly.yaml
kubectl apply -f platform/bootstrap/cluster-secret-store.yaml
@echo "=== Applying platform bootstrap (foundation for Argo CD) ==="
kubectl apply -f platform/bootstrap/

@echo "=== Creating platform secrets namespace ==="
kubectl create namespace platform-secrets --dry-run=client -o yaml | kubectl apply -f -
Expand All @@ -59,27 +54,25 @@ deploy:
--from-literal=db-password=$${DEV_DB_PASSWORD:-changeme} \
-n platform-secrets --dry-run=client -o yaml | kubectl apply -f -

@echo "=== Applying platform add-ons ==="
kubectl apply -f platform/addons/metrics-server.yaml
kubectl apply -f platform/addons/nginx-ingress.yaml
kubectl apply -f platform/addons/external-secrets.yaml
kubectl apply -f platform/addons/kube-prometheus-stack.yaml
kubectl apply -f platform/addons/grafana-dashboards-platform.yaml
@echo "=== Argo CD manages add-ons and apps via GitOps (app-of-apps) ==="
@echo " Root app: kubectl get application/root -n argocd"
@echo " Child apps: kubectl get applications -n argocd"
@echo ""

@echo "=== Deploying simple-app ==="
helm template simple-app-dev standardized-path/app \
-f platform/apps/dev/values.yaml \
--set image.repository=$(IMAGE_REPO) \
| kubectl apply -f - 2>&1 | grep -v 'unchanged' || true
@echo "=== Waiting for Argo CD to reconcile add-ons ==="
@for i in 1 2 3 4 5; do \
ready=$$(kubectl -n argocd get applications 2>/dev/null | tail -n+2 | wc -l); \
[ "$$ready" -gt 0 ] && break; \
sleep 3; \
done
kubectl get applications -n argocd 2>/dev/null || echo "(Argo CD syncing add-ons and apps)"

@echo "=== Deploying app-b ==="
helm template app-b-dev standardized-path/app \
-f platform/apps/app-b/dev/values.yaml \
--set image.repository=$(IMAGE_REPO) \
| kubectl apply -f - 2>&1 | grep -v 'unchanged' || true

@echo "=== App status ==="
kubectl get pods -n dev --show-labels
@echo ""
@echo "=== Pod status ==="
@for ns in dev stage prod; do \
echo "--- $$ns ---"; \
kubectl get pods -n $$ns --show-labels 2>/dev/null || echo "(no pods yet - Argo CD is syncing)"; \
done

.PHONY: test
test:
Expand All @@ -88,28 +81,48 @@ test:

.PHONY: validate
validate: test
@echo "=== Immutable tags and revisions ==="
@for f in platform/apps/**/values.yaml; do \
[ -f "$$f" ] || continue; \
tag_val=$$(grep -E '^\s+tag:' "$$f" | sed 's/.*tag:\s*"\{0,1\}\([^"]*\)"\{0,1\}/\1/' | xargs); \
if [ "$$tag_val" = "latest" ]; then \
echo " FAIL: $$f uses 'latest' tag"; exit 1; \
fi; \
done
@for f in argocd/**/*.yaml; do \
[ -f "$$f" ] || continue; \
if grep -qE 'targetRevision:\s*"?HEAD"?' "$$f" 2>/dev/null; then \
echo " FAIL: $$f uses 'HEAD' revision"; exit 1; \
fi; \
done
@echo " PASS"

@echo "=== Helm lint ==="
helm lint standardized-path/app -f platform/apps/dev/values.yaml
helm lint standardized-path/app -f platform/apps/stage/values.yaml
helm lint standardized-path/app -f platform/apps/prod/values.yaml

@echo "=== ServiceMonitor renders ==="
helm template simple-app-dev standardized-path/app -f platform/apps/dev/values.yaml \
--set image.repository=$(IMAGE_REPO) \
| grep -q "kind: ServiceMonitor" && echo " PASS: ServiceMonitor present"

@echo "=== OpenShift path renders correctly ==="
helm template test standardized-path/app \
--set image.repository=$(IMAGE_REPO) \
--set openshift.enabled=true \
--set openshift.route.enabled=true \
--set ingress.enabled=false \
| grep -q "kind: Route" && echo " PASS: Route present"

@echo "=== OPA policy: EKS manifests ==="
helm template simple-app-dev standardized-path/app -f platform/apps/dev/values.yaml \
--set image.repository=$(IMAGE_REPO) \
| tr -d '\r' | conftest test -p policy/eks/ --no-color -

@echo "=== OPA policy: OpenShift manifests ==="
helm template test standardized-path/app \
--set image.repository=$(IMAGE_REPO) \
--set openshift.enabled=true \
--set openshift.route.enabled=true \
--set ingress.enabled=false \
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ Every app deployed through the platform contract automatically gets a ServiceMon
## What I'd do next

- Add OPA/Gatekeeper policies for platform-level validation beyond what SCC provides
- Replace `legacy/` assets with a clean `examples/` directory
- Replaced `legacy/` assets with a clean `archive/` directory

---

Expand Down
Empty file added archive/legacy/ansible/ansible
Empty file.
29 changes: 29 additions & 0 deletions archive/legacy/ansible/ansible-inventory.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
resource "local_file" "ansible_inventory" {
count = var.enable_ansible ? 1 : 0

content = <<-EOT
[eks_nodes]
%{for ip in module.eks.worker_node_ips}
${ip} ansible_user=ec2-user
%{endfor}

[eks_nodes:vars]
ansible_ssh_common_args='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
EOT

filename = "${path.module}/inventory"
}

resource "null_resource" "ansible_playbook_runner" {
count = var.enable_ansible ? 1 : 0

depends_on = [local_file.ansible_inventory, module.eks]

provisioner "local-exec" {
command = "ansible-playbook -i inventory ansible-playbook.yml"
}

triggers = {
always_run = "${timestamp()}"
}
}
65 changes: 65 additions & 0 deletions archive/legacy/ansible/ansible-playbook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
- name: Configure EKS Worker Nodes
hosts: eks_nodes
become: yes

tasks:
- name: Update all packages
yum:
name: '*'
state: latest
update_only: yes

- name: Install required packages
yum:
name:
- docker
- git
- jq
- python3
- python3-pip
state: present

- name: Start and enable Docker service
systemd:
name: docker
state: started
enabled: yes

- name: Install AWS CLI
pip:
name: awscli
executable: pip3
state: present

- name: Install kubectl
get_url:
url: https://storage.googleapis.com/kubernetes-release/release/v1.23.6/bin/linux/amd64/kubectl
dest: /usr/local/bin/kubectl
mode: '0755'

- name: Create .kube directory
file:
path: /home/ec2-user/.kube
state: directory
owner: ec2-user
group: ec2-user
mode: '0755'

- name: Configure kubelet service
copy:
content: |
[Service]
Environment="KUBELET_EXTRA_ARGS=--node-labels=node.kubernetes.io/worker=true"
dest: /etc/systemd/system/kubelet.service.d/20-worker-labels.conf
owner: root
group: root
mode: '0644'
notify: Restart kubelet

handlers:
- name: Restart kubelet
systemd:
name: kubelet
state: restarted
daemon_reload: yes
6 changes: 6 additions & 0 deletions archive/legacy/ansible/ansible.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[defaults]
inventory = ./inventory
host_key_checking = False
remote_user = ec2-user
private_key_file = ~/.ssh/id_rsa
roles_path = ./roles
Loading
Loading