小西秀和です。
以前の記事でAWS Systems Manager Automationの承認アクションを使用してAWS Step Functionsのワークフローへ承認フローを追加する方法を紹介しました。
以前の記事ではAWS Lamba関数で実行したAWS Systems Manager AutomationからAWS Lamba関数を経由して承認結果をAWS Step Functionsステートマシンへ返却していました。
今回はAWS Systems Manager Automationでの承認結果をAmazon EventBridgeルールで検知する方法に変更し、AWS Step FunctionsへAWS Systems Manager Automationを使用した承認フローを追加する方法を試してみたいと思います。
この記事も前述の記事と同様に以下の動機および意図から作成したものです。
近年、AI技術の急速な進化により、従来人間が手動で行っていた承認プロセスを生成AIで置き換えたり、強力にサポートしたりすることが可能になってきました。しかし、専門知識や権限を持つ人間による最終判断も依然として重要です。
そこで私は、将来的に生成AIを承認フローに組み込むことを見据え、AWS Step Functionsを活用した承認フローシステムをAWSサービスを使用して試作しました。この試作の主な目的は以下の通りです。
なお、本記事ではAWS CloudFormationテンプレートを使用してこのデモを構築しています。AWS CDKやAWS SAMなど、より高度なIaCツールを使用しなかった理由には以下のことが挙げられます。
- APIを介して承認フローをシステム化することで、人間と生成AIの間で意思決定プロセスを柔軟に切り替えられる
- 初期段階では人間が承認を行い、生成AIの能力が十分と判断された場合に段階的にAIへ移行できる
- 生成AIの判断に不安がある場合や、最終確認が必要な場合は、人間が承認プロセスに介入できる
- 人間と生成AIを組み合わせた多段階承認フローにより、より高い精度での意思決定が可能になる
これらの理由により、CloudFormationテンプレートを使用することで、より多くの読者の方々が容易に理解し、実践できるデモ環境を提供できると考えました。
- 再現性と可搬性: CloudFormationテンプレート一つで完結させることで、環境に依存せず、誰でも同じ結果を得られるようにしました。CDKやSAMを使用すると、バージョンの違いや依存関係の問題が生じる可能性があり、再現性が低下する恐れがあります。
- 学習障壁の低さ: 多くのAWSユーザーにとって、CloudFormationは馴染みのある技術です。CDKやSAMを使用すると、追加のツールやプログラミング言語の知識が必要になる場合があり、読者の方々にとって障壁となる可能性があります。
- AWSリソースの直接的な理解: CloudFormationテンプレートでは、AWSリソースを直接定義します。これにより、AWSサービスの詳細な設定や動作を理解しやすくなり、教育的な価値が高まります。
- デバッグの容易さ: 単一のテンプレートファイルであるため、エラーの特定や修正が比較的容易です。これは、読者の方々が自身の環境で実装する際のトラブルシューティングを容易にします。
- バージョン管理とメンテナンスの簡素化: 単一ファイルでの管理は、バージョン管理を簡素化し、長期的な保守性を高めます。CloudFormationの基本的な構文は長年にわたり安定しており、将来的な変更や非推奨化のリスクが低いです。
- 迅速な展開とテスト: 追加のビルドステップが不要なため、テンプレートの変更をすぐに適用してテストできます。これにより、読者の方々が自身の環境で素早く試すことができます。
- AWSコンソールとの互換性: CloudFormationテンプレートは、AWSコンソールで直接編集・適用できます。これにより、GUIを通じた迅速な変更や確認が可能となり、より多くの方々にとって扱いやすいものとなります。
※本記事および当執筆者のその他の記事で掲載されているソースコードは自主研究活動の一貫として作成したものであり、動作を保証するものではありません。使用する場合は自己責任でお願い致します。また、予告なく修正することもありますのでご了承ください。
今回の記事の内容は次のような構成になっています。
本記事で試す構成図
今回試すAWS Step FunctionsへAWS Lambda、AWS Systems Manager Automation、Amazon EventBridgeで承認フローを追加する構成は次のようになります。

