Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cloud-Native Observability Platform

Infrastructure-as-Code for a self-healing, observable Kubernetes platform on AWS EKS — provisioned end-to-end with Terraform, deployed via GitHub Actions, and monitored with the Prometheus/Grafana stack out of the box.

This is a portfolio reference implementation. It is written to be cloned and adapted, not run as-is against a real AWS account: every account-specific value (state bucket, role ARNs, cluster name) is left as a placeholder that you supply via .tfvars, backend.hcl, or repository/environment variables — none of it is hardcoded or committed.

What this demonstrates

Skill area Where
Infrastructure as Code terraform/ — modular VPC + EKS stack, remote state with locking, no manual console steps
Container orchestration k8s/ — namespaced workloads, health probes, topology-aware scheduling, Helm-managed add-ons
Monitoring & observability k8s/monitoring/ — Prometheus Operator, Alertmanager routing, provisioned Grafana dashboards, ServiceMonitor-based scrape discovery
CI/CD .github/workflows/ — OIDC-authenticated pipelines for both infra (terraform.yml) and application (deploy-app.yml) delivery
Security-conscious defaults private subnets for workloads, no static AWS keys, no committed secrets, least-privilege IAM per component

Architecture

See architecture/architecture.md for the full diagram and design rationale. In short:

  • A VPC with public subnets (NAT/IGW only) and private subnets (all compute).
  • An EKS cluster with a managed node group, provisioned entirely by the terraform/modules/eks module.
  • kube-prometheus-stack deployed via the Terraform Helm provider into a dedicated monitoring namespace.
  • A sample application in its own namespace, instrumented with a ServiceMonitor so it's scraped automatically.
  • Two GitHub Actions pipelines: one plans/applies infrastructure changes, the other builds and rolls out the application — both authenticate to AWS via OIDC, with zero long-lived credentials.

Repository layout

.
├── terraform/                  # IaC: VPC, EKS, and the monitoring Helm release
│   ├── modules/
│   │   ├── vpc/
│   │   └── eks/
│   ├── main.tf / variables.tf / outputs.tf / providers.tf
│   ├── terraform.tfvars.example
│   └── backend.hcl.example
├── k8s/
│   ├── namespaces.yaml
│   ├── monitoring/              # Prometheus + Grafana Helm values
│   └── sample-app/              # Example instrumented workload
├── .github/workflows/
│   ├── terraform.yml            # plan on PR, apply on merge to main
│   └── deploy-app.yml           # build image, deploy, verify rollout
├── docs/runbook.md              # secrets handling, DR, troubleshooting
└── architecture/architecture.md # diagram + design notes

Getting started

Prerequisites: Terraform ≥ 1.7, an AWS account, kubectl, and helm installed locally if you want to interact with the cluster outside of CI.

  1. Configure remote state (never commit this):

    cp terraform/backend.hcl.example terraform/backend.hcl
    # edit terraform/backend.hcl with your own bucket/table
  2. Set your variables:

    cp terraform/terraform.tfvars.example terraform/terraform.tfvars
    # edit values for your environment — none are sensitive by design
  3. Provision the platform:

    cd terraform
    terraform init -backend-config=backend.hcl
    terraform plan
    terraform apply
  4. Point kubectl at the new cluster (Terraform prints this command as an output):

    aws eks update-kubeconfig --name <cluster_name> --region <aws_region>
  5. Deploy the sample app and confirm it's being scraped:

    kubectl apply -f k8s/namespaces.yaml
    kubectl apply -f k8s/sample-app/
    kubectl -n monitoring port-forward svc/kube-prometheus-stack-grafana 3000:80
    # open http://localhost:3000 — dashboards are pre-provisioned

CI/CD

Both workflows in .github/workflows/ use GitHub's OIDC provider to assume a scoped IAM role — set the following as repository/environment configuration rather than secrets where possible:

Name Type Purpose
AWS_DEPLOY_ROLE_ARN secret IAM role the pipeline assumes (ARN only, not credentials)
AWS_REGION variable Target region
EKS_CLUSTER_NAME variable Cluster to deploy the sample app into

terraform.yml runs plan on every pull request touching terraform/** and apply on merge to main. deploy-app.yml builds and pushes an image to GHCR, then rolls it out with kubectl set image and waits on rollout status.

Operations

See docs/runbook.md for secret handling, credential rotation, common failure modes, and disaster-recovery notes.

Notes on adapting this for a hybrid environment

This reference focuses on a single-cloud (AWS) setup for clarity, but the same patterns extend to hybrid/multi-cloud:

  • Swap the vpc/eks modules for a kubernetes_cluster abstraction (e.g. via Cluster API) that can target on-prem vSphere/bare-metal alongside cloud providers.
  • Keep the monitoring layer (kube-prometheus-stack) identical — Prometheus federation or Thanos/Mimir can aggregate metrics across on-prem and cloud clusters into one Grafana.
  • Route CI/CD through a self-hosted runner for on-prem targets while keeping cloud-hosted GitHub runners for cloud targets, sharing the same workflow files via environment-scoped variables.

License

MIT — use freely as a reference or starting point.

About

Infrastructure-as-Code for a self-healing, observable Kubernetes platform on AWS EKS — provisioned end-to-end with Terraform, deployed via GitHub Actions, and monitored with the Prometheus/Grafana stack out of the box.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages