[アップデート]AWS SAM CLIのローカル実行時のAWS::AccountIdの値にログイン中のアカウントのIDが利用されるようになりました

2024.06.14

初めに

本日 AWS SAM CLIのv1.119.0がリリースされました。

これまでAWS SAM CLIではローカル実行時に擬似参照パラメータであるAWS::AccountIdに関してはダミー値(123456789012)を利用するようになっておりました。

例えば以下のように環境変数でLambda関数に引き渡し出力させることでも確認できます。

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function 
    Properties:
      ...
      Environment:
        Variables:
          ACCOUNT_ID: !Ref AWS::AccountId
 % sam local invoke 
...
START RequestId: 923b06d3-f37d-4491-bca9-9728e114708f Version: $LATEST
AccountId: 123456789012

この仕様があるため例えば自アカウントの既存のLambda Layerを!Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:layer:hoge:1のような形で指定するとダミーアカウントID上のものを参照しようとし実行に失敗してしまいます。従来これを回避するためにはアカウントIDをParameters経由で値を引き渡す、テンプレート上にハードコードする等別の手段を取る必要がありました。

今回のアップデートでlocal invoke実行時に指定されたプロファイルのアカウントIDを参照するようになりその値が利用されるようになりました。
なおAWS::Regionの値関しては以前より--regionオプションが存在しこちらで指定することが可能でした。

動作確認

テスト用に適当にライブラリをインストールしたLamba Layerを作成しておきます。

% mkdir requests-layer && pip install requests -t requests-layer/ && zip -r requests.zip requests-layer
..別途手動でアップロード
% aws lambda list-layers
{
    "Layers": [
        {
            "LayerName": "requests-python12",
            "LayerArn": "arn:aws:lambda:ap-northeast-1:xxxxxxxxxx:layer:requests-python12",
            "LatestMatchingVersion": {
                "LayerVersionArn": "arn:aws:lambda:ap-northeast-1:xxxxxxxxxx:layer:requests-python12:1",
                "Version": 1,
                "CreatedDate": "2024-06-14T08:28:56.812+0000",
                "CompatibleRuntimes": [],
                "CompatibleArchitectures": [
                    "arm64"
                ]
            }
        }
    ]
}

SAM上で以下のような定義で関数を作成します。

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function 
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.12
      Layers:
        - !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:layer:requests-python12:1
      Architectures:
        - arm64
     Environment:
        Variables:
          LAYER_ARN: !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:layer:requests-python12:1

以前のバージョンでこれを実行するとAWS::AccountIdにはダミーパラメータが指定される関係で取得不可なLambda Layerを参照してしまい実行以前の状態で失敗してしまいます。

% sam --version
SAM CLI, version 1.117.0
 % sam local invoke --region ap-northeast-1
Invoking app.lambda_handler (python3.12)                                                                                                                                                                                  

Error: An error occurred (InvalidParameterValueException) when calling the GetLayerVersion operation: Invalid Layer name: arn:aws:lambda:ap-northeast-1:123456789012:layer:requests-python12

これを1.119.0のものにすると正常に自アカウントを参照するようになるのでレイヤーの読み込みおよび実行に成功するようになります。処理上で自動的に読み込むため設定変更等をせずとも利用できるので非常に良さそうです。

% sam --version
SAM CLI, version 1.119.0
% sam local invoke  --region ap-northeast-1
Invoking app.lambda_handler (python3.12)                                                                                                                                                                                  
Downloading arn:aws:lambda:ap-northeast-1:xxxxxxxx:layer:requests-python12  [####################################]  1026440/1026440
Local image was not found.                                                                                                                                                                                                
Building image................................................................................................................................................................................................
Using local image: samcli/lambda-python:3.12-arm64-xxxxxx.   
...
START RequestId: 77867784-f86f-4527-9c75-c158a2690afe Version: $LATEST                                                                                                                                          
layer_arn: arn:aws:lambda:ap-northeast-1:xxxxxx:layer:requests-python12:1

認証情報がない場合

アカウントIDはgetCallerIdentityの結果から取得しますがこれの実行のためにAWSのアカウントのが今後必須となる...というわけではございませんのでご安心ください。

認証情報がない状態で実行すると現行のようにダミー値123456789012が利用される現行の状態が維持されます。

## defaultプロファイルを削除
## テンプレート上Lambda Layerの指定を削除して`AWS::AccountId`をプログラム側で出力するように設定して実行
% sam local invoke 
No current session found, using default AWS::AccountId                                                                                                                                                                    
....                                                                                                                                                                                                                   
START RequestId: 4bd706e9-18f5-4c4b-bc2b-26e2de1576e0 Version: $LATEST
account_id: 123456789012
END RequestId: 36e49b54-7c8d-42e3-8203-15a28cee1e9d

終わりに

地味ながら必要としていた環境は結構ありそうなのでよさげなアップデートですね。

知らずとも上手く取り回すことでなんとかできる部分ではありますが、パラメータの指定量を減らしてシンプルにしたり複数環境間での取り回しが良くなるため該当するような環境の方はぜひ一度コードを整理してみてはいかがでしょうか。