Successfully reported this slideshow.
Your SlideShare is downloading. ×

【Ltech#10】LIFULL HOME'S ネイティブアプリ用APIのデプロイを自動化する

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 44 Ad

【Ltech#10】LIFULL HOME'S ネイティブアプリ用APIのデプロイを自動化する

Download to read offline

2020/1/28 Ltech#10 不動産・住宅情報サイト「LIFULL HOME'S」の中の人が語るAWS活用前線
LIFULL HOME'S事業本部プロダクトエンジニアリング部プロダクトエンジニアリング3ユニット開発2グループ
衛藤 剛史

2020/1/28 Ltech#10 不動産・住宅情報サイト「LIFULL HOME'S」の中の人が語るAWS活用前線
LIFULL HOME'S事業本部プロダクトエンジニアリング部プロダクトエンジニアリング3ユニット開発2グループ
衛藤 剛史

Advertisement
Advertisement

More Related Content

Slideshows for you (20)

Similar to 【Ltech#10】LIFULL HOME'S ネイティブアプリ用APIのデプロイを自動化する (20)

Advertisement

More from LIFULL Co., Ltd. (20)

Recently uploaded (20)

Advertisement

【Ltech#10】LIFULL HOME'S ネイティブアプリ用APIのデプロイを自動化する

  1. 1. LIFULL HOME'S ネイティブアプリ用API のデプロイを自動化する 株式会社LIFULL 衛藤 剛史 @doramusukotake Jan 28, 2020 @ LTech #10
  2. 2. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。2 自己紹介 衛藤 剛史(えとう たけし) @doramusukotake ● Android Developer ● Backend Developer ● Machine Learning ● Group Manager 執筆活動 Google Cloud AutoML Vision 入門 (2019/9/10 発売)
  3. 3. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。3 Agenda ● 現状の構成・仕組み ● 自動化の方針 ● SAM (Serverless Application Model) ● Parameter Store ● CodeDeploy ● CodePipeline ● 自動化後の効果
  4. 4. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。4 Agenda ● 現状の構成・仕組み ● 自動化の方針 ● SAM (Serverless Application Model) ● Parameter Store ● CodeDeploy ● CodePipeline ● 自動化後の効果 の予定でしたが、失敗したので変更します
  5. 5. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。5 なにが起こったか ******************************************* のちほど
  6. 6. LIFULL HOME'S ネイティブアプリ用APIのデプロイを自動化しようとして失敗した話 株式会社LIFULL 衛藤 剛史 @doramusukotake Jan 28, 2020 @ LTech #10
  7. 7. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。7 Agenda2 ● 現状の構成・仕組み ● 解消したい課題 ● 自動化の方針 ● 遭遇した壁1 ● 遭遇した壁2 ● 遭遇した壁3 ● 乗り越えられなかった最後の壁 ● 結局
  8. 8. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。8 現状の構成・仕組み
  9. 9. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。9 簡易図 AWS Cloud VPC AWS LambdaAmazon API Gateway VPC Amazon EC2
  10. 10. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。10 1APIG / 複数 Lambda 運用 ● Lambda用ソースコード ● swagger (API path 定義) ● Lambda用ソースコード ● swagger (API path 定義) ● Lambda用ソースコード ● swagger (API path 定義) ● Lambda 用ソースコード ● swagger (API path 定義) 1 RestAPI ID → 各 Lambda Function
  11. 11. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。11 APIGとLambdaはstage/alias運用 AWS LambdaAmazon API Gateway stage1 lambda-function:alias1 stage2 lambda-function:alias2 ${stageVariables.alias} stage変数により切り分け
  12. 12. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。12 抱えている課題
  13. 13. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。13 現在のデプロイフロー git pull deploy command --- profile {dev | prod} Unit Tests Lint Check deploy スクリプトで自動デプロイ ただし実行は個人のPCから
  14. 14. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。14 { "production": { "env1": "hoge-prod", "env2": "poge-prod" }, "development": { "env1": "hoge-dev", "env2": "poge-dev" } } 課題1 .envファイル env情報を.gitignoreして個人管理
  15. 15. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。15 課題2 deploy用スクリプトの複雑化 複雑なスクリプト 高いメンテ難易度 メンテナンスが大変
  16. 16. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。16 課題3 環境依存(今のデプロイ方法) 個人PCから 直接アップロード 個人環境依存が強い
  17. 17. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。17 自動化の方針
  18. 18. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。18 各種AWSサービスを組み合わせて完全自動化
  19. 19. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。19 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 Canary10Percent30Minutes Canary10Percent5Minutes Canary10Percent10Minutes Canary10Percent15Minutes Linear10PercentEvery10Minutes Linear10PercentEvery1Minutes Linear10PercentEvery2Minutes Linear10PercentEvery3Minutes AllOtOnce
  20. 20. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。20 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 Canary10Percent30Minutes Canary10Percent5Minutes Canary10Percent10Minutes Canary10Percent15Minutes Linear10PercentEvery10Minutes Linear10PercentEvery1Minutes Linear10PercentEvery2Minutes Linear10PercentEvery3Minutes AllOtOnce この記述のみで Auto Rollback / Canary Release が実現
  21. 21. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。21 Auto Rollback・Canaryリリースの実現 Canary Release の様子
  22. 22. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。22 遭遇した壁1
  23. 23. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。23 Parameter Store の制限と速度 .envからの読み出しと比較すると確実に時間がかかる → Lambdaのグローバル変数として保持しておきたい Latency
  24. 24. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。24 Parameter Store 取得処理 // load params from parameter store (async function () { await getParameters(); })(); async function handler(event, context) { // lambdaエントリーポイント } async function getParameters() { const ssm = new AWS.SSM(credentials); // パラメータストアから取得 const result = await ssm.getParametersByPath(request).promise(); // 後続処理 } hander() の外で実行により ● Lambda コンテナ立上時のみ実行 ただし以下の問題がある ● handler() の処理待ち合わせが必要 ● handler() の処理が終わるとコールバッ クが来ない
  25. 25. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。25 Parameter Store 取得処理 // load params from parameter store (async function () { await getParameters(); })(); 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(); // 後続処理 } Event loop が空になるまで待たせるひつ ようがある (取得処理が間に合わない問題はある)
  26. 26. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。26 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('env is already set'); } // 後続処理 } async function getParameters() { const ssm = new AWS.SSM(credentials); // パラメータストアから取得 const result = await ssm.getParametersByPath(request).promise(); // 後続処理 } Lambda のインスタンス立ち上がり後 1回のみ取得するように
  27. 27. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。27 遭遇した壁2
  28. 28. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。28 同じAPI Gateway ID がたくさんできる 気づいたら同じ名前の API がたくさんできている → Stack name と openapi.yaml の info を統一して解消
  29. 29. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。29 遭遇した壁3
  30. 30. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。30 Lambda alias / API Gateway stage が上書きされてしまう SAM Template stage1 stage2 alias1 alias2
  31. 31. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。31 Lambda alias / API Gateway stage が上書きされてしまう SAM Template stage1 stage2 alias1 alias2 Deleted ! 同じテンプレートで複数 stage / aliasはできない(既存のものが Delete される) → SAM ではなく CloudFormation の記述で回避(次項)
  32. 32. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。32 CloudFormationの記述で回避 - API Gateway - HelloDeployApiGateway: Type: AWS::Serverless::Api Properties: StageName: stage1 DefinitionUri: ./openapi.yaml Variables: alias: "stage1" Stage2: Type: AWS::ApiGateway::Stage Properties: RestApiId: !Ref HelloDeployApiGateway DeploymentId: !Ref HelloDeployApiGateway.Deployment StageName: stage2 Variables: alias: :stage2
  33. 33. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。33 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 [":", !Ref HelloDeployFunction.Version]] Name: dev2
  34. 34. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。34 乗り越えられなかった最後の壁
  35. 35. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。35 API複数リポジトリ運用の罠 極力APIごとの依存関係を消し去りたいため、 ● Lambda Function ごとに github repository ● 共有なものはライブラリ化として package.json に記述 ● そのため、SAM template をそれぞれ独立させておく必要がある ● Lambda用ソースコード ● swagger (API path 定義) ● Lambda用ソースコード ● swagger (API path 定義) ● Lambda用ソースコード ● swagger (API path 定義) ● Lambda用ソースコード ● swagger (API path 定義)
  36. 36. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。36 API複数リポジトリ運用の罠 既存 Path を一度 remove しないと 違う Template からデプロイできない・・・! 複数リポジトリ運用しているため、Template を分割する必要があ るが、制限があり実現できなかった
  37. 37. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。37 aaaaa 構成の実現が難しい状況であることがわかりました。 構成の実現が難しい状況であることがわかりました。
  38. 38. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。38 結果
  39. 39. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。39 Github Actions 使う
  40. 40. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。40 各種AWSサービスを組み合わせて完全自動化 AWS のサービスだけで自動化できなかった部分
  41. 41. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。41 まとめ
  42. 42. © LIFULL Co.,Ltd. 本書の無断転載、複製を固く禁じます。42 まとめ ● SAMは便利なので対応可能であればやるべき ○ CodeBuild / CodePipelineと組み合わせてより強力な自動化 ● SAMにも限界があることを知っておく ● 限界あるからといって諦めない ● Github Actionsという他の選択肢もある
  43. 43. END
  44. 44. We are hiring engineers!! エンジニア積極採用中 LIFULL 採用 検索

×