การใช้ Secret Manager กับ Python

1. ภาพรวม

ใน Codelab นี้ คุณจะได้มุ่งเน้นที่การใช้ Secret Manager ใน Python

Secret Manager ช่วยให้คุณจัดเก็บ จัดการ และเข้าถึงข้อมูลลับเป็น Blob แบบไบนารีหรือสตริงข้อความได้ โดยคุณจะดูเนื้อหาของข้อมูลลับได้หากมีสิทธิ์ที่เหมาะสม

Secret Manager เหมาะสำหรับการจัดเก็บข้อมูลการกำหนดค่า เช่น รหัสผ่านฐานข้อมูล คีย์ API หรือใบรับรอง TLS ที่แอปพลิเคชันต้องการในขณะรันไทม์

สิ่งที่คุณจะได้เรียนรู้

  • วิธีใช้ Cloud Shell
  • วิธีติดตั้งไลบรารีของไคลเอ็นต์ Secret Manager สำหรับ Python
  • วิธีสร้างและเข้าถึงข้อมูลลับโดยใช้ไลบรารีของไคลเอ็นต์ Python
  • วิธีเข้าถึงข้อมูลลับใน Cloud Functions โดยใช้ไลบรารีของไคลเอ็นต์ Python

สิ่งที่คุณต้องมี

  • โปรเจ็กต์ Google Cloud
  • เบราว์เซอร์ เช่น Chrome หรือ Firefox
  • ความคุ้นเคยกับการใช้ Python 3

แบบสำรวจ

คุณจะใช้บทแนะนำนี้อย่างไร

อ่านอย่างเดียว อ่านและทำแบบฝึกหัดให้เสร็จสมบูรณ์

คุณจะให้คะแนนประสบการณ์การใช้ Python ของคุณอย่างไร

ระดับเริ่มต้น ระดับกลาง ระดับสูง

คุณจะให้คะแนนประสบการณ์การใช้บริการ Google Cloud ของคุณอย่างไร

ระดับเริ่มต้น ระดับกลาง ระดับสูง

2. การตั้งค่าและข้อกำหนด

การตั้งค่าสภาพแวดล้อมแบบทำตามคำแนะนำ

  1. ลงชื่อเข้าใช้ คอนโซล Google Cloud แล้วสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ หากยังไม่มีบัญชี Gmail หรือ Google Workspace คุณต้อง สร้างบัญชี

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • ชื่อโปรเจ็กต์ คือชื่อที่แสดงสำหรับผู้เข้าร่วมโปรเจ็กต์นี้ ซึ่งเป็นสตริงอักขระที่ Google APIs ไม่ได้ใช้ คุณอัปเดตชื่อนี้ได้ทุกเมื่อ
  • รหัสโปรเจ็กต์ ต้องไม่ซ้ำกันในโปรเจ็กต์ Google Cloud ทั้งหมดและเปลี่ยนแปลงไม่ได้ (เมื่อตั้งค่าแล้วจะเปลี่ยนไม่ได้) Cloud Console จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ ซึ่งโดยปกติแล้วคุณไม่จำเป็นต้องสนใจว่าสตริงนั้นคืออะไร ใน Codelab ส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (โดยทั่วไปจะระบุเป็น PROJECT_ID) หากไม่ชอบรหัสที่สร้างขึ้น คุณสามารถสร้างรหัสแบบสุ่มอีกรหัสหนึ่งได้ หรือจะลองใช้รหัสของคุณเองและดูว่ารหัสนั้นพร้อมใช้งานหรือไม่ก็ได้ เมื่อผ่านขั้นตอนนี้แล้ว คุณจะเปลี่ยนรหัสไม่ได้และรหัสจะคงอยู่ตลอดระยะเวลาของโปรเจ็กต์
  • โปรดทราบว่ามีค่าที่ 3 คือหมายเลขโปรเจ็กต์ ซึ่ง API บางรายการใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าทั้ง 3 นี้ได้ใน เอกสารประกอบ
  1. จากนั้นคุณจะต้อง เปิดใช้การเรียกเก็บเงิน ใน Cloud Console เพื่อใช้ทรัพยากร/API ของระบบคลาวด์ การทำตาม Codelab นี้ไม่ควรมีค่าใช้จ่ายมากนัก หรืออาจไม่มีค่าใช้จ่ายเลย หากต้องการปิดทรัพยากรเพื่อไม่ให้เกิดการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ คุณสามารถลบทรัพยากรที่สร้างขึ้นหรือลบทั้งโปรเจ็กต์ได้ ผู้ใช้ Google Cloud รายใหม่มีสิทธิ์เข้าร่วมโปรแกรม ช่วงทดลองใช้ฟรีมูลค่า$300 USD

