🫥

AWS初心者がsamを使ってLambdaへデプロイする

2024/05/02に公開

はじめに

以前の記事でGitHub Actionsを使ってLambdaにデプロイしましたが、PrismaをLambdaで使う際は、samを使った方法を公式が推奨しているようです。(参考

なので、samを使った方法でlambdaへデプロイする方法を調査しました。
前回の記事の調査、実装で使った工数は無駄になりました

対象読者

  • samを使ってAWSへデプロイしたい人

書いてる人の実力

  • AWSほぼ初心者、Lambdaは4年前に少し使ったことがある程度、その時はブラウザからjsファイルをいじってた

1. samをインストール

公式の通りにインストールしました。

2. samプロジェクトを作成

sam init --runtime nodejs20.xとコマンドを打つ、この際色々聞かれるので答えていきます。
今回は以下のようにしました。

sam init --runtime nodejs20.x
Which template source would you like to use?
	1 - AWS Quick Start Templates
	2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
	1 - Hello World Example
	2 - GraphQLApi Hello World Example
	3 - Hello World Example with Powertools for AWS Lambda
	4 - Multi-step workflow
	5 - Standalone function
	6 - Scheduled task
	7 - Data processing
	8 - Serverless API
	9 - Full Stack
	10 - Lambda Response Streaming
Template: 1

Based on your selections, the only Package type available is Zip.
We will proceed to selecting the Package type as Zip.

Based on your selections, the only dependency manager available is npm.
We will proceed copying the template using npm.

Select your starter template
	1 - Hello World Example
	2 - Hello World Example TypeScript
Template: 2

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: y
X-Ray will incur an additional cost. View https://aws.amazon.com/xray/pricing/ for more details

Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]: y
AppInsights monitoring may incur additional cost. View https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/appinsights-what-is.html#appinsights-pricing for more details

Would you like to set Structured Logging in JSON format on your Lambda functions?  [y/N]: y
Structured Logging in JSON format might incur an additional cost. View https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs.html#monitoring-cloudwatchlogs-pricing for more details

Project name [sam-app]: 

    -----------------------
    Generating application:
    -----------------------
    Name: sam-app
    Runtime: nodejs20.x
    Architectures: x86_64
    Dependency Manager: npm
    Application Template: hello-world-typescript
    Output Directory: .
    Configuration file: sam-app/samconfig.toml
    
    Next steps can be found in the README file at sam-app/README.md
        

Commands you can use next
=========================
[*] Create pipeline: cd sam-app && sam pipeline init --bootstrap
[*] Validate SAM template: cd sam-app && sam validate
[*] Test Function in the Cloud: cd sam-app && sam sync --stack-name {stack-name} --watch

sam-appディレクトリが作成されていればOKです
今回は最小限の構成が欲しいので以下のようにテンプレートの一部を削除します。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  test-app

  Sample SAM Template for test-app

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 3

    Tracing: Active
  Api:
    TracingEnabled: true
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello-world/
      Handler: app.lambdaHandler
      Runtime: nodejs20.x
      Architectures:
      - x86_64
-      Events:
-        HelloWorld:
-          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
-          Properties:
-            Path: /hello
-            Method: get
    Metadata: # Manage esbuild properties
      BuildMethod: esbuild
      BuildProperties:
        Minify: true
        Target: es2020
        Sourcemap: true
        EntryPoints:
        - app.ts

Outputs:
  # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  # Find out more about other implicit resources you can reference within SAM
  # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
-  HelloWorldApi:
-    Description: API Gateway endpoint URL for Prod stage for Hello World function
-    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: Hello World Lambda Function ARN
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: Implicit IAM Role created for Hello World function
    Value: !GetAtt HelloWorldFunctionRole.Arn

3. SAMで使うIAMユーザーの作成

SAMで使うユーザーのアクセスキーとシークレットキーをここで作成します。
自分のアカウントで発行しても良いのですが、ここではSAM用にユーザーを作成します。
まず以下のポリシーを作成します。今回の構成ではこれで大丈夫ですが、複雑な構成になると他にもポリシーが必要になるかもしれません。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "cloudformation:*",
                "s3:*",
                "iam:*",
                "lambda:*",
                "resource-groups:*",
                "applicationinsights:*",
                "ec2:DescribeInstances",
                "ec2:DescribeNatGateways",
                "ec2:DescribeVolumes",
                "ec2:DescribeVPCs",
                "rds:DescribeDBInstances",
                "rds:DescribeDBClusters",
                "sqs:ListQueues",
                "elasticloadbalancing:DescribeLoadBalancers",
                "autoscaling:DescribeAutoScalingGroups",
                "dynamodb:ListTables",
                "sns:ListTopics",
                "states:ListStateMachines",
                "apigateway:GET",
                "ecs:ListClusters",
                "ecs:DescribeTaskDefinition",
                "ecs:ListServices",
                "ecs:ListTasks",
                "eks:ListClusters",
                "eks:ListNodegroups",
                "fsx:DescribeFileSystems",
                "route53:ListHealthChecks",
                "route53:ListHostedZones",
                "route53:ListQueryLoggingConfigs",
                "route53resolver:ListFirewallRuleGroups",
                "route53resolver:ListFirewallRuleGroupAssociations",
                "route53resolver:ListResolverEndpoints",
                "route53resolver:ListResolverQueryLogConfigs",
                "route53resolver:ListResolverQueryLogConfigAssociations",
                "logs:DescribeLogGroups",
                "resource-explorer:ListResources"
            ],
            "Resource": "*"
        }
    ]
}

その後、このポリシーを付与したIAMユーザーを作成して、アクセスキーとシークレットキーを作成します。
アクセスキーとシークレットキーはこの後使うのでどこかに保存してください。

3. AWS CLIの設定

まずAWS CLIをインストールします。下記コマンドでインストールできます。

curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
sudo installer -pkg AWSCLIV2.pkg -target /

下記コマンドで認証します。

aws configure

アクセスキーとシークレットキーとリージョンを入力します。
これで設定は完了です。

4. SAMを使ってdeploy

まずビルドします。

sam build

その後、デプロイします。

sam deploy --guided

色々聞かれますが、基本デフォルトとYでいいと思います。
これでLambdaにデプロイされたので、確認してみます。

デプロイされてることが確認できました。

終わりに

localからデプロイできたので、次はGitHub Actionsを使ってデプロイするようにしたいと思います。
(追記)
書きました。
https://zenn.dev/auagcu/articles/2dfa9e448e50cc

Discussion