---
title: 【Ltech#10】LIFULL HOME&#039;S ネイティブアプリ用APIのデプロイを自動化する
tags:  #ltech #lifull #lifull home&#039;s #api #aws #自動化 #auto rollback #canary release #parameter store #api gateway id  
author: [株式会社LIFULL](https://www.docswell.com/user/LIFULL)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/NPEXG1L57X.jpg?width=480
description: 2020/1/28　Ltech#10 不動産・住宅情報サイト「LIFULL HOME&#039;S」の中の人が語るAWS活用前線 LIFULL HOME&#039;S事業本部プロダクトエンジニアリング部プロダクトエンジニアリング3ユニット開発2グループ 衛藤 剛史
published: January 29, 20
canonical: https://www.docswell.com/s/LIFULL/5693M5-LIFULLHOME%27S%E3%83%8D%E3%82%A4%E3%83%86%E3%82%A3%E3%83%96%E3%82%A2%E3%83%97%E3%83%AA%E7%94%A8API%E3%81%AE%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E3%82%92%E8%87%AA%E5%8B%95%E5%8C%96%E3%81%99%E3%82%8B
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/NPEXG1L57X.jpg)

LIFULL HOME&#039;S ネイティブアプリ用API
のデプロイを自動化する
Jan 28, 2020 @ LTech #10
株式会社LIFULL 衛藤 剛史
@doramusukotake


# Page. 2

