Ubuntu Server in the Cloud

Ubuntu Server in the Cloud

Bitnesia Aug 29, 2026 2 ID

Bab 40 diakhiri dengan sebuah janji: begitu series ini berpindah fokus ke Ubuntu Server di lingkungan cloud, repository BorgBackup yang sudah tersinkronisasi ke object storage lewat rclone pada Bagian 40.4 akan langsung relevan lagi ketika kita membahas snapshot dan storage block milik penyedia cloud besar secara lebih spesifik. Bab 37 menyisakan janji serupa: file user-data cloud-init yang sudah kita tulis dan uji di VM KVM lokal pada Bagian 37.3.2 disebut "nyaris dapat digunakan apa adanya" begitu instance-nya sungguhan berjalan di AWS, Azure, atau GCP, seperti dijanjikan di Bagian 37.4.3. Bab 41 menepati kedua janji itu sekaligus.

Seluruh server yang kita kelola sejak Bab 2 hidup di jaringan lab 192.168.1.0/24, baik itu instalasi fisik, VM KVM di Bab 28, maupun container LXD di Bab 29. Skenario ini realistis untuk belajar, tetapi tidak realistis untuk melayani Visitor sungguhan dari internet publik. Developer yang sudah membangun aplikasi web sejak Bab 12 dan Bab 15, lengkap dengan TLS di Bab 17, pada satu titik pasti akan bertanya: bagaimana caranya server ini benar-benar bisa diakses dari luar jaringan kantor, tanpa Sysadmin harus membeli, memasang, dan merawat hardware fisik sendiri? Jawaban paling umum di industri saat ini adalah menyewa instance di penyedia cloud publik, membayar hanya untuk resource yang benar-benar dipakai (model pay-as-you-go), dan bisa membuat maupun menghapus server dalam hitungan menit lewat API atau command line.

Bab ini dimulai dari gambaran umum tiga penyedia cloud terbesar, Amazon Web Services (AWS), Microsoft Azure, dan Google Cloud Platform (GCP), lalu masuk ke praktik penuh meluncurkan Ubuntu Server 26.04 di AWS memakai cloud image resmi dan cloud-init persis seperti pola Bab 37. Setelah instance hidup, kita akan membahas security group sebagai firewall di level cloud yang bekerja berdampingan dengan UFW dan nftables dari Bab 31, dilanjutkan konsep elastic IP, storage block, dan snapshot cloud yang melengkapi strategi backup Bab 40. Bab ditutup dengan ringkasan alur yang setara di Azure dan GCP, supaya pola pikirnya tetap portabel meski nama layanan dan perintah CLI-nya berbeda.

41.1 Overview Deployment Ubuntu Server di AWS, Azure, dan GCP

41.1.1 Shared Responsibility Model: Bedanya dari Server Fisik dan VM Lokal

Seluruh hardening yang sudah kita praktikkan sejak Bagian VIII, mulai dari menonaktifkan service yang tidak perlu di Bab 30, mengatur firewall di Bab 31, sampai audit least privilege di Bab 34, tetap sepenuhnya relevan di cloud. Yang berubah adalah batas tanggung jawabnya. Ketiga penyedia besar ini menganut konsep yang sama, populer disebut Shared Responsibility Model: provider bertanggung jawab atas keamanan "of the cloud" (fasilitas fisik data center, hypervisor, jaringan inti, sampai ke titik hardware yang menjalankan instance kita), sedangkan Sysadmin tetap bertanggung jawab penuh atas keamanan "in the cloud", yaitu segala sesuatu di dalam guest OS: patching kernel dan paket (Bab 6), konfigurasi firewall di dalam instance (Bab 31), manajemen user dan akses (Bab 4), sampai enkripsi data aplikasi itu sendiri.

Praktisnya, memindahkan server ke cloud tidak pernah berarti "keamanan sudah diurus provider". Provider menjamin tidak ada orang asing yang bisa mencabut disk fisik dari rak server seperti ancaman yang dibahas di Bagian 30.4.3, tetapi provider sama sekali tidak bertanggung jawab jika Sysadmin lupa menutup port database ke publik, memakai password lemah, atau menjalankan paket yang sudah lama tidak di-update. Insiden kebocoran data cloud yang paling sering muncul di berita justru datang dari sisi tanggung jawab customer ini, bukan dari kegagalan infrastruktur provider.

41.1.2 Perbandingan Istilah Inti Antar Tiga Provider Besar

Ketiga provider ini memakai nama layanan yang berbeda untuk konsep yang secara fungsional serupa. Tabel berikut menjadi peta acuan supaya dokumentasi resmi masing-masing provider tetap mudah diikuti, sekalipun bab ini mempraktikkan AWS sebagai contoh utama.

KonsepAWSAzureGCP
Virtual machineEC2 (Elastic Compute Cloud)Virtual MachinesCompute Engine
Jaringan virtualVPC (Virtual Private Cloud)Virtual Network (VNet)VPC Network
Firewall di level cloudSecurity GroupNetwork Security Group (NSG)Firewall Rules
Block storageEBS (Elastic Block Store)Managed DiskPersistent Disk
Object storageS3Blob StorageCloud Storage
IP publik statisElastic IPPublic IP address (static)External IP address (static)
Identity dan accessIAMMicrosoft Entra ID + RBACCloud IAM

