AWS SAM で Step Functions と Lambda の連携を強化!エイリアスを使った自動バージョン管理術

記事タイトルとURLをコピーする

アプリケーションサービス部の遠藤です!

今回は Step Functions と Lambda の連携を強化するために、エイリアスを活用した事例をご紹介します。

AWS Step Functions を使ってサーバーレスワークフローを構築する際、Lambda 関数との連携は非常に一般的です。 しかし、Lambda 関数のコードを更新するたびに Step Functions の定義も手動で更新するのは手間がかかり、バージョン管理も複雑になりがちです。

本記事では、AWS SAM (Serverless Application Model) を活用し、Lambda 関数のエイリアスを自動的に更新し、Step Functions からはそのエイリアスを参照することで、より効率的で安全なバージョン管理を実現する方法をご紹介します。

なぜエイリアスとバージョン管理が重要か?

Step Functions から Lambda 関数を呼び出す際、以下のような課題が生じることがあります。

  • 手動更新の手間: Lambda 関数を更新するたびに、Step Functions のステートマシン定義内の Lambda ARN を新しいバージョンに書き換える必要がある。
  • バージョン指定の複雑さ: 常に $LATEST を参照すると予期せぬ変更の影響を受ける可能性があり、かといって特定のバージョンをハードコードすると更新が追いつかない。
  • ロールバックの煩雑さ: 問題発生時に特定の安定バージョンに迅速に戻したいが、定義の書き換えや再デプロイが必要になる。

これらの課題を解決するのが、Lambda の「バージョン」と「エイリアス」の機能、そしてそれを自動化する AWS SAM です。

解決策: SAM を使ったエイリアスの自動更新と参照

AWS SAM を使うと、以下の流れでこの問題を解決できます。

  1. Lambda 関数の自動バージョン発行とエイリアス更新: SAM テンプレートで Lambda 関数を定義する際、AutoPublishAlias プロパティを設定します。これにより、sam deploy を実行すると、コードに変更があれば新しい Lambda バージョンが発行され、指定したエイリアス (例: live) がその最新バージョンを指すように自動的に更新されます。
  2. Step Functions からエイリアスを参照: Step Functions のステートマシン定義 (ASL) では、Lambda 関数を呼び出す際に、この自動更新されるエイリアスの ARN を参照します。

これにより、Lambda 関数を更新・デプロイするだけで、Step Functions は常に指定したエイリアス(通常は最新の安定版)を指す Lambda 関数を実行できるようになります。

具体的な設定方法 (SAM テンプレートと ASL)

以下に SAM テンプレート (template.yaml) とステートマシン定義ファイル (statemachine.asl.json) の設定例を示します。

1. SAM テンプレート (template.yaml)

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Step Functions and Lambda with Alias versioning

Parameters:
  ServiceName:
    Type: String
    Default: myapp
  StageName:
    Type: String
    Default: dev

Resources:
  # Lambda 関数の定義
  MyLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub ${ServiceName}-${StageName}-my-lambda
      CodeUri: src/my_lambda_function/
      Handler: app.lambda_handler
      Runtime: python3.9
      # この設定で 'live' エイリアスが自動発行・更新される
      AutoPublishAlias: live
      DeploymentPreference:
        Type: AllAtOnce # 必要に応じてデプロイ戦略を設定
      Role: !GetAtt MyLambdaFunctionRole.Arn # 適切な実行ロールを指定
      # ... その他の Lambda 設定 ...

  MyLambdaFunctionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      # ここにLambda関数が必要とする適切な管理ポリシーやインラインポリシーをアタッチ

  # Step Functions ステートマシンの定義
  MyStateMachine:
    Type: AWS::Serverless::StateMachine # SAMリソースタイプ
    Properties:
      StateMachineName: !Sub ${ServiceName}-${StageName}-my-statemachine
      DefinitionUri: statemachine/statemachine.asl.json
      DefinitionSubstitutions:
        MyLambdaFunctionArn: !Ref MyLambdaFunction.Alias
      Role: !GetAtt MyStateMachineRole.Arn # 適切な実行ロールを指定

  MyStateMachineRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: states.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: LambdaInvokePolicyForStateMachine
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action: lambda:InvokeFunction
                Resource: !Ref MyLambdaFunction.Alias # Lambdaエイリアスを呼び出す権限
        # 必要に応じて、ステートマシンが他のAWSサービスを呼び出すための権限を追加

