hidekazu-konishi.com
How to Add an Approval Flow to AWS Step Functions Workflow (AWS Systems Manager Automation Edition)
First Published:
Last Updated:
In recent years, the rapid advancement of AI technology has made it possible to replace or strongly support traditionally manual approval processes performed by humans with generative AI. However, final judgment by humans with specialized knowledge and authority remains important.
Therefore, with a view to incorporating generative AI into approval flows in the future, I have prototyped an approval flow system using AWS Step Functions with AWS services. The main objectives of this prototype are as follows:
- By systematizing the approval flow through APIs, decision-making processes can be flexibly switched between humans and generative AI
- Initially, approvals are performed by humans, and can be gradually transitioned to AI when the capabilities of generative AI are deemed sufficient
- If there are concerns about the judgment of generative AI or if final confirmation is needed, humans can intervene in the approval process
- Multi-stage approval flows combining humans and generative AI enable decision-making with higher accuracy
- Reproducibility and portability: By making it self-contained with a single CloudFormation template, it ensures that anyone can obtain the same results regardless of their environment. Using CDK or SAM could potentially reduce reproducibility due to version differences or dependency issues.
- Lower learning barrier: CloudFormation is a familiar technology for many AWS users. Using CDK or SAM might require knowledge of additional tools or programming languages, which could be a barrier for readers.
- Direct understanding of AWS resources: CloudFormation templates directly define AWS resources. This makes it easier to understand the detailed settings and behavior of AWS services, increasing educational value.
- Ease of debugging: Being a single template file, identifying and fixing errors is relatively easy. This facilitates troubleshooting for readers when implementing in their own environments.
- Simplification of version control and maintenance: Management with a single file simplifies version control and improves long-term maintainability. The basic syntax of CloudFormation has been stable for many years, reducing the risk of future changes or deprecation.
- Rapid deployment and testing: Without additional build steps, changes to the template can be applied and tested immediately. This allows readers to quickly try it out in their own environments.
- Compatibility with AWS console: CloudFormation templates can be directly edited and applied in the AWS console. This enables quick changes and confirmation through the GUI, making it more accessible to a wider audience.
In this article, I would like to try adding an approval flow to an AWS Step Functions workflow using the approval action of AWS Systems Manager Automation, which can be built using AWS services.
* The source code published in this article and other articles by this author was developed as part of independent research and is provided 'as is' without any warranty of operability or fitness for a particular purpose. Please use it at your own risk. The code may be modified without prior notice.
Architecture Diagram to be tested in this article
The configuration for adding an approval flow to AWS Step Functions using AWS Lambda and AWS Systems Manager Automation that I will try this time is as follows:The flow is as follows:
First, in the AWS Step Functions state machine, a parent SSM Document is executed (parent SSM Automation) from an AWS Lambda function with
waitForTaskToken
specified.The parent SSM Automation executes a child SSM Document (child SSM Automation), and the child SSM Automation uses the approval action (
aws:approve
) to confirm approval or denial with the approver via an Amazon SNS topic email notification.If the result of the approval flow is approval, the child SSM Automation passes the approval and token parameters to the AWS Lambda function for returning results.
If the result of the approval flow is denial, the parent SSM Automation passes the denial and token parameters to the AWS Lambda function for returning results.
The reason for making the SSM Documents in a parent-child relationship is that the approval action (
aws:approve
) of AWS Systems Manager Automation fails and the subsequent AWS Lambda function is not called when denied.Therefore, the parent SSM Document catches the
Failed
status due to denial of the approval action in the child SSM Document and executes an AWS Lambda function to return the denied result.The advantage of using the approval action of AWS Systems Manager Automation as a component in this way is that it allows specifying the authentication of approvers and the permissions for the approval action.
When the Amazon SNS topic email notification sent by the approval action (
aws:approve
) of the child SSM Document is received, the approver can log in to the AWS Management Console via the link and decide whether to approve or deny only if they have an IAM role or IAM user allowed to perform the approval action.On the other hand, a consideration when updating the AWS CloudFormation template is that when updating the definitions of the parent SSM Document and child SSM Document, it is necessary to change the SSM Document name and recreate it due to the specifications of AWS CloudFormation.
Example of AWS CloudFormation template and parameters
AWS CloudFormation template (Adding an approval flow to AWS Step Functions using AWS Lambda and AWS Systems Manager Automation)
Example of input parameters
EmailForNotification: sample@ho2k.com #Email address to send approval requests SsmApprovers: arn:aws:iam::XXXXXXXXXXXX:role/ho2k.com #IAM role or IAM user to decide approval or denial for approval requests SsmMinRequiredApprovals: 1 #Number of people required for approval. The process is approved only when the number of people specified here approve. SsmAutomationAssumeRoleName: SsmAutomationAssumeRole #Name of the AutomationAssumeRole to be created (This role will be used for executing SSM Automation) SsmParentDocumentApprovalActionName: SsmParentDocumentApprovalAction #Name of the parent SSM Document SsmParentDocumentApprovalActionVersionName: 1 #Version name of the parent SSM Document SsmChildDocumentForApprovalActionName: SsmChildDocumentForApprovalAction #Name of the child SSM Document SsmChildDocumentForApprovalActionVersionName: 1 #Version name of the child SSM Document
Template body
File name:SfnApprovalCFnSfnWithSsmApproval.yml
AWSTemplateFormatVersion: '2010-09-09' Description: 'Add AWS Systems Manager Automation Approval Action to AWS Step Functions.' Parameters: SsmAutomationAssumeRoleName: Type: String Default: "SsmAutomationAssumeRole" SsmParentDocumentApprovalActionName: Type: String Default: "SsmParentDocumentApprovalAction" SsmChildDocumentForApprovalActionName: Type: String Default: "SsmChildDocumentForApprovalAction" SsmParentDocumentApprovalActionVersionName: Type: String Default: "1" SsmChildDocumentForApprovalActionVersionName: 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@ho2k.com" Resources: SsmAutomationAssumeRole: Type: AWS::IAM::Role Properties: RoleName: !Ref SsmAutomationAssumeRoleName 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' 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_parent_doc_name'], Parameters={ 'DocumentName': [event['ssm_child_doc_name']], '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']], 'LambdaNameForApproved': [event['ssm_lambda_for_approved']], 'LambdaParametersForApproved': [json.dumps({ 'result': event['ssm_lambda_parameters_for_approved'], 'token': event['token'] })], 'LambdaNameForRejected': [event['ssm_lambda_for_reject']], 'LambdaParametersForRejected': [json.dumps({ 'result': event['ssm_lambda_parameters_for_reject'], 'token': 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) sfn_client = boto3.client('stepfunctions', region_name=region) def lambda_handler(event, context): print(("Received event: " + json.dumps(event, indent=2))) if event.get('result','') == 'Approved': is_approved = True else: is_approved = False try: #Send task success to SFN side with the callback token. sfn_res = sfn_client.send_task_success( taskToken=event['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' 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' 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: - lambda:InvokeFunction Resource: - !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:Automation*' - Effect: Allow Action: - states:ListActivities - states:ListExecutions - states:ListStateMachines - states:DescribeActivity - states:DescribeExecution - states:DescribeStateMachine - states:DescribeStateMachineForExecution - states:GetExecutionHistory - states:SendTaskSuccess Resource: - '*' SsmParentDocumentApprovalAction: Type: AWS::SSM::Document Properties: Name: !Ref SsmParentDocumentApprovalActionName DocumentType: Automation VersionName: !Ref SsmParentDocumentApprovalActionVersionName DocumentFormat: YAML Content: description: 'SsmParentDocumentApprovalAction' 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: '' DocumentName: description: 'Document Name' type: String default: SsmChildDocumentForApprovalAction Description: description: 'Operation Description' type: String default: SsmChildDocumentForApprovalAction 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' LambdaNameForApproved: description: 'Lambda Function Name to Invoke if Approved.' type: String default: AutomationResultReceivedByLambda LambdaParametersForApproved: description: 'Lambda Function Parameters to Invoke if Approved.' type: String default: "{\"result\":\"Approved\",\"token\":\"XXXXXXXXXXXX\"}" LambdaNameForRejected: description: 'Lambda Function Name to Invoke if Rejected.' type: String default: AutomationResultReceivedByLambda LambdaParametersForRejected: description: 'Lambda Function Parameters to Invoke if Rejected.' type: String default: "{\"result\":\"Rejected\",\"token\":\"XXXXXXXXXXXX\"}" Approvers: description: 'The IAM User or IAM Role of the Approver.' type: StringList MinRequiredApprovals: description: MinRequiredApprovals type: Integer default: 1 mainSteps: - name: ParentExecuteAutomation action: 'aws:executeAutomation' timeoutSeconds: 43200 onFailure: 'step:LambdaNameForRejected' inputs: DocumentName: '{{DocumentName}}' RuntimeParameters: AutomationAssumeRole: '{{AutomationAssumeRole}}' Description: '{{Description}}' Message: '{{Message}}' NotificationArn: '{{NotificationArn}}' LambdaNameForApproved: '{{LambdaNameForApproved}}' LambdaParametersForApproved: '{{LambdaParametersForApproved}}' LambdaNameForRejected: '{{LambdaNameForRejected}}' LambdaParametersForRejected: '{{LambdaParametersForRejected}}' Approvers: '{{Approvers}}' MinRequiredApprovals: '{{MinRequiredApprovals}}' isEnd: true - name: LambdaNameForRejected action: 'aws:invokeLambdaFunction' maxAttempts: 3 timeoutSeconds: 120 onFailure: Abort inputs: FunctionName: '{{LambdaNameForRejected}}' Payload: '{{LambdaParametersForRejected}}' isEnd: true SsmChildDocumentForApprovalAction: Type: AWS::SSM::Document Properties: Name: !Ref SsmChildDocumentForApprovalActionName DocumentType: Automation VersionName: !Ref SsmChildDocumentForApprovalActionVersionName DocumentFormat: YAML Content: description: 'SsmChildDocumentForApprovalAction' 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: 'SsmChildDocumentForApprovalAction' 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' LambdaNameForApproved: description: 'Lambda Function Name to Invoke if Approved.' type: String default: AutomationResultReceivedByLambda LambdaParametersForApproved: description: 'Lambda Function Parameters to Invoke if Approved.' type: String default: "{\"result\":\"Approved\",\"token\":\"XXXXXXXXXXXX\"}" LambdaNameForRejected: description: 'Lambda Function Name to Invoke if Rejected.' type: String default: AutomationResultReceivedByLambda LambdaParametersForRejected: description: 'Lambda Function Parameters to Invoke if Rejected.' type: String default: "{\"result\":\"Rejected\",\"token\":\"XXXXXXXXXXXX\"}" Approvers: description: 'The IAM User or IAM Role of the Approver.' type: StringList MinRequiredApprovals: description: MinRequiredApprovals type: Integer default: 1 mainSteps: - name: ApprovalAction action: 'aws:approve' timeoutSeconds: 43200 onFailure: 'step:LambdaNameForRejected' inputs: Message: '{{Message}}' NotificationArn: '{{NotificationArn}}' Approvers: '{{Approvers}}' MinRequiredApprovals: '{{MinRequiredApprovals}}' - name: LambdaNameForApproved action: 'aws:invokeLambdaFunction' maxAttempts: 3 timeoutSeconds: 120 onFailure: Abort inputs: FunctionName: '{{LambdaNameForApproved}}' Payload: '{{LambdaParametersForApproved}}' isEnd: true - name: LambdaNameForRejected action: 'aws:invokeLambdaFunction' maxAttempts: 3 timeoutSeconds: 120 onFailure: Abort inputs: FunctionName: '{{LambdaNameForRejected}}' Payload: '{{LambdaParametersForRejected}}' 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": 43200, "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_parent_doc_name.$": "$$.Execution.Input.ssm_parent_doc_name", "ssm_automation_assume_role.$": "$$.Execution.Input.ssm_automation_assume_role", "ssm_child_doc_name.$": "$$.Execution.Input.ssm_child_doc_name", "ssm_description.$": "$$.Execution.Input.ssm_description", "ssm_lambda_for_approved.$": "$$.Execution.Input.ssm_lambda_for_approved", "ssm_lambda_parameters_for_approved.$": "$$.Execution.Input.ssm_lambda_parameters_for_approved", "ssm_lambda_for_reject.$": "$$.Execution.Input.ssm_lambda_for_reject", "ssm_lambda_parameters_for_reject.$": "$$.Execution.Input.ssm_lambda_parameters_for_reject", "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' 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' 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_parent_doc_name": "${SsmParentDocumentApprovalAction}", "ssm_automation_assume_role": "${SsmAutomationAssumeRole.Arn}", "ssm_child_doc_name": "${SsmChildDocumentForApprovalAction}", "ssm_description": "Automation Approval Action For AWS Step Functions.", "ssm_lambda_for_approved": "${LambdaForReceivingAutomationResult}", "ssm_lambda_parameters_for_approved": "Approved", "ssm_lambda_for_reject": "${LambdaForReceivingAutomationResult}", "ssm_lambda_parameters_for_reject": "Rejected", "ssm_notification_arn": "${SnsAutomationApprovalNotification}", "ssm_approvers": "${SsmApprovers}", "ssm_min_required_approvals": "${SsmMinRequiredApprovals}", "confirmation_url": "https://hidekazu-konishi.com/", "confirmation_file": "index.html" }
Build procedure
- Deploy with AWS CloudFormation by entering the necessary values for the template parameters in a region that supports AWS Step Functions and AWS Systems Manager Automation.
After creating the AWS CloudFormation stack, an example of input parameters (in JSON format) for AWS Step Functions execution will be output asStepFunctionsInputExample
in theOutput
field, so make a note of it. - Approve the SNS topic subscription request that will be sent to the email address you entered.
Executing the demo
- Modify the
confirmation_url
andconfirmation_file
in the JSON parameters ofStepFunctionsInputExample
noted in the "Build procedure" above, and use it as the input value to execute the AWS Step Functions state machineStepFunctionsWithSsmAutomationApproval
.
Theconfirmation_url
andconfirmation_file
will be included in the email from the AWS Systems Manager Automation approval action.confirmation_url
is expected to be the URL to refer to for approval, andconfirmation_file
is expected to be the file name within the URL to refer to for approval. For example, you could use the URL of the Amazon S3 console forconfirmation_url
and the file name of an Amazon S3 object forconfirmation_file
. - When you receive the email for the AWS Systems Manager Automation approval action at the email address specified during setup, choose to approve (
Approve
) or reject (Reject
) from the AWS Management Console. - Confirm that the steps of the AWS Step Functions state machine
StepFunctionsWithSsmAutomationApproval
transition according to the chosen approval (Approve
) or rejection (Reject
).
Deletion procedure
- Delete the AWS CloudFormation stack created in the "Build procedure".
References:
Tech Blog with curated related content
What is AWS Step Functions? - AWS Step Functions
AWS Systems Manager Automation - AWS Systems Manager
What is AWS CodePipeline? - AWS CodePipeline
Summary
In this article, I tried adding an approval flow to an AWS Step Functions workflow using the approval action of AWS Systems Manager Automation.By using this method, I confirmed that a flexible approval process can be incorporated into AWS Step Functions workflows.
By utilizing the approval action of AWS Systems Manager Automation and IAM roles, it's also possible to control the authentication of approvers and the permissions for approval actions.
Additionally, it's possible to perform appropriate continuous processing not only when approval is granted but also when it's denied, enabling it to handle complex approval flows that require intricate processes.
As next steps, we could consider integrating this approval flow with other AWS services or expanding it into a multi-stage approval flow with multiple approval steps.
I learned that by combining AWS serverless services, we can achieve flexible and applicable approval workflows while minimizing maintenance efforts.
I look forward to continuing to explore approval workflow management approaches using AWS services like this in the future.
Written by Hidekazu Konishi
Copyright © Hidekazu Konishi ( hidekazu-konishi.com ) All Rights Reserved.