StepFunctionsをCloudFormationで作成し、その勢いで今作ったStepFunctionsを実行してみた

2022.08.09

AWS事業本部の梶原@福岡オフィスです。

先日のアップデートでCloudFormation のスタック作成完了をEventBridgeで検知することが

可能になりました。

[アップデート] CloudFormationの各種イベントがAmazon EventBridgeに送信されるようになりました | DevelopersIO

このアップデートを見た時に、そういえば、CloudFormationのスタック(リソース)を作成後に、別途で実行コマンドを叩いたりすることがあるよなと時々感じておりこのアップデートで対応できないかと思ったのでやってみました。

基本的にはCloudFormation はあくまでリソース作成を宣言的にやるものだと思います。

スタックを作っただけなのに、こいつ動くぞ。っていうのは若干意図してないかと思いますが、できそうなので、できるかやってみました。

ということで、StepFunctionsをCloudFormationで作成し、そのスタックの完了を契機にStepFunctionsを実行してみましたので、テンプレート等を共有します。

ただStepFunctionsを呼ぶのもおもしろくなかったので、自らのStackの削除保護を設定してみました。

ということで、

実際にこのCloudFromation スタックを作成すると、一度スタックの削除保護を外さないとスタックが削除できないがある

のでご注意ください。

図にするとこんな感じです。

構成図

CloudFormationテンプレート

AWSTemplateFormatVersion: "2010-09-09"

Resources:
  MyStateMachine:
    Type: AWS::StepFunctions::StateMachine
    Properties:
      RoleArn: !GetAtt MyStateMachineRole.Arn
      Definition:
        StartAt: UpdateTerminationProtection
        States:
          UpdateTerminationProtection:
            Type: Task
            Parameters:
              EnableTerminationProtection: 'true'
              StackName.$: $.detail.stack-id
            Resource: arn:aws:states:::aws-sdk:cloudformation:updateTerminationProtection
            End: true

  MyCfnStackStatusChangeRule:
    Type: AWS::Events::Rule
    Properties:
      EventPattern:
        source:
          - "aws.cloudformation"
        detail-type:
          - "CloudFormation Stack Status Change"
        resources: 
          - !Ref AWS::StackId
        detail:
          status-details:
            status:
              - "CREATE_COMPLETE"
      Targets:
        - Id: !Sub
            - Id-${UniqueId}
            - UniqueId: !Select [0, !Split ['-', !Select [2, !Split [/, !Ref 'AWS::StackId']]]]
          Arn: !Ref MyStateMachine
          RoleArn: !GetAtt MyEventBridgeInvokeStepFunctionsRole.Arn

  MyEventBridgeInvokeStepFunctionsRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - events.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Policies:
        - PolicyName: root
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - states:StartExecution
                Resource: !Ref MyStateMachine

  MyStateMachineRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - states.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Policies:
        - PolicyName: root
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - cloudformation:UpdateTerminationProtection
                Resource: !Ref AWS::StackId

Stepfunctions ステートマシン

MyStateMachine

スタックの作成完了通知から、スタックのIDをパラメータにCloudFormatoinのスタックの削除保護APIを読んでいます。

Event Bridge イベントルール

MyCfnStackStatusChangeRule

{
  "detail-type": ["CloudFormation Stack Status Change"],
  "resources": ["arn:aws:cloudformation:ap-northeast-1:123456789012:stack/CfnEventsRule/XXXXXX-XXXX-XXXX-XXXX-XXXX"],
  "source": ["aws.cloudformation"],
  "detail": {
    "status-details": {
      "status": ["CREATE_COMPLETE"]
    }
  }
}

のイベントを定義して、CloudFormationのスタック作成の完了[CREATE_COMPLETE] を検知するようにしています。

そのあとターゲットでStepfunctions ステートマシンを指定しています。

IAM Role

それぞれ、Stepfunctions ステートマシン:MyStateMachineRole ,Event Bridge イベントルール:MyEventBridgeInvokeStepFunctionsRole で必要なIAMRole権限を作成しています。

やってみた

上記のCloudFormationテンプレートを作成しますと2つのRoleと2つのリソースが作成されるかと思います。

そして!スタックの作成後にイベントが検知されStepFunctionsが呼び出されます。

作成したStackの削除保護が無事設定されていれば、呼び出しは成功です。

ステートマシン

実行状況

まとめ

今回作成したStepFunctionsはサンプルでこれが有用とかいう事はないのですが、StepFunctionsが作成後に呼べる。リソースの作成が完了したあと、CloudFormationのスタック作成、更新をトリガーに何かできる。というのはいろいろ使い道がありそうです。 また、StackSetsでStackの展開を行い複数アカウントに対して展開することもできますので、その際になにかトリガー的にも使えそうです。 また、検知もスタックの作成ではなく、自らの作成したリソースのドリフトを検知して、修正を行うなどもできそうな気がしています。

スタック作成のタイミングによりスタックの作製の完了イベント通知がとれないかもしれないと思っていたのですが、手元の環境ではイベント抜けなどはなく、意図したとおり作成後に呼び出すことができました。環境によってはウェイト等が必要になるかもしれませんので、ご検証いただければと思います。

参考情報

https://aws.amazon.com/jp/about-aws/whats-new/2022/07/aws-cloudformation-event-notifications-amazon-eventbridge-event-driven-applications/

[アップデート] CloudFormationの各種イベントがAmazon EventBridgeに送信されるようになりました