1. 總覽
在本程式碼研究室中,您將專注於以 Python 使用 Secret Manager。
Secret Manager 能以二進位 blob 或文字字串的形式,儲存、管理及存取密鑰。具備適當的權限,即可查看密鑰內容。
Secret Manager 非常適合用來在執行階段儲存設定資訊,例如資料庫密碼、API 金鑰或應用程式所需的 TLS 憑證。
課程內容
- 如何使用 Cloud Shell
- 如何安裝 Python 適用的 Secret Manager 用戶端程式庫
- 如何使用 Python 用戶端程式庫建立及存取密鑰
- 如何使用 Python 用戶端程式庫存取 Cloud Functions 中的密鑰
軟硬體需求
問卷調查
您會如何使用這個教學課程?
您對 Python 的使用體驗有何評價?
針對使用 Google Cloud 服務的經驗,您會給予什麼評價?
2. 設定和需求
自修環境設定
- 登入 Google Cloud 控制台,建立新專案或重複使用現有專案。如果您還沒有 Gmail 或 Google Workspace 帳戶,請先建立帳戶。
- 「專案名稱」是這項專案參與者的顯示名稱。這是 Google API 未使用的字元字串。您隨時可以更新這項資訊。
- 所有 Google Cloud 專案的專案 ID 均不得重複,且設定後即無法變更。Cloud 控制台會自動產生一個不重複的字串。但通常是在乎它何在在大部分的程式碼研究室中,您必須參照專案 ID (通常為
PROJECT_ID
)。如果您對產生的 ID 不滿意,可以隨機產生一個 ID。此外,您也可以自行嘗試,看看系統是否提供該付款方式。在完成這個步驟後就無法變更,而且在專案期間仍會保持有效。 - 資訊中的第三個值是專案編號,部分 API 會使用這個編號。如要進一步瞭解這三個值,請參閱說明文件。
- 接下來,您需要在 Cloud 控制台中啟用計費功能,才能使用 Cloud 資源/API。執行這個程式碼研究室並不會產生任何費用,如果有的話。如要關閉資源,以免系統產生本教學課程結束後產生的費用,您可以刪除自己建立的資源,或刪除整個專案。Google Cloud 的新使用者符合 $300 美元免費試用計畫的資格。
啟動 Cloud Shell
雖然 Google Cloud 可以從筆記型電腦遠端操作,但在本程式碼研究室中,您將使用 Google Cloud Shell,這是一種在 Cloud 中執行的指令列環境。
啟用 Cloud Shell
- 在 Cloud 控制台中,按一下「啟用 Cloud Shell」圖示 。
如果您先前從未啟動 Cloud Shell,您會看見中繼畫面 (需捲動位置),說明螢幕內容。如果出現這種情況,請按一下「繼續」 (之後不會再顯示)。以下是單次畫面的外觀:
佈建並連線至 Cloud Shell 只需幾分鐘的時間。
這個虛擬機器搭載您需要的所有開發工具。提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作,大幅提高網路效能和驗證能力。在本程式碼研究室中,您的大部分作業都可以透過瀏覽器或 Chromebook 完成。
連線至 Cloud Shell 後,您應會發現自己通過驗證,且專案已設為您的專案 ID。
- 在 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`
- 在 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. 安裝 Python 適用的 Secret Manager 用戶端程式庫
pip3 install --user google-cloud-secret-manager==2.10.0
5. 啟動互動式 Python
在本教學課程中,您將使用 Cloud Shell 中預先安裝的 IPython 互動式 Python 解譯器。在 Cloud Shell 中執行 ipython
即可啟動工作階段:
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. 建立密鑰
一組密鑰包含一或多個密鑰版本。您也可以使用 gcloud
指令列建立這類資料庫,但也可以透過 Python 建立。
如要使用密鑰,您必須先使用密鑰的「名稱」建立密鑰,然後新增密鑰版本,做為密鑰的「值」。
在 IPython 中設定專案 ID:
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
新增密鑰版本
現在 Secret 已存在,您可以透過建立版本來為其指派值。
將下列程式碼複製到您的 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
Secret 可以有多個版本。使用不同的值再次呼叫函式:
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,也就是 Google 的事件導向無伺服器運算服務。
如果您想在 Cloud Functions 中使用 Python,請參閱在 Python 程式碼研究室中使用 HTTP Google Cloud Functions。
呼叫 exit
函式關閉 IPython:
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 右上角的程式碼編輯器:
前往 secret-manager-api-demo
資料夾中的 main.py
檔案。請將所有程式碼放在這裡。
9. 編寫存取密鑰的 Cloud 函式
雖然從指令列或 IPython 終端機儲存及擷取密鑰值會很實用,但若能在函式內存取這些密鑰,會更加實用。
您可以透過先前建立的 access_secret_version
函式,將該函式做為 Cloud 函式的基礎。
將下列程式碼複製到 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 存取您的密鑰。
切換回終端機:
授予 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 函式
根據您在前幾節的設定,您現在可以部署及測試 Cloud 函式。
在只包含您建立的兩個檔案的資料夾中,部署函式:
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 ...
使用下列指令擷取函式網址 (httpsTrigger.url
中繼資料):
FUNCTION_URL=$(gcloud functions describe secret_hello --format 'value(httpsTrigger.url)')
現在,請呼叫函式,以預期的傳回值存取該函式:
curl $FUNCTION_URL
您應該會看到以下的輸出內容:
We meet again!
這個函式會參照最新版本的密鑰,其設定為包含「Again」字串,因此這個函式會正常運作。
11. 恭喜!
您已瞭解如何透過 Python 使用 Secret Manager API!
清除所用資源
如要避免系統向您的 Google Cloud 帳戶收取您在本教學課程中所用資源的相關費用:
- 在 Cloud 控制台中,前往「管理資源」頁面。
- 在專案清單中,選取您的專案,然後按一下「Delete」(刪除)。
- 在對話方塊中輸入專案 ID,然後按一下「Shut down」(關閉) 即可刪除專案。
瞭解詳情
- Secret Manager:https://cloud.google.com/secret-manager/
- 在 Google Cloud 中使用 Python:https://cloud.google.com/python/
- Python 適用的 Cloud 用戶端程式庫:https://googlecloudplatform.github.io/google-cloud-python/
授權
這項內容採用的是創用 CC 姓名標示 2.0 通用授權。