เริ่มต้น Cloud Shell

แม้ว่าคุณจะใช้งาน Google Cloud จากระยะไกลผ่านแล็ปท็อปได้ แต่ใน Codelab นี้คุณจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมบรรทัดคำสั่งที่ทำงานในระบบคลาวด์

เปิดใช้งาน Cloud Shell

  1. จาก Cloud Console ให้คลิกเปิดใช้งาน Cloud Shell 853e55310c205094.png

55efc1aaa7a4d3ad.png

หากไม่เคยเริ่มใช้ Cloud Shell มาก่อน คุณจะเห็นหน้าจอระดับกลาง (ครึ่งหน้าล่าง) ที่อธิบายว่า Cloud Shell คืออะไร ในกรณีนี้ ให้คลิกดำเนินการต่อ (และคุณจะไม่เห็นหน้าจอนี้อีก) หน้าจอที่แสดงเพียงครั้งเดียวจะมีลักษณะดังนี้

9c92662c6a846a5c.png

การจัดเตรียมและเชื่อมต่อกับ Cloud Shell จะใช้เวลาเพียงไม่กี่นาที

9f0e51b578fecce5.png

เครื่องเสมือนนี้มาพร้อมกับเครื่องมือการพัฒนาทั้งหมดที่คุณต้องการ โดยมีไดเรกทอรีแรกขนาด 5 GB แบบถาวรและทำงานใน Google Cloud ซึ่งช่วยเพิ่มประสิทธิภาพเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก คุณสามารถทำงานส่วนใหญ่หรือทั้งหมดใน Codelab นี้ได้โดยใช้เพียงเบราว์เซอร์หรือ Chromebook

เมื่อเชื่อมต่อกับ Cloud Shell แล้ว คุณควรเห็นว่าคุณได้รับการตรวจสอบสิทธิ์แล้วและโปรเจ็กต์ตั้งค่าเป็นรหัสโปรเจ็กต์ของคุณแล้ว

  1. เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคุณได้รับการตรวจสอบสิทธิ์แล้ว
gcloud auth list

เอาต์พุตจากคำสั่ง

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคำสั่ง gcloud รู้จักโปรเจ็กต์ของคุณ
gcloud config list project

เอาต์พุตจากคำสั่ง

[core]
project = <PROJECT_ID>

หากไม่เป็นเช่นนั้น คุณสามารถตั้งค่าได้ด้วยคำสั่งนี้

gcloud config set project <PROJECT_ID>

เอาต์พุตจากคำสั่ง

Updated property [core/project].

3. เปิดใช้ Secret Manager API

คุณต้องเปิดใช้ Secret Manager API ก่อนจึงจะเริ่มใช้งานได้ โดยใช้ Cloud Shell คุณสามารถเปิดใช้ API ได้ด้วยคำสั่งต่อไปนี้

gcloud services enable secretmanager.googleapis.com

คุณควรเห็นเอาต์พุตลักษณะนี้

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

4. การติดตั้งไลบรารีของไคลเอ็นต์ Secret Manager สำหรับ Python

ติดตั้งไลบรารีของไคลเอ็นต์ Secret Manager โดยทำดังนี้

pip3 install --user google-cloud-secret-manager==2.10.0

5. เริ่มใช้ Python แบบอินเทอร์แอกทีฟ

ในบทแนะนำนี้ คุณจะได้ใช้ล่าม Python แบบอินเทอร์แอกทีฟที่เรียกว่า IPython ซึ่งติดตั้งไว้ล่วงหน้าใน Cloud Shell เริ่มเซสชันโดยเรียกใช้ ipython ใน Cloud Shell

ipython

คุณควรเห็นลักษณะดังนี้

Python 3.9.2 (default, Feb 28 2021, 17:03:44)
Type 'copyright', 'credits' or 'license' for more information
IPython 8.3.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]:

6. การสร้างข้อมูลลับ

ข้อมูลลับมีเวอร์ชันลับอย่างน้อย 1 รายการ คุณสร้างเวอร์ชันลับได้โดยใช้บรรทัดคำสั่ง gcloud หรือใช้ Python ก็ได้

หากต้องการใช้ข้อมูลลับ คุณต้องสร้างข้อมูลลับด้วย ชื่อ ของข้อมูลลับก่อน จากนั้นจึงเพิ่มเวอร์ชันของข้อมูลลับซึ่งเป็น ค่า ของข้อมูลลับ

ตั้งค่ารหัสโปรเจ็กต์ภายใน IPython โดยทำดังนี้

