Lewati ke konten

Praktik 11: Deployment GCP

InternalSebagian terujiArti badge ini

Audit ini memeriksa tiga dokumen dan lima berkas pada Praktik 11, terhadap empat aturan skema yang berlaku:

  1. Satu project dipakai beberapa peserta, dan peserta dipastikan masuk ke project yang sudah ditentukan.
  2. Role peserta sudah di-assign. Peserta hanya memakai role yang diberikan, tidak menambah sendiri.
  3. Setiap peserta wajib memakai slug. Slug menjadi dasar penamaan resource.
  4. Skema akhir memakai subdomain dari domain penyelenggara.

Sumber yang diperiksa, hanya dari paket hari 3:

  • Praktik 11/1. Konfigurasi Project
  • Praktik 11/2. Google Cloud Platform
  • Praktik 11/3. Penambahan Subdomain
  • Praktik 11/file latihan/: docker-compose.yml, nginx.conf, cloudbuild.yaml, scripts/check-config.mjs, scripts/periksa-nginx.mjs
Aturan Status Keterangan
1. Peserta masuk project yang ditentukan Sesuai Tahap 1 meminta memilih project yang disiapkan akun master dan memastikan Project ID benar
2. Role sudah di-assign Sesuai Sembilan role yang diberikan cukup untuk seluruh langkah IAM di modul. Modul hanya belum menyebut bahwa role itu berasal dari koordinator
3. Wajib pakai slug Tidak sesuai Istilah slug tidak pernah dipakai, dan aturan penulisannya tidak disebut
4. Skema akhir subdomain Sebagian Alurnya sudah benar, tetapi ada beberapa langkah yang belum didukung berkas

Rinciannya di bawah.

P11-1. Modul tidak menyebut role berasal dari koordinator (Sedang)

Section titled “P11-1. Modul tidak menyebut role berasal dari koordinator (Sedang)”

Tahap 4 meminta peserta membuat Service Account lalu memberinya enam role:

roles/cloudbuild.builds.builder
roles/artifactregistry.writer
roles/compute.instanceAdmin.v1
roles/compute.osAdminLogin
roles/iap.tunnelResourceAccessor
roles/logging.logWriter

Tahap 6 menambah dua binding lagi, salah satunya pada Service Account yang melekat di VM.

Modul tidak menyebut bahwa role peserta sendiri sudah ditetapkan koordinator, dan tidak menjelaskan bahwa langkah IAM di Tahap 4 dan 6 hanya bisa dikerjakan karena role itu memang sudah diberikan. Peserta yang membaca modul akan mengira dirinya bebas mengatur IAM di project.

Yang perlu ditambahkan: satu kalimat di bagian Prasyarat bahwa role sudah dipasang koordinator, dan bahwa langkah IAM di modul ini berlaku pada Service Account yang dibuat peserta sendiri, bukan pada role peserta.

P11-2. Role yang di-assign sudah cukup untuk langkah IAM di modul (Sesuai)

Section titled “P11-2. Role yang di-assign sudah cukup untuk langkah IAM di modul (Sesuai)”

Modul meminta peserta menjalankan perintah IAM di Tahap 4 dan Tahap 6. Saya petakan setiap perintah ke izin yang dibutuhkan, lalu mencocokkannya dengan sembilan role yang diberikan:

roles/editor
roles/resourcemanager.projectIamAdmin
roles/serviceusage.serviceUsageAdmin
roles/iam.serviceAccountAdmin
roles/iam.serviceAccountUser
roles/compute.osAdminLogin
roles/iap.tunnelResourceAccessor
roles/cloudbuild.connectionAdmin
roles/logging.viewer

Tahap 4, pembuatan Service Account deployment:

Perintah Izin dibutuhkan Role penyedia
iam service-accounts create iam.serviceAccounts.create iam.serviceAccountAdmin
enam kali projects add-iam-policy-binding resourcemanager.projects.setIamPolicy resourcemanager.projectIamAdmin

Tahap 6, penyiapan identitas VM:

Perintah Izin dibutuhkan Role penyedia
projects add-iam-policy-binding untuk artifactregistry.reader resourcemanager.projects.setIamPolicy resourcemanager.projectIamAdmin
iam service-accounts add-iam-policy-binding pada Service Account VM iam.serviceAccounts.setIamPolicy pada Service Account itu iam.serviceAccountAdmin

