🗒️

CloudFormationカスタムリソースを学ぶ

2021/01/25に公開

はじめに

動画配信基盤の構成を検討していたところ、いい感じにAWSのテンプレートがあった!
https://aws.amazon.com/jp/solutions/implementations/video-on-demand-on-aws/

CloudFormationを使ったリソースの作成が初めてだったので、定義内容を確認していたが、カスタムリソースが意味不明だったので整理する。

尚、調査したのは以下のawslabsで提供されているVideo on Demand on AWSのCloudFormation
https://github.com/awslabs/video-on-demand-on-aws

カスタムリソースとは

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-custom-resources.html

カスタムリソースを使用すると、テンプレートにカスタムのプロビジョニングロジックを記述し、ユーザーがスタックを作成、更新(カスタムリソースを変更した場合)、削除するたびに AWS CloudFormation がそれを実行します。たとえば、AWS CloudFormation のリソースタイプとして使用できないリソースを含める必要があるとします。それらのリソースは、カスタム リソースを使用して含めることができます。この方法により、すべての関連リソースを 1 つのスタックで管理できます。

CloudFormationが対応していないリソースの作成に使える。

テンプレートのカスタムリソースを定義するには、AWS::CloudFormation::CustomResource または Custom::MyCustomResourceTypeName リソースタイプを使用します。カスタムリソースにはサービストークンを示す 1 つのプロパティが必要です。このプロパティは、AWS CloudFormation がリクエストを送信する宛先 (Amazon SNS トピックなど) を指定します。

リソースタイプは独自の名前を設定できる。

AWS::CloudFormation::CustomResource

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-cfn-customresource.html

実際の定義箇所

  • 全てServiceTokenLambda(CustomResource)が指定されており、カスタムリソースのスタックイベント発生時はLambda(CustomResource)が実行される。
  • ServiceToken以外のPropertiesResourcePropertiesとして、Lambdaへイベントとして渡される。

S3Config

  S3Config:
    DependsOn: CloudFront
    Type: Custom::S3
    Properties:
      ServiceToken: !GetAtt CustomResource.Arn
      Source: !Ref Source
      IngestArn: !GetAtt StepFunctions.Arn
      Resource: S3Notification
      WorkflowTrigger: !Ref WorkflowTrigger
  • WorkflowTriggerパラメータ値によって、s3.putBucketNotificationConfigurationを設定する

MediaConvertEndPoint

  MediaConvertEndPoint:
    Type: Custom::LoadLambda
    Properties:
      ServiceToken: !GetAtt CustomResource.Arn
      Resource: EndPoint
  • mediaconvert.describeEndpointsにてmediaconvertのエンドポイントを取得する

MediaConvertTemplates

  MediaConvertTemplates:
    Type: Custom::LoadLambda
    Properties:
      ServiceToken: !GetAtt CustomResource.Arn
      Resource: MediaConvertTemplates
      StackName: !Ref AWS::StackName
      EndPoint: !GetAtt MediaConvertEndPoint.EndpointUrl
      EnableMediaPackage: !Ref EnableMediaPackage
      EnableNewTemplates: true
  • mediaconvert.createJobTemplateにてmediaPackageTemplatesNoPresetqvbrTemplatesNoPresetにて定義したジョブテンプレートファイルからジョブテンプレートを作成

MediaConvertのジョブテンプレートをカスタマイズしたいけどどうする

その1(ジョブテンプレートファイル書き換える)

以下で./lib/mediaconvert/templates/から読み込むテンプレートファイルを指定してるので、直接テンプレートファイルを修正するか、独自テンプレートをqvbrTemplatesNoPresetのリストに追加する。
https://github.com/awslabs/video-on-demand-on-aws/blob/56e9b09fef6fb3ca3c6ecb3491725aa53de195b0/source/custom-resource/lib/mediaconvert/index.js#L131-L144

以下で利用するジョブテンプレートを指定しているので、テンプレート名を変更した場合は合わせて変更する。
https://github.com/awslabs/video-on-demand-on-aws/blob/56e9b09fef6fb3ca3c6ecb3491725aa53de195b0/deployment/video-on-demand-on-aws.yaml#L736-L750

ちなみにこの方式だとテンプレートを書き換えた場合にCloudFormationのテンプレート自体には変更がないのでUpdateが走ってくれない。
aws cloudformation packageを利用すればLambdaのコードの変更も検知してくれるみたいなので試してみる。

その2(AWS::MediaConvert::JobTemplateを定義)

一応ジョブテンプレートのリソースタイプはあるみたいなので、カスタムリソースを使わずに直接リソースを定義する。

Discussion