serverless framework .yml을 작성해보았다.
이번 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]