![Page Image](https://bcdn.docswell.com/page/63EK42LR7D.jpg)

自己紹介
衛藤 剛史（えとう たけし）
@doramusukotake
● Android Developer
● Backend Developer
● Machine Learning
● Group Manager
2
執筆活動
Google Cloud AutoML Vision 入門
(2019/9/10 発売)
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 3

![Page Image](https://bcdn.docswell.com/page/4L73L43GJ5.jpg)

Agenda
●
●
●
●
●
●
●
3
現状の構成・仕組み
自動化の方針
SAM (Serverless Application Model)
Parameter Store
CodeDeploy
CodePipeline
自動化後の効果
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 4

![Page Image](https://bcdn.docswell.com/page/V87DNQ4NJG.jpg)

Agenda
●
●
●
●
●
●
●
現状の構成・仕組み
自動化の方針
SAM (Serverless Application Model)
Parameter Store
CodeDeploy
CodePipeline
自動化後の効果
の予定でしたが、失敗したので変更します
4
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 5

![Page Image](https://bcdn.docswell.com/page/4VJP5LMNJ8.jpg)

なにが起こったか
*******************************************
のちほど
5
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 6

![Page Image](https://bcdn.docswell.com/page/L2EVPQ9YEQ.jpg)

失敗した話
LIFULL HOME&#039;S ネイティブアプリ用APIのデプロイを自動化しようとして
Jan 28, 2020 @ LTech #10
株式会社LIFULL 衛藤 剛史
@doramusukotake


# Page. 7

![Page Image](https://bcdn.docswell.com/page/Z57GPWZW7L.jpg)

Agenda2
●
●
●
●
●
●
●
●
7
現状の構成・仕組み
解消したい課題
自動化の方針
遭遇した壁1
遭遇した壁2
遭遇した壁3
乗り越えられなかった最後の壁
結局
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 8

![Page Image](https://bcdn.docswell.com/page/V4EQ23LQJP.jpg)

現状の構成・仕組み
8
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 9

![Page Image](https://bcdn.docswell.com/page/DKJ4L1DYJ1.jpg)

簡易図
AWS Cloud
VPC
Amazon API Gateway
9
VPC
AWS Lambda
Amazon EC2
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 10

![Page Image](https://bcdn.docswell.com/page/PLE1LGZNEG.jpg)

1APIG / 複数 Lambda 運用
● Lambda用ソースコード
Lambda 用ソースコード
定義)
● swagger (API path 定義)
1 RestAPI ID → 各 Lambda Function
10
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 11

![Page Image](https://bcdn.docswell.com/page/8GEWVK6MJ2.jpg)

APIGとLambdaはstage/alias運用
stage1
lambda-function:alias1
AWS Lambda
Amazon API Gateway
stage2
${stageVariables.alias}
11
lambda-function:alias2
stage変数により切り分け
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 12

![Page Image](https://bcdn.docswell.com/page/W47Z4ZYMJ3.jpg)

抱えている課題
12
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 13

![Page Image](https://bcdn.docswell.com/page/KYJ63ZD5JV.jpg)

現在のデプロイフロー
git pull
deploy command
--- profile {dev | prod}
Unit Tests
Lint Check
deploy
スクリプトで自動デプロイ
ただし実行は個人のPCから
13
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 14

![Page Image](https://bcdn.docswell.com/page/5GJ5LW3G74.jpg)

課題1 .envファイル
{
&quot;production&quot;: {
&quot;env1&quot;: &quot;hoge-prod&quot;,
&quot;env2&quot;: &quot;poge-prod&quot;
},
&quot;development&quot;: {
&quot;env1&quot;: &quot;hoge-dev&quot;,
&quot;env2&quot;: &quot;poge-dev&quot;
}
env情報を.gitignoreして個人管理
}
14
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 15

![Page Image](https://bcdn.docswell.com/page/4LE3L46P75.jpg)

課題2 deploy用スクリプトの複雑化
複雑なスクリプト
高いメンテ難易度
メンテナンスが大変
15
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 16

![Page Image](https://bcdn.docswell.com/page/V8EDNQV37G.jpg)

課題3 環境依存（今のデプロイ方法）
個人PCから
直接アップロード
個人環境依存が強い
16
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 17

![Page Image](https://bcdn.docswell.com/page/4V7P5LVP78.jpg)

自動化の方針
17
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 18

![Page Image](https://bcdn.docswell.com/page/L2JVPQZVJQ.jpg)

各種AWSサービスを組み合わせて完全自動化
18
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 19

![Page Image](https://bcdn.docswell.com/page/Z5EGPW41EL.jpg)

Auto Rollback・Canaryリリースの実現
HelloDeployFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: HelloDeployFunction
AutoPublishAlias: dev1
Runtime: nodejs10.x
Handler: index.handler
Environment:
Variables:
NODE_ENV: test
CodeUri: ./
DeploymentPreference:
Type: Canary10Percent5Minutes
Alarms:
- !Ref AliasErrorMetricGreaterThanZeroAlarm
- !Ref LatestVersionErrorMetricGreaterThanZeroAlarm
Hooks:
PreTraffic: !Ref PreTrafficLambdaFunction
PostTraffic: !Ref PostTrafficLambdaFunction
MemorySize: 128
19
Canary10Percent30Minutes
Canary10Percent5Minutes
Canary10Percent10Minutes
Canary10Percent15Minutes
Linear10PercentEvery10Minutes
Linear10PercentEvery1Minutes
Linear10PercentEvery2Minutes
Linear10PercentEvery3Minutes
AllOtOnce
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 20

![Page Image](https://bcdn.docswell.com/page/V4JQ23GN7P.jpg)

Auto Rollback・Canaryリリースの実現
HelloDeployFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: HelloDeployFunction
AutoPublishAlias: dev1
Runtime: nodejs10.x
Handler: index.handler
Environment:
Variables:
NODE_ENV: test
CodeUri: ./
DeploymentPreference:
Type: Canary10Percent5Minutes
Alarms:
- !Ref AliasErrorMetricGreaterThanZeroAlarm
- !Ref LatestVersionErrorMetricGreaterThanZeroAlarm
Hooks:
PreTraffic: !Ref PreTrafficLambdaFunction
この記述のみで Auto
PostTraffic: !Ref PostTrafficLambdaFunction
MemorySize: 128
20
Canary10Percent30Minutes
Canary10Percent5Minutes
Canary10Percent10Minutes
Canary10Percent15Minutes
Linear10PercentEvery10Minutes
Linear10PercentEvery1Minutes
Linear10PercentEvery2Minutes
Linear10PercentEvery3Minutes
AllOtOnce
Rollback / Canary Release が実現
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 21

![Page Image](https://bcdn.docswell.com/page/DK74L15371.jpg)

Auto Rollback・Canaryリリースの実現
Canary Release の様子
21
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 22

![Page Image](https://bcdn.docswell.com/page/PLJ1LGWZJG.jpg)

遭遇した壁1
22
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 23

![Page Image](https://bcdn.docswell.com/page/8GJWVK6672.jpg)

Parameter Store の制限と速度
Latency
.envからの読み出しと比較すると確実に時間がかかる
→ Lambdaのグローバル変数として保持しておきたい
23
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 24

![Page Image](https://bcdn.docswell.com/page/W4EZ4ZYR73.jpg)

Parameter Store 取得処理
// load params from parameter store
(async function () {
await getParameters();
})();
hander() の外で実行により
● Lambda コンテナ立上時のみ実行
async function handler(event, context) {
// lambdaエントリーポイント
}
ただし以下の問題がある
● handler() の処理待ち合わせが必要
● handler() の処理が終わるとコールバッ
クが来ない
async function getParameters() {
const ssm = new AWS.SSM(credentials);
// パラメータストアから取得
const result = await ssm.getParametersByPath(request).promise();
// 後続処理
}
24
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 25

![Page Image](https://bcdn.docswell.com/page/KY763ZD17V.jpg)

Parameter Store 取得処理
// load params from parameter store
(async function () {
await getParameters();
})();
Event loop が空になるまで待たせるひつ
ようがある
(取得処理が間に合わない問題はある)
async function handler(event, context) {
// lambdaエントリーポイント
context.callbackWaitsForEmptyEventLoop = true
// 後続処理
}
async function getParameters() {
const ssm = new AWS.SSM(credentials);
// パラメータストアから取得
const result = await ssm.getParametersByPath(request).promise();
// 後続処理
}
25
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 26

![Page Image](https://bcdn.docswell.com/page/5G75LW3LE4.jpg)

Parameter Store 取得処理
// load params from parameter store
(async function () {
await getParameters();
})();
async function handler(event, context) {
// lambdaエントリーポイント
const testKey = process.env.TEST_KEY || null;
if (testKey === null) {
await getParameters();
} else {
console.log(&#039;env is already set&#039;);
}
// 後続処理
}
async function getParameters() {
const ssm = new AWS.SSM(credentials); Lambda のインスタンス立ち上がり後
// パラメータストアから取得
1回のみ取得するように
const result = await ssm.getParametersByPath(request).promise();
// 後続処理
}
26
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 27

![Page Image](https://bcdn.docswell.com/page/V9J2LQZ37R.jpg)

遭遇した壁2
27
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 28

![Page Image](https://bcdn.docswell.com/page/5DEYQWR87M.jpg)

同じAPI Gateway ID がたくさんできる
気づいたら同じ名前の API がたくさんできている
→ Stack name と openapi.yaml の info を統一して解消
28
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 29

![Page Image](https://bcdn.docswell.com/page/2VJNK9D9J8.jpg)

遭遇した壁3
29
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 30

![Page Image](https://bcdn.docswell.com/page/GYE9V2G3J3.jpg)

Lambda alias / API Gateway stage が上書きされてしまう
stage1
alias1
stage2
alias2
SAM
Template
30
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 31

![Page Image](https://bcdn.docswell.com/page/5GE8P5VLED.jpg)

Lambda alias / API Gateway stage が上書きされてしまう
Deleted !
stage1
alias1
stage2
alias2
SAM
Template
同じテンプレートで複数 stage / aliasはできない（既存のものが
Delete される）
→ SAM ではなく CloudFormation の記述で回避（次項）
31
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 32

![Page Image](https://bcdn.docswell.com/page/MLEL1Y5QER.jpg)

CloudFormationの記述で回避 - API Gateway HelloDeployApiGateway:
Type: AWS::Serverless::Api
Properties:
StageName: stage1
DefinitionUri: ./openapi.yaml
Variables:
alias: &quot;stage1&quot;
Stage2:
Type: AWS::ApiGateway::Stage
Properties:
RestApiId: !Ref HelloDeployApiGateway
DeploymentId: !Ref HelloDeployApiGateway.Deployment
StageName: stage2
Variables:
alias: :stage2
32
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 33

![Page Image](https://bcdn.docswell.com/page/54JMWNRKEW.jpg)

CloudFormationの記述で回避 - Lambda HelloDeployFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: HelloDeployFunction
AutoPublishAlias: dev1
// 略
LambdaAlias:
Type: AWS::Lambda::Alias
Properties:
FunctionName: !Ref HelloDeployFunction
FunctionVersion: !Select [7, !Split [&quot;:&quot;, !Ref HelloDeployFunction.Version]]
Name: dev2
33
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 34

![Page Image](https://bcdn.docswell.com/page/ZPJRYDR6E9.jpg)

乗り越えられなかった最後の壁
34
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 35

![Page Image](https://bcdn.docswell.com/page/NPEXG1RD7X.jpg)

API複数リポジトリ運用の罠
極力APIごとの依存関係を消し去りたいため、
● Lambda Function ごとに github repository
● 共有なものはライブラリ化として package.json に記述
● そのため、SAM template をそれぞれ独立させておく必要がある
● Lambda用ソースコード
Lambda用ソースコード
定義)
● swagger
swagger (API
(APIpath
path定義)
35
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 36

![Page Image](https://bcdn.docswell.com/page/63EK42RD7D.jpg)

API複数リポジトリ運用の罠
既存 Path を一度 remove しないと
違う Template からデプロイできない・・・！
複数リポジトリ運用しているため、Template を分割する必要があ
るが、制限があり実現できなかった
36
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 37

![Page Image](https://bcdn.docswell.com/page/4L73L48PJ5.jpg)

aaaaa
構成の実現が難しい状況であることがわかりました。
構成の実現が難しい状況であることがわかりました。
37
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 38

![Page Image](https://bcdn.docswell.com/page/V87DNQM3JG.jpg)

結果
38
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 39

![Page Image](https://bcdn.docswell.com/page/4VJP5LRPJ8.jpg)

Github Actions 使う
39
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 40

![Page Image](https://bcdn.docswell.com/page/L2EVPQRVEQ.jpg)

各種AWSサービスを組み合わせて完全自動化
AWS のサービスだけで自動化できなかった部分
40
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 41

![Page Image](https://bcdn.docswell.com/page/Z57GPWM17L.jpg)

まとめ
41
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 42

![Page Image](https://bcdn.docswell.com/page/V4EQ23RNJP.jpg)

まとめ
● SAMは便利なので対応可能であればやるべき
○ CodeBuild / CodePipelineと組み合わせてより強力な自動化
● SAMにも限界があることを知っておく
● 限界あるからといって諦めない
● Github Actionsという他の選択肢もある
42
© LIFULL Co.,Ltd.
本書の無断転載、複製を固く禁じます。


# Page. 43

![Page Image](https://bcdn.docswell.com/page/DKJ4L183J1.jpg)

END


# Page. 44

![Page Image](https://bcdn.docswell.com/page/PLE1LG2ZEG.jpg)

We are hiring engineers!!
エンジニア積極採用中
LIFULL 採用
検索


