การใช้ 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 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 ของระบบคลาวด์ การใช้งาน Codelab นี้น่าจะไม่มีค่าใช้จ่ายใดๆ หากมี หากต้องการปิดทรัพยากรเพื่อไม่ให้มีการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ คุณสามารถลบทรัพยากรที่คุณสร้างหรือลบทั้งโปรเจ็กต์ได้ ผู้ใช้ใหม่ของ Google Cloud จะมีสิทธิ์เข้าร่วมโปรแกรมทดลองใช้ฟรี$300 USD

เริ่มต้น Cloud Shell

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

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

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

55efc1aaa7a4d3ad.png

หากคุณไม่เคยเริ่มต้นใช้งาน 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

คุณต้องเปิดใช้ 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. การเข้าถึงข้อมูลลับ

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

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

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

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

หากสนใจใช้ Python ใน Cloud Functions ก็ทำตามฟังก์ชัน HTTP Google Cloud ใน Python Codelab

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

exit

คุณควรกลับสู่ Cloud Shell:

yourname@cloudshell:~ (<PROJECT_ID>)$

คุณต้องเปิดใช้ API ก่อนจึงจะเริ่มใช้ 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"

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

สร้างไฟล์ใหม่ชื่อ 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!

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

11. ยินดีด้วย

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

ล้างข้อมูล

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

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

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

ใบอนุญาต

ผลงานนี้ได้รับอนุญาตภายใต้ใบอนุญาตทั่วไปครีเอทีฟคอมมอนส์แบบระบุแหล่งที่มา 2.0