AWS-CloudFormation

CloudFormationでStep Functionsのステートマシンを作る際にDefinitionSubstitutionsが便利だった話

はじめに

こんにちは、omkです。
先日CloudFormationで複数のステートマシンを作成しました。
環境ごとのちょっとした差異以外すべて同一のDefinitionを持つ設定だったので、「DefinitionSubstitutions」を使うことで必要な手間を削減できました。
非常に便利なので記事にしてみます。

ざっくり概要

リファレンスのリンクを置いておきます。
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html#cfn-stepfunctions-statemachine-definition

ステートマシンのリソースのプロパティは以下です。

Type: AWS::StepFunctions::StateMachine
Properties: 
  Definition: 
    Definition
  DefinitionS3Location: 
    S3Location
  DefinitionString: 
    String
  DefinitionSubstitutions: 
    Key : Value
  LoggingConfiguration: 
    LoggingConfiguration
  RoleArn: String
  StateMachineName: String
  StateMachineType: String
  Tags: 
    - TagsEntry
  TracingConfiguration: 
    TracingConfiguration

Definitionに変数を入れてDefinitionSubstitutionsで代入置き換えで使うことが可能です。

やってみた

試しに以下のCFnテンプレートを作成しました 。

AWSTemplateFormatVersion: "2010-09-09"

Parameters:
  SNSRoleArn:
    Type: String
  SNSTopic:
    Type: String

Mappings:
  GreetMap:
    morning:
      greet: "おはよう"
    night:
      greet: "おやすみ"

Resources:

  MorningStateMachine:
    Type: AWS::StepFunctions::StateMachine
    Properties: 
      Definition: 
        {
          "Comment": "A description of my state machine",
          "StartAt": "SNS Publish",
          "States": {
            "SNS Publish": {
              "Type": "Task",
              "Resource": "arn:aws:states:::sns:publish",
              "Parameters": {
                "TopicArn": "${TOPIC}",
                "Message": "${GREET}"
              },
              "End": true
            }
          }
        }
      DefinitionSubstitutions:
        GREET: !FindInMap [GreetMap, morning, greet]
        TOPIC: !Ref SNSTopic
      RoleArn: !Ref SNSRoleArn
      StateMachineName: omk-state-morning

  NightStateMachine:
    Type: AWS::StepFunctions::StateMachine
    Properties: 
      Definition: 
        {
          "Comment": "A description of my state machine",
          "StartAt": "SNS Publish",
          "States": {
            "SNS Publish": {
              "Type": "Task",
              "Resource": "arn:aws:states:::sns:publish",
              "Parameters": {
                "TopicArn": "${TOPIC}",
                "Message": "${GREET}"
              },
              "End": true
            }
          }
        }
      DefinitionSubstitutions:
        GREET: !FindInMap [GreetMap, night, greet]
        TOPIC: !Ref SNSTopic
      RoleArn: !Ref SNSRoleArn
      StateMachineName: omk-state-night

MorningStateMachineでは「おはよう」、NightStateMachineでは「おやすみ」というメッセージがSNSから送信されるステートマシンが作成されます。
この2つのリソースはDefinitionの記述は両方まったく同じですが、${GREET}や${TOPIC}の値が実際には置き換わっています。
例えば、

 "Parameters": {
                "Message": "${GREET}"

のところですが、MorningStateMachineの出来たステートマシンの定義を確認すると

 "Parameters": {
        "Message": "おはよう",

に変わっています。
GREET: !FindInMap [GreetMap, morning, greet] でMappingから値を取ってきてくれていますね。

同様にNightStateMachineはおやすみになっています。

"Parameters": {
        "Message": "おやすみ",

こんな感じで変えたい箇所だけDefinitionSubstitutionsで変えるようにしておけば楽にステートマシンを設定出来ます。

さらにDefinitionの内容が全く同じなのであればDefinitionだけ別ファイルとしてS3アップロードして以下のように「DefinitionS3Location」で参照できるので、管理上も同じDefinitionの更新を複数回行わなくてよくなるので良いですね。

AWSTemplateFormatVersion: "2010-09-09"

Parameters:
  SNSRoleArn:
    Type: String
  SNSTopic:
    Type: String
  BucketName:
    Type: String
Mappings:
  GreetMap:
    morning:
      greet: "おはよう"
    night:
      greet: "おやすみ"

Resources:

  MorningStateMachine:
    Type: AWS::StepFunctions::StateMachine
    Properties: 
      DefinitionS3Location:
        Bucket: !Ref BucketName
        Key: definition.json
      DefinitionSubstitutions:
        GREET: !FindInMap [GreetMap, morning, greet]
        TOPIC: !Ref SNSTopic
      RoleArn: !Ref SNSRoleArn
      StateMachineName: omk-state-morning

  NightStateMachine:
    Type: AWS::StepFunctions::StateMachine
    Properties: 
      DefinitionS3Location:
        Bucket: !Ref BucketName
        Key: definition.json
      DefinitionSubstitutions:
        GREET: !FindInMap [GreetMap, night, greet]
        TOPIC: !Ref SNSTopic
      RoleArn: !Ref SNSRoleArn
      StateMachineName: omk-state-night

ちゃんとDefinitionSubstitutionsも機能してくれています。

おわりに

今回の例のレベルであればそもそもステートマシン自体を共有してしまってもいいのかもしれませんが、まぁこんなことが出来るよーという説明でした。
最後までお付き合いいただきありがとうございました。

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA