AWSKRUG Serverless Group์ ์ฒซ๋ฒ์งธ ํธ์ฆ์จ Part.2 ์นํฌ๋กค๋ฌ ๋ง๋ค๊ธฐ์ ๋๋ค.๐
Part.1์ ํ์ จ๋ค๋ฉด "Cloud9 ์์ํ๊ธฐ", "Serverless Framework ์๊ฐ", ๊ทธ๋ฆฌ๊ณ "S3 bucket ์์ฑํ๊ธฐ"๋ ๋์ด๊ฐ๋ ์ข์ต๋๋ค.
Amazon Web Service ๋ฅผ ํ์ฉํ์ฌ Serverless architecture๋ก ์นํฌ๋กค๋ฌ๋ฅผ ๋ฐฐํฌํฉ๋๋ค. ํฌ๋กค๋ง๋ ๋ฐ์ดํฐ๋ DynamoDB์ ์ ์ฅํฉ๋๋ค.
AWS์์ ์ฌ์ฉํ๋ ๋ฆฌ์์ค๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- Cloud9: ์ฝ๋ ์์ฑ, ์คํ ๋ฐ ๋๋ฒ๊น ์ ์ํ ํด๋ผ์ฐ๋ ๊ธฐ๋ฐ IDE.
- Lambda: ์๋ฒ๋ฅผ ํ๋ก๋น์ ๋ํ๊ฑฐ๋ ๊ด๋ฆฌํ์ง ์๊ณ ๋ ์ฝ๋๋ฅผ ์คํํ ์ ์๊ฒ ํด์ฃผ๋ ์ปดํจํ ์๋น์ค. ์๋ฒ๋ฆฌ์ค ์ํคํ ์ณ์ ํต์ฌ ์๋น์ค.
- DynamoDB: ์๋ฒฝํ๊ฒ ๊ด๋ฆฌ๋๋ NoSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋น์ค๋ก, ์ํํ ํ์ฅ์ฑ๊ณผ ํจ๊ป ๋น ๋ฅด๊ณ ์์ธก ๊ฐ๋ฅํ ์ฑ๋ฅ์ ์ ๊ณต.
Cloud9 ์ ํ๋์ IDE์ ๋๋ค. ๊ทธ๋ ์ง๋ง ์ด์ ์ ์ค์นํ IDE์๋ ๋ค๋ฆ ๋๋ค. ์ค์นํ IDE๋ ๋ก์ปฌ PC์ ํ๋ก๊ทธ๋จ์ ์ค์นํ๋๊ฐ ์คํํ๋ ๋ฐฉ์์ด์๋ค๋ฉด, Cloud9์ ๋ธ๋ผ์ฐ์ ๊ฐ ์คํ๊ฐ๋ฅํ ๋ชจ๋ OS์์ ์ฌ์ฉ์ด ๊ฐ๋ฅํฉ๋๋ค.
๋งจ ์ฒ์ Cloud9์ AWS ๋ด์์๊ฐ ์๋ ๋ณ๋์ ์๋น์ค๋ก ์ ๊ณต๋์์ต๋๋ค. AWS์ ์ธ์๋ ์ดํ Cloud9์ AWS์ Managed Serviceํํ๋ก ๋ฐ๋์๊ณ , AWS์ ์๋น์ค์ ๊ฒฐํฉํ์ฌ ์ฌ์ฉ์ด ๊ฐ๋ฅํด์ก์ต๋๋ค. ์ฝ๋ ํธ์ง๊ณผ ๋ช ๋ น์ค ์ง์ ๋ฑ์ ํ๋ฒํ IDE ๊ธฐ๋ฅ์ ์ง๋๊ณ ์๋ ๋ฐ๋ฉด์, ํ์ฌ๋ AWS ์๋น์ค์ ๊ฒฐํฉ๋์ด ์ง์ Lambda ์ฝ๋๋ฅผ ๋ฐฐํฌํ๋๊ฐ, ์ค์ ๋ก Cloud9์ด ์คํ๋๊ณ ์๋ EC2์ ์ปดํจํ ์ฑ๋ฅ์ ํฅ์์์ผ์ ๋ก์ปฌ PC์ ์ฌ์์ ์ข ์๋์ง ์์ ๊ฐ๋ฐ์ ํ ์๊ฐ ์์ต๋๋ค.
๊ทธ๋ฌ๋ฉด Cloud9 ํ๊ฒฝ์ ์์ํด๋ด ์๋ค.
Cloud 9 Console์ ์ ์ํฉ๋๋ค.
์๋์ ๊ฐ์ ํ๋ฉด์์ Create Environment ๋ฒํผ์ ๋๋ฆ ๋๋ค.
Name๊ณผ Description์ ๋ค์๊ณผ ๊ฐ์ด ์ ๋ ฅํฉ๋๋ค.
- Name: ServerlessHandsOn
- Description: Serverless hands-on in AWSKRUG Serverless Group
Configure Setting์ ๋ค์๊ณผ ๊ฐ์ด ํฉ๋๋ค.
- Environment Type: EC2
- Instance Type: T2.micro
- Cost Save Setting: After 30 minutes
- Network Settings: Default
๋ชจ๋ ์ค์ ์ ๋ง์ณค๋ค๋ฉด Cloud9 Environment๋ฅผ ์์ฑํ๊ณ Open IDE๋ฅผ ํตํด ๊ฐ๋ฐ ํ๊ฒฝ์ ์ ์ํฉ๋๋ค.
์ ์ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ํ๋ฉด์ ๋ณผ ์ ์์ต๋๋ค.
- ํ์ฌ Environment name
- EC2์์ ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํ ์ ์๋ Terminal
- Lambda Functions
- Local Functions: ๋ฐฐํฌ๋์ง ์์ ํธ์ง์ค์ธ Functions
- Remote Functions: ํ์ฌ ์ค์ ํด๋์ Region์ ๋ฐฐํฌ๋ Lambda Functions
- Preferences
ํ์ฌ ap-southeast-1 region์ Cloud9 Environment๋ฅผ ๋ฐฐํฌํ์ผ๋ฏ๋ก Default Region์ด ap-southeast-1์ผ๋ก ๋์ด ์์ต๋๋ค. Preferences(์ค์ ํ๋ฉด)์์ ap-northeast-2(Seoul Region)์ผ๋ก ๋ฐ๊พธ์ด์ค๋๋ค.
- Preferences > AWS Settings > Region > Asia Pacific(Seoul)
์ค์ ์ ๋ง์น ๋ค์ Node.js ๋ฒ์ ์ ์ฌ๋ ค์ผํฉ๋๋ค. ํ์ฌ(2018-06-30) ์ ๊ณตํ๋ node์ ๋ฒ์ ์ด 6.10์ด๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ณดํต์ nvm์ ๋ฐ๋ก ์ค์นํด์ผํ์ง๋ง Cloud9์ ์ฌ์ฉํ๋ฉด ๋ณ๋์ nvm ์ค์น๋ ํ์์์ต๋๋ค. ๋ค์์ ๋ช ๋ น์ด๋ฅผ terminal์ ์ ๋ ฅํ์ฌ node์ ๋ฒ์ ์ 8.10์ผ๋ก ์ค์ ํฉ๋๋ค.
$ sudo yum groupinstall 'Development Tools'
$ nvm install 8.10
Downloading https://nodejs.org/dist/v8.10.0/node-v8.10.0-linux-x64.tar.xz...
######################################################################## 100.0%
Now using node v8.10.0 (npm v5.6.0)
# 8.10์ default๋ก ์ฌ์ฉํ๊ธฐ
$ nvm alias default 8.10
Cloud9 ์ค์ ์ ์๋ฃํ์์ต๋๋ค.
Serverless Framework ๋ฉ์ธ์ ๋์์๋ ์๊ฐ๋ฌธ๊ตฌ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
Serverless is your toolkit for deploying and operating serverless architectures. Focus on your application, not your infrastructure.
์ ๋ด์ฉ์ ๋ฒ์ญํ ๋ด์ฉ์ "Serverless๋ ์๋ฒ ์๋ ์ํคํ ์ฒ๋ฅผ ๋ฐฐ์นํ๊ณ ์ด์ํ๊ธฐ ์ํ ํดํท์ ๋๋ค. ์ธํ๋ผ๊ฐ ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ง์คํฉ๋๋ค." ์ ๋๋ค. ์ด์ฒ๋ผ Serverless framework๋ Serverless architecture๋ฅผ ์ด์ํ๊ธฐ ์ํ ํด์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋ฉ๋๋ค.
๊ทธ๋ฌ๋ฉด serverless framework๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ํ๊ฒฝ์ ์ด๋ป๊ฒ ๋ ๊น์?
node.js๊ฐ ์ค์น๋์ด ์๋ ํ๊ฒฝ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
open source๋ก ๊ธฐ์ฌํ๊ณ ์ถ๋ค๋ฉด https://github.com/serverless/serverless์์ issue์ pull request๋ฅผ ๋ฑ๋กํด์ฃผ์ธ์.
Serverless Framework๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ ๋ช ๋ น์ด๋ค์ ์ดํด๋ด ์๋ค.
# Serverless Framework๋ฅผ ์ค์นํฉ๋๋ค.
$ npm i -g serverless
# ๋ช
๋ น์ด๋ค์ ํ์ธํด๋ด
๋๋ค.
$ serverless --help
Commands
* You can run commands with "serverless" or the shortcut "sls"
* Pass "--verbose" to this command to get in-depth plugin info
* Pass "--no-color" to disable CLI colors
* Pass "--help" after any <command> for contextual help
Framework
* Documentation: https://serverless.com/framework/docs/
config ........................ Configure Serverless
config credentials ............ Configures a new provider profile for the Serverless Framework
create ........................ Create new Serverless service
deploy ........................ Deploy a Serverless service
deploy function ............... Deploy a single function from the service
deploy list ................... List deployed version of your Serverless Service
deploy list functions ......... List all the deployed functions and their versions
info .......................... Display information about the service
install ....................... Install a Serverless service from GitHub or a plugin from the Serverless registry
invoke ........................ Invoke a deployed function
invoke local .................. Invoke function locally
logs .......................... Output the logs of a deployed function
metrics ....................... Show metrics for a specific function
package ....................... Packages a Serverless service
plugin ........................ Plugin management for Serverless
plugin install ................ Install and add a plugin to your service
plugin uninstall .............. Uninstall and remove a plugin from your service
plugin list ................... Lists all available plugins
plugin search ................. Search for plugins
print ......................... Print your compiled and resolved config file
remove ........................ Remove Serverless service and all resources
rollback ...................... Rollback the Serverless service to a specific deployment
rollback function ............. Rollback the function to the previous version
slstats ....................... Enable or disable stats
Platform (Beta)
* The Serverless Platform is currently in experimental beta. Follow the docs below to get started.
* Documentation: https://serverless.com/platform/docs/
emit .......................... Emits an event to a running Event Gateway
login ......................... Login or sign up for the Serverless Platform
logout ........................ Logout from the Serverless Platform
run ........................... Runs the Event Gateway and the Emulator
Plugins
AwsConfigCredentials, Config, Create, Deploy, Emit, Info, Install, Invoke, Login, Logout, Logs, Metrics, Package, Plugin, PluginInstall, PluginList, PluginSearch, PluginUninstall, Print, Remove, Rollback, Run, SlStats
์ฌ๊ธฐ์ ์์ฃผ ์ฌ์ฉํ๊ฒ ๋ ๋ช ๋ น์ด๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- create: ํ๋ก์ ํธ ์์ฑ์ ์ฌ์ฉ
- deploy: ๋ฐฐํฌํ ๋ ์ฌ์ฉ
- package: ๋ฐฐํฌ๋ ํจํค์ง์ ๊ตฌ์กฐ๋ฅผ ๋ณด๊ณ ์ถ์ ๋ ์ฌ์ฉ
- invoke: ํน์ handler๋ฅผ ๋์์ํฌ ๋ ์ฌ์ฉ
- remove: ๋ฐฐํฌ๋ ๋ฆฌ์์ค๋ฅผ ์ ๊ฑฐํ ๋ ์ฌ์ฉ
๊ฐ๋จํ๊ฒ ๋ก์ปฌ์์ serverless ๋ช ๋ น์ด๋ฅผ ํ ์คํธํด๋ด ๋๋ค. deploy ๋ช ๋ น์ด๋ ์ถํ์ ์ฌ์ฉํ๊ฒ ์ต๋๋ค.
# Global ๋ก serverless framework ์ค์น
$ npm i -g serverless
# serverless service ์์ฑ ํํธ ๋ฐ๊ธฐ
$ serverless create --help
Plugin: Create
create ........................ Create new Serverless service
--template / -t .................... Template for the service. Available templates: "aws-nodejs", "aws-nodejs-typescript", "aws-nodejs-ecma-script", "aws-python", "aws-python3", "aws-groovy-gradle", "aws-java-maven", "aws-java-gradle", "aws-kotlin-jvm-maven", "aws-kotlin-jvm-gradle", "aws-kotlin-nodejs-gradle", "aws-scala-sbt", "aws-csharp", "aws-fsharp", "aws-go", "aws-go-dep", "azure-nodejs", "fn-nodejs", "fn-go", "google-nodejs", "kubeless-python", "kubeless-nodejs", "openwhisk-java-maven", "openwhisk-nodejs", "openwhisk-php", "openwhisk-python", "openwhisk-swift", "spotinst-nodejs", "spotinst-python", "spotinst-ruby", "spotinst-java8", "webtasks-nodejs", "plugin" and "hello-world"
--template-url / -u ................ Template URL for the service. Supports: GitHub, BitBucket
--template-path .................... Template local path for the service.
--path / -p ........................ The path where the service should be created (e.g. --path my-service)
--name / -n ........................ Name for the service. Overwrites the default name of the created service. ## "
# node๋ฅผ ์ฌ์ฉํ๋ฏ๋ก ํ
ํ๋ฆฟ์ "aws-nodejs" ๋ก "sample-app" ์์ฑํ๊ธฐ
$ serverless create -t "aws-nodejs" -p sample-app
# sample-app์์ ๋ช
๋ น์ด ์ฐ์ตํ๊ธฐ
$ cd sample-app
~/sample-app $ serverless package
Serverless: Packaging service...
Serverless: Excluding development dependencies...
# ์ฌ๊ธฐ๊น์ง ์งํํ๋ค๋ฉด .serverless ๋๋ ํฐ๋ฆฌ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
~/sample-app $ cd .serverless
# ์์ฑ๋ ํ์ผ์ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์์ ์ ์ ์์ต๋๋ค.
~/sample-app/.serverless $ ls
cloudformation-template-create-stack.json
cloudformation-template-update-stack.json
sample-app.zip
serverless-state.json
์์ ์์ฑ๋ ํ์ผ์ด ์ด๋ป๊ฒ ๋์ํ๋์ง๋ ํ์ผ๋ช ๋ง์ผ๋ก๋ ์ ์ถํ ์ ์์ต๋๋ค.
ํ์ฌ cloudformation์ stack์ด ์กด์ฌํ์ง ์์ ๊ฒฝ์ฐ ์คํ์ ์์ฑํ ๋ค์, ์ ๋ฐ์ดํธ๋ฅผ ํ์ฌ ์ํ๋ ์ฝ๋๊ฐ Lambda์ ๋ฐฐํฌ๋๋๋ก ํ๋ ๊ฒ์ ๋๋ค.
serverless-state.jsonํ์ผ์ ํด๋น ๋ฒ์ ์ serverless application์ ๋ํ ์ ๋ณด๊ฐ ๋ด๊ฒจ ์์ต๋๋ค.
# ๋ค์ ์ฑ์ ๋ฃจํธ๋๋ ํฐ๋ฆฌ๋ก ๋์์์ invoke๋ฅผ ํด๋ณด๊ฒ ์ต๋๋ค.
~/sample-app/.serverless $ cd ..
~/sample-app $ serverless invoke local --function hello
{
"statusCode": 200,
"body": "{\"message\":\"Go Serverless v1.0! Your function executed successfully!\",\"input\":\"\"}"
}
S3๋ Object Storage๋ก ์ฝ๊ฒ ์ค๋ช ํ์๋ฉด ํ๋์ ์ ์ฅ์์ ๋๋ค. ํ์ผ๋ค์ ์ ๋ก๋ / ๋ค์ด๋ก๋ ํ ์ ์์ผ๋ฉฐ AWS์์ ํต์ฌ์ ์ธ ์๋น์ค ์ค ํ๋์ ๋๋ค. ์ฌ๋ฌ ๋ฐฉ๋ฉด์ผ๋ก ํ์ฉํ ์ ์์ง๋ง ์ฌ๊ธฐ์๋ ์์ค์ฝ๋์ ์ ์ฅ์ ์ญํ ์ ํฉ๋๋ค.
S3์ ๋ฉ์ธ์ผ๋ก ๊ฐ์ ๋ฒํท ์์ฑํ๊ธฐ ๋ฒํผ์ ํด๋ฆญํฉ๋๋ค.
์๋์ ๊ฐ์ด ์ ๋ ฅํ๊ณ ์์ฑ๋ฒํผ์ ํด๋ฆญํฉ๋๋ค.
- ๋ฒํท ์ด๋ฆ(Bucket name): USERNAME-serverless-hands-on-1 // ์ฌ๊ธฐ์ USERNAME์ ์์ ํฉ๋๋ค. ex) khbyun-serverless-hands-on-1
- ๋ฆฌ์ (Region): ์์์ ํํ์(์์ธ)
ํ์ผ ํธ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
environment
โโโ serverless-crawler : Crawler
โโโ handler.js : Lambda์์ triggerํ๊ธฐ ์ํ handler
โโโ handler.test.js : Local์์ handler๋ฅผ triggerํ๊ธฐ ์ํ ์คํฌ๋ฆฝํธ
โโโ config.yml : serverless.yml์์ ์ฌ์ฉํ๊ธฐ ์ํ ๋ณ์
โโโ package.json
โโโ serverless.yml : Serverless Framework config file
๋จผ์ ํฐ๋ฏธ๋์ ์ด์ด serverless-crawler ๋๋ ํฐ๋ฆฌ๋ฅผ ์์ฑํ๊ณ npm ์ด๊ธฐํ๋ฅผ ์์ผ์ค๋๋ค.
ec2-user:~/ $ cd ~/environment
ec2-user:~/environment $ mkdir serverless-crawler && cd ec2-user:~/environment/serverless-crawler $ npm init -y
ํ์ํ npm module๋ค์ installํฉ๋๋ค. ์ฌ๊ธฐ์ aws-sdk๋ ๊ฐ๋ฐ์ ์ํด ์ค์นํฉ๋๋ค. Lambda๋ aws-sdk๋ฅผ ๊ธฐ๋ณธ์ ์ผ๋ก ํฌํจํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์ค์ ๋ก ๋ฐฐํฌํ ๋๋ ํฌํจ์ํค์ง ์์์ผํฉ๋๋ค. dev-dependency๋ก ๋ฃ์ด๋๋ฉด ๋ฐฐํฌํ ๋ ์ ์ธ๋ฉ๋๋ค.
- Dependencies
- cheerio : HTMLํ์ด์ง๋ฅผ ํ์ฑํ๊ณ , ๊ฒฐ๊ณผ ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ธฐ ์ํ API๋ฅผ ์ ๊ณต
- got : ๋ช MB์ ๋ถ๊ณผํ http ์์ฒญ์ ๊ฐ๋จํ๊ฒ ํ๋ API ์ ๊ณต
- dynamoose : DynamoDB๋ฅผ ์ฌ์ฉํ๊ธฐ ์ฝ๋๋ก Modelingํ๋ ๋๊ตฌ
- Dev-Dependencies
- aws-sdk : AWS ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ SDK
- serverless : Serverless Framework
$ npm i -S cheerio got dynamoose
$ npm i -D aws-sdk serverless
๊ฐ ํ์ผ์ ํธ์งํฉ๋๋ค.
AWS_REGION: ap-northeast-2
STAGE: dev
DEPLOYMENT_BUCKET: USERNAME-serverless-hands-on-1 # USERNAME ์์ ํ์!
const got = require('got');
const cheerio = require('cheerio');
const dynamoose = require('dynamoose');
require('aws-sdk').config.region = "ap-northeast-2";
const PortalKeyword = dynamoose.model('PortalKeyword', {
portal: {
type: String,
hashKey: true
},
createdAt: {
type: String,
rangeKey: true
},
keywords: {
type: Array
}
}, {
create: false, // Create a table if not exist,
});
exports.crawler = async function (event, context, callback) {
try {
let naverKeywords = [];
let daumKeywords = [];
const result = await Promise.all([
got('https://naver.com'),
got('http://daum.net'),
]);
const createdAt = new Date().toISOString();
const naverContent = result[0].body;
const daumContent = result[1].body;
const $naver = cheerio.load(naverContent);
const $daum = cheerio.load(daumContent);
// Get doms containing latest keywords
$naver('.ah_l').filter((i, el) => {
return i===0;
}).find('.ah_item').each(((i, el) => {
if(i >= 20) return;
const keyword = $naver(el).find('.ah_k').text();
naverKeywords.push({rank: i+1, keyword});
}));
$daum('.rank_cont').find('.link_issue[tabindex=-1]').each((i, el) => {
const keyword = $daum(el).text();
daumKeywords.push({rank: i+1, keyword});
});
// console.log({
// naver: naverKeywords,
// daum: daumKeywords,
// });
await new PortalKeyword({
portal: 'naver',
createdAt,
keywords: naverKeywords
}).save();
await new PortalKeyword({
portal: 'daum',
createdAt,
keywords: daumKeywords
}).save();
return callback(null, "success");
} catch (err) {
callback(err);
}
}
const crawler = require('./handler').crawler;
crawler({}, {}, (err, result) => {
if(err) return console.error(err);
console.log(result);
});
...
...
"description": "AWSKRUG Serverless Group์ ์ฒซ๋ฒ์งธ ํธ์ฆ์จ Part.2 ์นํฌ๋กค๋ฌ ๋ง๋ค๊ธฐ์
๋๋ค.๐",
"main": "index.js",
"scripts": { // ์ด ๋ถ๋ถ์ ์ถ๊ฐํฉ๋๋ค.
"test": "node handler.test.js",
"deploy": "serverless deploy"
},
"repository": {
"type": "git",
"url": "git+https://github.com/novemberde/serverless-crawler-demo.git"
},
"keywords": [],
"author": "",
...
service: ServerlessHandsOnPart2
provider:
name: aws
runtime: nodejs8.10
memorySize: 256
timeout: 30
stage: ${file(./config.yml):STAGE}
region: ${file(./config.yml):AWS_REGION}
deploymentBucket: ${file(./config.yml):DEPLOYMENT_BUCKET}
environment:
NODE_ENV: production
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:DescribeTable
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:*"
functions:
crawler:
handler: handler.crawler
events:
- schedule: rate(10 minutes)
DynamoDB๋ฅผ ์ค๊ณํ ์ ์ฃผ์ํด์ผํ ์ ์ FAQ๋ฅผ ์ฐธ๊ณ ํ์๊ธธ ๋ฐ๋๋๋ค.
์ด์ DynamoDB์ Todo table์ ์์ฑํ ๊ฒ์ ๋๋ค. ํํฐ์ ํค์ ์ ๋ ฌ ํค๋ ๋ค์๊ณผ ๊ฐ์ด ์ค์ ํฉ๋๋ค.
- ํํฐ์ ํค(Partition Key): portal
- ์ ๋ ฌํค(Sort Key): createdAt
๊ทธ๋ผ DynamoDB Console๋ก ์ด๋ํฉ๋๋ค. ํ ์ด๋ธ ๋ง๋ค๊ธฐ๋ฅผ ํด๋ฆญํ์ฌ ์๋์ ๊ฐ์ด ํ ์ด๋ธ์ ์์ฑํฉ๋๋ค.
๊ทธ๋ฐ ๋ค์์ ๋ค์ Cloud9์ผ๋ก ๋์๊ฐ์ ํ ์คํธ ์ฝ๋๋ฅผ ๋๋ ค๋ด ๋๋ค.
ec2-user:~/environment/serverless-crawler $ npm test
> serverless-crawler-demo@1.0.0 test/home/ec2-user/environment/serverless-crawler-demo
> node handler.test.js
success
DynamoDB Console์ ๋ค์ด๊ฐ์ ์ฑ๊ณต์ ์ผ๋ก ํญ๋ชฉ๋ค์ด ์์ฑ๋์๋์ง ํ์ธํฉ๋๋ค.
Node๊ฐ 8.x๋ฒ์ ์ด ์ค์น๋์ด ์์ผ๋ฉด dev-dependency์ ์ค์น๋ serverless ๋ช ๋ น์ด๋ฅผ ๋ฐ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ง์ผ node 6.x๋ฒ์ ์ด๋ผ๋ฉด Global๋ก serverless๋ฅผ ์ค์นํ์ฌ ์ค๋๋ค. ํ์ฌ๋ 8.x์ ๋ฒ์ ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋ค์ ๋ช ๋ น์ด๋ ๋์ด๊ฐ๊ฒ ์ต๋๋ค.
ec2-user:~/environment/serverless-crawler (master) $ npm i -g serverless
์ค์น๊ฐ ์๋ฃ๋์์ผ๋ฉด ๋ฐฐํฌ๋ฅผ ํฉ๋๋ค. package.json์ script์ serverless deploy๋ฅผ ๋ฃ์ด ๋์๊ธฐ ๋๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ด ๋ฐฐํฌ๋ฅผ ํฉ๋๋ค.
ec2-user:~/environment/serverless-crawler (master) $ npm run deploy
> serverless-crawler@1.0.0 deploy /home/ec2-user/environment/serverless-crawler
> serverless deploy
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (8.69 MB)...
Serverless: Validating template...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
....................
Serverless: Stack create finished...
Service Information
service: ServerlessHandsOnPart2
stage: dev
region: ap-northeast-2
stack: ServerlessHandsOnPart2-dev
api keys:
None
endpoints:
None
functions:
crawler: ServerlessHandsOnPart2-dev-crawler
์ฑ๊ณต์ ์ผ๋ก ๋ฐฐํฌ๋์์ต๋๋ค. ์ง๊ธ๋ถํฐ ์ฃผ๊ธฐ์ ์ผ๋ก DynamoDB์ ๊ฒ์์ด ๋ญํน์ด ์์ ๋๋ค.
์๋ฒ๋ฆฌ์ค ์ฑ์ ๋ด๋ฆฌ๋ ๊ฒ์ด ์ด๋ ต์ง ์์ต๋๋ค. ๊ฐ๋จํ Command ํ๋๋ฉด ๋ชจ๋ ์คํ์ด ๋ด๋ ค๊ฐ๋๋ค. Cloud9์์ ์๋ก์ด ํฐ๋ฏธ๋์ ์ด๊ณ ๋ค์๊ณผ ๊ฐ์ด ์ ๋ ฅํฉ๋๋ค.
$ cd ~/environment/serverless-crawler
$ serverless remove
Serverless: Getting all objects in S3 bucket...
Serverless: Removing objects in S3 bucket...
Serverless: Removing Stack...
Serverless: Checking Stack removal progress...
............
Serverless: Stack removal finished...
DynamoDB Console๋ก ๋ค์ด๊ฐ์ Table์ ์ญ์ ํฉ๋๋ค. ๋ฆฌ์ ์ ์์ธ์ ๋๋ค.
Cloud9 Console๋ก ๋ค์ด๊ฐ์ IDE๋ฅผ ์ญ์ ํฉ๋๋ค. ๋ฆฌ์ ์ ์ฑ๊ฐํฌ๋ฅด์ ๋๋ค.
S3 Console๋ก ๋ค์ด๊ฐ์ ์์ฑ๋ ๋ฒํท์ ์ญ์ ํฉ๋๋ค.