Baris object storage pada tabel di atas bukan kebetulan relevan dengan Bab 40. S3, Blob Storage, dan Cloud Storage adalah tiga dari lebih 70 jenis remote yang didukung rclone sejak Bagian 40.4.2, sehingga repository Borg yang sudah kita sinkronkan ke cloud storage pada bab itu bisa memakai penyedia mana pun dari ketiganya tanpa mengubah cara kerja intinya.

41.2 Cloud Image Ubuntu 26.04 dan Cloud-init di AWS EC2

41.2.1 Menyiapkan AWS CLI dan Kredensial Akses

AWS menyediakan console berbasis web, tetapi seluruh series ini konsisten memakai pendekatan command line supaya setiap langkah bisa diulang dan didokumentasikan sebagai kode, sejalan dengan semangat Infrastructure as Code yang sudah diperkenalkan di Bab 36. Dokumentasi resmi AWS merekomendasikan memasang AWS CLI v2 lewat installer resmi, bukan lewat repository distro yang seringkali membawa versi lama.

Langkah Praktik

  1. Unduh dan pasang AWS CLI v2 di komputer kerja kita (bukan di server Ubuntu manapun, karena AWS CLI ini hanya dipakai untuk mengontrol resource cloud dari luar).
    curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
    unzip awscliv2.zip
    sudo ./aws/install
  2. Buat IAM user khusus untuk kebutuhan lab ini lewat AWS Console, sesuai prinsip least privilege yang sudah dibahas di Bagian 34.2, alih-alih memakai kredensial root account yang punya akses penuh tanpa batas ke seluruh layanan. Lampirkan dua policy bawaan ke user ini: AmazonEC2FullAccess untuk seluruh operasi EC2 sepanjang bab ini, dan AmazonSSMReadOnlyAccess yang secara khusus dibutuhkan untuk membaca parameter AMI resmi lewat SSM Parameter Store di Bagian 41.2.2. Permission SSM ini gampang terlewat karena tidak otomatis ikut serta dalam AmazonEC2FullAccess, meski dipakai lewat notasi resolve:ssm: di dalam perintah EC2 sendiri seperti di Bagian 41.2.4. Simpan Access Key ID dan Secret Access Key yang diberikan saat pembuatan user tersebut.
  3. Konfigurasikan kredensial itu ke AWS CLI.
    aws configure
    Perintah ini meminta empat input berurutan: AWS Access Key ID, AWS Secret Access Key, Default region name (isi ap-southeast-1, region Singapura yang paling dekat secara latency dari Indonesia), dan Default output format (isi json).

Verifikasi dan Troubleshooting

  • Pastikan kredensial benar-benar terpasang dan valid.
    aws sts get-caller-identity
    Output sehat menampilkan JSON berisi UserId, Account, dan Arn milik IAM user yang baru dikonfigurasi. Error Unable to locate credentials berarti langkah aws configure belum selesai atau tersimpan di profile yang salah.
  • Error AccessDenied pada perintah EC2 di bab ini biasanya berarti policy AmazonEC2FullAccess belum terpasang. Error serupa yang muncul khusus saat memanggil aws ssm get-parameters di Bagian 41.2.2, atau saat run-instances gagal meresolusi resolve:ssm: di Bagian 41.2.4, menandakan policy AmazonSSMReadOnlyAccess yang belum terpasang, bukan masalah pada AMI atau region yang dipilih. Untuk kebutuhan lab, kombinasi dua policy bawaan ini sudah cukup, meski di lingkungan produksi sungguhan policy sedetail itu sebaiknya dipersempit lagi sesuai kebutuhan nyata, mengikuti semangat Bagian 34.2.

41.2.2 Mencari AMI Resmi Ubuntu 26.04 Lewat SSM Parameter Store

AMI (Amazon Machine Image) adalah istilah AWS untuk cloud image, setara dengan file .img yang kita unduh langsung dari cloud-images.ubuntu.com di Bagian 37.3.1. Bedanya, AMI adalah image yang sudah didaftarkan di dalam sistem AWS itu sendiri dan diidentifikasi lewat ID unik per region, bukan file yang kita unduh dan simpan sendiri. Canonical mempublikasikan ID AMI resmi Ubuntu secara terprogram lewat AWS Systems Manager (SSM) Parameter Store, sehingga kita tidak perlu mencari dan menyalin ID tersebut secara manual dari halaman web yang bisa saja berubah kapan pun ada rilis image baru.

Langkah Praktik

  1. Ambil ID AMI Ubuntu Server 26.04 LTS terbaru untuk arsitektur amd64 di region ap-southeast-1.
    aws ssm get-parameters \
      --region ap-southeast-1 \
      --names /aws/service/canonical/ubuntu/server/26.04/stable/current/amd64/hvm/ebs-gp3/ami-id \
      --query 'Parameters[0].Value' \
      --output text

