Praktik 11: Deployment GCP
Audit ini memeriksa tiga dokumen dan lima berkas pada Praktik 11, terhadap empat aturan skema yang berlaku:
- Satu project dipakai beberapa peserta, dan peserta dipastikan masuk ke project yang sudah ditentukan.
- Role peserta sudah di-assign. Peserta hanya memakai role yang diberikan, tidak menambah sendiri.
- Setiap peserta wajib memakai slug. Slug menjadi dasar penamaan resource.
- Skema akhir memakai subdomain dari domain penyelenggara.
Sumber yang diperiksa, hanya dari paket hari 3:
Praktik 11/1.Konfigurasi ProjectPraktik 11/2.Google Cloud PlatformPraktik 11/3.Penambahan SubdomainPraktik 11/file latihan/:docker-compose.yml,nginx.conf,cloudbuild.yaml,scripts/check-config.mjs,scripts/periksa-nginx.mjs
Hasil audit terhadap empat aturan
Section titled “Hasil audit terhadap empat aturan”| 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.
Aturan 2: role sudah di-assign
Section titled “Aturan 2: role sudah di-assign”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.builderroles/artifactregistry.writerroles/compute.instanceAdmin.v1roles/compute.osAdminLoginroles/iap.tunnelResourceAccessorroles/logging.logWriterTahap 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/editorroles/resourcemanager.projectIamAdminroles/serviceusage.serviceUsageAdminroles/iam.serviceAccountAdminroles/iam.serviceAccountUserroles/compute.osAdminLoginroles/iap.tunnelResourceAccessorroles/cloudbuild.connectionAdminroles/logging.viewerTahap 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:
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.
Aturan 3: wajib pakai slug
Section titled “Aturan 3: wajib pakai slug”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_IDmenggunakan “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
PESERTAdan 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.
Aturan 4: skema akhir subdomain
Section titled “Aturan 4: skema akhir subdomain”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:
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:
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 · iapdns · domains · secretmanagerTiga 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.
Cacat pada berkas latihan
Section titled “Cacat pada berkas latihan”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
listendanssl_certificateharus berada di dalam blokserver { }. Nginx tidak menerimalistendi luar blokserver, sehingganginx -tdi tahap yang sama akan menolaknya. nginx.conftidak punyainclude, 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:roSertifikat 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:
cp .env.example .envFolder 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:
VM_SA="${PROJECT_NUMBER}-asisten01@example.com"Service Account default Compute Engine berbentuk:
${PROJECT_NUMBER}-asisten02@example.comPerintah 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_IDDua 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
Section titled “Solusi”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:roMount /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:
cd /opt/webgis/appsudo docker compose exec -T nginx nginx -t && \ sudo docker compose exec -T nginx nginx -s reloadBerkas 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_IDadalah 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:
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.
# Ganti dengan Project ID dari koordinatorPROJECT_ID=
# Slug peserta, dari daftar yang dikirim koordinator, maksimal 18 karakterPARTICIPANT_ID=
# Nilai bersama, jangan diubahREGION=asia-southeast2ZONE=asia-southeast2-bREPOSITORY=katalog-imagesAPP_DIR=/opt/webgis/app2. Ganti check-config.mjs dengan periksa-yaml.mjs, yang tidak butuh paket yaml.
Perintahnya tetap sama:
node scripts/periksa-yaml.mjs docker-compose.yml cloudbuild.yaml3. 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-SLUGGanti 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:
SUBDOMAIN="${PARTICIPANT_ID}.gisbigtrainer.com"Dengan begitu peserta tidak perlu menetapkannya ulang di Dokumen 3.
VM_SA perbaiki di Tahap 6:
VM_SA="${PROJECT_NUMBER}-asisten02@example.com"Daftar API di Tahap 3 sesuaikan dengan yang benar-benar dipakai:
compute · cloudbuild · artifactregistry · iapTiga 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:
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/editorroles/resourcemanager.projectIamAdminroles/serviceusage.serviceUsageAdminroles/iam.serviceAccountAdminroles/iam.serviceAccountUserroles/compute.osAdminLoginroles/iap.tunnelResourceAccessorroles/cloudbuild.connectionAdminroles/logging.viewerBila 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 pemeriksa
Section titled “Alat pemeriksa”| 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 |
Ringkasan
Section titled “Ringkasan”| 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 |
Urutan perbaikan
Section titled “Urutan perbaikan”Empat butir Kritikal semuanya berada di satu blok, dan saling bergantung. Memperbaiki sebagian tidak cukup.
- Blok HTTPS. Empat hal sekaligus:
- Tambahkan
location ^~ /.well-known/acme-challenge/ { root /var/www/certbot; }dinginx.conf, lalu tambahkaninclude /etc/nginx/tls/*.conf; - Tambahkan volume
./certbot-webroot:/var/www/certbot:ro,./tls:/etc/nginx/tls:ro, dan/etc/letsencrypt:/etc/letsencrypt:ropada servicenginx - Publikasikan port 443 di
docker-compose.yml - Ganti isi
tls/aktifkan.confmenjadi server block utuh, bukan tiga directive lepas
- Tambahkan
- Sertakan
.env.exampledi folderfile latihan. Modul sudah menyuruh membuatnya dan memakainya, hanya berkasnya belum ikut. - Perbaiki
VM_SAmenjadi${PROJECT_NUMBER}-asisten02@example.com. - Satu baris di Tahap 2 soal aturan penulisan identitas peserta: huruf kecil, angka, dan tanda hubung, maksimal 18 karakter.
- Satu baris di checklist penyerahan koordinator: periksa daftar identitas peserta tidak memuat nilai kembar di project yang sama.
- Jelaskan jalur pemulihan di kedua sisi: peserta berhenti dan melapor, koordinator menetapkan nilai pengganti.
- Sesuaikan daftar API di Tahap 3 menjadi
compute,cloudbuild,artifactregistry, daniap. Tiga API lain tidak punya langkah yang memakainya. - Pindahkan
SUBDOMAINke blok variabel Tahap 2, dan hapusDNS_ZONE_NAME. - Ubah Tahap 3 Dokumen 3 menjadi langkah pelaporan ke koordinator, bukan pembuatan record.
- Samakan
NEXTAUTH_URLdi semua tempat, memakai bentuk yang memuat/portal.