PROJECT_ID = "<PROJECT_ID>"

สร้างข้อมูลลับ

คัดลอกโค้ดต่อไปนี้ลงในเซสชัน IPython

from google.cloud import secretmanager

def create_secret(secret_id):
    # Create the Secret Manager client.
    client = secretmanager.SecretManagerServiceClient()

    # Build the resource name of the parent project.
    parent = f"projects/{PROJECT_ID}"

    # Build a dict of settings for the secret
    secret = {'replication': {'automatic': {}}}

    # Create the secret
    response = client.create_secret(secret_id=secret_id, parent=parent, secret=secret)

    # Print the new secret name.
    print(f'Created secret: {response.name}')   

เรียกใช้ฟังก์ชันเพื่อสร้างข้อมูลลับใหม่ชื่อ my_secret_value โดยทำดังนี้

create_secret("my_secret_value")

คุณควรเห็นเอาต์พุตต่อไปนี้

Created secret: projects/<PROJECT_NUM>/secrets/my_secret_value

เพิ่มเวอร์ชันของข้อมูลลับ

เมื่อมีข้อมูลลับแล้ว คุณสามารถกำหนด ค่า ให้ข้อมูลลับได้โดยการสร้างเวอร์ชัน

คัดลอกโค้ดต่อไปนี้ลงในเซสชัน IPython

def add_secret_version(secret_id, payload):
    # Create the Secret Manager client.
    client = secretmanager.SecretManagerServiceClient()

    # Build the resource name of the parent secret.
    parent = f"projects/{PROJECT_ID}/secrets/{secret_id}"

    # Convert the string payload into a bytes. This step can be omitted if you
    # pass in bytes instead of a str for the payload argument.
    payload = payload.encode('UTF-8')

    # Add the secret version.
    response = client.add_secret_version(parent=parent, payload={'data': payload})

    # Print the new secret version name.
    print(f'Added secret version: {response.name}')   

เรียกใช้ฟังก์ชันเพื่อสร้างและเพิ่มเวอร์ชันใหม่ของข้อมูลลับโดยทำดังนี้

add_secret_version("my_secret_value", "Hello Secret Manager")

คุณควรเห็นเอาต์พุตต่อไปนี้

Added secret version: projects/<PROJECT_NUM>/secrets/my_secret_value/versions/1

ข้อมูลลับมีได้หลายเวอร์ชัน เรียกใช้ฟังก์ชันอีกครั้งด้วยค่าอื่นโดยทำดังนี้

add_secret_version("my_secret_value", "Hello Again, Secret Manager")

คุณควรเห็นเอาต์พุตต่อไปนี้

Added secret version: projects/<PROJECT_NUM>/secrets/my_secret_value/versions/2

สังเกตว่าเวอร์ชันใหม่ของข้อมูลลับยาวกว่าเวอร์ชันเดิมมาก เราจะอ้างอิงแอตทริบิวต์นี้ในภายหลัง

7. การเข้าถึงข้อมูลลับ

การเข้าถึงเวอร์ชันของข้อมูลลับจะแสดงเนื้อหาของข้อมูลลับ รวมถึงข้อมูลเมตาเพิ่มเติมเกี่ยวกับเวอร์ชันของข้อมูลลับ เมื่อเข้าถึงเวอร์ชันของข้อมูลลับ คุณสามารถระบุเวอร์ชันที่ต้องการหรือขอเวอร์ชันล่าสุดโดยระบุ "latest" ก็ได้

ข้อมูลลับควรเก็บไว้เป็นความลับ จัดเก็บข้อมูลเข้าสู่ระบบของฐานข้อมูลเป็นข้อมูลลับ แล้วใช้ข้อมูลดังกล่าวเพื่อตรวจสอบสิทธิ์ หรือจัดเก็บใบรับรองแล้วใช้ใบรับรอง แต่ห้ามพิมพ์ข้อมูลลับออกมาโดยตรง เนื่องจากวิธีนี้จะทำให้ข้อมูลลับไม่เป็นความลับตามวัตถุประสงค์

คุณจะดำเนินการกับข้อมูลลับโดยประเมินค่าของข้อมูลลับโดยไม่ต้องพิมพ์ออกมาโดยตรง แต่จะพิมพ์ แฮช ของค่าข้อมูลลับแทน

คัดลอกโค้ดต่อไปนี้ลงในเซสชัน IPython

def access_secret_version(secret_id, version_id="latest"):
    # Create the Secret Manager client.
    client = secretmanager.SecretManagerServiceClient()

    # Build the resource name of the secret version.
    name = f"projects/{PROJECT_ID}/secrets/{secret_id}/versions/{version_id}"

    # Access the secret version.
    response = client.access_secret_version(name=name)

    # Return the decoded payload.
    return response.payload.data.decode('UTF-8')
    
