目次
はじめに
こんにちは、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: 
    TracingConfigurationDefinitionに変数を入れて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-nightMorningStateMachineでは「おはよう」、NightStateMachineでは「おやすみ」というメッセージがSNSから送信されるステートマシンが作成されます。
この2つのリソースはDefinitionの記述は両方まったく同じですが、${GREET}や${TOPIC}の値が実際には置き換わっています。
例えば、
 "Parameters": {
                "Message": "${GREET}"のところですが、MorningStateMachineの出来たステートマシンの定義を確認すると
 "Parameters": {
        "Message": "おはよう",に変わっています。
 GREET: !FindInMap [GreetMap, morning, greet]
同様に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も機能してくれています。
おわりに
今回の例のレベルであればそもそもステートマシン自体を共有してしまってもいいのかもしれませんが、まぁこんなことが出来るよーという説明でした。
最後までお付き合いいただきありがとうございました。

アーキテクト課のomkです。
AWSについて雑多に取り組んだ内容を発信しています!!