Verifikasi dan Troubleshooting

  • Output sehat berupa satu baris ID AMI berformat ami-xxxxxxxxxxxxxxxxx. ID ini unik per region, jadi ID yang sama tidak akan valid jika dipakai di region selain ap-southeast-1 pada perintah run-instances nanti.
  • Struktur path parameter ini sengaja hierarkis: segmen server bisa diganti server-minimal untuk image yang lebih ramping, segmen 26.04 bisa diganti current menjadi tanggal spesifik (misalnya 20260615) untuk mengunci ke satu snapshot rilis tertentu, dan segmen ebs-gp3 menandakan root volume-nya nanti otomatis berjenis EBS dengan tipe gp3, detail yang relevan lagi di Bagian 41.4.2.
  • Path SSM ini juga bisa dipakai langsung di dalam perintah run-instances lewat notasi resolve:ssm: tanpa perlu menyalin ID-nya secara manual lebih dulu, seperti yang akan kita pakai di Bagian 41.2.4.

41.2.3 Mendaftarkan Key Pair dan Menulis user-data Cloud-init

AWS punya konsep key pair tersendiri yang harus didaftarkan ke region tertentu sebelum dipakai instance mana pun. Alih-alih membuat key baru khusus AWS, kita bisa mengimpor public key ed25519 yang sudah kita buat sendiri sejak Bagian 3.2.2, supaya satu private key yang sama tetap dipakai untuk login ke seluruh server series ini, baik lokal maupun cloud.

Langkah Praktik

  1. Impor public key kita ke AWS sebagai key pair bernama sysadmin-key.
    aws ec2 import-key-pair \
      --region ap-southeast-1 \
      --key-name sysadmin-key \
      --public-key-material fileb://$HOME/.ssh/id_ed25519.pub
    Perhatikan path-nya memakai $HOME, bukan ~. Tanda ~ hanya diekspansi shell ketika berada di awal sebuah kata, sedangkan di sini ia menempel setelah prefix fileb://, sehingga tidak pernah diekspansi dan AWS CLI akan mencari file bernama harfiah ~ yang tidak ada. Variable $HOME tidak punya batasan posisi seperti itu dan selalu diekspansi shell di mana pun letaknya.
  2. Buat file user-data.yaml, isinya mengikuti pola persis seperti user-data di Bagian 37.3.2: membuat user sysadmin dengan akses sudo tanpa password, mendaftarkan SSH key yang sama, lalu memasang nginx sebagai bukti provisioning berhasil.
    nano user-data.yaml
  3. Isi dengan konfigurasi berikut. Ganti baris ssh_authorized_keys dengan isi sesungguhnya dari ~/.ssh/id_ed25519.pub milik kita sendiri.
    #cloud-config
    users:
      - name: sysadmin
        groups: sudo
        shell: /bin/bash
        sudo: ALL=(ALL) NOPASSWD:ALL
        lock_passwd: true
        ssh_authorized_keys:
          - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGXampleKeyMaterialGantiDenganPublicKeyAsli
    
    package_update: true
    package_upgrade: true
    packages:
      - nginx
    
    runcmd:
      - [ sh, -c, "echo Provisioned via cloud-init di AWS EC2 on $(date) > /var/www/html/provisioned.txt" ]

Verifikasi dan Troubleshooting

  • Validasi sintaks user-data.yaml sebelum dipakai meluncurkan instance sungguhan, persis seperti kebiasaan yang sudah dibangun di Bagian 37.2.2.
    cloud-init schema --config-file user-data.yaml --annotate
  • Karena key users di atas tidak menyertakan entri default, instance hasil provisioning nanti hanya memiliki user sysadmin, bukan user ubuntu yang biasanya menjadi default login di kebanyakan tutorial AWS memakai cloud image Ubuntu polos. Detail ini penting diingat saat login di Bagian 41.2.4, sumber kebingungan paling umum bagi yang baru pertama kali menulis user-data sendiri di AWS.

41.2.4 Meluncurkan Instance dan Verifikasi Provisioning

Bagian 37.4.3 sudah menyinggung bahwa datasource cloud-init di AWS bernama EC2, mengambil user-data lewat metadata service internal di 169.254.169.254, bukan lewat media cidata seperti datasource NoCloud yang kita pakai manual di Bagian 37.3.3. Konsekuensinya, kita tidak perlu membuat seed ISO sama sekali di sini. Cukup serahkan file user-data.yaml lewat flag --user-data pada perintah run-instances, dan AWS yang mengurus sisanya lewat metadata service miliknya.

