この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
이번 Developers.IO 한국 블로그를 준비하면서 serverless framework를 도입해보려고 하고 있습니다. 이번에는 홍기님이 작성하신 AWS Lambda와 DynamoDB Streams를 활용한 트위터 포스팅봇 만들기 을 기준으로 serverless framework의 .yml 파일을 간단히 작성해보도록 하겠습니다.
serverless framework의 .yml(YAML)이란
serverless framework에서는 serverless.yml라는 구성 파일을 작성하여 여러 Resource 등을 설정하고 생성할 수 있습니다. 간단하게 필요한 Lambda 함수에 연결할 여러 Resource 등을 설정하는 파일이라고 생각하시면 됩니다.
그럼 어떻게 이런 동작이 가능할까요?
위의 내용에 따르면 AWS에 deploy(배포)시
실제로는 serverless framework는 serverless.yml을 AWS cloudFormation 템플릿으로 변환 후
cloudFormation을 통해 필요한 Lambda function과 Resource등을 생성하게 됩니다.
더욱 자세한 동작 방식에 대해서 알고 싶으시다면
두 개의 링크를 참고해 주세요.
.yml(YAML)작성
Lambda functions작성
먼저 필요한 두 개의 함수를 작성하겠습니다.
- request.js
module.exports.handler = async (event) => {
return {
statusCode: 200,
body: JSON.stringify(
{
message: '첫번째 function'
},
null,
2
)
}
}
- response.js
module.exports.handler = async (event) => {
return {
statusCode: 200,
body: JSON.stringify(
{
message: '두 번째 function'
},
null,
2
)
}
}
첫 번째 Lambda
functions:
request:
handler: request.handler
runtime: nodejs12.x
memorySize: 512
timeout: 6
environment:
developerIO_Korea_rss: "rss"
events:
- schedule:
name: developerIOKorea-scheduled
rate: cron(----)
enabled: true
- handler: 처음설정한 reuqest.js function을 연결합니다.
- runtime: nodejs12.x로 설정합니다.
- momoerySize: Lambda의 memorySize를 설정합니다. 여기서는 512MB로 설정하도록 하겠습니다.
- timeout: lambda가 한번 호출 할 때 마다 실행되는 시간입니다. 여기서는 6초로 설정하도록 하겠습니다.
- environment: lambda의 환경변수를 설정할 수 있습니다. (블로그 기사를 가져오기 위한 RSS를 설정하도록 하겠습니다.)
- event: lambda에 필요한 이벤트를 설정 할 수 있습니다. 첫 번째 lambda에는 AWS Lambda와 DynamoDB Streams를 활용한 트위터 포스팅봇 만들기를 토대로 필요한 cloudWatch의 rules을 설정하였습니다.
두 번째 Lambda
functions:
response:
handler: response.handler
runtime: nodejs12.x
memorySize: 512
timeout: 6
environment: <- Twitter을 이용하기 위한 token등을 환경변수로 등록 하였습니다.
access_token_key: "---"
access_token_secret: "---"
consumer_key: "---"
consumer_secret: "---"
events:
- stream:
type: dynamodb
arn:
Fn::GetAtt: [usersTable, StreamArn]
두 번째 Lambda는 첫 번째 Lambda와 다른 events에 대해서 알아보겠습니다.
AWS Lambda와 DynamoDB Streams를 활용한 트위터 포스팅봇 만들기 내용과 마찬가지로 dynamodb stream을 연결해야 합니다.
그럼 먼저 dynamodb을 설정해보도록 하겠습니다.
resources:
Resources:
usersTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: devloperIO_Korea
AttributeDefinitions:
- AttributeName: link
AttributeType: S
KeySchema:
- AttributeName: link
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
StreamSpecification:
StreamViewType: NEW_AND_OLD_IMAGES
- Type: db의 type입니다. dynamodb로 설정하도록 하겠습니다.
- AttributeDefinitions: 속성을 설정합니다.
- KeySchema: dynamodb의 key를 설정합니다.
- ProvisionedThroughput: 읽기/쓰기 용량을 설정합니다.(dynamodb의 용량란에서 확인할 수 있습니다.)
- ReadCapacityUnitys: dynamodb의 읽기 용량 설정
- WriteCapacityUnitys: dynamodb의 쓰기 용량 설정
- StreamSpecification: dynamodb stream을 설정합니다.
- StreamViewType: dynamodb stream의 type을 설정합니다. 여기서는 New Image 와 OLD Image로 설정하도록 하겠습니다.
events:
- stream:
type: dynamodb
arn:
Fn::GetAtt: [usersTable, StreamArn]
이후 위처럼 설정하면 끝입니다.
events: arn:~
와 같이 설정해도 괜찮습니다.
이번에는 Fn::GetAtt 을 참고로 작성해 보았습니다.
마지막으로 필요한 Role(역할)을 설정하도록 하겠습니다.
Role(역할)작성
Role(역할)은 AWS Lambda와 DynamoDB Streams를 활용한 트위터 포스팅봇 만들기의 Role을 기준으로 2개로 나뉘어 각 Lambda에 연결해 주도록 하겠습니다.
policy에 관한 내용도 홍기님이 작성하신 policy에 맞춰서 작성하였습니다.
2개의 Role과 관련된 정책을 작성해 줍니다.
devKoreaRequestRole:
Type: AWS::IAM::Role
Properties:
Path: /my/default/path/
RoleName: devKoreaRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: devloperIO_Korea_policy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: "*"
- Effect: Allow
Action:
- dynamodb:PutItem
Resource:
Fn::GetAtt: [usersTable, Arn]
devKoreaResponseRole:
Type: AWS::IAM::Role
Properties:
Path: /my/default/path/
RoleName: devKoreaRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: devloperIO_Korea_policy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: "*"
- Effect: Allow
Action:
- dynamodb:DescribeStream
- dynamodb:GetRecords
- dynamodb:GetShardIterator
- dynamodb:ListStreams
Resource:
Fn::GetAtt: [usersTable, StreamArn]
크게 두 부분으로 나누어져 있습니다.
- Role: lambda에 연결할 Role(역할)을 정의합니다.
- RoleName: Role의 이름을 설정
- AssumeRolePolicyDocument: 자신이 원하는 역할의 policy를 설정하시면 됩니다.
- Policies: 원하시는 policy를 정의하시면 됩니다. 구조는 기존 policy를 작성 할 때와 비슷합니다.
- PolicyName: policy의 이름을 설정
- PolicyDocument: 자신이 원하는 policy설정하시면 됩니다.
- Reousrce: arn은 Fn::GetAtt을 참고로 작성하였습니다.
Lambda에 연결해 줍니다.
functions:
request:
handler: request.handler
...
role: devKoreaRequestRole <- Role(역할)을 연결
response:
handler: response.handler
...
role: devKoreaResponseRole <- Role(역할)을 연결
전체
마지막으로 전체 내용입니다.
service: developerIO
provider:
name: aws
stage: dev
region: ap-northeast-2
functions:
request:
handler: request.handler
runtime: nodejs12.x
memorySize: 512
timeout: 6
environment:
developerIO_Korea_rss: "---/"
events:
- schedule:
name: developerIOKorea-scheduled
rate: cron(---)
enabled: true
role: devKoreaRequestRole
response:
handler: response.handler
runtime: nodejs12.x
memorySize: 512
timeout: 6
environment:
access_token_key: "---"
access_token_secret: "---"
consumer_key: "---"
consumer_secret: "---"
events:
- stream:
type: dynamodb
arn:
Fn::GetAtt: [usersTable, StreamArn]
role: devKoreaResponseRole
resources:
Resources:
usersTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: devloperIO_Korea
AttributeDefinitions:
- AttributeName: link
AttributeType: S
KeySchema:
- AttributeName: link
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
StreamSpecification:
StreamViewType: NEW_AND_OLD_IMAGES
devKoreaRequestRole:
Type: AWS::IAM::Role
Properties:
Path: /my/default/path/
RoleName: devKoreaRequestRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: devloperIO_Korea_policy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: "*"
- Effect: Allow
Action:
- dynamodb:PutItem
Resource:
Fn::GetAtt: [usersTable, Arn]
devKoreaResponseRole:
Type: AWS::IAM::Role
Properties:
Path: /my/default/path/
RoleName: devKoreaResponseRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: devloperIO_Korea_policy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: "*"
- Effect: Allow
Action:
- dynamodb:DescribeStream
- dynamodb:GetRecords
- dynamodb:GetShardIterator
- dynamodb:ListStreams
Resource:
Fn::GetAtt: [usersTable, StreamArn]