CloudFormationカスタムリソースを最速理解できる簡単な例
最近CloudFormation Lambda-backedカスタムリソースを触りはじめて、やっと理解できた気がしたので投稿します。
「CloudFormationとLambdaには馴染みがある」「カスタムリソースは、Lambda関数を使ってリソースが作れるらしいけど、具体的には知らない」という人が見れば、一瞬でカスタムリソースの実装の要点を掴めそうなCloudFormationテンプレートのサンプルを用意しました[1]。
自分でデプロイして動きを確認してみると、理解が深まると思います。
言語はYAML、Pythonです。
サンプル
AWSTemplateFormatVersion: 2010-09-09
Description: Deploy sample custom resource
Outputs:
ResponseData:
Value: !GetAtt SampleResource.Data
Resources:
SampleResource:
Type: AWS::CloudFormation::CustomResource
Properties:
ServiceToken: !GetAtt Function.Arn
Input: 2
Function:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.12
Role: !GetAtt FunctionRole.Arn
Handler: index.handler
LoggingConfig:
LogGroup: !Ref FunctionLogGroup
Code:
ZipFile: |
import json
import cfnresponse
def handler(event, context):
responseValue = int(event['ResourceProperties']['Input']) * 5
responseData = {}
responseData['Data'] = responseValue
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
FunctionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
FunctionLogGroup:
DeletionPolicy: Delete
UpdateReplacePolicy: Delete
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: /aws/lambda/MyFunction
※2024/05/23追記:ロググループに関する記述を少し修正しました。詳細はこちら。
ざっくり解説
まずは、裏側のLambda関数を作成します。AWS提供のcfn-response
モジュールを使うと、CloudFormationへの応答を書くのが若干楽になります。ZipFile
でimport cfnresponse
した場合、Lambda関数の作成時に自動的にcfnresponse.py
が作られます(作成したLambda関数をコンソールで見ると、index.py
の横にcfnresponse.py
が置いてあることが確認できます)。
参考:
カスタムリソースの作成が開始されると、裏側のLambda関数が実行されます。コードを見てのとおり、今回のカスタムリソースは特に何も作らず、CloudFormationに成功と戻り値(Input
を5倍した数。サンプルなら10
)を返すだけです。
次のステップ
カスタムリソースに対して作成、更新、削除が実行される時、それぞれevent['RequestType']
にCreate
、Delete
、Update
の文字列が入るので、それぞれの場合の処理を書きましょう。また、応答ステータスにはcfnresponse.SUCCESS
とcfnresponse.FAILED
があるので、うまくいかなかったら失敗を返すように実装しましょう。
これ以降は、公式リファレンスと戦ってください:
-
本文中にもリンクを貼っていますが、Pythonコードはcfn-response module - AWS CloudFormationから拝借しました ↩︎
Discussion