Langkah Praktik

  1. Luncurkan instance memakai AMI hasil pencarian di Bagian 41.2.2 (langsung lewat notasi resolve:ssm, tanpa perlu menyalin ID-nya), key pair dari Bagian 41.2.3, dan user-data.yaml yang sama.
    aws ec2 run-instances \
      --region ap-southeast-1 \
      --image-id resolve:ssm:/aws/service/canonical/ubuntu/server/26.04/stable/current/amd64/hvm/ebs-gp3/ami-id \
      --instance-type t3.medium \
      --key-name sysadmin-key \
      --user-data file://user-data.yaml \
      --count 1 \
      --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=vm-cloud01}]'
    Catat nilai InstanceId (formatnya i-xxxxxxxxxxxxxxxxx) dari output JSON perintah ini, dipakai berulang kali di sisa bab ini.
  2. Tunggu sampai instance benar-benar berstatus running sebelum melangkah lebih jauh.
    aws ec2 wait instance-running --region ap-southeast-1 --instance-ids i-xxxxxxxxxxxxxxxxx
  3. Ambil alamat IP publik yang otomatis diberikan AWS ke instance ini.
    aws ec2 describe-instances \
      --region ap-southeast-1 \
      --instance-ids i-xxxxxxxxxxxxxxxxx \
      --query 'Reservations[0].Instances[0].PublicIpAddress' \
      --output text
  4. Coba login SSH ke alamat IP tersebut.
    ssh [email protected]

Verifikasi dan Troubleshooting

  • Percobaan SSH di langkah terakhir kemungkinan besar gagal, bukan dengan Permission denied, melainkan macet total tanpa respons sampai akhirnya timeout. Ini bukan kegagalan cloud-init. Instance yang baru diluncurkan lewat run-instances tanpa menyebutkan --security-group-ids otomatis memakai security group default milik VPC, dan security group default di AWS tidak mengizinkan satu pun koneksi masuk dari internet, termasuk SSH. Bagian 41.3 menuntaskan celah ini secara eksplisit, jadi jangan buru-buru mengira instance-nya rusak.
  • Instance ini tetap bisa diperiksa tanpa SSH lewat console output, berguna untuk memastikan proses boot dan tahap awal cloud-init berjalan normal meski akses SSH belum terbuka.
    aws ec2 get-console-output --region ap-southeast-1 --instance-id i-xxxxxxxxxxxxxxxxx --output text
  • Catatan biaya yang jujur perlu disampaikan sebelum instance ini dibiarkan menyala lama-lama: tipe t3.medium di atas tidak termasuk cakupan AWS Free Tier, yang hanya mencakup t2.micro atau t3.micro sebanyak 750 jam per bulan selama 12 bulan pertama akun aktif. Instance ini langsung dikenakan tarif on-demand sejak menit pertama berjalan. Ganti --instance-type pada langkah 1 menjadi t3.micro jika bab ini murni dipakai untuk latihan dan ingin tetap dalam cakupan Free Tier, atau cek kalkulator harga resmi AWS untuk region ap-southeast-1 sebelum menjalankan lab ini dalam waktu lama.

41.3 Security Group / Firewall Cloud vs Firewall Lokal

41.3.1 Apa Itu Security Group dan Bedanya dengan UFW/nftables

Security group adalah firewall virtual yang diterapkan AWS di level infrastruktur software-defined networking, bukan di dalam kernel guest OS seperti UFW dan nftables yang sudah kita kuasai di Bab 31. Perbedaan letak ini membawa beberapa konsekuensi penting. Pertama, security group bersifat stateful persis seperti nftables modern, artinya traffic balasan dari koneksi yang sudah diizinkan otomatis boleh lewat tanpa perlu rule terpisah untuk arah pulang, sama seperti perilaku ct state established,related yang sudah kita tulis manual di Bagian 31.4.1. Kedua, dan ini yang paling penting dipahami: security group menerapkan prinsip default deny untuk seluruh traffic masuk secara otomatis sejak awal dibuat, tanpa perlu langkah aktivasi eksplisit seperti ufw enable di Bagian 31.3.1. Semua traffic masuk ditolak sampai kita menambahkan rule allow secara spesifik, seperti yang baru saja terbukti sendiri di Bagian 41.2.4.

Ketiga, karena security group bekerja di luar guest OS, security group tidak bisa dilihat, diubah, atau bahkan disadari keberadaannya dari dalam instance itu sendiri. Menjalankan ufw status atau nft list ruleset di dalam instance EC2 tidak akan pernah menampilkan satu pun rule security group, karena keduanya benar-benar berada di lapisan yang berbeda. Mengubah security group butuh kredensial API AWS (kredensial IAM yang sama seperti Bagian 41.2.1), bukan akses root ke server, sebuah pemisahan yang justru menjadi keunggulan tersendiri dari sisi keamanan, dibahas lebih lanjut di Bagian 41.3.3.

41.3.2 Membuat dan Mengatur Rule Security Group

Praktik terbaik yang direkomendasikan AWS sendiri adalah membuat security group khusus untuk tiap kebutuhan, bukan menumpuk rule pada security group default milik VPC, supaya batas akses tiap instance tetap jelas dan mudah diaudit satu per satu.

