Cloud-Pulse: En Komplett Guide (DevOps & Cloud)
January 31, 202612 min read

Cloud-Pulse: En Komplett Guide (DevOps & Cloud)

How I built a self-healing AWS infrastructure with Terraform, Ansible, and Docker.

AWSTerraformAnsibleDockerPrometheusGrafana

Cloud-Pulse: A Resilient "Ops-in-a-Box" Platform

Föreställ dig en server som inte bara kraschar när den blir överbelastad, utan som känner av smärtan och visuellt signalerar! Den är automatiskt övervakad, "self-aware" om sin hälsa, och reagerar dynamiskt på sin egen status.

Projektets Mål

  1. Ops-in-a-Box: Fullständig automatisering från tom AWS-miljö till driftklar applikation med ett enda kommando.
  2. Observability: Implementera djup övervakning (Metrics) för att se infrastrukturens "puls" i realtid.
  3. Chaos Engineering: Simulera verkliga katastrofscenarion (CPU-spikar) och bevisa systemets stabilitet.
  4. Self-Awareness: Webbsidan ska reagera dynamiskt på serverns hälsa.

Arkitektur & Tech Stack

Systemet är byggt enligt Day 2 Operations-principer (fokus på drift och underhåll).

Cloud-Pulse Architecture

Verktyg

  • AWS (EC2, VPC, Security Groups): Molnleverantör. Region: eu-north-1 (Stockholm).
  • Terraform: Infrastructure as Code - bygger VPC, subnets, security groups och EC2-instansen.
  • Ansible: Configuration Management - installerar Docker, Nginx, Prometheus, Grafana.
  • Docker Compose: Kör monitoring-stacken (Prometheus + Grafana + Node Exporter).
  • Python (psutil): status_monitor.py - hjärnan som övervakar CPU och byter HTML.
  • Nginx: Webbserver som visar den dynamiska statussidan.

Projektstruktur

cloud-pulse/
├── terraform/              # Skapar Infrastrukturen
│   ├── modules/            # Modulär kod
│   │   ├── compute/        # EC2-instans
│   │   ├── networking/     # VPC, Subnet, Internet Gateway
│   │   └── security/       # Security Groups
│   └── main.tf             # Huvudfilen som binder ihop allt
│
├── ansible/                # Konfigurerar Servern
│   ├── roles/
│   │   ├── common/         # Baspaket (curl, htop, git)
│   │   ├── docker/         # Docker + Docker Compose
│   │   ├── monitoring/     # Prometheus, Grafana, Node-Exporter
│   │   └── web/            # Nginx + Self-Healing Script
│   ├── inventory.ini       # Pekar på vår EC2-instans (auto-genererad)
│   └── setup.yml           # Playbook som kör allt
│
└── README.md

Del 1: Terraform - Infrastructure as Code

Terraform låter oss beskriva hela infrastrukturen i kod. Ingen manuell klickning i AWS-konsolen. Om något går fel, ändrar vi en rad och kör terraform apply igen.

Modulär Arkitektur

Filen main.tf styr hela orkestern med tre moduler som pratar med varandra:

module "networking" {
  source = "./modules/networking"
  # Skapar VPC, Subnet, Internet Gateway, Route Tables
}

module "security" {
  source     = "./modules/security"
  vpc_id     = module.networking.vpc_id  # ← Beroendekedja!
  vpc_cidr   = module.networking.vpc_cidr
  # Skapar Security Groups med rätt regler
}

module "compute" {
  source           = "./modules/compute"
  subnet_id        = module.networking.subnet_id
  security_group_id = module.security.web_sg_id
  # Skapar EC2-instansen
}

Security Groups - Dual Stack

En viktig lärdom: moderna ISP:er använder ofta IPv6. Vi måste stödja Dual Stack:

ingress {
  description      = "SSH Access"
  from_port        = 22
  to_port          = 22
  protocol         = "tcp"
  cidr_blocks      = ["0.0.0.0/0"]    # IPv4
  ipv6_cidr_blocks = ["::/0"]         # IPv6 ← VIKTIGT!
}

ingress {
  description = "Node Exporter - VPC internal only"
  from_port   = 9100
  to_port     = 9100
  protocol    = "tcp"
  cidr_blocks = [var.vpc_cidr]  # ← Endast intern trafik
  # Känslig data ska INTE exponeras mot internet
}

Automatisk Inventory

inventory.tf löser "IP-problemet" automatiskt:

