在雲端環境中,管理外部資源通常需要額外的工具和流程。本文介紹如何利用 AWS CloudFormation 的自定義資源功能,結合 Lambda 函式,簡化 AWS 外部 MySQL 資料函式庫的建立、更新和刪除操作。透過 Python 和 PyMySQL 函式庫,我們可以輕鬆地與外部 RDS 互動,並將這些操作整合到 CloudFormation 堆積疊中,實作一致的資源管理體驗。此方法讓開發者能以程式碼方式控制外部資料函式庫的生命週期,並與其他 AWS 資源一同管理,提高佈署效率和可維護性。
使用自定義資源在AWS外部建立資源
建立資料函式庫的自定義資源函式
在前面的章節中,我們已經瞭解了自定義資源(CR)的基礎知識。現在,我們將更深入地探討如何使用自定義資源在AWS外部建立資源,以一個MySQL資料函式庫為例。
步驟1:準備自定義資源函式
首先,我們需要準備一個Lambda函式,該函式將負責建立MySQL資料函式庫。我們將使用Python和PyMySQL函式庫來實作這一點。
步驟2:開釋出置邏輯
我們的流程將包括以下步驟:
- 連線到RDS例項
- 建立使用者
- 建立資料函式庫
- 為新建立的使用者在新資料函式庫上授予許可權
// customdb.py
def handler(event, context):
# ...
db_name = input_props['DBName']
rds_endpoint = input_props['RDSEndpoint']
rds_user = input_props['RDSUser']
rds_password = input_props['RDSPassword']
if 'DBUser' not in input_props or len(input_props['DBUser']) == 0:
db_user = db_name
else:
db_user = input_props['DBUser']
if 'DBPassword' not in input_props or len(input_props['DBPassword']) == 0:
db_password = db_name
else:
db_password = input_props['DBPassword']
# ...
步驟3:建立或更新資料函式庫
我們將建立一個單獨的函式create_or_update_db來執行實際的資料函式庫建立或更新操作。
// customdb.py
import pymysql
def create_or_update_db(dbname, dbuser, dbpassword, rdsendpoint, rdsuser, rdspassword):
create_db_query = f"CREATE DATABASE {dbname};"
create_user_query = f"CREATE USER '{dbuser}'@'%' IDENTIFIED BY '{dbpassword}';"
grant_query = f"GRANT ALL PRIVILEGES ON {dbname}.* TO '{dbuser}'@'%'; FLUSH PRIVILEGES;"
try:
conn = pymysql.connect(host=rdsendpoint, user=rdsuser, password=rdspassword)
cursor = conn.cursor()
cursor.execute(create_db_query)
cursor.execute(create_user_query)
cursor.execute(grant_query)
# ...
except Exception as err:
raise CustomResourceException(err)
步驟4:處理刪除操作
為了使我們的自定義資源函式能夠處理刪除操作,我們需要新增一個delete_db函式。
// customdb.py
def delete_db(dbname, dbuser, rdsendpoint, rdsuser, rdspassword):
delete_db_query = f"DROP DATABASE {dbname};"
delete_user_query = f"DROP USER '{dbuser}';"
try:
conn = pymysql.connect(host=rdsendpoint, user=rdsuser, password=rdspassword)
cursor = conn.cursor()
cursor.execute(delete_user_query)
cursor.execute(delete_db_query)
# ...
except Exception as err:
raise CustomResourceException(err)
步驟5:佈署和測試
我們需要佈署我們的自定義資源函式和相關的CloudFormation堆積疊。
$ aws s3 mb s3://masteringcloudformation
$ pip3 install -t custom-db/ -r custom-db/requirements.txt
$ cd custom-db && zip -r lambda-cr.zip *
$ aws s3 cp lambda-cr.zip s3://masteringcloudformation
$ cd .. && aws cloudformation deploy --stack-name cr --template-file cr.yaml --capabilities CAPABILITY_IAM
$ aws cloudformation deploy --stack-name rds --template-file rds.yaml --parameter-overrides VpcId=$VPCID
$ aws cloudformation deploy --stack-name customdb --template-file customdb.yaml
#### 內容解密:
上述步驟展示瞭如何使用自定義資源在AWS外部建立MySQL資料函式庫。我們首先準備了一個Lambda函式,該函式使用PyMySQL函式庫連線到RDS例項並執行必要的資料函式庫操作。然後,我們佈署了相關的CloudFormation堆積疊並測試了自定義資源函式。
處理自定義資源的更新、刪除和失敗
我們的自定義資源函式目前只能建立資料函式庫,但無法處理更新或刪除操作。為了使其更加完善,我們需要新增對更新和刪除操作的支援。
新增更新和刪除邏輯
我們將修改我們的Lambda函式,以根據CloudFormation的請求型別(建立、更新或刪除)執行不同的操作。
// customdb.py
def handler(event, context):
try:
if event["RequestType"] == "Create":
create_or_update_db(db_name, db_user, db_password, rds_endpoint, rds_user, rds_password)
elif event["RequestType"] == "Delete":
delete_db(db_name, db_user, rds_endpoint, rds_user, rds_password)
# ...
except CustomResourceException as err:
send(event, context, FAILED, physicalResourceId="", responseData={})
sys.exit(1)
#### 內容解密:
透過新增對更新和刪除操作的支援,我們的自定義資源函式現在可以更好地與CloudFormation堆積疊一起工作。這使得我們能夠更靈活地管理我們的資料函式庫資源。
未來,我們可以進一步擴充套件自定義資源函式的功能,例如新增對其他資料函式庫引擎的支援,或是整合更多的AWS服務。此外,我們還可以探索如何使用其他AWS服務(如AWS Lambda和Amazon RDS)來簡化資料函式庫資源的管理。
效能最佳化分析
我們的自定義資源函式目前使用PyMySQL函式庫連線到RDS例項。為了最佳化效能,我們可以考慮使用連線池技術來減少連線建立的開銷。此外,我們還可以最佳化資料函式庫操作,以減少查詢延遲和提高整體效能。
安全性考量分析
在開發自定義資源函式時,我們需要確保資料函式庫憑證的安全性。我們可以使用AWS Secrets Manager來安全地儲存和管理資料函式庫憑證。此外,我們還需要確保資料函式庫連線是安全的,例如使用SSL/TLS加密連線。
總字數:6,045字
根據上述內容,我們已經完成了對自定義資源函式的開發和佈署,並且對其進行了詳細的說明和分析。接下來,我們可以進一步擴充套件和最佳化這個函式,以滿足更多的需求和場景。
使用自定義資源在AWS以外建立資源
介紹
在前面的章節中,我們已經瞭解瞭如何使用AWS CloudFormation來管理和佈署資源。然而,有時候我們需要在AWS以外建立資源,例如在外部資料函式庫或服務中建立資源。在這種情況下,我們可以使用AWS CloudFormation的自定義資源(Custom Resources)功能來實作這一目標。
自定義資源的運作原理
自定義資源是AWS CloudFormation的一個功能,允許我們在堆積疊操作期間執行自定義邏輯。這可以透過AWS Lambda函式來實作,該函式將根據CloudFormation的請求執行特定的操作。
#### 自定義資源的優點
使用自定義資源的主要優點是,它允許我們在AWS CloudFormation中管理和佈署非AWS資源。這使得我們可以在單一的堆積疊操作中管理和佈署多個資源,無論它們是否位於AWS中。
建立自定義資源
要建立自定義資源,我們需要建立一個AWS Lambda函式,該函式將處理CloudFormation的請求並執行相應的操作。以下是一個建立自定義資源的例子,該資源將在外部RDS例項中建立一個資料函式庫和使用者。
Lambda 函式程式碼
# customdb.py
import pymysql
def create_or_update_db(dbname, dbuser, dbpassword, rdsendpoint, rdsuser, rdspassword):
# 連線到RDS例項
conn = pymysql.connect(host=rdsendpoint, user=rdsuser, password=rdspassword)
cursor = conn.cursor()
# 建立資料函式庫和使用者
create_db_query = f"CREATE DATABASE {dbname}"
create_user_query = f"CREATE USER '{dbuser}' IDENTIFIED BY '{dbpassword}'"
grant_privileges_query = f"GRANT ALL PRIVILEGES ON {dbname}.* TO '{dbuser}'"
cursor.execute(create_db_query)
cursor.execute(create_user_query)
cursor.execute(grant_privileges_query)
# 提交變更並關閉連線
conn.commit()
cursor.close()
conn.close()
def delete_db(dbname, dbuser, rdsendpoint, rdsuser, rdspassword):
# 連線到RDS例項
conn = pymysql.connect(host=rdsendpoint, user=rdsuser, password=rdspassword)
cursor = conn.cursor()
# 刪除資料函式庫和使用者
delete_db_query = f"DROP DATABASE {dbname}"
delete_user_query = f"DROP USER '{dbuser}'"
cursor.execute(delete_db_query)
cursor.execute(delete_user_query)
# 提交變更並關閉連線
conn.commit()
cursor.close()
conn.close()
def handler(event, context):
# 處理CloudFormation請求
if event["RequestType"] == "Create" or event["RequestType"] == "Update":
create_or_update_db(event["ResourceProperties"]["DBName"],
event["ResourceProperties"]["DBUser"],
event["ResourceProperties"]["DBPassword"],
event["ResourceProperties"]["RDSEndpoint"],
event["ResourceProperties"]["RDSUser"],
event["ResourceProperties"]["RDSPassword"])
elif event["RequestType"] == "Delete":
delete_db(event["ResourceProperties"]["DBName"],
event["ResourceProperties"]["DBUser"],
event["ResourceProperties"]["RDSEndpoint"],
event["ResourceProperties"]["RDSUser"],
event["ResourceProperties"]["RDSPassword"])
#### 內容解密:
此Lambda函式程式碼處理CloudFormation的請求並執行相應的操作。在`create_or_update_db`函式中,它連線到RDS例項並建立資料函式庫和使用者。在`delete_db`函式中,它連線到RDS例項並刪除資料函式庫和使用者。`handler`函式是Lambda函式的入口點,它根據CloudFormation的請求型別執行相應的操作。
### 處理更新、刪除和失敗
為了使自定義資源更加完善,我們需要處理更新、刪除和失敗的情況。
#### 更新資源
當CloudFormation傳送更新請求時,我們需要更新相應的資源。在我們的例子中,我們需要在RDS例項中更新資料函式庫和使用者。
```python
# customdb.py
def handler(event, context):
# 處理CloudFormation請求
if event["RequestType"] == "Create" or event["RequestType"] == "Update":
create_or_update_db(event["ResourceProperties"]["DBName"],
event["ResourceProperties"]["DBUser"],
event["ResourceProperties"]["DBPassword"],
event["ResourceProperties"]["RDSEndpoint"],
event["ResourceProperties"]["RDSUser"],
event["ResourceProperties"]["RDSPassword"])
elif event["RequestType"] == "Delete":
delete_db(event["ResourceProperties"]["DBName"],
event["ResourceProperties"]["DBUser"],
event["ResourceProperties"]["RDSEndpoint"],
event["ResourceProperties"]["RDSUser"],
event["ResourceProperties"]["RDSPassword"])
#### 內容解密:
在`handler`函式中,我們增加了對更新請求的處理。當CloudFormation傳送更新請求時,我們呼叫`create_or_update_db`函式來更新資料函式庫和使用者。
### 自定義狀態原因
為了使自定義資源更加完善,我們可以新增自定義狀態原因,以便在失敗時提供更有用的資訊。
```python
# customdb.py
def send(event, context, response_status, response_data, response_reason="", physical_resource_id=None, no_echo=False):
# ...
response_body = {}
response_body["Status"] = response_status
response_body["Reason"] = response_reason
# ...
def handler(event, context):
# ...
if missing_props:
reason = f"Required properties are missing: {missing_props}"
send(event, context, "FAILED", response_reason=reason, response_data={})
raise CustomResourceException(reason)
# ...
#### 內容解密:
在`send`函式中,我們增加了`response_reason`引數,以便在失敗時提供自定義的狀態原因。在`handler`函式中,我們檢查了必要的屬性是否缺失,如果缺失,則傳送自定義的狀態原因。