ポイント

MyLambdaFunction のAutoPublishAlias: liveにより、デプロイごとに live エイリアスが最新バージョンを指します。 MyStateMachine の DefinitionSubstitutions でMyLambdaFunctionArnというキーに対して!Ref MyLambdaFunction.Aliasを指定しています。これにより、live エイリアスの完全な ARN が ASL ファイルに渡されます。

2. ステートマシン定義ファイル (statemachine.asl.json)

{
  "Comment": "A simple Step Functions state machine that calls a Lambda function via an alias",
  "StartAt": "CallMyLambda",
  "States": {
    "CallMyLambda": {
      "Type": "Task",
      "Resource": "${MyLambdaFunctionArn}",
      "End": true
    }
  }
}

ポイント

Resource フィールドの値が${MyLambdaFunctionArn}となっています。 これは SAM テンプレートの DefinitionSubstitutions で指定された値(Lambda の live エイリアスの ARN)に置き換えられます。 これにより、Lambda 関数の新しいコードがデプロイされ、新しいバージョンが発行されて live エイリアスが、新しく発行されたバージョンを指すように更新されています。 ステートマシン定義内の${MyLambdaFunctionArn}が、更新された live エイリアスの ARN に置換されます。 更新された定義でステートマシンがデプロイ(または更新)されます。 結果として、Step Functions は常に live エイリアス経由で Lambda 関数を呼び出すため、最新のデプロイされたロジックが実行されます。

メリット

  • デプロイの簡素化: Lambda の更新と Step Functions の定義更新がsam deploy一発で完了します。
  • 安定性の向上: Step Functions は常に特定のエイリアス(例: live)を参照するため、開発中の $LATEST バージョンを誤って本番で実行してしまうリスクを避けられます。
  • 容易なロールバック: Lambda のエイリアスが指すバージョンを AWS マネジメントコンソールや AWS CLI で過去の安定バージョンに切り替えるだけで、Step Functions の定義を変更せずに Lambda のロジックをロールバックできます。
  • IaC の推進: インフラ構成とアプリケーションロジックの連携がコードで管理され、再現性と一貫性が向上します。

Lambda バージョンの管理

  • 過去バージョンの保持: AutoPublishAlias を使用しても、過去に発行された Lambda バージョンは自動的には削除されず、保持されます。不要なバージョンは手動またはスクリプトで削除管理することを検討してください。
  • 変更がない場合のバージョン発行: Lambda 関数のコードや設定に一切変更がない場合、sam deploy を実行しても新しいバージョンは発行されません。強制的に発行したい場合は、コードコメントの変更やテンプレート内の Description、Tags の更新など、何らかの「変更」を意図的に加える必要があります。

まとめ

AWS SAM のテンプレートにて AutoPublishAlias を設定し、 DefinitionSubstitutions を組み合わせることで、Step Functions から呼び出す Lambda 関数のバージョン管理とエイリアスの更新を効果的に自動化できます。 これにより、デプロイプロセスの簡素化・システムの安定性向上・迅速なロールバック対応が可能となり、より堅牢なサーバーレスアプリケーションの構築と運用が実現します。

是非この方法を活用してサーバーレスワークフローに活用いただければと思います!

遠藤 広也
(エンジニアブログ記事一覧)
(サバワク記事一覧)

アプリケーションサービス本部

2024年中途入社 アプリケーションサービス本部にてAWSを活用したアプリケーション開発に携わっています!
趣味はお酒とバンドです