import hashlib

def secret_hash(secret_value): 
  # return the sha224 hash of the secret value
  return hashlib.sha224(bytes(secret_value, "utf-8")).hexdigest()

เรียกใช้ฟังก์ชันเพื่อดึงข้อมูลลับเป็นแฮชของค่าข้อมูลลับโดยทำดังนี้

secret_hash(access_secret_version("my_secret_value"))

คุณควรเห็นเอาต์พุตที่มีลักษณะคล้ายแฮช (ค่าที่แน่นอนอาจไม่ตรงกับเอาต์พุตนี้)

83f8a4edb555cde4271029354395c9f4b7d79706ffa90c746e021d11

เนื่องจากคุณไม่ได้ระบุเวอร์ชัน ระบบจึงดึงค่าล่าสุด

เรียกใช้ฟังก์ชันโดยเพิ่มหมายเลขเวอร์ชันที่คาดไว้เพื่อยืนยันโดยทำดังนี้

secret_hash(access_secret_version("my_secret_value", version_id=2))

คุณควรเห็นเอาต์พุตเดียวกับคำสั่งสุดท้าย

83f8a4edb555cde4271029354395c9f4b7d79706ffa90c746e021d11

เรียกใช้ฟังก์ชันอีกครั้ง แต่คราวนี้ระบุเวอร์ชันแรกโดยทำดังนี้

secret_hash(access_secret_version("my_secret_value", version_id=1))

คุณควรเห็นแฮชอื่นในครั้งนี้ ซึ่งบ่งบอกถึงเอาต์พุตที่แตกต่างกัน

9a3fc8b809ddc611c82aee950c636c7557e220893560ec2c1eeeb177

8. การใช้ Secret Manager กับ Cloud Functions

คุณสามารถใช้ประโยชน์จากข้อมูลลับใน Google Cloud หลายส่วน ในส่วนนี้ คุณจะมุ่งเน้นที่ Cloud Functions ซึ่งเป็นบริการ Compute แบบไร้เซิร์ฟเวอร์ที่ขับเคลื่อนด้วยเหตุการณ์ของ Google

หากสนใจใช้ Python ใน Cloud Functions คุณสามารถทำตาม Codelab HTTP Google Cloud Functions ใน Python

ปิด IPython โดยเรียกใช้ฟังก์ชัน exit โดยทำดังนี้

exit

ระบบจะนำคุณกลับไปที่ Cloud Shell

yourname@cloudshell:~ (<PROJECT_ID>)$

คุณต้องเปิดใช้ Cloud Functions API ก่อนจึงจะเริ่มใช้งานได้ โดยใช้ Cloud Shell คุณสามารถเปิดใช้ API ได้ด้วยคำสั่งต่อไปนี้

gcloud services enable cloudfunctions.googleapis.com cloudbuild.googleapis.com

สร้างโฟลเดอร์ใหม่เพื่อสร้างฟังก์ชัน โดยสร้างไฟล์ว่างเพื่อเขียนลงในไฟล์

mkdir secret-manager-api-demo
cd secret-manager-api-demo
touch main.py
touch requirements.txt

เปิดตัวแก้ไขโค้ดจากด้านขวาบนของ Cloud Shell โดยทำดังนี้

7651a97c51e11a24.png

ไปที่ไฟล์ main.py ภายในโฟลเดอร์ secret-manager-api-demo ซึ่งเป็นที่ที่คุณจะวางโค้ดทั้งหมด

9. การเขียน Cloud Function เพื่อเข้าถึงข้อมูลลับ

แม้ว่าการจัดเก็บและดึงค่าข้อมูลลับจากบรรทัดคำสั่งหรือเทอร์มินัล IPython จะมีประโยชน์ แต่การเข้าถึงข้อมูลลับเหล่านี้ภายในฟังก์ชันจะมีประโยชน์มากกว่า

คุณสามารถใช้ฟังก์ชัน access_secret_version ที่สร้างไว้ก่อนหน้านี้เป็นฐานสำหรับ Cloud Function ได้

คัดลอกโค้ดต่อไปนี้ลงในไฟล์ main.py

main.py

import os

from google.cloud import secretmanager

project_id = os.environ["PROJECT_ID"]

client = secretmanager.SecretManagerServiceClient()
name = f"projects/{project_id}/secrets/my_secret_value/versions/latest"
response = client.access_secret_version(name=name)
my_secret_value = response.payload.data.decode("UTF-8")