Langkah Praktik

  1. Cari ID VPC default yang dipakai instance vm-cloud01.
    aws ec2 describe-vpcs \
      --region ap-southeast-1 \
      --filters Name=isDefault,Values=true \
      --query 'Vpcs[0].VpcId' \
      --output text
  2. Buat security group baru khusus instance ini.
    aws ec2 create-security-group \
      --region ap-southeast-1 \
      --group-name sg-vm-cloud01 \
      --description "SSH, HTTP, HTTPS untuk vm-cloud01" \
      --vpc-id vpc-xxxxxxxxxxxxxxxxx
    Catat nilai GroupId (formatnya sg-xxxxxxxxxxxxxxxxx) dari output perintah ini.
  3. Cari tahu alamat IP publik kita sendiri, supaya rule SSH nanti hanya mengizinkan koneksi dari IP ini, bukan dari seluruh internet.
    curl -s https://checkip.amazonaws.com
  4. Izinkan koneksi SSH hanya dari IP kita sendiri.
    aws ec2 authorize-security-group-ingress \
      --region ap-southeast-1 \
      --group-id sg-xxxxxxxxxxxxxxxxx \
      --protocol tcp --port 22 --cidr 103.10.20.30/32
  5. Izinkan koneksi HTTP dan HTTPS dari mana saja, sesuai kebutuhan aplikasi web publik yang nanti dipasang lewat Nginx.
    aws ec2 authorize-security-group-ingress \
      --region ap-southeast-1 \
      --group-id sg-xxxxxxxxxxxxxxxxx \
      --protocol tcp --port 80 --cidr 0.0.0.0/0
    aws ec2 authorize-security-group-ingress \
      --region ap-southeast-1 \
      --group-id sg-xxxxxxxxxxxxxxxxx \
      --protocol tcp --port 443 --cidr 0.0.0.0/0
  6. Pasang security group baru ini ke instance vm-cloud01, menggantikan security group default yang terpasang otomatis saat peluncuran.
    aws ec2 modify-instance-attribute \
      --region ap-southeast-1 \
      --instance-id i-xxxxxxxxxxxxxxxxx \
      --groups sg-xxxxxxxxxxxxxxxxx

Verifikasi dan Troubleshooting

  • Ulangi percobaan SSH yang gagal di Bagian 41.2.4.
    ssh [email protected]
    Berbeda dari mengaktifkan ulang UFW yang butuh proses reload rule di dalam kernel, perubahan security group di AWS berlaku hampir seketika begitu API mengembalikan respons sukses, karena rule-nya diterapkan di lapisan jaringan virtual AWS, bukan menunggu proses apa pun di dalam instance.
  • Jika IP publik kita berubah-ubah (umum terjadi pada koneksi rumahan tanpa IP statis), ulangi langkah 3 dan 4 untuk memperbarui rule SSH dengan IP terbaru. Rule lama yang sudah tidak relevan sebaiknya dihapus lewat aws ec2 revoke-security-group-ingress dengan parameter yang sama persis seperti saat rule itu dibuat, supaya security group tidak menumpuk rule basi yang membuka akses dari IP yang sudah bukan milik kita lagi.
  • Rule dengan --cidr 0.0.0.0/0 pada port 80 dan 443 memang disengaja di sini karena keduanya melayani Visitor publik. Pola ini tidak boleh disamakan dengan membuka SSH ke 0.0.0.0/0, kesalahan konfigurasi yang paling sering ditemui di lapangan dan menjadi target utama bot pemindai otomatis milik Attacker dalam hitungan menit setelah sebuah instance baru live di internet publik.

41.3.3 Kombinasi Security Group dan Firewall Lokal sebagai Defense in Depth

Peta lapisan pertahanan berlapis (defense in depth) yang sudah digambar di Bagian 30.1.2 kini bertambah satu lapisan baru di paling luar. Security group menjadi lapisan pertama yang harus dilewati traffic sebelum sempat menyentuh kernel instance sama sekali, sedangkan UFW atau nftables dari Bab 31 tetap berjalan di dalam guest OS sebagai lapisan kedua. Kedua lapisan ini sengaja tidak saling menggantikan.

Skenario yang menunjukkan pentingnya kombinasi ini: seandainya kredensial IAM milik kita bocor dan Attacker berhasil membuka port database ke 0.0.0.0/0 lewat security group, firewall lokal di dalam instance yang sudah dikonfigurasi mengikuti prinsip default deny pada Bagian 31.5.2 tetap bisa menjadi penghalang terakhir, asalkan rule di dalamnya memang sengaja tidak mengikuti perubahan security group secara membabi buta. Sebaliknya, jika Attacker berhasil mendapat shell di dalam instance lewat celah aplikasi dan mencoba mengubah rule UFW untuk membuka jalur keluar tambahan, security group yang dikontrol lewat API terpisah dengan kredensial berbeda tetap membatasi apa yang secara fisik bisa dijangkau dari instance tersebut. Dua lapisan yang independen secara kredensial maupun secara teknis inilah inti sesungguhnya dari defense in depth, bukan sekadar mengulang aturan yang sama dua kali di tempat berbeda.

41.4 Elastic IP, Storage Block, dan Snapshot Cloud

