Terraform Security: เลิกพก Key File แล้วเปลี่ยนมาใช้ Service Account Impersonation
ปกติแล้วเวลาเราจะรัน Terraform เพื่อจัดการ Infrastructure บน Google Cloud Platform (GCP) ท่ามาตรฐานที่เราคุ้นเคยกันคือการสร้าง Service Account แล้ว download JSON Key file ลงมาเก็บไว้ในเครื่อง ซึ่งวิธีนี้มันก็ง่ายดีครับ แต่มันแลกมาด้วยความเสี่ยงเรื่อง Security เพราะถ้าไฟล์นี้หลุดไปใครก็ได้สิทธิ์นั้นไปทันที แถมยังต้องมานั่งจัดการเรื่อง Key Rotation อีก
วันนี้ผมจะพามาดูวิธีที่ปลอดภัยกว่า นั่นคือการใช้ Service Account Impersonation ครับ
แนวคิดก็คือ ตัวเรา (User Account) จะไปขอยืมสิทธิ์ของ Service Account ชั่วคราว (Generate Short-lived Token) เพื่อไปรัน Terraform แทนที่จะถือ Key ถาวรเอาไว้ครับ
มาเริ่ม Setup กันเลยครับ โจทย์คือเราจะสร้าง Project ใหม่ และเตรียม Service Account ให้พร้อมสำหรับการรัน Terraform โดยใช้ gcloud command ล้วนๆ
สมมติว่าทุกคน Login gcloud เรียบร้อย และมี Permission ในการสร้าง Project นะครับ
เริ่มต้น
- กำหนดค่าตัวแปร (Variables)
เริ่มจากการเตรียม Environment กันก่อน เพื่อให้ Script นี้เอากลับมาใช้ซ้ำได้ง่าย และลดความผิดพลาดครับ
export PROJ_NAME="proj-tflab"
- สร้าง Project
สร้าง Project พร้อมกำหนด Label ในกรณีนี้ กำหนดว่าเป็น Lab และใครเป็น Owner
gcloud projects create ${PROJ_NAME} \ --name="TF Lab" \ --labels=environment=lab,owner=d8kหลังจากสร้าง Project เสร็จ เนื่องจากจะวางแผนให้ใช้งาน Infrastructure จำเป็นต้องเปิด API ครับ ในเคสนี้เราจะลองสร้าง VM ดังนั้นต้องเปิด Compute API ก่อน
# เปิด Compute Engine API gcloud services enable compute.googleapis.com \ --project=${PROJ_NAME} - Link project กับ Billing Account
สร้าง Project เสร็จ ถ้าไม่ผูก Billing ก็ทำอะไรไม่ได้ครับ ขั้นตอนนี้เราต้องหา Billing Account ID ของเราก่อน ใน Console เราใช้คำสั่ง filter หาจากชื่อ Billing ของเราได้เลย (ในตัวอย่างนี้ Billing ผมชื่อ "Bill-2-KTC")
# กำหนดชื่อ Billing ที่ต้องการค้นหา BILLING_NAME="Bill-2-KTC" # ดึง ID มาเก็บใส่ตัวแปร (ใส่ --limit=1 เพื่อความชัวร์ว่าจะได้ค่าเดียว) BILLING_ID=$(gcloud billing accounts list \ --filter="displayName='${BILLING_NAME}'" \ --format="value(name)" \ --limit=1) echo "Billing ID found: ${BILLING_ID}" # ทำการ Link Project เข้ากับ Billing Account gcloud billing projects link ${PROJ_NAME} --billing-account=${BILLING_ID}เช็คความเรียบร้อยอีกครั้ง:# แสดงรายการ Billing Account ที่ผูกกับ Project gcloud billing projects describe ${PROJ_NAME} - The Core Concept: Service Account Impersonation
สร้าง Service Account (SA) ขึ้นมา เพื่อใช้กำหนดบทบาท (Role) 2 มุม
- ให้สิทธิ์ Service Account ไปจัดการ Resource ใน Lab นี้ผมจะให้สิทธิ์ compute.instanceAdmin.v1 กับ SA ตัวนี้ เพื่อให้มันสร้าง VM ได้
- ให้สิทธิ์ "ตัวเรา" ไป Impersonate เป็น Service Account ตรงนี้แหละครับคือหัวใจสำคัญ เราต้องอนุญาตให้ email ของเรา (d8k.student0@gmail.com) สามารถ "สร้าง Token" ในนามของ Service Account ได้ ผ่าน role ที่ชื่อว่า roles/iam.serviceAccountTokenCreator
# กำหนดชื่อ SA และ Email ของเราที่จะใช้รันงาน export SA_NAME="sa-d8k-tflab" export SA_EMAIL="${SA_NAME}@${PROJ_NAME}.iam.gserviceaccount.com" export USER_EMAIL="d8k.student0@gmail.com" # เปลี่ยนเป็น Email ของคุณที่ login gcloudสร้าง Service Account และกำหนดสิทธิ์gcloud iam service-accounts create ${SA_NAME} \ --display-name="Service Account for Terraform Lab" \ --project=${PROJ_NAME} gcloud projects add-iam-policy-binding ${PROJ_NAME} \ --member="serviceAccount:${SA_EMAIL}" \ --role="roles/compute.instanceAdmin.v1"การอนุญาตให้ User ของเราสามารถขอ Token ในนามของ SA ได้gcloud iam service-accounts add-iam-policy-binding ${SA_EMAIL} \ --member="user:${USER_EMAIL}" \ --role="roles/iam.serviceAccountTokenCreator" \ --project=${PROJ_NAME}เปิด API ที่จำเป็นสำหรับการทำ Credentials เพื่อให้ขอ token ผ่าน API ได้gcloud services enable \ iam.googleapis.com \ --project=${PROJ_NAME}
ในตอนต่อไป ก็จะพูดถึงการใช้ Service Account Impersonation ผ่าน Terraform กันครับ
end of document