def secret_hello(request):
    if "Again" in my_secret_value:
        return "We meet again!\n"

    return "Hello there.\n"

คุณต้องตั้งค่าสภาพแวดล้อมให้เสร็จสมบูรณ์ก่อนจึงจะทำให้ฟังก์ชันใช้งานได้ ซึ่งกำหนดให้คุณต้องตั้งค่าการขึ้นต่อกันของฟังก์ชัน

สร้างไฟล์ใหม่ชื่อ requirements.txt แล้วเพิ่มแพ็กเกจ google-cloud-secret-manager ลงในไฟล์

requirements.txt

google-cloud-secret-manager==2.10.0

ตอนนี้คุณควรมีโฟลเดอร์ที่มีเพียงไฟล์ main.py และ requirements.txt

การอนุญาตให้เข้าถึงข้อมูลลับ

คุณต้องอนุญาตให้ Cloud Functions เข้าถึงข้อมูลลับได้ก่อนจึงจะทำให้ฟังก์ชันใช้งานได้

เปลี่ยนกลับไปที่เทอร์มินัลโดยทำดังนี้

c5b686edf94b5222.png

ให้สิทธิ์เข้าถึงบัญชีบริการ Cloud Functions เพื่อเข้าถึงข้อมูลลับโดยทำดังนี้

export PROJECT_ID=$(gcloud config get-value core/project)

gcloud secrets add-iam-policy-binding my_secret_value \
    --role roles/secretmanager.secretAccessor \
    --member serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com

คุณควรเห็นเอาต์พุตต่อไปนี้

Updated IAM policy for secret [my_secret_value].
bindings:
- members:
  - serviceAccount:<PROJECT_ID>@appspot.gserviceaccount.com
  role: roles/secretmanager.secretAccessor
etag: BwWiRUt2oB4=
version: 1

10. การทำให้ Cloud Function ใช้งานได้

เมื่อตั้งค่าในส่วนก่อนหน้าแล้ว ตอนนี้คุณก็ทำให้ Cloud Function ใช้งานได้และทดสอบได้

ภายในโฟลเดอร์ที่มีเพียงไฟล์ 2 ไฟล์ที่คุณสร้างขึ้น ให้ทำให้ฟังก์ชันใช้งานได้โดยทำดังนี้

gcloud functions deploy secret_hello \
    --runtime python39 \
    --set-env-vars PROJECT_ID=${PROJECT_ID} \
    --trigger-http \
    --allow-unauthenticated

คุณควรเห็นเอาต์พุตต่อไปนี้ (ตัดทอน)

Deploying function (may take a while - up to 2 minutes)...done.

...

entryPoint: secret_hello
httpsTrigger:
  url: https://<REGION>-<PROJECT_ID>.cloudfunctions.net/secret_hello
...
status: ACTIVE
...

ดึงข้อมูล URL ของฟังก์ชัน (ข้อมูลเมตา httpsTrigger.url) ด้วยคำสั่งต่อไปนี้

FUNCTION_URL=$(gcloud functions describe secret_hello --format 'value(httpsTrigger.url)')

ตอนนี้ให้ทดสอบว่าเข้าถึงฟังก์ชันได้โดยมีค่าที่แสดงผลตามที่คาดไว้โดยเรียกใช้ฟังก์ชันโดยทำดังนี้

curl $FUNCTION_URL

คุณควรเห็นเอาต์พุตต่อไปนี้

We meet again!

ฟังก์ชันนี้อ้างอิงเวอร์ชันล่าสุดของข้อมูลลับ ซึ่งตั้งค่าให้มีสตริง "Again" ดังนั้นฟังก์ชันนี้จึงทำงานตามที่คาดไว้

11. ยินดีด้วย

คุณได้เรียนรู้วิธีใช้ Secret Manager API โดยใช้ Python แล้ว

ล้างข้อมูล

โปรดดำเนินการดังนี้เพื่อเลี่ยงไม่ให้เกิดการเรียกเก็บเงินกับบัญชี Google Cloud สำหรับทรัพยากรที่ใช้ในบทแนะนำนี้

  • ใน Cloud Console ให้ไปที่หน้า จัดการทรัพยากร
  • ในรายการโปรเจ็กต์ ให้เลือกโปรเจ็กต์ แล้วคลิกลบ
  • ในกล่องโต้ตอบ ให้พิมพ์รหัสโปรเจ็กต์ แล้วคลิกปิด เพื่อลบโปรเจ็กต์

ดูข้อมูลเพิ่มเติม

ใบอนุญาต

ผลงานนี้ได้รับอนุญาตภายใต้ Creative Commons Attribution 2.0 Generic License