#AWS Certified Developer Associate
356. AWS SAM - 섹션 소개
SAM 은 애플리케이션이 작동하고 배포되어야 하는 방향에 맞는 YAML 파일과 템플릿 작성을 지원함
cloudformation 실행을 간단히 한 것이지만 개발자 친화적이며 aws 내에서도 주류로 자리잡고 있다고 함
357. SAM (AWS Serverless Apllication Model) 개요
서버리스 애플리케이션 개발 및 배포를 위한 프레임워크
모든 구성은 YAML 형식으로 실행됨
- 간단한 yaml 파일을 통해서 SAM CLI 를 활용한 복잡한 CloudFormation 템플릿을 생성할 수 있음
CloudFormation 과 호환이 가능하므로 모든 CloudFormation 구조를 실시할 수 있음
- outputs, mappings, parameters, resources 등
aws 에 배포하기 위한 2가지 명령
SAM 에서 CodeDeploy 로 람다 함수를 배포하고 버전 간 트래픽이 점진적으로 변하는지 확인 가능
SAM 을 이용해서 람다, api gateway, DynamoDB 를 로컬에서 실행할 수 있으므로 애플리케이션 테스트를 위해 aws 에 배포할 필요가 없음
Recipe
Transform 헤더 : 'AWS::Serverless-2016-10-31'
이 헤더는 SAM 템플릿을 나타내며 CloudFormation 은 이 템플릿을 CloudFormation 용 템플릿으로 변환할 수 있음
YAML 파일 내 코드 :
- AWS::Serverless::Function
- AWS::Serverless::Api
- AWS::Serverless::SimpleTable
Package & Deploy : (패키징과 배포를 위한 2가지 명령)
- aws cloudformation package / sam package
- aws cloudformation deploy / sam deploy
SAM - CLI Debugging
SAM CLI 를 통해 로컬에 람다와 같은 실행 환경을 갖출 수 있음
SAM CLI + AWS Toolkits 를 사용해 코드를 천천히 살펴보고 디버깅 하는 방식 사용
- aws 에 배포하는일 없이 lambda 를 사용한 개발을 로컬에서 완료 가능
SAM CLI 를 지원하는 IDE
- Cloud9, VSC, JetBrains, PyCharm, IntelliJ 등
- SAM CLI 와 IDE 를 함께 사용하면 람다 함수를 로컬 컴퓨터에서 실행할 수 있고 디버깅 또한 가능함
358. SAM CLI 설치
개발을 데스크탑에서 주로 하기때문에 window 에 설치해줬다
구글에 SAM framwork cli install 검색
사전 설정인 aws cli 를 최신버전으로 업데이트 해주고 진행했다
aws 가 버전 1이 아나콘다 파일에 설치되어있어서 pip을 이용해서 제거해주고 최신버전으로 다시 설치해줬다
https://docs.aws.amazon.com/ko_kr/cli/v1/userguide/install-windows.html#awscli-install-windows-pip
aws configure 로 내가 사용하는 2개의 aws 계정을 각각 profile 로 입력해줬다
default 는 프로젝트용, aws-student profile 을 따로 만들었다
359. 첫 번째 SAM 프로젝트 생성
먼저 작업 디렉토리를 하나 만들어주고
src 디렉토리를 하나 만들고 그 안에 app.py 를 하나 생성
이후 작업 디렉토리 상단에 template.yaml 파일과 commands.sh 파일을 하나씩 생성해줬다
이후 amazon archives 에서 serverless-app-examples 에서 python 예제를 다운받는다고 한다
https://github.com/amazon-archives/serverless-app-examples/tree/master/python
여기서 hello-world-python3 로 들어가서
lambda_function.py 의 내용을 작업 디렉토리의 app.py 에 붙여넣고
template.yaml 의 내용은 template.yaml 에 붙여넣어줬다
app.py 의 함수 부분은 간단하게 hello world 만 반환하도록 바꿨다
template.yaml 파일을 살펴본다고 함
맨위에 버전은 cloudformation 템플릿을 나타냄
Transform 을 보면 sam 템플릿을 사용하는 것을 알 수 있다
- 위에서 설명 transform 헤더
Parameters 부분은 실습을 간단히 하기 위해 모두 삭제
리소스 부분에서 1개 리소스가 정의되어있는데, 타입으로 서버리스 함수라고 정의되어있다
속성으로 내려가서
람다함수가 핸들러를 갖는다고 나와있다
- 핸들러는 파일이름.함수이름 의 형식을 따라야 한다
런타임은 그대로 두고
CodeUri 는 소스 디렉토리 내에 있으니 src/ 라고 바꿔줌
- CodeUri 는 코드가 있는 로컬 위치를 나타냄
메모리 사이즈와 타임아웃은 그대로 사용함
기존 코드의 정책은 사용하지 않으니 삭제한다고 함
360. SAM 프로젝트 배포
먼저 commands.sh 파일로 가서 S3 버킷을 생성한다고 함
D:\DEV\General\aws-sam-Training>aws s3 mb s3://yeonwoo-code-sam --profile aws-student
make_bucket: yeonwoo-code-sam
D:\DEV\General\aws-sam-Training>
이후 패키징을 위해 aws cloudformation package 명령어를 사용할텐데
이를 위한 옵션을 help 로 살펴봤다
Synopsis
********
package
--template-file <value>
--s3-bucket <value>
[--s3-prefix <value>]
[--kms-key-id <value>]
[--output-template-file <value>]
[--use-json]
[--force-upload]
[--metadata <value>]
[--debug]
[--endpoint-url <value>]
[--no-verify-ssl]
[--no-paginate]
[--output <value>]
[--query <value>]
[--profile <value>]
[--region <value>]
[--version <value>]
[--color <value>]
[--no-sign-request]
[--ca-bundle <value>]
[--cli-read-timeout <value>]
[--cli-connect-timeout <value>]
[--cli-binary-format <value>]
[--no-cli-pager]
[--cli-auto-prompt]
[--no-cli-auto-prompt]
필수인 버킷 이름과 템플릿 파일을 입력해주고
이후 변환한 파일을 저장할 경로와 파일명을 입력해주고 실행
이걸로 코드가 s3 에 업로드 되었다고 한다
로컬에서도 변환된 파일이 저장된것을 확인할 수 있다
코드 uri 가 s3 버킷 객체를 가리키고 있다
버킷 안에서도 내용을 확인할 수 있다
위 명령 실행의 결과에서 배포를 위해 아래 명령을 실행하라고 나오는데
그대로 실행하면 Requires capabilities : [CAPABILITY_IAM] 라고 나오면서 failed 된다
그래서 명령문에 기능을 추가해줘야 한다
D:\DEV\General\aws-sam-Training>aws cloudformation deploy --template-file gen/template-generated.yaml --stack-name hello-world-sam --capabilities CAPABILITY_IAM --profile aws-student
Waiting for changeset to be created..
Waiting for stack create/update to complete
이렇게 추가해주면 생성 및 업데이트 단계로 넘어간다
강의에선 스택 생성에 성공했지만 나는 실패했다
이벤트를 뜯어보니
런타임 버전을 지원안한다고 한다
3.9로 바꿔서 다시 해보자
cloudformation 으로 가서 롤백된 스택을 지워주고 다시 명령어 실행
lambda 함수와 iam role 리소스 2개가 잘 생성된 것을 확인할 수 있다
로컬에서 작성했던 app.py 가 잘 들어가있는 것을 확인할 수 있다
(2.26 끝)
(2.28 시작)
361. SAM API Gateway
간단히 sam 파일에 api gateway stage 를 추가하는 실
함수 전에 api gateway 를 설정한다고 한다
다시 예제 github 로 가서 api gateway 예제를 찾아서 붙여넣는다고 함
먼저 여기서 lambda_function.py 를 작업 디렉토리의 app.py 로 붙여넣기 하고 필요한 부분만 사용한다고 함
수정한 app.py
import boto3
import json
import os
print('Loading function')
# 오류나 결과를 반환하는 함수
# 양식 자체도 api gateway 에서 사용하는 양식
def respond(err, res=None):
return {
'statusCode': '400' if err else '200',
'body': err.message if err else json.dumps(res),
'headers': {
'Content-Type': 'application/json',
},
}
def lambda_handler(event, context):
print("Received event: " + json.dumps(event, indent=2))
return respond(None, res="hello world!")
이제 template.yaml 에 api gateway 정보를 붙여넣어준다고 함
수정된 template.yaml
# SAM FILE
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: A starter AWS Lambda function.
Resources:
helloworldpython3:
Type: 'AWS::Serverless::Function'
Properties:
Handler: app.lambda_handler
Runtime: python3.9
CodeUri: src/
Description: A starter AWS Lambda function.
MemorySize: 128
Timeout: 3
Events:
HelloWorldSAMAPI:
Type: Api
Properties:
Path: /hello
Method: GET
기존 코드에 아래 events 항목을 더해줬다
이제 cloudformation package 를 실행해서 아티팩트를 업로드하고 생성된 탬플릿을 업데이트 되도록 명령을 다시 실행한다
cloudformation package 명령
aws cloudformation package --s3-bucket yeonwoo-code-sam --template-file template.yaml --output-template-file gen/template-generated.yaml --profile aws-student
위 명령을 실행하면 template-generated.yaml 이 업데이트 된다
업데이트된 template-generated.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: A starter AWS Lambda function.
Resources:
helloworldpython3:
Type: AWS::Serverless::Function
Properties:
Handler: app.lambda_handler
Runtime: python3.9
CodeUri: s3://yeonwoo-code-sam/843f6e0aedc039e25757d2c06f0c6357
Description: A starter AWS Lambda function.
MemorySize: 128
Timeout: 3
Events:
HelloWorldSAMAPI:
Type: Api
Properties:
Path: /hello
Method: GET
생성된 템플릿을 보면
s3 uri 가 자동으로 업데이트 된 것을 확인할 수 있다
이제 cloudformation deploy 명령어를 실행한다고 함
위 명령을 실행하면 changeset 이 생성되도록 잠깐 기다린 다음 생성이 끝나면
본 cloudformation 에 실행될 것
업데이트가 완료되면 새로 생성된 리소스들을 확인할 수 있음
코드에서의 조금의 변화로 많은 리소스를 새로 생성할 수 있음
SAM 의 장점
- cloudformation 에서 실행되는 복잡한 템플릿과 다른 여러 모든 항목을 자동으로 생성해줌
event 로 생성해준 api gateway 를 확인할 수 있다
실행하면 오류가 나는데 위 코드에서 return 을 추가안해줘서 에러가 났다 *(나중에 추가해줌)
362. SAM DynamoDB
SAM 파일에 서버리스 db 인 dynamoDB 테이블 추가 실습
api gateway 에서 썻던 예제 github 파일을 보면 dynamoDB 테이블이 추가되어있음
이전 실습에선 해당 코드를 제거하고 사용했었음
코드에서 클라이언트를 핸드러 밖에 선언해주는데
lambda 챕터에서 배웠듯이 가장 좋은 방법이다
그리고 코드를 조금 추가해줘야 하는데 바로 리전이다
dynamoDB 를 생성할 리전을 정해줘야 하는데 새로운 환경변수를 생성해서 전달해준다고 한다
그리고 함수에 dynamoDB 를 활용한 작업을 추가한다고 함
람다 핸들러에 db 테이블을 스캔한 후 결과를 저장하고 리턴하도록 코드를 수정했다
수정된 app.py
import boto3
import json
import os
print('Loading function')
# create the client outside of the handler
region_name = os.environ['REGION_NAME']
dynamo = boto3.client('dynamodb', region_name=region_name)
table_name = os.environ['TABLE_NAME']
# 오류나 결과를 반환하는 함수
# 양식 자체도 api gateway 에서 사용하는 양식
def respond(err, res=None):
return {
'statusCode': '400' if err else '200',
'body': err.message if err else json.dumps(res),
'headers': {
'Content-Type': 'application/json',
},
}
def lambda_handler(event, context):
print("Received event: " + json.dumps(event, indent=2))
scan_result=dynamo.scan(TableName=table_name)
return respond(None, res=scan_result)
위에서 생성해준 환경변수인 RESION_NAME 과 TABLE_NAME 은 template.yaml 에서 설정해줘야 한다
예제 github 파일에서 리소스 하위의 table 코드를 가져와 준다
여기에 추가로 몇가지 속성을 지정해서 과도한 비용이 청구되지 않도록 설정한다고 함
table 속성
Table:
Type: AWS::Serverless::SimpleTable
Properties:
PrimaryKey:
Name: greeting
Type : String
ProvisionedThroughput:
ReadCapacityUnits: 2
WriteCapacityUnits: 2
이제 람다 핸들러에 대한 환경변수를 지정해준다고 함
!Ref 함수를 이용해서 CloudFormation 으로 앞서 생성한 simpletable 에 포함되는 함수이다
리전에 관한 환경변수도 생성해주는데 AWS::Region 이라는 의사 매개변수를 사용해준다
- 의사 매개변수란 aws cloudformation 탬플릿에서 직접 제공하는 매개변수
환경변수 추가
Environment:
Variables:
TABLE_NAME: !Ref Table
REGION_NAME: !Ref AWS::Region
이렇게 환경변수와 아래에 테이블까지 정의해주면
lambda 에서 이 테이블에 접근할 수 있는 액세스 권한도 정의해줘야 한다고 함
이때 정책은 람다 함수에 추가 가능한 IAM 정책을 사용해야 한다고 함
수정된 template.yaml
# SAM FILE
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: A starter AWS Lambda function.
Resources:
helloworldpython3:
Type: 'AWS::Serverless::Function'
Properties:
Handler: app.lambda_handler
Runtime: python3.9
CodeUri: src/
Description: A starter AWS Lambda function.
MemorySize: 128
Timeout: 3
Environment:
Variables:
TABLE_NAME: !Ref SAM-Table
REGION_NAME: !Ref AWS::Region
Events:
HelloWorldSAMAPI:
Type: Api
Properties:
Path: /hello
Method: GET
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref SAM-Table
Table:
Type: AWS::Serverless::SimpleTable
Properties:
PrimaryKey:
Name: greeting
Type : String
ProvisionedThroughput:
ReadCapacityUnits: 2
WriteCapacityUnits: 2
이제 sam명령을 통해 sam 파일을 cloudformation 파일로 변환하고 배포해보면
dynamodb 테이블이 잘 생성된 것을 확인할 수 있다
스캔을 위해 테이블에 몇가지 아이템을 직접 넣고
람다함수로 가서 생성된 함수의 환경변수를 확인해보면
환경변수를 가져오는 함수가 제대로 동작해서 테이블 이름과 배포할 리전의 이름을 잘 가져온것을 확인할 수 있다
api gateway 의 resources 의 get 으로 가서 테스트를 해보면
status 200 으로 람다가 db에서 정상으로 항목들을 불러와진 것을 확인할 수 있다
유니코드로 반환되는데 반환 타입을 지정해주지 않아서 그런가보다
이제 stage 에서 prod 의 url 로 들어가서 확인해보면
역시 같은 결과를 반환해주는 것을 확인할 수 있다
'AWS > AWS Certified Developer Associate' 카테고리의 다른 글
[Udemy][day-59] Section25 : 클라우드 개발 키트 (Cloud Development Kit, CDK) (0) | 2023.03.02 |
---|---|
[Udemy][day-58] Section24 : AWS SAM - 2 (0) | 2023.02.28 |
[Udemy][day-56,57] Section23 : AWS 서버리스 : API Gateway - 3 (0) | 2023.02.23 |
[Udemy][day-55] Section23 : AWS 서버리스 : API Gateway - 2 (0) | 2023.02.21 |
[Udemy][day-54,55] Section23 : AWS 서버리스 : API Gateway (0) | 2023.02.15 |