AWS Lambdaアーキテクチャをarm64にする時のAWS SAMテンプレート

# nodeの場合

## functionのArchitectures

sam-function-architectures

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-resource-function.html#sam-function-architectures

## layerのCompatibleArchitectures

#sam-layerversion-compatiblearchitectures

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-resource-layerversion.html#sam-layerversion-compatiblearchitectures

```template.yaml
Parameters:
  Service:
    Type: String
    Description: "サービス名"
  Stage:
    Type: String
    Description: "デプロイステージ"
  FunctionRuntime:
    Type: String
    Default: nodejs18.x
    Description: "Lambda関数のランタイム"
  FunctionArchitecture:
    Type: String
    Default: arm64
    Description: "Lambda関数のアーキテクチャ"
    AllowedValues:
      - x86_64
      - arm64

Conditions:
  IsArm64: !Equals [!Ref FunctionArchitecture, "arm64"]

Globals:
  Function:
    Architectures:
      - !If [ IsArm64, arm64, x86_64 ]
    Runtime: !Ref FunctionRuntime  # Lambda関数のランタイム
    Layers:
      - !Sub "arn:aws:lambda:${AWS::Region}:094274105915:layer:AWSLambdaPowertoolsTypeScriptV2:19"
      - !Ref NodeBaseLayer  # 使用するレイヤー

Resources:
  NodeBaseLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: !Sub "${Service}-${Stage}-layer"  # レイヤーの名前
      ContentUri: layer/node-base-layer  # レイヤーのコンテンツURI
      CompatibleRuntimes:
        - !Ref FunctionRuntime  # 対応するランタイム
      CompatibleArchitectures:
        - !If [ IsArm64, arm64, x86_64 ]
      RetentionPolicy: Delete  # レイヤーの保持ポリシー
    Metadata:
      BuildMethod: makefile
      BuildArchitecture: !If [ IsArm64, arm64, x86_64 ]
      BuildProperties:
        Minify: false
        External:
          - "@aws-lambda-powertools/*"
          - "@aws-sdk/*"

  NodeBaseLayerPermission:
    Type: AWS::Lambda::LayerVersionPermission
    Properties:
      Action: lambda:GetLayerVersion  # アクション: レイヤーのバージョン取得
      LayerVersionArn: !Ref NodeBaseLayer  # 対象のレイヤーARN
      Principal: !Ref AWS::AccountId  # アクセスを許可するプリンシパル
```

# docker

## DOCKER_DEFAULT_PLATFORM は、Docker でビルドや実行を行う際のデフォルトのターゲットプラットフォームを指定する環境変数です。

## image latest-arm64

```
.template_sam:
  variables:
    DOCKER_DEFAULT_PLATFORM: linux/arm64
  image: public.ecr.aws/sam/build-nodejs18.x:latest-arm64
  before_script:
    - sam --version
```

# pythonの場合

```
Parameters:
  Service:
    Type: String
  Stage:
    Type: String
  FunctionRuntime:
    Type: String
  FunctionArchitecture:
    Type: String

Conditions:
  IsArm64: !Equals
    - !Ref FunctionArchitecture
    - arm64

Globals:
  Function:
    Architectures:
      - !If
        - IsArm64
        - arm64
        - x86_64
    Runtime: !Ref FunctionRuntime # Lambda関数のランタイム
    Layers:
      # https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Lambda-Insights-extension-versionsARM.html
      - !If
        - IsArm64
        - !Sub arn:aws:lambda:${AWS::Region}:580247275435:layer:LambdaInsightsExtension-Arm64:31
        - !Sub arn:aws:lambda:${AWS::Region}:580247275435:layer:LambdaInsightsExtension:80
      # https://docs.powertools.aws.dev/lambda/python/latest/#extra-dependencies
      - !Join
        - "-"
        - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV3
          - !Join
            - ""
            - !Split
              - .
              - !Ref FunctionRuntime
          - !Join
            - ":"
            - - !If
                - IsArm64
                - arm64
                - x86_64
              - "5"
      - !Ref PythonBaseLayer # 使用するレイヤー

Resources:
  PythonBaseLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: !Sub ${Service}-${Stage}-layer # レイヤーの名前
      ContentUri: . # レイヤーのコンテンツURI
      CompatibleRuntimes:
        - !Ref FunctionRuntime # 対応するランタイム
      CompatibleArchitectures:
        - !If
          - IsArm64
          - arm64
          - x86_64
      RetentionPolicy: Delete # レイヤーの保持ポリシー
    Metadata:
      BuildMethod: makefile
      BuildArchitecture: !If
        - IsArm64
        - arm64
        - x86_64

  PythonBaseLayerPermission:
    Type: AWS::Lambda::LayerVersionPermission
    Properties:
      Action: lambda:GetLayerVersion # アクション: レイヤーのバージョン取得
      LayerVersionArn: !Ref PythonBaseLayer # 対象のレイヤーARN
      Principal: !Ref AWS::AccountId # アクセスを許可するプリンシパル
```

```
.template_sam:
  variables:
    PYTHON_VERSION: 3.11
    DOCKER_DEFAULT_PLATFORM: linux/arm64
  image: public.ecr.aws/sam/build-python$PYTHON_VERSION:latest-arm64
  before_script:
    - python -V
    - sam --version
```