sam 시작하기

  • sam을 이용해서 hello world 프로젝트 만들어 보기
  • nodejs로 만든다

전제조건

SAM(Serverless Application Model)

  • 겁나 어려워 보이는데 그냥 람다 생성기라고 생각하면 된다
  • 로컬에서 편하게 vscode로 람다함수짜고 yml 파일 수정해서..!
  • 로컬 테스트 환경도 제공한다!

따라하기

cmd
1
2
3
4
5
6
7
sam init

C:\tmp>sam init
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice:
  • 1번, 1번해서
  • AWS Quick Start Templates, nodejs 를 골라준다
cmd
1
Project name [sam-app]: hello-world
  • 프로젝트명 설정하면, 샘플 프로젝트를 가져온다
cmd
1
2
3
4
5
6
7
8
9
10
AWS quick start application templates:
1 - Hello World Example
2 - Step Functions Sample App (Stock Trader)
3 - Quick Start: From Scratch
4 - Quick Start: Scheduled Events
5 - Quick Start: S3
6 - Quick Start: SNS
7 - Quick Start: SQS
8 - Quick Start: Web Backend
Template selection: 1
  • 1번 선택하여 헬로월드 템플릿을 받아온다
cmd
1
cd hello-world
  • 이제 생성된 프로젝트로 들어간다
1
2
3
4
5
6
7
8
9
10
11
.
├── events
│ └── event.json
├── hello-world
│ ├── tests/
│ ├── .npmignore
│ ├── app.js
│ └── package.json
├── .gitignore
├── README.md
└── template.yaml
  • 디렉터리 구조는 이러하다
  • 여기서 중요한 파일은 hello-world/app.jstemplate.yaml이다

  • 2개 파일 소스 대충 어떻게 생겼는지 봐보고 빌드해본다
cmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
sam build

C:\tmp\hello-world>sam build
Building function 'HelloWorldFunction'
Running NodejsNpmBuilder:NpmPack
Running NodejsNpmBuilder:CopyNpmrc
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:NpmInstall
Running NodejsNpmBuilder:CleanUpNpmrc

Build Succeeded

Built Artifacts : .aws-sam\build
Built Template : .aws-sam\build\template.yaml

Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided
  • .aws-sam 이라는 폴더가 생성된다
1
2
3
4
5
6
7
.aws-sam
└── build
├── HelloWorldFunction
│ ├── node_modules/
│ ├── app.js
│ └── package.json
└── template.yaml
  • 이제 배포해보자
cmd
1
sam deploy -g
  • 배포하자. -g옵션은 --guided 와 동일하다
  • 이 옵션은 최초에 배포할때만 사용된다
cmd log
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Configuring SAM deploy
======================

Looking for samconfig.toml : Not found

Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]: test-sam-app
AWS Region [us-east-1]: ap-northeast-2
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [y/N]: y
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]: y
HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
Save arguments to samconfig.toml [Y/n]: y
  • 먼저 Stack Name을 지정해준다. 공란으로 하면 sam-app으로 적용된다
  • 다음은 리전 설정이다. 나는 서울 ap-northeast-2로 지정했다
  • 다음은 전부다 y 해준다
cmd log
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CloudFormation stack changeset
----------------
Operation LogicalResourceId ResourceType
----------------
+ Add HelloWorldFunctionHelloWorldPermissionProd AWS::Lambda::Permission
+ Add HelloWorldFunctionRole AWS::IAM::Role
+ Add HelloWorldFunction AWS::Lambda::Function
+ Add ServerlessRestApiDeployment47fc2d5f9d AWS::ApiGateway::Deployment
+ Add ServerlessRestApiProdStage AWS::ApiGateway::Stage
+ Add ServerlessRestApi AWS::ApiGateway::RestApi
----------------

Changeset created successfully. arn:aws:cloudformation:ap-northeast-2:111111111111:changeSet/samcli-deploy1600652952/89cf8cb3-a626-44ef-bd26-815dacedaa8e


Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y
  • 또 어쩌구 저쩌구 나오면서 마지막 확인을 받는데 y 해준다
cmd log
1
Successfully created/updated stack - test-sam-app in ap-northeast-2
  • 그러면 시간이 쫌 걸리면서 aws에 올라가게 된다

  • samconfig.toml 파일이 생성된 것을 확인할 수 있다

  • 이제 브라우저를 열어서 aws lambda 로 들어간다

  • 위와 같이 [스택네임]-HelloWorldFunction이름의 함수 하나가 생성되었다
  • 눌러서 들어간다
  • 이런 화면이 나온다
  • api 게이트웨이를 클릭한다. 그러면 아래 화면이 api 게이트웨이로 바뀐다. 거기서 다시 세부 정보를 클릭해서 api 엔드포인트를 확인한다
  • 엔드포인트를 눌러 접속한다
  • {"message":"hello world"}이 보이면 성공이다
  • 이렇게 다짜고짜 sam으로 람다를 만들어 보았다

해설

  • sam Hello World Example template를 이용해서 람다를 만들었다
  • 이 람다는 어떤 주소로 접속하면 hello world를 반환하는 람다이다
  • 현재 프로젝트 구조를 잘 살펴보면 sam을 익히면 된다
  • 먼저 이 {"message":"hello world"}는 어디서 왔을까?
hello-world/app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
exports.lambdaHandler = async (event, context) => {
try {
// const ret = await axios(url);
response = {
statusCode: 200,
body: JSON.stringify({
message: 'hello world',
// location: ret.data.trim()
}),
};
} catch (err) {
console.log(err);
return err;
}

return response;
};
  • lambdaHandler라는 함수가 있는데 response객체를 반환한다
  • 근데 우리는 {“message”:”hello world”} 만 보이니까 body에 있는 내용을 조작하면 우리가 원하는 내용을 보낼 수 있겠구나 생각할 수 있다
  • 그러면 이 함수를 실행시키는 트리거, s22xid3g26.execute-api.ap-northeast-2.amazonaws.com/Prod/hello
  • api 게이트웨이의 엔드포인트는 어디서 설정되었을까?
template.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
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: nodejs12.x
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
  • template.yaml을 보면 Events 아래 Type: Api가 보인다
  • hello라는 Path로 get 요청이 왔을때 라고 이해할 수 있다

  • 이제 이를 토대로 람다를 업그레이드 해보자