41.4.1 Elastic IP: Alamat IP Publik yang Persisten

Alamat IP publik yang otomatis didapat instance vm-cloud01 sejak Bagian 41.2.4 sifatnya ephemeral. Setiap kali instance itu dihentikan (stop) lalu dinyalakan lagi, AWS berpotensi memberikan alamat IP publik yang benar-benar baru, berbeda dari sebelumnya. Perilaku ini merepotkan untuk server produksi yang alamatnya sudah didaftarkan di DNS publik, sesuatu yang sudah kita pelajari di Bab 9, karena setiap pergantian IP berarti record DNS harus diperbarui manual.

Elastic IP menjawab masalah ini: alamat IP publik yang kita alokasikan secara eksplisit ke akun AWS, lalu diasosiasikan ke instance mana pun sesuai kebutuhan, dan tetap menjadi milik akun kita sampai benar-benar dilepaskan, terlepas dari status instance yang sedang memakainya.

Langkah Praktik

  1. Alokasikan satu Elastic IP baru.
    aws ec2 allocate-address --region ap-southeast-1 --domain vpc
    Catat nilai AllocationId (formatnya eipalloc-xxxxxxxxxxxxxxxxx) dan PublicIp dari output-nya.
  2. Asosiasikan Elastic IP tersebut ke instance vm-cloud01.
    aws ec2 associate-address \
      --region ap-southeast-1 \
      --instance-id i-xxxxxxxxxxxxxxxxx \
      --allocation-id eipalloc-xxxxxxxxxxxxxxxxx

Verifikasi dan Troubleshooting

  • Uji ulang SSH memakai Elastic IP yang baru saja diasosiasikan (nilai PublicIp dari output allocate-address pada langkah sebelumnya), bukan alamat IP lama.
    ssh [email protected]
  • Catatan biaya yang jujur perlu disampaikan di sini. Anggapan lama bahwa "Elastic IP gratis selama terpasang ke instance yang sedang berjalan" sudah tidak berlaku lagi. Sejak 1 Februari 2024, AWS mengenakan biaya per jam untuk setiap alamat IPv4 publik, baik itu Elastic IP maupun alamat publik otomatis biasa seperti yang dipakai di Bagian 41.2.4, terlepas dari status asosiasinya ke instance. Manfaat utama Elastic IP karenanya bukan lagi soal biaya, melainkan soal alamat yang stabil dan bisa dipindah-pindahkan antar instance tanpa mengubah record DNS. Jika Elastic IP ini hanya untuk latihan bab ini, lepaskan kembali setelah selesai lewat aws ec2 release-address --region ap-southeast-1 --allocation-id eipalloc-xxxxxxxxxxxxxxxxx supaya tidak terus tertagih.

41.4.2 Storage Block (EBS) vs Instance Store: Konsep

Root volume instance vm-cloud01 sejak awal sebenarnya sudah memakai EBS (Elastic Block Store), terlihat dari segmen ebs-gp3 pada path SSM di Bagian 41.2.2. EBS adalah block storage yang terhubung lewat jaringan internal AWS ke instance, konsepnya setara dengan logical volume LVM di Bagian 7.2, hanya saja disk fisiknya berada di storage cluster milik AWS, bukan tertancap langsung ke motherboard server. Karena terpisah dari hardware instance itu sendiri, volume EBS bisa dilepas dari satu instance dan dipasang ke instance lain, serta tetap ada meski instance-nya dihentikan atau bahkan dihapus, asalkan opsi delete on termination-nya tidak diaktifkan.

Sebagai pembanding, sebagian tipe instance AWS lain menyediakan instance store, yaitu disk NVMe yang secara fisik tertancap langsung ke server fisik tempat instance kita berjalan. Instance store jauh lebih cepat karena tidak melewati jaringan sama sekali, tetapi datanya benar-benar hilang permanen begitu instance di-stop atau di-terminate, bukan cuma di-reboot. Instance store cocok untuk cache sementara atau data yang memang boleh hilang, tapi sama sekali tidak cocok untuk data yang perlu bertahan, sebuah jebakan yang beberapa kali ditemui Sysadmin pemula yang mengira seluruh disk di cloud otomatis persisten seperti EBS.

Langkah Praktik

  1. Lihat detail volume EBS yang terpasang di vm-cloud01.
    aws ec2 describe-volumes \
      --region ap-southeast-1 \
      --filters Name=attachment.instance-id,Values=i-xxxxxxxxxxxxxxxxx \
      --query 'Volumes[0].{VolumeId:VolumeId,Size:Size,Type:VolumeType}' \
      --output table
    Catat nilai VolumeId (formatnya vol-xxxxxxxxxxxxxxxxx), dipakai di Bagian 41.4.3.

Verifikasi dan Troubleshooting

  • Output tabel semestinya menampilkan Type: gp3, sesuai jenis volume yang sudah ditentukan lewat path AMI di Bagian 41.2.2, dan Size mengikuti ukuran default AMI Ubuntu (umumnya 8 GiB), bisa diperbesar kapan pun lewat aws ec2 modify-volume tanpa downtime, konsepnya mirip resize volume LVM tanpa downtime di Bagian 7.2.2, hanya saja filesystem di dalam guest tetap perlu diperbesar menyusul lewat growpart dan resize2fs/xfs_growfs setelah perubahan di sisi AWS selesai.

