{"id":385,"date":"2017-07-14T14:29:03","date_gmt":"2017-07-14T05:29:03","guid":{"rendered":"https:\/\/p-corporate-blog-cms.mmmcorp.co.jp\/blog\/2017\/07\/14\/serverless-dev-flow"},"modified":"2017-07-14T14:29:03","modified_gmt":"2017-07-14T05:29:03","slug":"serverless-dev-flow","status":"publish","type":"post","link":"https:\/\/p-corporate-blog-cms.mmmcorp.co.jp\/blog\/2017\/07\/14\/serverless-dev-flow\/","title":{"rendered":"Serverless Framework+Node.js\u3092\u3064\u304b\u3063\u305fLambda\u95a2\u6570\u306e\u958b\u767a\u30d5\u30ed\u30fc"},"content":{"rendered":"
<\/head><\/p>\n\u4eca\u56de\u306f\u3001Serverless Framework+Node.js\u3092\u3064\u304b\u3063\u305fLambda\u95a2\u6570\u306e\u5177\u4f53\u7684\u306a\u958b\u767a\u30d5\u30ed\u30fc\u3092\u66f8\u3044\u3066\u307f\u308b\u3002\u52d5\u4f5c\u78ba\u8a8d\u3084\u30c6\u30b9\u30c8\u3001CI\u9023\u643a\u307e\u3067\u4e00\u8cab\u3057\u3066\u884c\u306a\u3063\u305f\u306e\u3067\u3001\u53c2\u8003\u306b\u306a\u308c\u3070\u3068\u601d\u3046\u3002<\/p>\n
Web\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5074\u3067\u3042\u308b\u5909\u66f4\u304c\u306f\u3044\u3063\u305f\u969b\u306b\u3001\u8907\u6570\u306eRDB\u3068Elasticsearch\u306b\u307e\u305f\u304c\u308b\u30c7\u30fc\u30bf\u3092\u5408\u308f\u305b\u3066\u66f4\u65b0\u3059\u308b\u3001\u3068\u3044\u3046\u3001\u4e2d\u9593\u7684\u306a\u5f79\u5272\u3092\u5b9f\u88c5\u3057\u305f\u3002S3\u306b\u66f4\u65b0\u306e\u30c7\u30fc\u30bf\u304c5\u5206\u6bce\u306bPUT\u3055\u308c\u308b\u306e\u3067\u3001\u305d\u3053\u304b\u3089\u30a4\u30d9\u30f3\u30c8\u3092\u53d6\u308b\u3002<\/p>\n
\u4e00\u9023\u306e\u958b\u767a\u30d5\u30ed\u30fc\u3068\u3057\u3066\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u6d41\u308c\u306b\u306a\u308b\u3002<\/p>\n
development<\/code>\u74b0\u5883\u3067\u306e\u7d50\u5408\u30c6\u30b9\u30c8<\/li>\n- PR\u4f5c\u6210(CI\u3067\u30c6\u30b9\u30c8\u306e\u5b9f\u884c)<\/li>\n
- \u30ec\u30d3\u30e5\u30fc<\/li>\n
- \u30de\u30fc\u30b8(CI\u3067\u30c6\u30b9\u30c8\u306e\u5b9f\u884c)<\/li>\n
staging<\/code>(production<\/code>)\u74b0\u5883\u3078\u30c7\u30d7\u30ed\u30a4<\/li>\nstaging<\/code>(production<\/code>)\u74b0\u5883\u3067\u306e\u7d50\u5408\u30c6\u30b9\u30c8<\/li>\n<\/ol>\nUI\u304c\u306a\u3044\u3068\u3044\u3046\u306e\u3082\u3042\u308a\u3001\u578b\u3068\u30c6\u30b9\u30c8\u3092\u4e3b\u8ef8\u306b\u958b\u767a\u3092\u3059\u3059\u3081\u308b\u30b9\u30bf\u30a4\u30eb\u3068\u306a\u3063\u305f\u3002\u578b\u30fb\u30c6\u30b9\u30c8\u3067\u52d5\u4f5c\u62c5\u4fdd\u3057\u3064\u3064\u3001\u30ed\u30fc\u30ab\u30eb\u3067\u52d5\u4f5c\u78ba\u8a8d\u3001\u30c7\u30d7\u30ed\u30a4\u3057\u3066\u7d50\u5408\u52d5\u4f5c\u78ba\u8a8d\u3001\u672c\u756a\u3078\u3001\u3068\u3044\u3046\u30a4\u30e1\u30fc\u30b8\u3002\u4ee5\u4e0b\u3001\u4e00\u3064\u4e00\u3064\u8aac\u660e\u3057\u3066\u3044\u304f\u3002<\/p>\n
\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3<\/h2>\n
Serverless Framework+Node.js\u3067\u666e\u901a\u306b\u8a2d\u8a08\u3059\u308b<\/a>\u3068\u3044\u3046\u8a18\u4e8b\u306b\u3082\u66f8\u3044\u305f\u304c\u3001\u69cb\u6210\u3068\u3057\u3066\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u611f\u3058\u3067\u3042\u308b\u3002<\/p>\n\n- \u30c7\u30d7\u30ed\u30a4\/\u30d1\u30c3\u30b1\u30fc\u30b8\u30f3\u30b0\n
\n- Serverless Framework<\/li>\n<\/ul>\n<\/li>\n
- \u30d3\u30eb\u30c9\n
\n- webpack+Babel<\/li>\n<\/ul>\n<\/li>\n
- \u958b\u767a\u52b9\u7387\u7cfb\n
\n- AVA<\/li>\n
- Flow<\/li>\n
- eslint<\/li>\n
- yarn<\/li>\n<\/ul>\n<\/li>\n
- \u305d\u306e\u4ed6\n
\n- axios\/bluebird\/lodash\/moment\u306a\u3069<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n
\u30e2\u30b8\u30e5\u30fc\u30eb\u7b49\u306fLambda\u306e\u30b5\u30a4\u30ba\u3092\u524a\u6e1b\u3059\u308b\u305f\u3081\u3001\u4f8b\u3048\u3070\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u8aad\u307f\u8fbc\u307f\u65b9\u3092\u3057\u3066\u3044\u308b\u3002<\/p>\n
\/\/ ????\u4f7f\u3044\u305f\u3044\u30e2\u30b8\u30e5\u30fc\u30eb\u306e\u307f\u3092\u8aad\u307f\u8fbc\u3080\nimport {isArray} from 'lodash';\nisArray([1, 2, 3]);\n\n\/\/ ????\u30e2\u30b8\u30e5\u30fc\u30eb\u5168\u90e8\u3092\u8aad\u307f\u8fbc\u3080\nimport lodash from 'lodash';\nlodash.isArray([1, 2, 3]);<\/code><\/pre>\nLambda\u95a2\u4fc2\u306a\u3057\u306b\u3053\u3046\u3059\u308b\u3079\u304d\u3060\u304c\u3001\u4eca\u56de\u306f\u7279\u306b\u5fc3\u304c\u3051\u305f\u3002\u305d\u308c\u3067\u3082AWS\u30b3\u30f3\u30bd\u30fc\u30eb\u4e0a\u3067\u66f8\u304fLambda\u95a2\u6570\u3088\u308a\u306f\u3060\u3044\u3076\u5927\u304d\u304f\u306a\u3063\u3066\u3057\u307e\u3046\u304c\u2026\u305d\u3053\u306f\u591a\u5c11\u8907\u96d1\u306b\u306a\u308b\u3068\u3084\u3080\u3092\u5f97\u306a\u3044\u306e\u304b\u306a\u3068\u601d\u3046\u3002\u3082\u3057\u304f\u306f\u3001webpack\u4ee5\u5916\u306ebundler\u3092\u4f7f\u3063\u3066\u5bb9\u91cf\u3092\u524a\u6e1b\u3059\u308b\u306e\u306f\u6b63\u3057\u3044\u6c17\u304c\u3059\u308b\u3002<\/p>\n
UI\u3092\u8003\u616e\u3059\u308b\u5fc5\u8981\u304c\u306a\u3044\u5206\u304b\u306a\u308a\u30b7\u30f3\u30d7\u30eb\u306a\u8a2d\u8a08\u306b\u843d\u3068\u3057\u8fbc\u3081\u305f\u3068\u3002\u7279\u306b\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u7b49\u3082\u4f7f\u3046\u5fc5\u8981\u306f\u306a\u304b\u3063\u305f\u304c\u3001\u30e2\u30b8\u30e5\u30fc\u30eb\u5358\u4f4d\u3067\u958b\u767a\u304c\u3067\u304d\u305f\u306e\u306f\u54c1\u8cea\u306b\u8ca2\u732e\u3057\u305f\u304b\u306a\u3068\u601d\u3046\u3002\u666e\u6bb5\u4f7f\u3063\u3066\u3044\u308b\u30b9\u30bf\u30c3\u30af\u3068\u5909\u308f\u3089\u306a\u3044\u69cb\u6210\u3067\u958b\u767a\u304c\u3067\u304d\u305f\u304c\u3001\u7279\u306b\u3001\u958b\u767a\u52b9\u7387\u7cfb\u304c\u305d\u306e\u307e\u307e\u4f7f\u3048\u305f\u306e\u306f\u5b09\u3057\u304b\u3063\u305f\u3002<\/p>\n
\u30ed\u30b8\u30c3\u30af\u5b9f\u88c5\/\u30c6\u30b9\u30c8<\/h2>\nAWS SDK\u306e\u30c6\u30b9\u30c8<\/h3>\n
Writing Testable AWS Lambda Functions<\/a>\u3084Testable Lambda: Working Effectively with Legacy Lambda<\/a>\u3067\u3082\u8ff0\u3079\u3089\u308c\u3066\u3044\u308b\u304c\u3001Seam(\u63a5\u5408\u90e8)\u306b\u7740\u76ee\u3057\u3001\u30ed\u30b8\u30c3\u30af\u3092\u5207\u308a\u5206\u3051\u308c\u3070\u30c6\u30b9\u30c8\u3092\u66f8\u304f\u306e\u306f\u96e3\u3057\u304f\u306a\u3044\u3002\u6700\u521d\u306e\u8a18\u4e8b\u3067\u306fLocalStack\u3092\u4f7f\u7528\u3057\u3066\u3044\u308b\u304c\u3001\u4eca\u56de\u306f\u305d\u3053\u307e\u3067\u306e\u3053\u3068\u306f\u305b\u305a\u3001\u95a2\u6570\u306e\u8cac\u52d9\u3092\u5207\u308a\u5206\u3051\u3001\u30c6\u30b9\u30bf\u30d6\u30eb\u306b\u306a\u308b\u3088\u3046\u5b9f\u88c5\u3057\u305f\u3002\u4f8b\u3048\u3070\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u611f\u3058\u3067\u3042\u308b\u3002<\/p>\nexport const putToS3 = (params: TParams, s3: TS3Instance = S3Instance) => {\n const putObject = promisify(s3.putObject, {context: s3});\n return putObject(params)\n .then((data) => data)\n .catch((error) => error);\n};\n\n\/\/ \u5b9f\u969b\u306b\u4f7f\u3046\u6642\nimport S3 from 'aws-sdk\/clients\/s3';\nputToS3(new S3());\n\n\/\/ \u30c6\u30b9\u30c8\nimport S3 from 'aws-sdk\/clients\/s3';\nconst s3Mock = {\n putObject: (param, callback) => {\n callback('', DATA_SUCCESS); \/\/ \u30ec\u30b9\u30dd\u30f3\u30b9\u3082\u30e2\u30c3\u30af\u3092\u8fd4\u3059\n },\n};\nputToS3(s3Mock);<\/code><\/pre>\n\u3053\u308c\u3060\u3051\u3060\u3068\u610f\u5473\u304c\u306a\u3044\u30c6\u30b9\u30c8\u306e\u3088\u3046\u306b\u3082\u898b\u3048\u308b\u304c\u3001\u5b9f\u969b\u306b\u306f\u8907\u6570\u306e\u95a2\u6570\u304c\u7d50\u5408\u3055\u308c\u308b\u306e\u3067\u3001\u3053\u306e\u624b\u6cd5\u3092\u5fdc\u7528\u3057\u3066\u30c6\u30b9\u30c8\u3092\u66f8\u3044\u3066\u304a\u304f\u3068\u3001\u30ea\u30d5\u30a1\u30af\u30bf\u3084\u6a5f\u80fd\u8ffd\u52a0\u6642\u306b\u304b\u306a\u308a\u5b89\u5fc3\u3067\u304d\u308b\u3002RDB\u306e\u30c6\u30b9\u30c8\u3082\u3001\u30b3\u30ec\u3068\u540c\u3058\u8981\u9818\u3067DB\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u30e2\u30c3\u30af\u3057\u3066\u3084\u3063\u305f\u308a\u3001mockery<\/a>\u3092\u4f7f\u3046\u306a\u3069\u3057\u3066\u307e\u308b\u3054\u3068\u66f8\u304d\u63db\u3048\u305f\u308a\u3092\u3057\u305f\u3002\u3053\u308c\u306b\u3088\u308a\u3001\u3042\u3068\u3042\u3068\u306b\u306a\u3063\u3066\u958b\u767a\u52b9\u7387\u304c\u4e0a\u304c\u3063\u3066\u3086\u304f\u611f\u3058\u306b\u306a\u308a\u3068\u3066\u3082\u3088\u304b\u3063\u305f\u3002<\/p>\n\u95a2\u6570\u306e\u5206\u96e2<\/h3>\n
\u2191\u306e\u8a71\u3068\u3082\u304b\u3076\u3063\u3066\u3057\u307e\u3046\u306e\u3060\u304c\u3001\u95a2\u6570\u306e\u8cac\u52d9\u3092\u308f\u3051\u3066\u3001\u306a\u308b\u3079\u304f\u526f\u4f5c\u7528\u306e\u306a\u3044\u7d14\u7c8b\u95a2\u6570<\/a>\u306b\u306a\u308b\u3088\u3046\u306b\u6c17\u3092\u3064\u3051\u305f\u3002\u3053\u308c\u306b\u3088\u3063\u3066Lambda\u95a2\u6570\u304c\u30c6\u30b9\u30bf\u30d6\u30eb\u306b\u306a\u308b\u3068\u3044\u3046\u306e\u306f\u3082\u3061\u308d\u3093\u3060\u304c\u3001\u8cac\u52d9\u304c\u5c0f\u3055\u3044\u305f\u3081\u306b\u3001\u5b9f\u88c5\u306e\u30b9\u30d4\u30fc\u30c9\u306b\u3082\u5f71\u97ff\u3059\u308b\u3068\u611f\u3058\u305f\u3002<\/p>\nNode Function\u3092Promise\u5316<\/h3>\n
\u4ed6\u306b\u6c17\u3092\u3064\u3051\u305f\u70b9\u3068\u3057\u3066\u3001\u4f8b\u5916\u304c\u8d77\u304d\u305f\u6642\u306e\u30d3\u30b8\u30cd\u30b9\u7684\u306a\u640d\u5931\u304c\u5927\u304d\u306a\u6a5f\u80fd\u3060\u3063\u305f\u305f\u3081\u3001Node Function\u306a\u3069\u306f\u3059\u3079\u3066Promise\u5316\u3057\u3066\u3001\u3069\u3053\u3067\u30a8\u30e9\u30fc\u304c\u8d77\u304d\u3066\u3082catch<\/code>\u3067\u304d\u308b\u3088\u3046\u306b\u3057\u305f\u3068\u3044\u3046\u306e\u304c\u3042\u308b\u3002\u4f8b\u3048\u3070\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u611f\u3058\u3067\u3042\u308b\u3002<\/p>\nimport xml2js from 'xml2js';\nconst parser = new xml2js.Parser();\nconst parseString = promisify(parser.parseString, {context: parser});\nreturn parseString(xmlData)\n .then((results) => results)\n .catch((error) => error);<\/code><\/pre>\n\u3053\u306e\u3088\u3046\u306b\u30b7\u30f3\u30d7\u30eb\u306a\u51e6\u7406\u306a\u3089\u3082\u3061\u308d\u3093Node Function\u3067\u3082\u3088\u3044\u306e\u3060\u304c\u3001\u3084\u306f\u308aPromise\u306b\u3057\u305f\u65b9\u304c\u898b\u901a\u3057\u304c\u826f\u304f\u306a\u308a\u5024\u304c\u6271\u3044\u3084\u3059\u3044\u306e\u3068\u3001\u4e07\u304c\u4e00\u3001\u6210\u529f\u6642\u306e\u51e6\u7406\u306e\u306a\u304b\u3067\u30a8\u30e9\u30fc\u304c\u8d77\u304d\u3066\u3082catch<\/code>\u3055\u308c\u308b\u306e\u3067\u5b89\u5fc3\u3067\u304d\u305f\u3002<\/p>\n\u30a8\u30e9\u30fc\u30ed\u30b0<\/h3>\n
\u524d\u8ff0\u3057\u305f\u304c\u3001\u4f8b\u5916\u304c\u8d77\u304d\u305f\u6642\u306e\u640d\u5931\u306b\u8010\u3048\u3046\u308b\u3088\u3046\u306b\u3001\u57fa\u672c\u7684\u306b\u78ba\u8a8d\u3057\u3046\u308b\u3059\u3079\u3066\u306e\u7b87\u6240\u3067\u30a8\u30e9\u30fc\u30ed\u30b0\u3092\u3068\u3063\u305f(CloudWatch\u306b\u30ed\u30b0\u3055\u308c\u308b)\u3002\u307e\u305f\u3001Slack\u3084\u30e1\u30fc\u30eb\u901a\u77e5\u3001Lambda\u81ea\u4f53\u306e\u76e3\u8996(\u3053\u3061\u3089\u306f\u30b3\u30fc\u30c9\u306e\u7ba1\u8f44\u5916\u3060\u304c)\u3082\u884c\u306a\u3063\u305f\u3002<\/p>\n
\u30ed\u30fc\u30ab\u30eb\u3067\u306e\u7d50\u5408\u30c6\u30b9\u30c8<\/h2>\n
Serverless Framework\u3092\u4f7f\u3046\u3068Lambda\u95a2\u6570\u3092\u30ed\u30fc\u30ab\u30eb\u3067\u3082\u5b9f\u884c\u3067\u304d\u308b\u3002\u3053\u308c\u306fWeb\u958b\u767a\u3067\u3044\u3046\u3068\u3001\u30d6\u30e9\u30a6\u30b6\u3067\u306e\u52d5\u4f5c\u78ba\u8a8d\u306e\u3088\u3046\u306a\u3082\u306e\u3067\u3001\u57fa\u672c\u7684\u306b\u958b\u767a\u30d5\u30ed\u30fc\u3068\u3057\u3066\u306f\u3001\u30c6\u30b9\u30c8\u304c\u901a\u3063\u305f\u5f8c\u306b\u7d50\u5408\u30c6\u30b9\u30c8\u7684\u306a\u610f\u5473\u5408\u3044\u3067\u78ba\u8a8d\u3057\u305f\u3002\u4f8b\u3048\u3070\u3001handler.js<\/code>\u306bLambda\u3078\u9732\u51fa\u3055\u305b\u308b\u95a2\u6570\u3092\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u66f8\u3044\u3066\u3044\u305f\u3068\u3059\u308b\u3002<\/p>\nexport const runDeleteFromDB = async () => {\n const ids = ['50681112', '50733612'];\n const result = await deleteFromDB(ids);\n console.log(result);\n};<\/code><\/pre>\n\u3053\u308c\u306f\u4e0b\u8a18\u306e\u3088\u3046\u306a\u30b3\u30de\u30f3\u30c9\u3067\u5b9f\u884c\u3067\u304d\u308b(\u5b9f\u969b\u306fyarn\u30b3\u30de\u30f3\u30c9\u306b\u307e\u3068\u3081\u3066\u3042\u308b)\u3002<\/p>\n
$(npm bin)\/serverless webpack invoke --function runDeleteFromDB<\/code><\/pre>\nDB\u306e\u74b0\u5883\u306fDocker\u3067\u7528\u610f\u3057\u3066\u3082\u3089\u3063\u3066\u3044\u305f\u304c\u3001\u95a2\u6570\u3092\u5b9f\u884c\u3059\u308b\u3053\u3068\u3067\u304d\u3061\u3093\u3068\u30ed\u30fc\u30ab\u30eb\u306eDB\u306b\u5bfe\u3057\u3066\u66f4\u65b0\u306e\u51e6\u7406\u3092\u304b\u3051\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3002\u307e\u305f\u3001\u30a4\u30d9\u30f3\u30c8\u306a\u3069\u3082\u4efb\u610f\u3067\u6307\u5b9a\u3067\u304d\u308b\u3002<\/p>\n
development<\/code>\u74b0\u5883\u3067\u306e\u7d50\u5408\u30c6\u30b9\u30c8<\/h2>\n\u4e00\u901a\u308a\u30c6\u30b9\u30c8\u3068\u52d5\u4f5c\u78ba\u8a8d\u304c\u3067\u304d\u305f\u3089\u3001\u30c7\u30d7\u30ed\u30a4\u3057\u3066\u7d50\u5408\u30c6\u30b9\u30c8\u3092\u884c\u3046\u3002\u3053\u308c\u306f\u3001\u3042\u3089\u304b\u3058\u3081development<\/code>\u74b0\u5883\u3092\u7528\u610f\u3057\u3066\u304a\u304d\u3001\u672c\u756a\u306b\u3044\u304f\u524d\u306b\u78ba\u8a8d\u3059\u308b\u3002<\/p>\nAWS\u306e\u8a2d\u5b9a<\/h3>\n
Serverless Framework\u3067\u306f\u30c7\u30d7\u30ed\u30a4\u3059\u308b\u95a2\u6570\u306b\u5bfe\u3057\u3066\u6307\u5b9a\u3059\u308bIAM\u30ed\u30fc\u30eb\u3092\u81ea\u52d5\u751f\u6210\u3057\u3066\u304f\u308c\u308b\u3002\u4f8b\u3048\u3070\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u6307\u5b9a\u3059\u308b\u3068\u3001BUCKET_NAME<\/code>\u306b\u5bfe\u3057\u3066S3\u306eGET\u30a2\u30af\u30b7\u30e7\u30f3\u304c\u304b\u3051\u3089\u308c\u308b\u3088\u3046\u306b\u306a\u308b\u3002<\/p>\nprovider:\n iamRoleStatements:\n - Effect: Allow\n Action:\n - s3:GetObject\n Resource: \"arn:aws:s3:::BUCKET_NAME\/*\"<\/code><\/pre>\nBUCKET_NAME<\/code>\u306a\u3069\u306e\u5024\u3092\u74b0\u5883\u6bce\u306b\u5207\u308a\u66ff\u3048\u308b\u306b\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u8a18\u8ff0\u3067\u304d\u308b\u3002\u3053\u308c\u3067\u3001Serverless CLI\u306estage<\/code>\u30aa\u30d7\u30b7\u30e7\u30f3\u306b\u3088\u3063\u3066\u30d0\u30b1\u30c3\u30c8\u540d\u304c\u5207\u308a\u66ff\u3048\u3089\u308c\u305f\u308a\u3059\u308b\u3002\u74b0\u5883\u6bce\u306b\u5024\u3092\u5207\u308a\u66ff\u3048\u305f\u3051\u308c\u3070\u57fa\u672c\u7684\u306bcustom<\/code>\u306b\u74b0\u5883\u3054\u3068\u306e\u5024\u3092\u4f5c\u3063\u3066\u304a\u3051\u3070\u5207\u308a\u5206\u3051\u304c\u3067\u304d\u308b\u3002<\/p>\nprovider:\n iamRoleStatements:\n - Effect: Allow\n Action:\n - s3:GetObject\n Resource: \"arn:aws:s3:::${self:custom.bucketNameForUpload.${opt:stage}}\/*\"\n\ncustom:\n bucketNameForUpload:\n development: ${env:S3_BUCKET_NAME_FOR_UPLOAD_LOCAL} # ${env:}\u3067\u74b0\u5883\u5909\u6570\u3092\u53d6\u5f97\u3067\u304d\u308b\n staging: ${env:S3_BUCKET_NAME_FOR_UPLOAD_STAGING}\n production: ${env:S3_BUCKET_NAME_FOR_UPLOAD_PRODUCTION}<\/code><\/pre>\nVPC\u3082\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u8a2d\u5b9a\u3067\u304d\u308b\u3002<\/p>\n
provider:\n vpc: ${self:custom.vpc.${opt:stage}}\n\ncustom:\n vpc:\n development:\n securityGroupIds:\n subnetIds:\n staging:\n securityGroupIds:\n - sg-xxx\n subnetIds:\n - subnet-xxx\n - subnet-xxx\n production:\n securityGroupIds:\n - sg-yyy\n subnetIds:\n - subnet-yyy\n - subnet-yyy<\/code><\/pre>\n\u3053\u306e\u3088\u3046\u306b\u3001\u5b9f\u88c5\u306b\u3088\u3063\u3066AWS\u306e\u8a2d\u5b9a\u3092\u5909\u66f4\u3059\u308b\u5834\u5408\u304c\u3042\u308c\u3070\u305d\u306e\u5bfe\u5fdc\u3092\u3059\u308b\u3002<\/p>\n
\u30c7\u30d7\u30ed\u30a4\u30fb\u5b9f\u884c<\/h3>\n
\u6e96\u5099\u304c\u3067\u304d\u305f\u3089development<\/code>\u74b0\u5883\u3078\u30c7\u30d7\u30ed\u30a4\u3057\u3001\u52d5\u4f5c\u78ba\u8a8d\u3059\u308b\u3002<\/p>\n# \u30c7\u30d7\u30ed\u30a4\n$(npm bin)\/serverless deploy --stage development\n\n# \u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3055\u308c\u3066\u3044\u308bLambda\u95a2\u6570\u3092\u30bf\u30fc\u30df\u30ca\u30eb\u304b\u3089\u5b9f\u884c\n$(npm bin)\/serverless invoke --log --stage development --function runDeleteFromDB<\/code><\/pre>\nPR\u4f5c\u6210(CI\u3067\u30c6\u30b9\u30c8\u306e\u5b9f\u884c)<\/h2>\n
\u3053\u3053\u307e\u3067\u3067\u304d\u305f\u3089\u30d7\u30c3\u30b7\u30e5\u3057\u3066\u3001PR\u3092\u4f5c\u6210\u3059\u308b\u3002CI\u3067\u30c6\u30b9\u30c8\u306e\u5b9f\u884c\u306f\u3001yarn test<\/code>\u3067lint\u3068\u30e6\u30cb\u30c3\u30c8\u30c6\u30b9\u30c8\u304c\u6d41\u308c\u308b\u3002<\/p>\n\u30ec\u30d3\u30e5\u30fc\u3001\u30de\u30fc\u30b8(CI\u3067\u30c6\u30b9\u30c8\u306e\u5b9f\u884c)<\/h2>\n
\u30ec\u30d3\u30e5\u30fc\u3067\u6307\u6458\u4e8b\u9805\u304c\u3042\u308c\u3070\u4fee\u6b63\u3057\u3001\u30de\u30fc\u30b8\u3059\u308b\u3002\u30de\u30fc\u30b8\u5f8c\u3001\u518d\u5ea6CI\u3067\u30c6\u30b9\u30c8\u304c\u5b9f\u884c\u3055\u308c\u308b\u3002<\/p>\n
staging<\/code>(production<\/code>)\u74b0\u5883\u3078\u30c7\u30d7\u30ed\u30a4<\/h2>\n\u30de\u30fc\u30b8\u5148\u304cmaster\u30d6\u30e9\u30f3\u30c1\u306a\u3089\u30b9\u30c6\u30fc\u30b8\u30f3\u30b0\u3078\u3001release\u306a\u3089\u672c\u756a\u74b0\u5883\u3078\u30c7\u30d7\u30ed\u30a4\u3055\u308c\u308b\u3002<\/p>\n
staging<\/code>(production<\/code>)\u74b0\u5883\u3067\u306e\u7d50\u5408\u30c6\u30b9\u30c8<\/h2>\nWeb\u3067\u3082\u306a\u3093\u3067\u3082\u305d\u3046\u304b\u3082\u3057\u308c\u306a\u3044\u304c\u3001\u672c\u756a\u3078\u30c7\u30d7\u30ed\u30a4\u3055\u308c\u305f\u3089\u7d50\u5408\u30c6\u30b9\u30c8\u3092\u884c\u3044\u3001\u52d5\u4f5c\u78ba\u8a8d\u7d42\u4e86\u3001\u3053\u308c\u306b\u3066\u4e00\u9023\u306e\u30d5\u30ed\u30fc\u304c\u5b8c\u4e86\u3067\u3042\u308b\u3002<\/p>\n
\u305d\u306e\u4ed6<\/h2>\n\n- MySQL\u306e\u30b3\u30cd\u30af\u30b7\u30e7\u30f3\u306f\u5b9f\u884c\u7d42\u4e86\u5f8c\u306b\u6bce\u56de\u5207\u3063\u3066\u304a\u304b\u306a\u3044\u3068\u3001\u4f8b\u3048\u3070VPC\u306e\u8a2d\u5b9a\u3092\u63a5\u7d9a\u3067\u304d\u306a\u3044\u3088\u3046\u306b\u5909\u3048\u3066\u3082\u3001\u540c\u3058\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3067\u63a5\u7d9a\u3057\u7d9a\u3051\u3066\u3057\u307e\u3046\u306e\u3067\u3001Lambda\u3067\u3042\u308b\u306b\u3082\u304b\u304b\u308f\u3089\u305a\u30b9\u30c6\u30fc\u30c8\u30ec\u30b9\u3067\u306a\u304f\u306a\u3063\u3066\u3057\u307e\u3046\u3002\u307e\u305f\u3001JS\u5074\u306e\u5074\u3067\u306e\u63a5\u7d9a\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u4f5c\u6210\u51e6\u7406\u306f\u3001\u5909\u6570\u306a\u3069\u306b\u3044\u308c\u305a\u306b\u6bce\u56de\u30ea\u30d5\u30ec\u30c3\u30b7\u30e5\u3057\u306a\u3044\u3068\u3001\u3053\u308c\u3082\u540c\u3058\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u4f7f\u3044\u7d9a\u3051\u3066\u3057\u307e\u3046\u3002<\/li>\n
- \u7a00\u306b\u3001Lambda\u306e\u95a2\u6570\u5b9f\u884c\u4e2d\u306e\u30bf\u30a4\u30df\u30f3\u30b0\u3068\u5408\u308f\u305b\u3066\u30c7\u30d7\u30ed\u30a4\u3059\u308b\u3068(?)\u3001
Unable to import module 'handler': Error<\/code>\u307f\u305f\u3044\u306a\u30a8\u30e9\u30fc\u304c\u8d77\u3053\u308b\u3053\u3068\u304c\u3042\u3063\u3066\u3001\u8a73\u7d30\u307e\u3067\u539f\u56e0\u3092\u5207\u308a\u5206\u3051\u3089\u308c\u3066\u3044\u306a\u3044\u2026\u3002\u305d\u306e\u305f\u3081\u3001\u30c7\u30d7\u30ed\u30a4\u306e\u30bf\u30a4\u30df\u30f3\u30b0\u306f\u5b9f\u969b\u306b\u306fCI\u81ea\u52d5\u30c7\u30d7\u30ed\u30a4\u3067\u306f\u306a\u304f\u3001\u624b\u52d5\u3067\u3084\u308b\u3053\u3068\u3082\u591a\u304b\u3063\u305f\u3002\u3082\u3057\u308f\u304b\u308b\u65b9\u3044\u308c\u3070\u6559\u3048\u3066\u304f\u3060\u3055\u3044\u3002<\/li>\n- \u30cf\u30de\u3063\u305f\u6642\u306bAWS\u5074\u306e\u57fa\u790e\u77e5\u8b58\u304c\u305d\u3053\u305d\u3053\u5fc5\u8981\u3002\u50d5\u306e\u3088\u3046\u306b\u666e\u6bb5\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3092\u3084\u3063\u3066\u308b\u4eba\u306f\u6700\u521d\u306f\u8f9b\u3044\u6642\u304c\u3042\u308b\u304b\u3082<\/li>\n
- \u65e2\u5b58\u306eS3\u30d0\u30b1\u30c3\u30c8\u306b\u30c8\u30ea\u30ac\u30fc\u3092\u30a2\u30bf\u30c3\u30c1\u3059\u308b\u3068\u304d\u306f\u3053\u3061\u3089<\/a><\/li>\n<\/ul>\n
\u307e\u3068\u3081<\/h2>\n
Web\u306e\u958b\u767a\u30d5\u30ed\u30fc\u3092\u304b\u306a\u308a\u8e0f\u8972\u3067\u304d\u308b\u3068\u306f\u3044\u3048\u3001Lambda\u7279\u6709\u306e\u304f\u305b\u3082\u3042\u3063\u305f\u306e\u3067\u3001\u4eca\u56de\u3084\u3063\u3066\u307f\u3066\u3001Lambda\u306e\u958b\u767a\u30d5\u30ed\u30fc\u3092\u901a\u3057\u3067\u3067\u304d\u305f\u306e\u306f\u826f\u304b\u3063\u305f\u3002\u3057\u3063\u304b\u308a\u8a2d\u8a08\u3092\u884c\u3063\u3066\u958b\u767a\u304c\u3067\u304d\u305f\u3053\u3068\u306f\u3001\u54c1\u8cea(\u306b\u5bfe\u3059\u308b\u8981\u6c42\u3092\u697d\u306b\u5b9f\u88c5\u3059\u308b\u305f\u3081\u306b\u2026)\u306b\u8ca2\u732e\u3057\u305f\u3068\u601d\u3046\u3002\u307e\u3060Lambda\u306e\u958b\u767a\u30d5\u30ed\u30fc\u306f\u78ba\u7acb\u3055\u308c\u3066\u3044\u306a\u3044\u3068\u3053\u308d\u304c\u3042\u308b\u306e\u3067\u3001\u3088\u308a\u3088\u3044\u30b9\u30bf\u30a4\u30eb\u3092\u76ee\u6307\u3057\u3066\u3084\u3063\u3066\u3044\u304d\u305f\u3044\u3002<\/p>\n
<\/body><\/html><\/p>\n","protected":false},"excerpt":{"rendered":"
\u4eca\u56de\u306f\u3001Serverless Framework+Node.js\u3092\u3064\u304b\u3063\u305fLambda\u95a2\u6570\u306e\u5177\u4f53\u7684\u306a\u958b\u767a\u30d5\u30ed\u30fc\u3092\u66f8\u3044\u3066\u307f\u308b\u3002\u52d5\u4f5c\u78ba\u8a8d\u3084\u30c6\u30b9\u30c8\u3001CI\u9023\u643a\u307e\u3067\u4e00\u8cab\u3057\u3066\u884c\u306a\u3063\u305f\u306e\u3067\u3001\u53c2\u8003\u306b\u306a\u308c\u3070\u3068\u601d\u3046\u3002 \u3064\u304f\u3063\u305f\u3082\u306e Web\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5074\u3067\u3042\u308b\u5909\u66f4\u304c\u306f\u3044\u3063\u305f\u969b\u306b\u3001\u8907\u6570\u306eRDB\u3068Elasticsearch\u306b\u307e\u305f\u304c\u308b\u30c7\u30fc\u30bf\u3092\u5408\u308f\u305b\u3066\u66f4\u65b0\u3059\u308b\u3001\u3068\u3044\u3046\u3001\u4e2d\u9593\u7684\u306a\u5f79\u5272\u3092\u5b9f\u88c5\u3057\u305f\u3002S3\u306b\u66f4\u65b0\u306e\u30c7\u30fc\u30bf\u304c5\u5206\u6bce\u306bP […]<\/p>\n","protected":false},"author":1,"featured_media":826,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[13,21,7],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/p-corporate-blog-cms.mmmcorp.co.jp\/wp-json\/wp\/v2\/posts\/385"}],"collection":[{"href":"https:\/\/p-corporate-blog-cms.mmmcorp.co.jp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/p-corporate-blog-cms.mmmcorp.co.jp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/p-corporate-blog-cms.mmmcorp.co.jp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/p-corporate-blog-cms.mmmcorp.co.jp\/wp-json\/wp\/v2\/comments?post=385"}],"version-history":[{"count":0,"href":"https:\/\/p-corporate-blog-cms.mmmcorp.co.jp\/wp-json\/wp\/v2\/posts\/385\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/p-corporate-blog-cms.mmmcorp.co.jp\/wp-json\/wp\/v2\/media\/826"}],"wp:attachment":[{"href":"https:\/\/p-corporate-blog-cms.mmmcorp.co.jp\/wp-json\/wp\/v2\/media?parent=385"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/p-corporate-blog-cms.mmmcorp.co.jp\/wp-json\/wp\/v2\/categories?post=385"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/p-corporate-blog-cms.mmmcorp.co.jp\/wp-json\/wp\/v2\/tags?post=385"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}