Yang terakhir sempat diragukan, karena izinnya berada di tingkat resource Service Account, bukan di tingkat project. Ternyata roles/iam.serviceAccountAdmin memang memuat iam.serviceAccounts.setIamPolicy pada resource tersebut, sehingga perintah itu bisa dijalankan.

roles/iam.serviceAccountUser memberi izin actAs yang dibutuhkan saat memasang Service Account pada VM di Tahap 7, dan roles/compute.instanceAdmin.v1 yang diberikan ke Service Account Cloud Build memuat izin yang sama untuk keperluan SSH.

Perlu dicatat: roles/editor saja tidak cukup untuk langkah-langkah itu. Yang membuatnya bisa dijalankan adalah iam.serviceAccountAdmin dan resourcemanager.projectIamAdmin.

Cara memeriksa sendiri di project masing-masing:

Terminal window
gcloud projects get-iam-policy "$PROJECT_ID" \
--flatten="bindings[].members" \
--filter="bindings.members:$(gcloud config get-value account)" \
--format="table(bindings.role)"

Sembilan role di atas harus muncul. Bila ada yang kurang, laporkan ke koordinator sebelum Tahap 4.

P11-3. Aturan penulisan identitas peserta tidak disebut (Rendah)

Section titled “P11-3. Aturan penulisan identitas peserta tidak disebut (Rendah)”

Modul memakai istilah “identitas peserta” dan “kode/nama peserta”:

Peserta juga perlu mengetahui Project ID dan identitas peserta yang digunakan sebagai PARTICIPANT_ID

Pada contoh ini PARTICIPANT_ID menggunakan “nama01”. Ganti nilai tersebut dengan kode/nama peserta yang diberikan koordinator.

Istilah itu sudah sepadan dengan yang dipakai koordinator, dan nilainya memang ditetapkan koordinator, bukan dipilih peserta. Jadi tidak ada masalah penamaan, dan tidak ada peserta yang memilih sendiri.

Yang belum disebut adalah aturan penulisannya. Tiga hal berikut menentukan berhasil atau gagalnya Tahap 4, dan tidak satu pun dijelaskan:

  • Nama VM, Service Account, dan trigger Google Cloud hanya menerima huruf kecil, angka, dan tanda hubung. Peserta yang menerima kode memuat huruf besar atau spasi akan gagal dengan pesan yang menyebut nama resource, bukan nama variabelnya.
  • Batas 18 karakter. Nama Service Account ID dibatasi 30 karakter, sedangkan awalan cb-deployer- sudah memakai 12 karakter.
  • Nilai itu diturunkan menjadi delapan nama resource sekaligus.

Karena nilainya ditetapkan koordinator, risiko ini berpindah ke daftar yang disusun koordinator, dan bukan ke peserta. Satu baris di Tahap 2 sudah cukup menutupnya.

P11-4. Tidak ada pemeriksaan keunikan identitas peserta (Sedang)

Section titled “P11-4. Tidak ada pemeriksaan keunikan identitas peserta (Sedang)”

Modul peserta baru mengetahui nilai identitasnya bermasalah ketika nama sudah dipakai, yaitu pada Tahap 4 saat gcloud iam service-accounts create gagal dengan ALREADY_EXISTS.

Tidak ada pemeriksaan sebelum titik itu, di sisi mana pun:

  • Modul peserta tidak memuat langkah pemeriksaan sebelum Tahap 4.
  • Panduan koordinator menetapkan nilainya lewat peta PESERTA dan tabel contoh, tanpa langkah pemeriksaan keunikan.

Karena nilainya ditetapkan koordinator dan dikirim ke peserta, satu-satunya jalan masuknya adalah salah ketik pada daftar yang disusun koordinator. Peluangnya kecil, tetapi akibatnya besar: peserta kedua buntu di Tahap 4 dengan pesan yang tidak menyebut penyebabnya.

P11-5. Tidak ada jalur pemulihan bila identitas bentrok (Sedang)

Section titled “P11-5. Tidak ada jalur pemulihan bila identitas bentrok (Sedang)”

Modul peserta tidak menjelaskan apa yang harus dilakukan bila nilai yang diterimanya ternyata sudah dipakai peserta lain.