流れとしては、
まず、AWS Step FunctionsステートマシンでwaitForTaskTokenを指定したAWS Lambda関数からAWS Systems Manager Document(SSM Document)をAWS Systems Manager Automation(SSM Automation)として実行します。
SSM Automationの実行ステップは承認アクション(aws:approve)で承認者にAmazon SNSトピックのメール通知で承認の可否を確認します。
承認フローの承認、拒否の決定に伴うSSM Automation実行ステップのイベントをAmazon EventBridgeルールで検知して、結果返却用のAWS Lambda関数を実行します。
結果返却用のAWS Lambda関数ではSSM Automationの実行ステップの内容からAWS Step Functionsステートマシンのトークンと承認結果を取得して、結果をAWS Step Functionsステートマシンに返却します。
このようにAWS Systems Manager Automationの承認アクションを部品化して使用する利点は、承認者の認証と承認アクションの権限を指定できることにあります。
SSM Documentの承認アクション(aws:approve)で送信されるAmazon SNSトピックのメール通知が届くと、承認者はリンクからAWSマネジメントコンソールへログインし、承認アクションを許可されたIAMロールまたはIAMユーザーの場合のみ承認の可否を決定できます。
次の記事で紹介した親子関係のあるSSM Automationの実行結果をAWS Lamba関数で連携してく方法に比べて、今回のAmazon EventBridgeルールでSSM Automation実行ステップのイベントを検知する方法はSSM Automationを親子関係にする必要がなく、イベントベースで承認結果を取得するので処理がシンプルになります。
一方で上記の記事と同様にAWS CloudFormationテンプレートを更新する場合の考慮事項として、親SSM Document、子SSM Documentの定義を更新する場合にAWS CloudFormationの仕様上、SSM Document名を変更して再作成する必要があることが挙げられます。
AWS CloudFormationテンプレートとパラメータの例
AWS CloudFormationテンプレート(AWS Step FunctionsへのAWS LambdaとAWS Systems Manager Automationによる承認フローの追加)
入力パラメータ例
EmailForNotification: sample@h-o2k.com #承認リクエストを送信するメールアドレス EventRuleForAutomationResultState: ENABLED #Amazon EventBridgeの有効化(ENABLED)、無効化(DISABLED)の設定 SsmApprovers: arn:aws:iam::XXXXXXXXXXXX:role/ho2k.com #承認リクエストに対して承認、拒否を決定するIAMロールまたはIAMユーザー SsmMinRequiredApprovals: 1 #承認に必要な人数。ここに記載の人数が承認して初めて処理として承認される。 SsmAutomationAssumeRoleName: SsmAutomationAssumeRole #作成するAutomationAssumeRoleの名称(SSM Automationの実行にこのロールを使用する) SsmDocumentForApprovalActionName: SsmParentDocumentApprovalAction #SSM Documentの名称 SsmDocumentForApprovalActionVersionName: 1 #SSM Documentのバージョン名
テンプレート本体
ファイル名:SfnApprovalCFnSfnWithSsmApprovalAndEventBridge.yml
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Add AWS Systems Manager Automation Approval Action to AWS Step Functions.'
Parameters:
SsmAutomationAssumeRoleName:
Type: String
Default: "SsmAutomationAssumeRole"
SsmDocumentForApprovalActionName:
Type: String
Default: "SsmDocumentForApprovalAction"
SsmDocumentForApprovalActionVersionName:
Type: String
Default: "1"
SsmApprovers:
Type: String
Default: "arn:aws:iam::XXXXXXXXXXXX:role/ho2k.com"
SsmMinRequiredApprovals:
Type: String
Default: "1"
EmailForNotification:
Type: String
Default: "sample@h-o2k.com"
EventRuleForAutomationResultState:
Type: String
Default: ENABLED
AllowedValues:
- ENABLED
- DISABLED
Resources:
SsmAutomationAssumeRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub '${SsmAutomationAssumeRoleName}-${AWS::Region}'
Path: /
MaxSessionDuration: 43200
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- ssm.amazonaws.com
- lambda.amazonaws.com
- edgelambda.amazonaws.com
- events.amazonaws.com
- scheduler.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: !Sub 'IAMPolicy-AdditionalPolicyForAutomationRole-${AWS::Region}'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- iam:PassRole
Resource:
- !Sub 'arn:aws:iam::${AWS::AccountId}:role/*'
- Effect: Allow
Action:
- logs:CreateLogGroup
Resource:
- 'arn:aws:logs:*:*:*'
- Effect: Allow
Action:
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- !Sub 'arn:aws:logs:*:*:log-group:/aws/*/*:*'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole'
LambdaForSsmStartAutomationExecution:
Type: AWS::Lambda::Function
DependsOn:
- SsmAutomationAssumeRole
Properties:
FunctionName: LambdaForSsmStartAutomationExecution
Description : 'LambdaForSsmStartAutomationExecution'
Runtime: python3.9
MemorySize: 10240
Timeout: 900
Role: !GetAtt SsmAutomationAssumeRole.Arn
Handler: index.lambda_handler
Code:
ZipFile: |
import botocore
import boto3
import json
import os
import sys
region = os.environ.get('AWS_REGION')
sts_client = boto3.client("sts", region_name=region)
account_id = sts_client.get_caller_identity()["Account"]
ssm_client = boto3.client('ssm', region_name=region)
def lambda_handler(event, context):
print(("Received event: " + json.dumps(event, indent=2)))
try:
ssm_auto_resp = ssm_client.start_automation_execution(
DocumentName=event['ssm_doc_name'],
Parameters={
'AutomationAssumeRole': [event['ssm_automation_assume_role']],
'Description': [event['ssm_description']],
'Message': [event['ssm_message']],
'NotificationArn': [event['ssm_notification_arn']],
'Approvers': [event['ssm_approvers']],
'MinRequiredApprovals': [event['ssm_min_required_approvals']],
'SfnToken': [event['token']]
},
Mode='Auto'
)
except Exception as ex:
print(f'Exception:{ex}')
tb = sys.exc_info()[2]
print(f'ssm_client start_automation_execution FAIL. Exception:{str(ex.with_traceback(tb))}')
raise
result = {}
result['params'] = event.copy()
return result
LambdaForReceivingAutomationResult:
Type: AWS::Lambda::Function
DependsOn:
- AutomationResultReceivedByLambdaRole
Properties:
FunctionName: AutomationResultReceivedByLambda
Description : 'LambdaForReceivingAutomationResult'
Runtime: python3.9
MemorySize: 10240
Timeout: 900
Role: !GetAtt AutomationResultReceivedByLambdaRole.Arn
Handler: index.lambda_handler
Code:
ZipFile: |
import botocore
import boto3
import json
import os
import sys
region = os.environ.get('AWS_REGION')
sts_client = boto3.client("sts", region_name=region)
account_id = sts_client.get_caller_identity()["Account"]
sns_client = boto3.client('sns', region_name=region)
ssm_client = boto3.client('ssm', region_name=region)
sfn_client = boto3.client('stepfunctions', region_name=region)
def lambda_handler(event, context):
print(("Received event: " + json.dumps(event, indent=2)))
sfn_token = ''
is_approved = False
try:
#EventのExecutionIdからSSM DocumentパラメータにあるStep Functionsのトークンを取得する。
ssm_exe_res = ssm_client.get_automation_execution(
AutomationExecutionId=event['detail']['ExecutionId']
)
print('ssm_client.get_automation_execution: ')
print(ssm_exe_res)
sfn_token = ssm_exe_res['AutomationExecution']['Parameters']['SfnToken'][0]
print(f'sfn_token: {sfn_token}')
#EventのExecutionIdとActionから承認結果を取得する。
ssm_step_res = ssm_client.describe_automation_step_executions(
AutomationExecutionId=event['detail']['ExecutionId'],
Filters=[
{
'Key': 'Action',
'Values': ['aws:approve']
},
]
)
print('ssm_client.describe_automation_step_executions: ')
print(ssm_step_res)
approval_result = ssm_step_res['StepExecutions'][0]['Outputs']['ApprovalStatus'][0]
print(f'approval_result:{approval_result}')
#EventのExecutionIdとステップ名から承認結果を取得する。
if approval_result == 'Approved':
is_approved = True
except Exception as ex:
print(f'Exception:{ex}')
tb = sys.exc_info()[2]
print(f'ssm_client get_automation_execution, describe_automation_step_executions FAIL. Exception:{str(ex.with_traceback(tb))}')
is_approved = False
try:
#コールバックしたトークンでSFN側にタスクの成功を送信する。
sfn_res = sfn_client.send_task_success(
taskToken=sfn_token,
output=json.dumps({'is_approved':is_approved})
)
except Exception as ex:
print(f'Exception:{ex}')
tb = sys.exc_info()[2]
print(f'sfn_client send_task_success FAIL. Exception:{str(ex.with_traceback(tb))}')
raise
return {'is_approved':is_approved}
AutomationResultReceivedByLambdaRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub 'IAMRole-LambdaForReceivingAutomationResult-${AWS::Region}'
Path: /
MaxSessionDuration: 43200
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- edgelambda.amazonaws.com
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: !Sub 'IAMPolicy-LambdaForReceivingAutomationResult-${AWS::Region}'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
Resource:
- 'arn:aws:logs:*:*:*'
- Effect: Allow
Action:
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- !Sub 'arn:aws:logs:*:*:log-group:/aws/lambda/AutomationResultReceivedByLambda:*'
- Effect: Allow
Action:
- ssm:GetAutomationExecution
- ssm:DescribeAutomationStepExecutions
Resource:
- '*'
- Effect: Allow
Action:
- states:ListActivities
- states:ListExecutions
- states:ListStateMachines
- states:DescribeActivity
- states:DescribeExecution
- states:DescribeStateMachine
- states:DescribeStateMachineForExecution
- states:GetExecutionHistory
- states:SendTaskSuccess
Resource:
- '*'
LambdaForReceivingAutomationResultPermission:
Type: AWS::Lambda::Permission
DependsOn:
- LambdaForReceivingAutomationResult
- EventRuleForAutomationResult
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt LambdaForReceivingAutomationResult.Arn
Principal: events.amazonaws.com
SourceArn: !GetAtt EventRuleForAutomationResult.Arn
EventRuleForAutomationResult:
Type: AWS::Events::Rule
DependsOn:
- LambdaForReceivingAutomationResult
- EventRuleForAutomationResultRole
Properties:
Name: EventRuleForAutomationResult
EventBusName: default
Description: 'EventRuleForAutomationResult'
State: !Ref EventRuleForAutomationResultState
EventPattern:
source:
- aws.ssm
detail-type:
- 'EC2 Automation Step Status-change Notification'
detail:
Definition:
- !Ref SsmDocumentForApprovalActionName
Status:
- 'Success'
- 'Failed'
Action:
- 'aws:approve'
Targets:
- Id: 'EventRuleForAutomationResultTarget'
Arn: !GetAtt LambdaForReceivingAutomationResult.Arn
EventRuleForAutomationResultRole:
Type: AWS::IAM::Role
DependsOn:
- LambdaForReceivingAutomationResult
Properties:
RoleName: !Sub 'EventRuleForAutomationResultRole-${AWS::Region}'
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- events.amazonaws.com
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: !Sub 'EventRuleForAutomationResultRole-${AWS::Region}'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- lambda:InvokeFunction
Resource:
- !Sub '${LambdaForReceivingAutomationResult.Arn}:*'
SsmDocumentForApprovalAction:
Type: AWS::SSM::Document
Properties:
Name: !Ref SsmDocumentForApprovalActionName
DocumentType: Automation
VersionName: !Ref SsmDocumentForApprovalActionVersionName
DocumentFormat: YAML
Content:
description: 'SsmDocumentForApprovalAction'
schemaVersion: '0.3'
assumeRole: "{{ AutomationAssumeRole }}"
parameters:
AutomationAssumeRole:
type: String
description: "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf."
default: ''
Description:
description: 'Operation Description'
type: String
default: 'SsmDocumentForApprovalAction'
Message:
description: Message
type: String
default: 'Please Approve after Confirmation.'
NotificationArn:
description: 'Amazon SNS Topic ARN for Approval Notification.'
type: String
default: 'arn:aws:sns:ap-northeast-1:000000000000:AutomationApprovalNotification'
Approvers:
description: 'The IAM User or IAM Role of the Approver.'
type: StringList
SfnToken:
description: 'AWS Step Functions State Machine Token'
type: String
default: ''
MinRequiredApprovals:
description: MinRequiredApprovals
type: Integer
default: 1
mainSteps:
- name: ApprovalAction
action: 'aws:approve'
timeoutSeconds: 604800
inputs:
Message: '{{Message}}'
NotificationArn: '{{NotificationArn}}'
Approvers: '{{Approvers}}'
MinRequiredApprovals: '{{MinRequiredApprovals}}'
isEnd: true
SnsAutomationApprovalNotification:
Type: AWS::SNS::Topic
Properties:
TopicName: AutomationApprovalNotification
DisplayName: AutomationApprovalNotification
FifoTopic: False
Subscription:
- Endpoint: !Ref EmailForNotification
Protocol: email
StepFunctionsWithSsmAutomationApproval:
Type: AWS::StepFunctions::StateMachine
DependsOn:
- LambdaForSsmStartAutomationExecution
- LambdaForReceivingAutomationResult
- StepFunctionsWithSsmAutomationApprovalRole
- StepFunctionsWithSsmAutomationApprovalLogGroup
Properties:
StateMachineName: StepFunctionsWithSsmAutomationApproval
StateMachineType: STANDARD
RoleArn: !GetAtt StepFunctionsWithSsmAutomationApprovalRole.Arn
LoggingConfiguration:
Level: ALL
IncludeExecutionData: true
Destinations:
- CloudWatchLogsLogGroup:
LogGroupArn: !GetAtt StepFunctionsWithSsmAutomationApprovalLogGroup.Arn
DefinitionString: !Sub |-
{
"Comment": "Sample of adding an Approval flow to AWS Step Functions.",
"TimeoutSeconds": 604800,
"StartAt": "InvokeLambdaForSsmStartAutomationExecution",
"States": {
"InvokeLambdaForSsmStartAutomationExecution": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke.waitForTaskToken",
"Parameters": {
"FunctionName": "${LambdaForSsmStartAutomationExecution.Arn}:$LATEST",
"Payload": {
"step.$": "$$.State.Name",
"token.$": "$$.Task.Token",
"ssm_automation_assume_role.$": "$$.Execution.Input.ssm_automation_assume_role",
"ssm_doc_name.$": "$$.Execution.Input.ssm_doc_name",
"ssm_description.$": "$$.Execution.Input.ssm_description",
"ssm_notification_arn.$": "$$.Execution.Input.ssm_notification_arn",
"ssm_approvers.$": "$$.Execution.Input.ssm_approvers",
"ssm_min_required_approvals.$": "$$.Execution.Input.ssm_min_required_approvals",
"ssm_message.$": "States.Format('Approval request has been received. Please review file {} at the following URL to decide whether to approve or deny. URL: {}', $$.Execution.Input.confirmation_file, $$.Execution.Input.confirmation_url)"
}
},
"Retry": [
{
"ErrorEquals": [
"Lambda.ServiceException",
"Lambda.AWSLambdaException",
"Lambda.SdkClientException",
"Lambda.TooManyRequestsException"
],
"IntervalSeconds": 2,
"MaxAttempts": 6,
"BackoffRate": 2
}
],
"Catch": [
{
"ErrorEquals": [
"States.ALL"
],
"Next": "Fail"
}
],
"Next": "ApprovalResult"
},
"ApprovalResult": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.is_approved",
"BooleanEquals": true,
"Next": "Approved"
},
{
"Variable": "$.is_approved",
"BooleanEquals": false,
"Next": "Rejected"
}
],
"Default": "Rejected"
},
"Approved": {
"Type": "Succeed"
},
"Rejected": {
"Type": "Succeed"
},
"Fail": {
"Type": "Fail"
}
}
}
StepFunctionsWithSsmAutomationApprovalRole:
Type: AWS::IAM::Role
DependsOn:
- LambdaForSsmStartAutomationExecution
- LambdaForReceivingAutomationResult
Properties:
RoleName: !Sub 'IAMRole-StepFunctionsWithSsmAutomationApproval-${AWS::Region}'
Path: /
MaxSessionDuration: 43200
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- states.amazonaws.com
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: !Sub 'IAMPolicy-StepFunctionsWithSsmAutomationApproval-${AWS::Region}'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- lambda:InvokeFunction
Resource:
- !Sub '${LambdaForSsmStartAutomationExecution.Arn}:*'
- !Sub '${LambdaForReceivingAutomationResult.Arn}:*'
- Effect: Allow
Action:
- lambda:InvokeFunction
Resource:
- !Sub '${LambdaForSsmStartAutomationExecution.Arn}'
- !Sub '${LambdaForReceivingAutomationResult.Arn}'
- PolicyName: CloudWatchLogsDeliveryFullAccessPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:DescribeResourcePolicies
- logs:DescribeLogGroups
- logs:GetLogDelivery
- logs:CreateLogDelivery
- logs:DeleteLogDelivery
- logs:UpdateLogDelivery
- logs:ListLogDeliveries
- logs:PutResourcePolicy
Resource:
- '*'
- PolicyName: XRayAccessPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- xray:PutTraceSegments
- xray:PutTelemetryRecords
- xray:GetSamplingRules
- xray:GetSamplingTargets
Resource:
- '*'
StepFunctionsWithSsmAutomationApprovalLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: /aws/vendedlogs/states/Logs-StepFunctionsWithSsmAutomationApproval
Outputs:
Region:
Value:
!Ref AWS::Region
StepFunctionsInputExample:
Description: "AWS Step Functions Input Example"
Value: !Sub |-
{
"region": "${AWS::Region}",
"ssm_automation_assume_role": "${SsmAutomationAssumeRole.Arn}",
"ssm_doc_name": "${SsmDocumentForApprovalAction}",
"ssm_description": "Automation Approval Action For AWS Step Functions.",
"ssm_notification_arn": "${SnsAutomationApprovalNotification}",
"ssm_approvers": "${SsmApprovers}",
"ssm_min_required_approvals": "${SsmMinRequiredApprovals}",
"confirmation_url": "https://hidekazu-konishi.com/",
"confirmation_file": "index.html"
}
構築手順
- AWS Step FunctionsやAWS Systems Manager Automationをサポートしているリージョンで、テンプレートのパラメータに必要な値を入力してAWS CloudFormationでデプロイする。
AWS CloudFormationスタック作成後にOutputフィールドへAWS Step Functions実行時の入力パラメータ例(JSON形式)がStepFunctionsInputExampleとして出力されるのでメモしておく。 - 入力したEmailアドレスにSNSトピックのサブスクリプション承認リクエストが届くので承認しておく。
デモの実行
上記「構築手順」でメモした
StepFunctionsInputExampleのJSONパラメータのうち、confirmation_urlとconfirmation_fileを修正し、AWS Step FunctionsステートマシンStepFunctionsWithSsmAutomationApprovalの入力値にして実行する。
confirmation_urlとconfirmation_fileはAWS Systems Manager Automation承認アクションのメールに記載されます。confirmation_urlが承認するために参照するURL、confirmation_fileが承認するために参照するURL中にあるファイルを想定しています。例えば、confirmation_urlにAmazon S3コンソールへのURL、confirmation_fileにAmazon S3オブジェクトのファイル名を記載することなどが考えられます。構築時に指定したEmailアドレスにAWS Systems Manager Automation承認アクションのメールが届くので、承認(
Approve)するか拒否(Reject)するかをAWSマネジメントコンソールから選択する。- AWS Step Functionsステートマシン
StepFunctionsWithSsmAutomationApprovalのステップが選択した承認(Approve)、拒否(Reject)の通りに遷移することを確認する。
削除手順
- 「構築手順」で作成したAWS CloudFormationスタックを削除する。
参考:
What is AWS Step Functions? - AWS Step Functions
AWS Systems Manager Automation - AWS Systems Manager
What is AWS CodePipeline? - AWS CodePipeline
Tech Blog with related articles referenced
まとめ
今回はAWS Systems Manager Automationの承認アクションとAmazon EventBridgeを使用してAWS Step Functionsのワークフローへ承認フローを追加する方法を試しました。
この方法を使用することで、AWS Step Functionsのワークフローに柔軟な承認プロセスを組み込むことが確認できました。
AWS Systems Manager Automationの承認アクションとIAMロールを利用することで、承認者の認証と承認アクションの権限も制御できできます。
また、承認が許諾された場合に加えて、承認が拒否された場合にも適切に継続的な処理を行うことができ、複雑な承認フローが必要なプロセスにも対応可能です。
次のステップとして、この承認フローを他のAWSサービスと連携させたり、複数の承認ステップを持つ多段階承認フローへ拡張したりすることも考えられます。
AWSのサーバーレスサービスを組み合わせることで、メンテナンスの手間を最小限に抑えつつ、柔軟で応用可能な承認ワークフローを実現できることが分かりました。
今後もこのようなAWSサービスを使用したアプローチによる承認ワークフロー管理を試していきたいと思います。
次回は今回試したAWS Step Function承認フローを別のAWS Step Functionsのワークフローから呼び出して多段階承認フローを作成する方法を紹介したいと思います。
- [English Edition] How to Add an Approval Flow to AWS Step Functions Workflow (AWS Systems Manager Automation and Amazon EventBridge Edition)