41.4.3 Snapshot Cloud sebagai Pelengkap Strategi Backup Bab 40

Snapshot EBS adalah salinan point-in-time dari sebuah volume, disimpan AWS secara terpisah di S3 tanpa terlihat langsung sebagai object biasa, dan bersifat incremental: snapshot kedua dan seterusnya hanya menyimpan blok data yang berubah sejak snapshot sebelumnya, walau saat dipulihkan setiap snapshot tetap merepresentasikan volume penuh secara utuh pada momen snapshot itu diambil, konsep yang mirip dengan strategi --link-dest pada Bagian 40.2.2, hanya saja diimplementasikan AWS di level storage backend, bukan lewat hardlink filesystem.

Langkah Praktik

  1. Buat snapshot dari volume root vm-cloud01.
    aws ec2 create-snapshot \
      --region ap-southeast-1 \
      --volume-id vol-xxxxxxxxxxxxxxxxx \
      --description "Snapshot awal vm-cloud01" \
      --tag-specifications 'ResourceType=snapshot,Tags=[{Key=Name,Value=vm-cloud01-root}]'
    Catat nilai SnapshotId (formatnya snap-xxxxxxxxxxxxxxxxx) dari output-nya.
  2. Pantau status snapshot sampai selesai.
    aws ec2 describe-snapshots \
      --region ap-southeast-1 \
      --snapshot-ids snap-xxxxxxxxxxxxxxxxx \
      --query 'Snapshots[0].{State:State,Progress:Progress}' \
      --output table

Verifikasi dan Troubleshooting

  • Status akhir yang sehat adalah State: completed dengan Progress: 100%. Snapshot besar bisa memakan waktu beberapa menit tergantung ukuran volume dan seberapa banyak data yang berubah sejak snapshot sebelumnya.
  • Bagian 7.2.3, Bagian 28.4.4, dan Bagian 29.3.5 sudah menegaskan hal yang sama dan tetap berlaku persis di sini: snapshot bukan pengganti backup sungguhan. Snapshot EBS secara default tetap tersimpan di region dan akun AWS yang sama dengan volume aslinya, sehingga satu insiden yang menghabisi seluruh akun (kredensial API bocor dan disalahgunakan Attacker untuk menghapus resource secara massal, misalnya) berpotensi menghabisi snapshot-nya sekaligus. Snapshot bisa disalin lintas region lewat aws ec2 copy-snapshot untuk mendekati syarat off-site pada aturan 3-2-1 Bagian 40.1.1, tetapi tetap berada di dalam ekosistem AWS yang sama, berbeda dari repository Borg di Bagian 40.3 yang sudah terenkripsi penuh sebelum meninggalkan server dan sama sekali tidak bergantung pada satu provider cloud manapun.
  • Pembagian tugas yang paling masuk akal di lapangan: snapshot EBS dipakai untuk pemulihan cepat di level infrastruktur, misalnya sebelum menjalankan upgrade besar atau perubahan konfigurasi berisiko, sedangkan BorgBackup dan rclone dari Bab 40 tetap menjadi lapisan backup utama yang application-aware, terenkripsi end-to-end, dan tidak terikat pada satu provider cloud tertentu. Keduanya saling melengkapi, bukan saling menggantikan.
  • Snapshot yang hanya dibuat untuk latihan bab ini sebaiknya dihapus setelah selesai supaya tidak terus memakan biaya penyimpanan di S3.
    aws ec2 delete-snapshot --region ap-southeast-1 --snapshot-id snap-xxxxxxxxxxxxxxxxx

41.4.4 Membersihkan Resource Lab

Berbeda dari VM KVM lokal di Bab 28 yang berhenti memakan resource begitu di-shutdown, instance EC2 yang berstatus running maupun stopped tetap menagih biaya untuk komponen tertentu (root volume EBS tetap tertagih walau instance berstatus stopped, dan Elastic IP yang sudah diasosiasikan sejak Bagian 41.4.1 tetap tertagih terlepas status instance-nya, berbeda dari alamat IP publik otomatis biasa yang langsung dilepas AWS begitu instance di-stop). Kebiasaan yang jujur dan bertanggung jawab, terutama untuk lingkungan lab dan latihan seperti bab ini, adalah membersihkan seluruh resource begitu selesai dipakai, bukan sekadar men-stop instance-nya saja.

Langkah Praktik

  1. Hentikan instance secara permanen.
    aws ec2 terminate-instances --region ap-southeast-1 --instance-ids i-xxxxxxxxxxxxxxxxx
  2. Lepaskan Elastic IP yang sudah tidak terpakai.
    aws ec2 release-address --region ap-southeast-1 --allocation-id eipalloc-xxxxxxxxxxxxxxxxx
  3. Hapus security group khusus yang sudah dibuat, setelah instance yang memakainya benar-benar terhapus.
    aws ec2 delete-security-group --region ap-southeast-1 --group-id sg-xxxxxxxxxxxxxxxxx