Yang paling berbahaya adalah reaksi yang wajar diambil peserta: mengganti nilainya sendiri agar bisa lanjut. Tindakan itu membuat empat hal tidak lagi cocok:

  • Nama VM dan Service Account berbeda dari yang dicatat koordinator.
  • Subdomain yang diminta koordinator ke penyelenggara tidak menunjuk ke VM peserta itu.
  • Record DNS yang sudah dibuat penyelenggara menjadi tidak terpakai.
  • Peserta kehilangan kemampuan memakai filter nama saat membersihkan resource sendiri.

Karena itu jalur pemulihannya perlu ditulis di kedua sisi: peserta berhenti dan melapor, lalu koordinator menetapkan nilai pengganti dan memperbarui daftarnya.

P11-6. SUBDOMAIN dipakai di delapan tempat tetapi tidak pernah dideklarasikan (Tinggi)

Section titled “P11-6. SUBDOMAIN dipakai di delapan tempat tetapi tidak pernah dideklarasikan (Tinggi)”

Blok variabel di Tahap 2 mendeklarasikan 15 variabel, dan SUBDOMAIN bukan salah satunya. Namun Dokumen 3 memakainya di delapan tempat, termasuk perintah dig dan perintah certbot:

Terminal window
curl -sS -o /dev/null -w "acme %{http_code}\n" \
"http://${SUBDOMAIN}/.well-known/acme-challenge/uji"

Dokumen 3 baru menetapkan nilainya pada Tahap 2 dan lagi pada Tahap 9:

Terminal window
SUBDOMAIN="nama01.gisbigtrainer.com"

Peserta yang menjalankan Tahap 1 sampai 8 dengan sesi Cloud Shell yang sudah terputus akan menemukan variabel kosong, dan perintah curl di Tahap 8 gagal tanpa menjelaskan sebabnya. Karena SUBDOMAIN diturunkan dari PARTICIPANT_ID, tempatnya sebenarnya di blok Tahap 2 bersama variabel turunan lain.

P11-7. DNS_ZONE_NAME dideklarasikan tetapi tidak pernah dipakai (Sedang)

Section titled “P11-7. DNS_ZONE_NAME dideklarasikan tetapi tidak pernah dipakai (Sedang)”

DNS_ZONE_NAME="geoportal-${PARTICIPANT_ID}" ada di blok variabel, dan tidak muncul lagi di seluruh tiga dokumen. Pada skema subdomain, peserta tidak membuat zone apa pun, sehingga variabel ini hanya menyisakan pertanyaan apakah dirinya perlu mengurus DNS.

P11-8. Tahap 3 memeriksa tiga API yang tidak dipakai (Sedang)

Section titled “P11-8. Tahap 3 memeriksa tiga API yang tidak dipakai (Sedang)”

Tahap 3 meminta memastikan tujuh API aktif:

compute · cloudbuild · artifactregistry · iap
dns · domains · secretmanager

Tiga di antaranya tidak punya langkah yang memakainya di seluruh tiga dokumen:

API Dipakai untuk
dns.googleapis.com Tidak ada. Record DNS dibuat penyelenggara di luar GCP
domains.googleapis.com Tidak ada. Peserta tidak mendaftarkan domain
secretmanager.googleapis.com Tidak ada. Tidak ada penyimpanan rahasia di modul

Daftar itu berasal dari kebutuhan skema domain sendiri. Pada skema subdomain, ketiganya hanya menambah kebingungan, dan domains.googleapis.com bahkan mengarahkan peserta untuk mendaftarkan domain, yang tidak perlu dilakukan.

P11-9. Record A dibuat peserta, bukan penyelenggara (Sedang)

Section titled “P11-9. Record A dibuat peserta, bukan penyelenggara (Sedang)”

Tahap 3 pada Dokumen 3 bertanda:

Dijalankan di: Pengelola DNS / Registrar

dan berbunyi “Buka pengelola DNS pada tempat domain didaftarkan”, lalu “Tambahkan record DNS baru”. Pada skema subdomain, domain beserta zone-nya dipegang penyelenggara, sehingga peserta tidak bisa membuka pengelola DNS-nya.

Bagian ini perlu menyebut bahwa peserta melaporkan slug dan alamat IP statisnya, lalu penyelenggara yang membuat record A-nya.