resource "local_file" "ansible_inventory" {
  content = templatefile("inventory.tpl", {
    web_ip      = aws_instance.web.public_ip
    private_key = var.private_key_path
  })
  filename = "../ansible/inventory.ini"
}

Resultatet? Du behöver aldrig kopiera och klistra in IP-adresser manuellt.

Del 2: Ansible - Configuration Management

Terraform gav oss ett tomt hus (Ubuntu-server). Ansible fyller det med möbler (mjukvara).

Roller (Roles)

  • common: Installerar baspaket - curl, htop, git, python3-pip
  • docker: Installerar Docker + Docker Compose, startar tjänsten
  • monitoring: Deployer docker-compose.yml med Prometheus, Grafana, Node Exporter
  • web: Installerar Nginx, kopierar HTML-filer, installerar status_monitor.py som systemd-tjänst

Idempotence

En viktig princip: Ansible-tasks ska kunna köras 100 gånger utan att förstöra något. Vi använder handlers för att bara starta om tjänster när konfiguration faktiskt ändras:

- name: Copy nginx config
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/sites-available/default
  notify: Restart nginx  # ← Bara om filen ändras

handlers:
  - name: Restart nginx
    service:
      name: nginx
      state: restarted

Del 3: "The Magic Loop" - Event-Driven Automation

Det unika med Cloud-Pulse är hur komponenterna pratar med varandra under en incident:

  1. Incident: Vi injicerar kaos med stress-ng (100% CPU-last)
  2. Detektion: status_monitor.service upptäcker att CPU-lasten överstiger 80%
  3. Reaktion: Tjänsten byter automatiskt ut Nginx-landningssidan från GRÖN → RÖD
  4. Visualisering: Grafana visar exakt vad som händer under huven
  5. Återhämtning: När lasten sjunker, återställer systemet sig själv till grönt
# status_monitor.py (förenklad)
import psutil
import shutil
import time

THRESHOLD = 80
GREEN_PAGE = "/var/www/html/index_ok.html"
RED_PAGE = "/var/www/html/index_critical.html"
LIVE_PAGE = "/var/www/html/index.html"

while True:
    cpu = psutil.cpu_percent(interval=1)
    
    if cpu > THRESHOLD:
        shutil.copy(RED_PAGE, LIVE_PAGE)   # CRITICAL
    else:
        shutil.copy(GREEN_PAGE, LIVE_PAGE)  # OK
    
    time.sleep(1)

Event-Driven Automation: Inget larm behövde skickas till en människa. Systemet ändrade sitt eget beteende baserat på sin hälsa.

Hur man kör projektet

Steg 1: Bygg Infrastruktur (Terraform)

cd terraform
terraform init
terraform plan
terraform apply  # Skapar VPC, EC2, Security Groups

Steg 2: Konfigurera Servern (Ansible)

cd ../ansible
ansible-playbook -i inventory.ini setup.yml

Steg 3: The Chaos Demo

# SSH in på servern
ssh -i key.pem ubuntu@<EC2-IP>

# Starta kaos (100% CPU i 60 sekunder)
stress-ng --cpu 2 --timeout 60s

# Öppna webbläsaren och se sidan gå från GRÖN → RÖD → GRÖN

Lärdomar & Utmaningar

1. Säkerhet & Nätverk (Dual Stack)

Utmaning: SSH fungerade inte pga. att min ISP använder IPv6.

Lösning: Byggde Security Groups för Dual Stack (0.0.0.0/0 + ::/0).

2. Idempotence i Ansible

Lärdom: Skriv tasks som kan köras 100 gånger utan att förstöra något. Använd handlers för att bara starta om tjänster när konfiguration faktiskt ändras.

3. Terraform State

Lärdom: Terraform håller koll på resurser via terraform.tfstate. Använd terraform state show för att inspektera resurser manuellt.

4. Från "Static" till "Self-Aware"

Utmaning: En statisk HTML-sida visar inte om servern håller på att brinna upp.

Lösning: Ett Python-script med psutil agerar brygga mellan systemkärnan och presentationslagret.

Framtid (Next Steps)

Cloud-Pulse är ett fantastiskt Proof-of-Concept. I produktion skulle vi lägga till:

  • Auto Scaling Group + ALB: Självläkande flotta istället för enskild server
  • ChatOps Alerting: Webhook till Slack/Teams vid incidenter
  • HTTPS + VPN: Grafana bakom säker tunnel med OAuth
  • Managed Services: AWS CloudWatch istället för self-hosted Prometheus
  • Terraform Remote State: S3 + DynamoDB för state-locking i team

Enjoyed this article?