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

1. ภาพรวม

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

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

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 Console แล้วสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ หากยังไม่มีบัญชี 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 ของ Cloud การทำตาม 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 ซึ่งช่วยเพิ่มประสิทธิภาพเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก คุณสามารถทำงานในโค้ดแล็บนี้ได้โดยใช้เพียงเบราว์เซอร์หรือ 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 ก่อนจึงจะเริ่มใช้งานได้ คุณเปิดใช้ API ได้โดยใช้ Cloud Shell ด้วยคำสั่งต่อไปนี้

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. การสร้างข้อมูลลับ

Secret มีเวอร์ชันลับอย่างน้อย 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. การเข้าถึงข้อมูลลับ

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

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

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

คัดลอกโค้ดต่อไปนี้ลงในเซสชัน 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 ซึ่งเป็นข้อเสนอการประมวลผลแบบไร้เซิร์ฟเวอร์ที่ขับเคลื่อนด้วยเหตุการณ์ของ Google

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

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

exit

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

yourname@cloudshell:~ (<PROJECT_ID>)$

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

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 ใช้งานได้

เมื่อตั้งค่าในส่วนก่อนหน้าแล้ว ตอนนี้คุณก็สามารถทําให้ฟังก์ชันระบบคลาวด์ใช้งานได้และทดสอบได้แล้ว

ภายในโฟลเดอร์ที่มีเพียง 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 License) 2.0 แบบทั่วไป