Verifikasi dan Troubleshooting

  • Perintah delete-security-group akan gagal dengan pesan DependencyViolation jika masih ada resource lain yang memakainya, termasuk instance yang belum sepenuhnya berstatus terminated. Tunggu beberapa saat dan ulangi jika ini terjadi.
  • Volume root EBS pada AMI Ubuntu resmi memakai opsi delete on termination aktif secara default, sehingga otomatis ikut terhapus begitu instance-nya di-terminate, tidak perlu dihapus manual terpisah seperti snapshot pada Bagian 41.4.3.

41.5 Ringkasan Alur yang Sama di Azure dan GCP

Seluruh alur di Bagian 41.2 sampai 41.4, mencari cloud image resmi, menyuntikkan konfigurasi lewat cloud-init, mengatur firewall di level cloud, sampai memberi alamat IP publik yang persisten, berlaku dengan pola pikir yang sama persis di Azure maupun GCP, hanya berbeda nama perintah dan sedikit detail teknis. Tabel berikut merangkum padanan perintah CLI resmi masing-masing provider untuk meluncurkan instance dengan cloud-init.

ProviderCLI resmiContoh perintah inti
AWSawsaws ec2 run-instances --image-id resolve:ssm:... --instance-type t3.medium --user-data file://user-data.yaml
Azureazaz vm create --resource-group rg-vm-cloud01 --name vm-cloud01 --image Canonical:ubuntu-26_04-lts:server:latest --size Standard_B2s --admin-username sysadmin --custom-data @user-data.yaml
GCPgcloudgcloud compute instances create vm-cloud01 --zone asia-southeast1-a --image-family ubuntu-2604-lts --image-project ubuntu-os-cloud --machine-type e2-medium --metadata-from-file user-data=user-data.yaml

Dua detail layak digarisbawahi soal tabel di atas. Pertama, nama offer Azure (ubuntu-26_04-lts) dan image family GCP (ubuntu-2604-lts) mengikuti pola penamaan yang konsisten dipakai Canonical untuk rilis LTS sebelumnya, tetapi nama persis untuk sebuah rilis baru sebaiknya selalu diverifikasi ulang lewat perintah pencarian resmi masing-masing provider (az vm image list --publisher Canonical --all --output table untuk Azure, gcloud compute images list --project ubuntu-os-cloud --filter="family~ubuntu-2604" untuk GCP) sebelum benar-benar dipakai, bukan disalin mentah-mentah dari mana pun termasuk dari bab ini, karena nama family dan versi image bisa saja diperbarui Canonical sewaktu-waktu. Kedua, baik Azure lewat flag --custom-data maupun GCP lewat metadata key user-data sama-sama meneruskan isi file cloud-config ke datasource cloud-init masing-masing, Azure dan GCE, persis seperti yang sudah dipetakan di tabel datasource pada Bagian 37.4.1. Perhatikan tanda @ di depan user-data.yaml pada perintah Azure di atas, konvensi Azure CLI untuk memberi tahu bahwa isi argumen harus dibaca dari file, bukan diperlakukan sebagai teks literal; tanpa tanda ini, Azure CLI akan mengira nama file itu sendiri adalah isi konfigurasinya. File user-data.yaml yang sudah kita tulis dan validasi di Bagian 41.2.3 karenanya bisa dipakai ulang apa adanya di ketiga provider ini tanpa perlu ditulis ulang, satu bukti nyata bahwa portabilitas cloud-init yang dijanjikan Bab 37 benar-benar terbukti lintas provider, bukan cuma klaim di atas kertas.

Pemetaan region juga layak dicatat untuk kebutuhan latency dari Indonesia: region AWS ap-southeast-1 yang dipakai sepanjang bab ini setara dengan southeastasia di Azure dan asia-southeast1 di GCP, ketiganya berlokasi fisik di Singapura.

Instance vm-cloud01 di bab ini, kalau tidak sengaja dihapus mengikuti Bagian 41.4.4 untuk latihan, sekarang sudah punya cloud image resmi dan cloud-init yang berjalan lewat metadata service AWS, firewall dua lapis lewat security group dan UFW/nftables, alamat IP publik yang persisten, serta snapshot volume yang melengkapi (bukan menggantikan) repository Borg dari Bab 40. Seluruh proses ini masih dijalankan manual lewat perintah aws satu per satu, cukup untuk memahami konsep dasarnya, tetapi jelas tidak praktis diulang setiap kali ada deployment baru atau perubahan kode dari Developer. Bab 42 mengambil alih dari sini, menyambungkan repository Git yang sudah jadi fondasi workflow modern ke server yang baru saja kita bangun ini lewat pipeline CI/CD, supaya proses deployment yang tadinya serangkaian perintah manual berubah menjadi alur otomatis yang konsisten setiap kali kode baru siap dirilis.