Top 5 Tips for Keeping a Learner AWS Account on Free Tier at Minimum Costs

Watch your storage like a hawk

    • EBS → Stay within 30 GB total for all volumes combined.
    • S3 → Keep under 5 GB or set lifecycle rules to auto-delete old files.
    • Delete unused volumes and snapshots — stopping an instance isn’t enough.
    • Pro tip: Use one volume per instance when possible.

    Track your compute hours

    • 750 hours/month = one free-tier-eligible instance running 24/7.
    • More instances = hours add up across all VMs.
    • Run extra VMs for short bursts and stop when not in use.

    Avoid “premium” services unless testing briefly

    • Some AWS services have no free tier: NAT Gateways, Load Balancers, some RDS setups,
      Provisioned IOPS volumes.
    • Spin up, test, and delete the same day to avoid charges.

    Clean up aggressively

    • Delete unused EBS volumes, snapshots, AMIs, idle Elastic IPs.
    • Remove old CloudWatch logs.
    • AWS charges for provisioned resources, even if idle.

    Use the AWS Budgets & Billing Alarms

    • Set a $1–$2 monthly budget alert in AWS Billing → Budgets.
    • Alerts you early if you exceed free tier limits.
    • Prevents surprises like a forgotten NAT Gateway burning $20/month.

    Extra learner hack: Keep one main free-tier t3.micro/t2.micro running 24/7 for your baseline lab, and spin up larger instances only when actively testing — delete them afterward. Your $100 credit will then go only toward high-power bursts, not slow leaks.

    Uptime Kuma este un tool dragut de monitorizare, face automat rapoarte SLA, monitorizeaza site-uri, este destul de util. Pentru a monitoriza ill.ro folosesc altceva (UptimeRobot), m-am gandit sa fie independent de homelab, ca daca pica homelab-ul nu mai imi zice nimeni ca a cazut site-ul…
    Voi folosi ArgoCD pentru a testa si invata cum functioneaza acest tool… l-am instalat si pana acum e doar o interfata web… Asadar sa instalam cu ArgoCD.

    Pentru pasii astia avem niste prerechizite:
    1. Un share nfs pentru persistent storage (il foloseste uptime kuma ca sa tina minte tot ce face)
    2. Un cont de github sau orice repo, eu o sa folosesc github ca inca nu am deployat asa ceva in homelab.
    3. metalLB functional 🙂

    1. Mai intai share-ul NFS: am folosit v3 pentru simplitate, am permis accesul full din reteaua de acasa, desigur in afara homelab-ului vom avea autentificare si altele. Am creat un share numit uptime-kuma.

    Pe nodurile k8s (control/worker) vom instala nfs-common si testam daca share-ul nfs este disponibil si putem scrie pe el.

    apt install -y nfs-common
    mkdir /mnt/test-nfs
    mount -t nfs -o nfsvers=3 IP_NFS:/uptime-kuma /mnt/test-nfs
    touch testnfs
    cd /mnt/test-nfs && ls

    Ar trebui sa vedem fisierul. Daca e acolo, inseamna ca nodurile noastre pot accesa NFS, trecem mai departe.

    2. Github. Facem un nou repo, o sa il numesc argoCD si vom crea intr-un director nou urmatoarele fisiere:

    Prima oara facem un namespace, fisierul uptimekuma-namespace.yaml.

    apiVersion: v1
    kind: Namespace
    metadata:
      name: uptime-kuma

    Definim un persistent volume – uptimekuma-pv.yaml

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: nfs-pv-uptime-kuma
    spec:
      capacity:
        storage: 10Gi
      volumeMode: Filesystem
      accessModes:
        - ReadWriteMany
      persistentVolumeReclaimPolicy: Retain
      storageClassName: slow
      mountOptions:
        - hard
        - nfsvers=3
      nfs:
        path: /uptime-kuma
        server: IP_NFS #adresa ip a serverului nfs

    Persistent volume claim uptimekuma-pvclaim.yaml

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: uptime-kuma-pvc
      namespace: uptime-kuma
    spec:
      accessModes:
        - ReadWriteMany
      volumeMode: Filesystem
      resources:
        requests:
          storage: 1Gi
      storageClassName: slow

    Definim serviciul – uptimekuma-service.yaml

    apiVersion: v1
    kind: Service
    metadata:
      name: uptime-kuma-tcp
      namespace: uptime-kuma
    spec:
      type: LoadBalancer #nu specificam ip, lasam metallb sa aleaga pentru noi
      ports:
      - name: web-ui
        protocol: TCP
        port: 3001
        targetPort: 3001
      selector:
        app: uptime-kuma
    

    Si in final, deployment-ul uptimekuma-deplyment.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: uptime-kuma
      namespace: uptime-kuma
    spec:
      selector:
        matchLabels:
          app: uptime-kuma
      replicas: 1
      strategy:
        type: RollingUpdate
        rollingUpdate:
          maxSurge: 1
          maxUnavailable: 0
      template:
        metadata:
          labels:
            app: uptime-kuma
        spec:
          containers:
          - name: uptime-kuma
            image: louislam/uptime-kuma:1
            imagePullPolicy: IfNotPresent
            env:
            # only need to set PUID and PGUI because of NFS server
            - name: PUID
              value: "1000"
            - name: PGID
              value: "1000"
            ports:
            - containerPort: 3001
              name: web-ui
            resources:
              limits:
                cpu: 200m
                memory: 512Mi
              requests:
                cpu: 50m
                memory: 128Mi
            livenessProbe:
              tcpSocket:
                port: web-ui
              initialDelaySeconds: 60
              periodSeconds: 10
            readinessProbe:
              httpGet:
                scheme: HTTP
                path: /
                port: web-ui
              initialDelaySeconds: 30
              periodSeconds: 10
            volumeMounts:
            - name: data
              mountPath: /app/data
          volumes:
          - name: data
            persistentVolumeClaim:
              claimName: uptime-kuma-pvc

    Pasul 2, sa intram in ArgoCD, sa definim un repository si o aplicatie. Rezultatele ar arata ca in printscreen-urile de mai jos. Avem nevoie de 2-3 lucruri:
    – repository URL: tip https sau cum vreti voi, si path-ul.
    – project – o sa fie default, ca nu am altceva definit
    – cluster – o sa aleaga automat clusterul pe care este instalat
    – path: uptimekuma – e directorul unde am pus tot.
    – sync: am lasat manual

    Dupa ce accesezi aplicatia si dai click pe sync, argo o sa downloadeze yaml-urile din repo, din directorul ales si o sa inceapa sa le aplice.
    Rezultatul ar trebui sa arate asa:

    Teoretic ar trebui sa poti accesa uptime kuma, pe ip-ul pe care il aloca metallb… si sa vezi interfata.

    Orice schimbare a yaml-urilor din github vor fi semnalate de ArgoCD. Daca ai pus sincronizarea pe automat ar trebui ca orice modificare faci sa fie deployata in Kubernetes automat, sa zicem ca modifici numarul de replici (pod-uri) pentru aplicatia ta.. sau faci un update… Mai jos exemplu:

    “BestMan” m-a sfatuit sa ma uit si la ArgoCD. Rachete, magie, gitops, kubernetzi…
    Sa incepem cu o traducere:

    Argo CD este un instrument declarativ CICD pentru aplicațiile Kubernetes. Acesta utilizează stilul GitOps pentru a crea și gestiona clustere Kubernetes. Atunci când se fac modificări în configurația aplicației din Git, Argo CD o compară cu configurația aplicației care rulează și notifică utilizatorii pentru a sincroniza starea dorită cu cea actuală.
    Argo CD a fost dezvoltat în cadrul proiectului Argo al Cloud Native Computing Foundation (CNCF), un proiect destinat în special gestionării ciclului de viață al aplicațiilor Kubernetes. Acest proiect include, de asemenea, Argo Workflow, Argo Rollouts și Argo Events. Fiecare dintre acestea rezolvă un set specific de probleme în procesul de dezvoltare agilă și contribuie la livrarea scalabilă și securizată a aplicațiilor Kubernetes.

    Cumva in github pui yaml-urile, asta verifica ce e acolo si face treaba. Asta e magie, ca pana acum stateam cu 20j de fisiere yaml pe nodu de control si le pierdeam, le suprascriam, nu mai stiam care fisier e ce imi trebuie… nah, gandire de sysadmin.
    Am deja cont de github, o sa fac un repo nou si o sa il folosesc pentru a instala “Uptime Kuma” cu ArgoCD.

    Instalarea ArgoCD e simpla, am facut un namespace nou si am folosit manifestul lor.
    kubectl create namespace argocd
    kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

    Dupa 2-3 minute am vazut si podurile:

    Mai devreme am pus MetalLB si as vrea sa il folosesc sa ajung la ArgoCD. Se poate folosi si nodeport dar e mai elegant asa, fara sa accesezi porturi ciudate. Dezavantajul pe care il vad eu pe termen lung o sa trebuiasca sa extinzi pool-ul de ip-uri folosit de metallb. Deci, revenim:
    kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

    Teoretic acum ar trebui sa am ArgoCD publicat pe unu din ip-urile alea din loadbalancer, pe porturile 443 si 80.

    O sa avem nevoie de parola (userul e admin). Avem o parola random creata la instalare…
    kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
    Accesam 192.168.111.220:80, user si parola avem. Iaca!

    Avem ArgoCD functional, teoretic putem incepe sa il folosim.
    Next post, instalare “Uptime Kuma” cu ArgoCD.

    MetalLB este o soluție de LoadBalancer pentru clusterele Kubernetes care de pe infrastructură bare-metal, asa cum am si eu in HomeLab. Spre deosebire de cloud-uri (eks de ex) unde ai deja solutii native… pe onprem (bare metal) ai nevoie de o solutie pentru a expune serviciile catre retea si de acolo… mai departe, pe internet daca este cazul 😀

    Instalarea MetalLB

    Eu am folosit manifestul lor..
    kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/main/config/manifests/metallb-native.yaml
    In cateva zeci de secunde se for initializa toate componentele si vom avea ceva de genul
    kubectl get pods -n metallb-system

    Pentru a configura MetalLB vom avea nevoie de un spatiu de ip-uri din zona in care tinem si nodurile de k8s. Daca avem DHCP va trebui sa rezervam zona aceea… Creaza un fisier de ex metallb-config.yaml si aplica configuratia.

    apiVersion: metallb.io/v1beta1
    kind: IPAddressPool
    metadata:
      name: default-pool
      namespace: metallb-system
    spec:
      addresses:
      - 192.168.111.220-192.168.111.230
    ---
    apiVersion: metallb.io/v1beta1
    kind: L2Advertisement
    metadata:
      name: l2advertisement
      namespace: metallb-system

    kubectl apply -f metallb-config.yaml

    Destul de simplu… pentru a vedea logurile metallb

    kubectl logs -n metallb-system -l app=metallb

    Ca sa ii vedem utilitatea putem sa cream un nginx mic si stingher, facem un yaml nou, nginx-lb.yaml iar la serviciu specificam tipul LoadBalancer.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-lb
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx-lb
      template:
        metadata:
          labels:
            app: nginx-lb
        spec:
          containers:
          - name: nginx
            image: nginx
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-lb
      namespace: default
    spec:
      selector:
        app: nginx-lb
      ports:
        - protocol: TCP
          port: 80
          targetPort: 80
      type: LoadBalancer

    Se aplica configuratia, dupa care K8s va crea un POD conform specificatiilor si un serviciu prin care publicam nginx-ul pe portul 80.
    kubectl apply -f nginx-lb.yaml

    Va trebui sa se regaseasca in lista serviciul si un IP din pool-ul setat mai sus pentru metallb.

    Din browser va trebui sa puteti accesa serviciul pe portul 80, pe acel ip.

    Easy peasy!

    In postul trecut am scris despre un NAS home-made. Nu e o idee rea, ar fi fost maximum de performant pentru ce am eu nevoie dar nu am facut proiectul. M-am oprit la un NAS comercial, adica ala din titlu. Am vazut niste dezavantaje care m-au enervat, in speta lipsa pe piata a placilor de baza cu 4-6 porturi SATA si 2 NVME-uri. Domne, nu exista! Eu spun ca e blat cu aia care fac NAS-uri, ca altfel cum sa nu fie posibil sa pui 2NVME si 4SATA pe langa un PCIEx cu care sa extinzi cu diverse nebunii?

    Am ales calea usoara, nu imi pare rau, ba mai mult decat atat, chiar ma bucur ca am facut pasul.

    Configuratia este
    – 2 nvme x 512GB – folosit pentru cache, raid0 ca sa am mai mult. Riscul este ca daca moare vreunu as putea sa pierd date…. (filme, vm-uri sau containere de test, deci nimic grav)
    – 4 sata x 10TB HGST HUH721010ALE604, raid 5. M-am gandit sa le pun la raid10 dar pierdeam 2 disk-uri de capacitate. Asa un disk poate sa pice si nu pierd date vs 2 disk-uri care pot pica. E safe si asa, parerea mea.
    – 32 GB RAM – 2 sodimm-uri de 16GB de la Kingston, pe care le aveam deja.

    Likes:
    – Compact si cat de cat silentios
    – 2 x 2.5gbps retea
    – Plex / Qbittorrent / *arr ruleaza direct pe NAS, nu mai trebuie sa ruleze pe nodurile de proxmox
    – Out of the box cam orice share ai nevoie, pot sa il folosesc ca timemachine pentru laptops

    Software-ul pe care il poti instala pe el este cat se poate de divers, folosesc deja container station si am cateva containere Docker, printre care si tehnitium dns pe care il folosesc pentru dhcp dar si DNS blackhole in locul lui PiHole. Container station poate porni si k3s. Pe langa container station mai este un Virtualisation Station in care poti rula VM-uri micute (nu as recomanda ceva resource intensive din cauza procesorului)…

    Consum:
    – In jur de 40W in idle. Daca as fi avut sistemul de operare instalat pe NVME-uri ar fi intrat in idle disk-urile rotative si as fi economisit vreo 20W… asta atata vreme cat nu ar fi soft nici un request catre ele (qbittorrent oprit, nfs oprit…) deci nu se aplica.

    Il folosesc deja sa rulez din proxmox VM-uri de pe un shared storage (NFS mi-a parut cel mai simplu si rapid), am caching pe acel volum deci nu trag “direct” de pe discurile rotative – cache read-write, evident. Il folsesc sa fac backup-uri VM-urilor din proxmox, zilnic.
    In laboratorul de k8s (kubernetes) deja e folosit pentru persistent storage… Very nice!