로컬에서 sam 테스트하기

  • 이제 테스트할 때 build, deploy 기다리기… 할 필요가 없다!

전제조건


sam local start-api

cmd
1
sam local start-api --skip-pull-image
cmd log
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
C:\tmp\hello-world>sam local start-api --skip-pull-image
Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM
CLI if you update your AWS SAM template
2020-09-21 13:40:36 * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
2020-09-21 13:40:41 127.0.0.1 - - [21/Sep/2020 13:40:41] "GET / HTTP/1.1" 403 -
2020-09-21 13:40:41 127.0.0.1 - - [21/Sep/2020 13:40:41] "GET /favicon.ico HTTP/1.1" 403 -
Invoking app.lambdaHandler (nodejs12.x)
Requested to skip pulling images ...

Mounting C:\tmp\hello-world\.aws-sam\build\HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: 00b5b190-1c8d-184f-5ab5-c0e0764041d3 Version: $LATEST
END RequestId: 00b5b190-1c8d-184f-5ab5-c0e0764041d3
REPORT RequestId: 00b5b190-1c8d-184f-5ab5-c0e0764041d3 Init Duration: 438.88 ms
Duration: 4.53 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 44 MB
No Content-Type given. Defaulting to 'application/json'.
2020-09-21 13:40:48 127.0.0.1 - - [21/Sep/2020 13:40:48] "GET /hello HTTP/1.1" 200 -
2020-09-21 13:40:48 127.0.0.1 - - [21/Sep/2020 13:40:48] "GET /favicon.ico HTTP/1.1" 403 -
  • 나는 이렇게 명령을 쓴다
  • 나는 보통 매 실행마다 3-4초 정도 걸린다
  • build, deploy 하면서 테스트할때보다 획기적으로 빠르게 로컬에서 테스트 해볼 수 있다
  • --skip-pull-image옵션을 주는 이유는 매 실행마다 이미지를 받아오는 과정이 있는게 그걸 스킵하면 2초정도 빨라진다
  • 변경 사항은 자동으로 반영된다
  • 단점 ; 근데 변경사항이 없어도 매 실행 3초이상 걸린다
  • template.yaml 파일을 수정하면 수동으로 재시작 해줘야한다

samconfig.toml 에서 sam deploy 자동 y 설정하기

cmd log
1
2
3
Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y
  • deploy를 자주하다보면 이 y 누르는게 힘들다…

samconfig.toml 설정하기

samconfig.toml
1
2
3
4
5
6
7
8
9
10
version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "test-sam-app"
s3_bucket = "00000000000000000000000000000000000000000000000000000000000"
s3_prefix = "test-sam-app"
region = "ap-northeast-2"
confirm_changeset = false
capabilities = "CAPABILITY_IAM"
  • 처음 배포할때 -g옵션에서 설정했던것이 samconfig.toml에 저장되어있다
1
confirm_changeset = false
  • 여기서 confirm_changeset을 flase로 바꿔주면 중간에 확인 과정을 생략할 수 있다
  • 편안..!

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 요청이 왔을때 라고 이해할 수 있다

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

aws 카테고리 생성

  • aws 공부한 내용 올리기