P11-10. nginx.conf belum memuat blok ACME (Kritikal)

Section titled “P11-10. nginx.conf belum memuat blok ACME (Kritikal)”

nginx.conf pada file latihan hanya punya satu directive listen, yaitu port 80, dan tidak punya location untuk /.well-known/acme-challenge/:

server {
listen 80;
server_name _;

Padahal Tahap 8 memeriksa jalur itu, menyatakan 404 sebagai hasil yang diharapkan, dan menambah catatan “periksa kembali konfigurasi location untuk ACME pada Nginx”. Blok location yang dimaksud tidak pernah disuruh dibuat di dokumen mana pun. Dokumen 1 hanya menyuruh menyalin nginx.conf apa adanya, dan Dokumen 3 hanya menyebut “blok location pada langkah sebelumnya” tanpa langkah sebelumnya yang menambahkannya.

Akibatnya permintaan challenge diteruskan ke aplikasi Next.js, bukan ke webroot, dan Certbot di Tahap 9 gagal dengan kode 404.

P11-11. Berkas TLS bukan server block yang sah, dan tidak pernah dibaca (Kritikal)

Section titled “P11-11. Berkas TLS bukan server block yang sah, dan tidak pernah dibaca (Kritikal)”

Tahap 10 menulis tiga baris ke tls/aktifkan.conf:

listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/SUBDOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/SUBDOMAIN/privkey.pem;

Dua masalah:

  • Tiga baris itu bukan server block. Directive listen dan ssl_certificate harus berada di dalam blok server { }. Nginx tidak menerima listen di luar blok server, sehingga nginx -t di tahap yang sama akan menolaknya.
  • nginx.conf tidak punya include, sehingga berkas itu tidak berpengaruh walaupun isinya benar.

P11-12. Port 443 tidak dipublikasikan (Kritikal)

Section titled “P11-12. Port 443 tidak dipublikasikan (Kritikal)”

docker-compose.yml hanya memuat satu pemetaan port:

ports:
- "80:80"

Tahap 10 mengarahkan Nginx untuk mendengarkan di port 443 di dalam container, tetapi host tidak meneruskan trafik ke port itu, sehingga Tahap 11 tidak bisa berhasil walaupun sertifikatnya terbit.

P11-13. Direktori sertifikat tidak di-mount ke container (Kritikal)

Section titled “P11-13. Direktori sertifikat tidak di-mount ke container (Kritikal)”

Service nginx hanya me-mount satu berkas:

volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro

Sertifikat Let’s Encrypt berada di /etc/letsencrypt pada host dan tidak tersedia di dalam container. nginx -t pada Tahap 10 akan gagal dengan pesan bahwa berkas sertifikat tidak ditemukan.

P11-14. .env.example disuruh dibuat tetapi tidak disertakan (Tinggi)

Section titled “P11-14. .env.example disuruh dibuat tetapi tidak disertakan (Tinggi)”

Dokumen 1 memuat isi .env.example, dan Tahap 16 memakainya:

Terminal window
cp .env.example .env

Folder file latihan hanya berisi cloudbuild.yaml, docker-compose.yml, nginx.conf, dan dua skrip. Berkas .env.example tidak ada, padahal docker-compose.yml mewajibkan NEXTJS_IMAGE terisi dan menolak start bila nilainya kosong.

P11-15. check-config.mjs butuh paket yang tidak terpasang (Tinggi)

Section titled “P11-15. check-config.mjs butuh paket yang tidak terpasang (Tinggi)”

Berkas scripts/check-config.mjs memuat:

const YAML = createRequire(import.meta.url)('yaml');

Paket yaml tidak ada di dependencies maupun devDependencies pada package.json yang dipakai Praktik 10, sehingga perintah yang diminta Dokumen 1 berhenti dengan Error: Cannot find module 'yaml'. Node 24 juga tidak punya parser YAML bawaan.

P11-16. VM_SA bukan alamat service account yang sah (Tinggi)

Section titled “P11-16. VM_SA bukan alamat service account yang sah (Tinggi)”

Perbaikannya tersedia sebagai berkas jadi: Praktik 11/perbaikan/vm-sa.md.

Tahap 6:

Terminal window
VM_SA="${PROJECT_NUMBER}-asisten01@example.com"

Service Account default Compute Engine berbentuk:

${PROJECT_NUMBER}-asisten02@example.com

Perintah berikutnya akan gagal dengan pesan bahwa service account tidak ada. Nilainya juga sama untuk semua peserta dalam satu project, karena hanya bergantung pada nomor project.

P11-17. Tahap 22 memakai placeholder yang berbeda gaya (Sedang)

Section titled “P11-17. Tahap 22 memakai placeholder yang berbeda gaya (Sedang)”

Tabel substitution variable menulis nilai sebagai teks biasa:

_VM_NAME = webgis-PARTICIPANT_ID
_VM_ZONE = ${ZONE}
_VM_APP_DIR = ${APP_DIR}
_IMAGE_NAME = nextjs-PARTICIPANT_ID

Dua baris memakai sintaks ${...}, dua baris lain memakai PARTICIPANT_ID sebagai teks. Peserta yang menyalin tabel itu apa adanya akan mengisi webgis-PARTICIPANT_ID secara harfiah, dan build akan mencoba SSH ke VM yang tidak ada.

P11-18. NEXTAUTH_URL ditulis dalam dua bentuk (Sedang)

Section titled “P11-18. NEXTAUTH_URL ditulis dalam dua bentuk (Sedang)”
Lokasi Nilai
Dokumen 1 http://IP_EKSTERNAL_VM/portal/
Dokumen 3, Tahap 13 https://SUBDOMAIN/portal

NextAuth memakai NEXTAUTH_URL untuk menentukan nama cookie dan alamat pengalihan. Bila nilainya sudah https:// sedangkan aplikasi masih dibuka lewat http://, cookie bertanda Secure tidak dikirim browser, dan sesi tampak seperti tidak pernah login tanpa pesan galat.

P11-19. AUTH_API_URL menunjuk ke localhost (Sedang)

Section titled “P11-19. AUTH_API_URL menunjuk ke localhost (Sedang)”

Dokumen 1 memuat AUTH_API_URL=http://localhost:3000/portal/api. Di dalam container Next.js, localhost menunjuk ke container itu sendiri, bukan ke VM.

P11-20. Setelan CORS tidak diperlukan (Rendah)

Section titled “P11-20. Setelan CORS tidak diperlukan (Rendah)”

docker-compose.yml menyetel GEOSERVER_CORS_ENABLED dan GEOSERVER_CORS_ALLOWED_ORIGINS. Nginx melayani aplikasi dan GeoServer pada origin yang sama, sehingga CORS tidak diperlukan pada konfigurasi ini. Kedua variabel itu juga tidak dibaca oleh image yang dipakai, seperti diterangkan pada P7-3.

P11-21. Dokumen disertakan dalam dua format (Rendah)

Section titled “P11-21. Dokumen disertakan dalam dua format (Rendah)”

Praktik 11 punya DOCX dan PDF untuk ketiga bagiannya, sedangkan Praktik 6 sampai 10 hanya DOCX. Bila isi keduanya berbeda, tidak ada cara mengetahui mana yang terbaru.

Solusi di bawah dikelompokkan supaya bisa dikerjakan bertahap. Kelompok pertama menutup semua butir Kritikal.

Temuan Kelompok solusi
P11-1 E, penyampaian dan kebersihan
P11-2 Tidak ada perbaikan, role sudah mencukupi
P11-3, P11-4, P11-5 B, identitas peserta
P11-6, P11-7, P11-8, P11-9 D, alamat dan variabel
P11-10, P11-11, P11-12, P11-13 A, blok HTTPS
P11-14, P11-15, P11-17 C, berkas yang kurang
P11-16, P11-18, P11-19 D, alamat dan variabel
P11-20, P11-21 E, penyampaian dan kebersihan

Kelompok A: blok HTTPS (P11-10 sampai P11-13)

Section titled “Kelompok A: blok HTTPS (P11-10 sampai P11-13)”

Empat butir ini saling bergantung. Memperbaiki sebagian tidak cukup, jadi kerjakan sekaligus.

1. Tambahkan blok ACME di nginx.conf. Letakkan sebelum location /:

location ^~ /.well-known/acme-challenge/ {
root /var/www/certbot;
default_type "text/plain";
try_files $uri =404;
}

Perhatikan ^~. Tanpa itu, permintaan challenge bisa jatuh ke location / dan diteruskan ke Next.js.

2. Tambahkan include untuk berkas TLS, di akhir nginx.conf:

include /etc/nginx/tls/*.conf;

3. Publikasikan port 443 dan mount dua direktori pada service nginx di docker-compose.yml:

nginx:
image: nginx:1.27-alpine
container_name: nginx_proxy
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./certbot-webroot:/var/www/certbot:ro
- ./tls:/etc/nginx/tls:ro
- /etc/letsencrypt:/etc/letsencrypt:ro

Mount /etc/letsencrypt wajib. Tanpa itu, nginx -t gagal dengan pesan bahwa berkas sertifikat tidak ditemukan.

4. Tulis server block utuh, bukan tiga baris. Tahap 10 pada modul menulis tiga directive lepas. Bentuk yang benar adalah blok server penuh:

server {
listen 443 ssl;
http2 on;
server_name SUBDOMAIN;
ssl_certificate /etc/letsencrypt/live/SUBDOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/SUBDOMAIN/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
location ^~ /.well-known/acme-challenge/ { root /var/www/certbot; }
location = / { return 302 /portal; }
location = /geoserver { return 302 /geoserver/web; }
location /geoserver/ {
resolver 127.0.0.11 valid=10s ipv6=off;
set $geoserver_upstream http://geoserver:8080;
rewrite ^/geoserver/(.*)$ /geoserver/$1 break;
proxy_pass $geoserver_upstream;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto https;
}
location / {
resolver 127.0.0.11 valid=10s ipv6=off;
set $nextjs_upstream http://nextjs:3000;
proxy_pass $nextjs_upstream;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
}
}

Tulis blok itu ke /opt/webgis/app/tls/aktifkan.conf, lalu periksa dan muat ulang:

Terminal window
cd /opt/webgis/app
sudo docker compose exec -T nginx nginx -t && \
sudo docker compose exec -T nginx nginx -s reload

Berkas perbaikan/nginx.conf memuat versi nginx.conf yang sudah lengkap, dan perbaikan/tls-aktifkan.conf.md memuat perintahnya siap tempel.

Cara memastikan berhasil: curl -sSIL https://SUBDOMAIN/portal mengembalikan 200, dan /var/log/letsencrypt/letsencrypt.log tidak memuat baris Invalid response.

Kelompok B: identitas peserta (P11-3 sampai P11-5)

Section titled “Kelompok B: identitas peserta (P11-3 sampai P11-5)”

1. Ganti istilah dan sebutkan aturannya di Dokumen 2, Tahap 2:

PARTICIPANT_ID adalah slug peserta. Pakai nilai yang dikirim koordinator, jangan mengetik sendiri. Slug hanya boleh berisi huruf kecil, angka, dan tanda hubung, maksimal 18 karakter.

Batas 18 karakter berasal dari nama Service Account: cb-deployer- memakai 12 karakter, sedangkan Service Account ID dibatasi 30 karakter.

2. Tambahkan pemeriksaan sebelum Tahap 4. Satu perintah, dijalankan peserta:

Terminal window
gcloud iam service-accounts describe \
"cb-deployer-${PARTICIPANT_ID}@${PROJECT_ID}.iam.gserviceaccount.com" \
--project="$PROJECT_ID" >/dev/null 2>&1 \
&& echo "BERHENTI: slug sudah dipakai peserta lain. Lapor koordinator." \
|| echo "Aman, lanjutkan ke Tahap 4."

Bila Service Account itu sudah ada, hentikan dan lapor. Jangan mengganti slug sendiri.

3. Tambahkan satu baris di checklist penyerahan koordinator: periksa daftar slug tidak memuat nilai kembar di project yang sama, lalu kirim daftar itu ke setiap peserta.

4. Tulis jalur pemulihan di kedua sisi. Peserta berhenti dan melapor. Koordinator menetapkan slug pengganti, memperbarui daftarnya, dan menyampaikan slug baru ke peserta.

5. Hapus DNS_ZONE_NAME dari blok variabel, karena tidak dipakai pada skema subdomain.

Kelompok C: berkas yang kurang (P11-14, P11-15, P11-17)

Section titled “Kelompok C: berkas yang kurang (P11-14, P11-15, P11-17)”

1. Sertakan .env.example di folder file latihan. Isinya diambil dari Dokumen 1, dengan satu penajaman: komentari setiap variabel yang harus diisi peserta.

Terminal window
# Ganti dengan Project ID dari koordinator
PROJECT_ID=
# Slug peserta, dari daftar yang dikirim koordinator, maksimal 18 karakter
PARTICIPANT_ID=
# Nilai bersama, jangan diubah
REGION=asia-southeast2
ZONE=asia-southeast2-b
REPOSITORY=katalog-images
APP_DIR=/opt/webgis/app

2. Ganti check-config.mjs dengan periksa-yaml.mjs, yang tidak butuh paket yaml. Perintahnya tetap sama:

Terminal window
node scripts/periksa-yaml.mjs docker-compose.yml cloudbuild.yaml

3. Perbaiki placeholder pada tabel substitution variable di Tahap 22, supaya keempatnya memakai gaya yang sama:

_VM_NAME = webgis-SLUG
_VM_ZONE = asia-southeast2-b
_VM_APP_DIR = /opt/webgis/app
_IMAGE_NAME = nextjs-SLUG

Ganti SLUG dengan nilai slug peserta. Tulis juga satu kalimat peringatan: jangan menyalin SLUG secara harfiah.

Kelompok D: alamat dan variabel (P11-6 sampai P11-9, P11-16, P11-18, P11-19)

Section titled “Kelompok D: alamat dan variabel (P11-6 sampai P11-9, P11-16, P11-18, P11-19)”

SUBDOMAIN pindahkan ke blok Tahap 2, bersama variabel turunan lain:

Terminal window
SUBDOMAIN="${PARTICIPANT_ID}.gisbigtrainer.com"

Dengan begitu peserta tidak perlu menetapkannya ulang di Dokumen 3.

VM_SA perbaiki di Tahap 6:

Terminal window
VM_SA="${PROJECT_NUMBER}-asisten02@example.com"

Daftar API di Tahap 3 sesuaikan dengan yang benar-benar dipakai:

compute · cloudbuild · artifactregistry · iap

Tiga API lain, dns, domains, dan secretmanager, tidak punya langkah yang memakainya pada skema subdomain.

Tahap 3 Dokumen 3 ubah menjadi langkah pelaporan, bukan pembuatan record:

Catat slug dan alamat IP statis VM, lalu laporkan keduanya ke koordinator. Koordinator meneruskan ke penyelenggara untuk dibuatkan record A.

NEXTAUTH_URL samakan di semua tempat, memakai bentuk yang memuat /portal:

NEXTAUTH_URL=http://IP_STATIS_VM/portal/

AUTH_API_URL perbaiki menjadi alamat yang bisa dijangkau dari dalam container, atau hapus bila tidak dipakai.

Kelompok E: penyampaian dan kebersihan (P11-1, P11-20, P11-21)

Section titled “Kelompok E: penyampaian dan kebersihan (P11-1, P11-20, P11-21)”

Tambahkan satu kalimat di Prasyarat:

Role IAM Anda sudah dipasang koordinator. Sembilan role berikut berlaku pada project, dan Anda tidak perlu menambahkannya sendiri.

Hapus dua baris CORS dari docker-compose.yml, karena tidak dibaca image dan tidak diperlukan saat aplikasi serta GeoServer berada pada origin yang sama.

Pilih satu format dokumen. Bila DOCX dan PDF disertakan bersama, pastikan isinya identik, atau simpan salah satunya saja.

Cara memeriksa sendiri di project masing-masing

Section titled “Cara memeriksa sendiri di project masing-masing”

Untuk memastikan role sudah terpasang sesuai daftar:

Terminal window
gcloud projects get-iam-policy "$PROJECT_ID" \
--flatten="bindings[].members" \
--filter="bindings.members:$(gcloud config get-value account)" \
--format="table(bindings.role)"

Sembilan role berikut harus muncul:

roles/editor
roles/resourcemanager.projectIamAdmin
roles/serviceusage.serviceUsageAdmin
roles/iam.serviceAccountAdmin
roles/iam.serviceAccountUser
roles/compute.osAdminLogin
roles/iap.tunnelResourceAccessor
roles/cloudbuild.connectionAdmin
roles/logging.viewer

Bila ada yang kurang, laporkan ke koordinator sebelum Tahap 4. Sembilan role itu sudah mencukupi seluruh langkah IAM di modul, termasuk binding pada Service Account VM di Tahap 6.

Alat Kegunaan
periksa-deploy.mjs Periksa keterkaitan docker-compose.yml, nginx.conf, dan cloudbuild.yaml
periksa-yaml.mjs Pengganti check-config.mjs tanpa dependensi
periksa-nginx.mjs Periksa struktur nginx.conf
uji-subdomain.mjs Periksa DNS, jalur ACME, dan sertifikat sebelum dan sesudah Certbot
pra-terbang.mjs Periksa slug peserta sebelum menyentuh Tahap 4
audit-tabrakan.mjs Jalankan skenario pesimistis terhadap teks modul
Butir Tingkat Inti
P11-3 Rendah Aturan penulisan identitas peserta tidak disebut
P11-10 Kritikal nginx.conf belum memuat blok ACME
P11-11 Kritikal Berkas TLS bukan server block, dan tidak pernah dibaca
P11-12 Kritikal Port 443 tidak dipublikasikan
P11-13 Kritikal Direktori sertifikat tidak di-mount ke container
P11-4 Sedang Tidak ada pemeriksaan keunikan identitas peserta
P11-6 Tinggi SUBDOMAIN dipakai 8 kali tetapi tidak dideklarasikan
P11-14 Tinggi .env.example disuruh dibuat tetapi tidak disertakan
P11-15 Tinggi check-config.mjs butuh paket yang tidak terpasang
P11-16 Tinggi VM_SA bukan alamat service account yang sah
P11-1 Sedang Modul tidak menyebut role berasal dari koordinator
P11-5 Sedang Tidak ada jalur pemulihan bila identitas bentrok
P11-7 Sedang DNS_ZONE_NAME tidak pernah dipakai
P11-8 Sedang Tiga API diperiksa tetapi tidak dipakai
P11-9 Sedang Record A dibuat peserta, bukan penyelenggara
P11-17 Sedang Placeholder substitution memakai dua gaya
P11-18 Sedang NEXTAUTH_URL ditulis dalam dua bentuk
P11-19 Sedang AUTH_API_URL menunjuk ke localhost
P11-20 Rendah Setelan CORS tidak diperlukan
P11-21 Rendah Dokumen disertakan dalam dua format

Empat butir Kritikal semuanya berada di satu blok, dan saling bergantung. Memperbaiki sebagian tidak cukup.

  1. Blok HTTPS. Empat hal sekaligus:
    • Tambahkan location ^~ /.well-known/acme-challenge/ { root /var/www/certbot; } di nginx.conf, lalu tambahkan include /etc/nginx/tls/*.conf;
    • Tambahkan volume ./certbot-webroot:/var/www/certbot:ro, ./tls:/etc/nginx/tls:ro, dan /etc/letsencrypt:/etc/letsencrypt:ro pada service nginx
    • Publikasikan port 443 di docker-compose.yml
    • Ganti isi tls/aktifkan.conf menjadi server block utuh, bukan tiga directive lepas
  2. Sertakan .env.example di folder file latihan. Modul sudah menyuruh membuatnya dan memakainya, hanya berkasnya belum ikut.
  3. Perbaiki VM_SA menjadi ${PROJECT_NUMBER}-asisten02@example.com.
  4. Satu baris di Tahap 2 soal aturan penulisan identitas peserta: huruf kecil, angka, dan tanda hubung, maksimal 18 karakter.
  5. Satu baris di checklist penyerahan koordinator: periksa daftar identitas peserta tidak memuat nilai kembar di project yang sama.
  6. Jelaskan jalur pemulihan di kedua sisi: peserta berhenti dan melapor, koordinator menetapkan nilai pengganti.
  7. Sesuaikan daftar API di Tahap 3 menjadi compute, cloudbuild, artifactregistry, dan iap. Tiga API lain tidak punya langkah yang memakainya.
  8. Pindahkan SUBDOMAIN ke blok variabel Tahap 2, dan hapus DNS_ZONE_NAME.
  9. Ubah Tahap 3 Dokumen 3 menjadi langkah pelaporan ke koordinator, bukan pembuatan record.
  10. Samakan NEXTAUTH_URL di semua tempat, memakai bentuk yang memuat /portal.