ดำทำไรบันทึกวิธีคิด · ชีวิต · เทคโนโลยี
← กลับหน้าแรก
Tech

Terraform ทำงานกับ Google Cloud เปลี่ยนมาใช้ Service Account Impersonation

Terraform ทำงานกับ Google Cloud เปลี่ยนมาใช้ Service Account Impersonation

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 นะครับ

เริ่มต้น

  1. กำหนดค่าตัวแปร (Variables)

    เริ่มจากการเตรียม Environment กันก่อน เพื่อให้ Script นี้เอากลับมาใช้ซ้ำได้ง่าย และลดความผิดพลาดครับ

    bash
    export PROJ_NAME="proj-tflab-student0"
  2. สร้าง Project

    สร้าง Project พร้อมกำหนด Label ในกรณีนี้ กำหนดว่าเป็น Lab และใครเป็น Owner

    bash
    gcloud projects create ${PROJ_NAME} \
                --name="TF Lab" \
                --labels=environment=lab,owner=d8k

    หลังจากสร้าง Project เสร็จ เนื่องจากจะวางแผนให้ใช้งาน Infrastructure จำเป็นต้องเปิด API ครับ ในเคสนี้เราจะลองสร้าง VM ดังนั้นต้องเปิด Compute API ก่อน

    bash
    # เปิด Compute Engine API
    gcloud services enable compute.googleapis.com \
                --project=${PROJ_NAME}
  3. Link project กับ Billing Account

    สร้าง Project เสร็จ ถ้าไม่ผูก Billing ก็ทำอะไรไม่ได้ครับ ขั้นตอนนี้เราต้องหา Billing Account ID ของเราก่อน ใน Console เราใช้คำสั่ง filter หาจากชื่อ Billing ของเราได้เลย (ในตัวอย่างนี้ Billing ผมชื่อ “Bill-2-KTC”)

    bash
    # กำหนดชื่อ 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}

    เช็คความเรียบร้อยอีกครั้ง:

    bash
    # แสดงรายการ Billing Account ที่ผูกกับ Project
    gcloud billing projects describe ${PROJ_NAME}
  4. The Core Concept: Service Account Impersonation

    สร้าง Service Account (SA) ขึ้นมา เพื่อใช้กำหนดบทบาท (Role) 2 มุม

    bash
    # กำหนดชื่อ 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 และกำหนดสิทธิ์

    bash
    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 ได้

    bash
    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 ได้

    bash
    gcloud services enable \
        iam.googleapis.com \
        --project=${PROJ_NAME}
  5. ให้สิทธิ์ Service Account ไปจัดการ Resource ใน Lab นี้ผมจะให้สิทธิ์ compute.instanceAdmin.v1 กับ SA ตัวนี้ เพื่อให้มันสร้าง VM ได้

  6. ให้สิทธิ์ “ตัวเรา” ไป Impersonate เป็น Service Account ตรงนี้แหละครับคือหัวใจสำคัญ เราต้องอนุญาตให้ email ของเรา (d8k.student0@gmail.com) สามารถ “สร้าง Token” ในนามของ Service Account ได้ ผ่าน role ที่ชื่อว่า roles/iam.serviceAccountTokenCreator

ในตอนต่อไป ก็จะพูดถึงการใช้ Service Account Impersonation ผ่าน Terraform กันครับ

end of document

#มูลค่าความสุขที่เรียบง่าย