snaqme Engineers Blog

おやつ体験BOX snaq.me エンジニアによる開発プロダクトブログ

スナックミーのエンジニアチームで直近動きたいこと (2021年10月)

こんにちは スナックミー CTO の三好 (@miyoshihayato) です
四半期ごとにチームに共有している直近動いていきたいことを一部変えてこちらのエンジニアブログに載せたいと思います。

歩み寄りの意識

スナックミーにとってエンジニアが開発することで全体が前進できる部分が多く存在しています。(おやつ選定のアルゴリズム、出荷システム、LINEやメールを用いたCRM、おやつのリクエストなど)
一つの機能、1回の分析、パフォーマンス改善全てが無駄なことなんて1つもなく、何かしらプラスに起因してます。
よりプラスに働くには、互いに(エンジニア同士、他チーム)押さえ合うのではなく、良い方向に引き合う関係である必要があると思います。
そのためにも、ただ要望を受け対応するだけではなく、相互に高め合えるような姿勢を意識したいと考えています。
そこで高め合えるためには互いに歩み寄りの意識が必要だと思っています。
完全に任せっきりにするのではなく、少しでも知っていく姿勢 (100知る必要はなく、1でも知ろうとする動き)
1 知っている状態と知らない状態では議論の深さが違いより良質なアウトプットになると思っています。
また、知っていくことで開発も相手の目線で提案・開発ができるようになると考えています。

非エンジニアから見るとエンジニアがやっていることは一番ブラックボックスに近い仕事かと思います。UI/UXなど目に見えるものは認識されやすいが、それ以外のことはなかなかイメージしずらいため、何をしているのが話してもよくわからない。
そのためエンジニアから歩み寄ることで認識できる部分があるはずなので、この実践をエンジニアチームではやっていきたいと思っています。

仕様追加 と 仕様変更 (改善)

機能の要望をもらうとき、追加と変更・改善を一緒に考えて対応している場合はないでしょうか? それぞれの立ち位置を考えないと、システム全体が劣化していく可能性があります。 (リファクタしていく話とは違う話です)

仕様追加

仕様追加は現時点から

  • プラス+ に寄与
  • マイナス- に転じる

にもなりうる

例えば、ある商品登録するシステムにおいて必要だと認識していた1つの機能を追加されることは、数年前から利用している人にとって学習コストはさほど上がらず、便利になったと感じることが多い。
一方、これから始める人(始めたての人)にとってこの追加機能は追加されたことで学習コストを数倍にも膨れ上がる可能性があります。 (将来的には属人化さ理解すらできなくなる)

f:id:snaqme-labs:20210930212415j:plain

仕様変更 (改善)

一方でこの仕様変更や改善は

  • マイナス- から 0 or プラス+
  • プラス+ から プラス+α

全方面にとってプラスに寄与することが多い
マイナスに寄与する可能性がある場合は A/Bテストなどで検証は必要になる

f:id:snaqme-labs:20210930212426j:plain

毎回問いたい

追加要望がNGと言っているわけではなく、本当に必要なことって何なのか?ということです

追加の場合

  • 解決したいことは何か
  • 本当に追加する必要性があるのか
  • 追加することによって紛らわしくなってないか など

変更・改善の場合

  • 何を良くしたい(ペイン)のか
  • 何が良くなるといいのか
  • 変更の場合、利用者が混乱する時があるので許容範囲なのか など

考えて実装できるように、 コードが書けるだけのエンジニアになってほしくないそんな思いが強いです。
しかし、深く考えすぎて何もできなくなると元も子もないので、シンプルにすることを忘れないようにしたい。

開発から最短デプロイ

先にお伝えしますがなんでもテストしないで、何が変更されたのか共有しないで好き勝手に一人でデプロイできるようにしたいという話ではないです。
チームで100、120動けるようになることは素晴らしいが、誰か欠けると1歩すら動けなくなることは好ましい状態じゃないです。

開発者の一つの価値として機能を開発しユーザーさんに届けることで生み出せます。
「変化なくして、進化なし。」とあるように何もしないことは衰退の始まりだと考えています。

そこでどうしたら 開発したものをいかに早くデリバリーできるか を考え実行する

  • 中間地点のタッチポイントをいかに減らせるか
    • チェックなしでOKということではない
    • テストなどの検証を抑える (100%は目指さない)
    • QAの観点
  • チーム間の仕様の共有は行き届いている状態 (slackなどにポストすればいいという話でも、esaなどのdocsにまとめればいいという話ではない)
  • メンバーが何をするべきかわかっている状態 など要点を現時点から中期の状態を想定しチームで考え試していくことが大事だと考えています。
    (互いのストロングポイントを活かしながら)

最後に
先月の9月でスナックミーは創立から6年経ちました。snaq.me は来年の3月で丸6年になる予定です。
エンジニアメンバーは今、10名ほどになり少しずつですができることが増えてきています。メンバーが増えると対数的にスピード感や意思決定が遅くなっていく傾向がありますが、早期の段階から取り組むことで良くなると思っています。
また、スタートアップはスピードが命といっても過言ではない、そのため立ち上げ時のスピードをより加速させるためのアプローチはチーム全体で取り組むことで達成できると私は思っています。
これからも定期的にこういう発信はしていこうと思います。

おやつと、世界を面白く。」 一緒に面白くしたい仲間をお待ちしてます!!

meety.net

engineers.snaq.me

おやつのアサイン最適化を求めて〜4時間かかった処理を20分に短縮した取り組み〜

こんにちは、SRE の多田(@tada_infra)です!

この記事ではスナックミーのお客様にお届けする,おやつのアサインをカイゼンした話についてです.私と開発者の加藤(id:hisaaki_kato)で記事を書いていきます.

課題とカイゼンの経緯

スナックミーではお客様にお届けするおやつを決めて,専用の BOX に梱包する作業を「アサイ」と呼びます(下記資料イメージ参照).このアサイン工程で事前に○日のアサインはどれくらいの人数に対してどれくらいのおやつを確保しておく必要があるかを計算する処理を「プレアサイ」と呼ぶのですが,この処理がユーザー数の増加に伴い4時間かかる課題がありました.

現状4時間かかるのだからこのままユーザーが推移していけば自然と「プレアサイ」にかかる時間が増えることが予測されます.その分,内部のオペレーション的に①無駄な待ち時間が発生する,②在庫確認するためとはいえ気軽に処理を実行できないのは不都合が多いと言った課題があったので,私と加藤を中心にカイゼンを行うことにしました.

カイゼンの取り組み

次からは具体的にプログラム側で行ったカイゼンAWS 側で行ったカイゼンを紹介してきます.

プログラム側のカイゼン

プログラム側では、以下のAWS 側のカイゼンで後述しますが、処理を並列化することを念頭にボトルネックとなっていた処理を別リポジトリへと外出しを行いました.

ボトルネックとなっていた処理の概要

一連の処理時間の計測によってボトルネックとなっていた処理は判明しており,DBから取得したユーザー情報をユーザークラスへと格納する処理に全体の8割ほどの時間がかかっていました.アサインを行うための前段階として,ユーザーごとのおやつの好き嫌いやこれまでにお届けしたおやつの評価情報などを格納するだけの処理ですが,ユーザー規模の増加によって指数的に処理時間が増大してしまっていた形です.

必然的に,この部分の処理時間が短縮すれば大幅な高速化が見込めます.そのため,この部分について並列化のために処理の外出しを行いました.

データの受け渡し

処理の外出しに伴い,データの受け渡しを行う必要が生じます.元側の処理ではDBからデータの取得のみを行い,これを外出しした処理でユーザークラスに格納し,再度元側の処理でこれらを受け取って後続の処理をしていくイメージです.ただしユーザーデータそのものは大きすぎて受け渡せないため,S3に保存してそれらのパスをパラメータとしてやり取りする形を取りました.

ファイルの読み書きの高速化

S3へと保存するファイルについては当初はcsvjsonの形式で保存する想定でしたが,これらファイルの大量の読み書きが新たなボトルネックとなってしまうことが分かりました.そのため,ファイルはpickle形式で保存することでこの部分についても大幅な高速化が実現できました.

AWS 側のカイゼン

AWS 側のカイゼンとして当初 AWS Batch 1台で全て処理したところを、プログラム側で外だしした処理を以下の観点で考慮し Step Functions のワークフローにすることにしてカイゼンを試みることにしました.

  • Map を使った並列処理を組める
  • 並列処理実行時の成功/失敗のステータスを Step Functions のワークフローで分岐して組める
  • AWS Batch にも配列処理があるが,特定の処理だけ並列実行ができなさそうであるため

構成イメージ

Step Functions のワークフロー 構成イメージは下記のものになります.ECS Fargate の起動とパラメーターを渡す Lambda と Map を使って多数の ECS Fargate が起動するため各コンテナのジョブステータスをポーリングする Lambda が並列処理の成功と失敗を判定します.Fargate は起動後インプットファイルの取得とアウトプットの出力で S3 バケットを使うような動きをします.

f:id:sadayoshi_tada:20210809214619p:plain

Step Functions の 定義

Step Functions の定義は下記のような ASL を設定しました.最初の Lambda で ECS Fargate を起動して次の Lambda で ECS Fargate のタスク実行状況をポーリングして成功か失敗かを判定する動作をします.60秒待機した後,再度ポーリングし,ジョブが終了していた場合,成功か失敗かを判定するような形です.

ASL 定義

{
    "Comment": "Processing ECS Fargate",
    "StartAt": "test",
    "States": {
      "test": {
        "Type": "Map",
        "End": true,
        "Iterator": {
          "StartAt": "Lambda Invoke",
          "States": {
            "Lambda Invoke": {
              "Type": "Task",
              "Resource": "arn:aws:states:::lambda:invoke",
              "OutputPath": "$.Payload",
              "Parameters": {
                "Payload.$": "$",
                "FunctionName": "arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:run-sfn-execute"
              },
              "Retry": [
                {
                  "ErrorEquals": [
                    "Lambda.ServiceException",
                    "Lambda.AWSLambdaException",
                    "Lambda.SdkClientException"
                  ],
                  "IntervalSeconds": 2,
                  "MaxAttempts": 6,
                  "BackoffRate": 2
                }
              ],
              "Next": "status Lambda Invoke"
            },
            "status Lambda Invoke": {
              "Type": "Task",
              "Resource": "arn:aws:states:::lambda:invoke",
              "ResultPath": "$.status",
              "Parameters": {
                "Payload.$": "$",
                "FunctionName": "arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:job-polling"
              },
              "Retry": [
                {
                  "ErrorEquals": [
                    "Lambda.ServiceException",
                    "Lambda.AWSLambdaException",
                    "Lambda.SdkClientException"
                  ],
                  "IntervalSeconds": 2,
                  "MaxAttempts": 6,
                  "BackoffRate": 2
                }
              ],
              "Next": "Job Complete Check"
            },
            "Job Complete Check": {
              "Type": "Choice",
              "Choices": [
                {
                  "Variable": "$.status.Payload",
                  "StringEquals": "FAILLED",
                  "Next": "Notify Fail"
                },
                {
                  "Variable": "$.status.Payload",
                  "StringEquals": "SUCCEEDED",
                  "Next": "Notify Success"
                }
              ],
              "Default": "Wait 60 Seconds"
            },
            "Wait 60 Seconds": {
              "Type": "Wait",
              "Seconds": 60,
              "Next": "status Lambda Invoke"
            },
            "Notify Success": {
              "Type": "Pass",
              "Result": "Success",
              "End": true
            },
            "Notify Fail": {
              "Type": "Pass",
              "Result": "Fail",
              "End": true
            }
          }
        },
        "ItemsPath": "$.parameter",
        "Parameters": {
          "hoge.$": "$.fuga",
          "s3_bucket.$": "$.s3_bucket"
        }
      }
    }
  }

ワークフロー の処理結果確認

ワークフローの処理結果を確認すると以下のようなイメージで遷移し,期待通り動作していることを確認できました.

ワークフロー動作イメージ

f:id:sadayoshi_tada:20210809215552p:plain

一点だけ使っていて注意点があったのですが,Map の同時実行数が40以上を超えるとMaxConcurrencyの注記にもあるように一気に処理しない動作でした.ただ,一気に処理しきれない分も失敗にならず順次実行されるのでこの点を認識していれば問題ないのかなという感想を持ちました.

同時反復は制限される場合があります。この現象が発生すると、一部の反復は前の反復が完了するまで開始されません。入力配列に40項目を超えると、この問題が発生する可能性が高くなります。

docs.aws.amazon.com

40以上実行した場合の処理イメージ(第1弾の処理)

f:id:sadayoshi_tada:20210809221833p:plain

40以上実行した場合の処理イメージ(第2弾の処理)

f:id:sadayoshi_tada:20210809221843p:plain

40以上実行した場合の処理イメージ(最終結果)

f:id:sadayoshi_tada:20210809221852p:plain

まとめ

おやつのアサイン最適化を求めたカイゼンの取り組みを紹介しました.今回のカイゼンですが,検証や本番適用まで3日間に収めつつ大幅な時間の短縮により社内関係者から感謝の言葉をもらえたのは嬉しかったです.これからもよりよい運用の形を開発者と目指していければと思います.

f:id:sadayoshi_tada:20210809225514p:plain f:id:sadayoshi_tada:20210809225548p:plain

スナックミー もMeety始めてみました!

こんにちは!スナックミーでPM兼エンジニアをやっている渡邉(nabepiyo)です。 新しいプロダクトが好きで日々情報収集しています。

最近TwitterのTLでMeetyをとても目にするようになりましたね。

meety.net

Meetyめちゃくちゃ良い

Meetyめちゃくちゃ良いプロダクトや...!

なぜそう感じているかというと、僕がスナックミー に入社したのはちょうど1年ほど前で、当時もコロナ禍でした。 コロナ禍で次の職場を探す時はちょっと特殊だなと感じていて、どこの採用面接もオンラインでした。

面接後に会社の中を見学させてもらったり、面接官以外とちょっと話してみたりみたいなことがなくなりました。(もし入社しなかったとしてもあの会社の中はこんな感じだったとかが知れるのは面白くて、お互いにフィードバックすることで組織改善に役立てたりできるので、個人的には生の情報が得られるすごく良い機会だと思っています。)

一方で、全ての採用フローがオンラインで進む状態だと、採用のミスマッチが起こりやすくなるのではと感じていて、入社を検討している人にとっても採用する企業側にとっても損だと感じていました。

カジュアル面談は採用フローに入っていないので、気になることを事前に話して疑問を解消できる

そんな上のような課題を解決する時に、カジュアル面談だったり、ミートアップみたいな場が必要になるのかなと感じています。

スナックミーでは当時もCTOの三好と最初にカジュアル面談がありました。

当時snaq.meユーザでなかった僕が感じていた疑問として、おやつを作って送っている会社になんでエンジニアがいるの?とか、エンジニア募集しているのはなんで?などなど素朴な疑問から会社が目指していることまで、カジュアル面談の時に疑問を解消してきました。 しかし、他のメンバーと話せる機会が選考が進むにつれて、という点が結構もったいない気がしていて。 普段一緒に働くメンバーとも話して価値観が合うかな?みたいなことは感じていました。

また、Meetyはそんな採用の枠だけに留まらないのではと感じており、もっと繋がっていきたいなと思っています。

オンラインなので時間が無駄にならない

これはオンラインでやることのメリットで、企業に訪問するコストがありません。

移動時間も交通費もかからないので、気楽に話せます。

カジュアル面談って大事だと思っているのですが、例えば採用のケースで言えば、片道1時間以上の企業に採用に直結しない部分のために訪問して、「ここは違ったな」と感じた時の帰り道の足の重さと言ったら...となるので、オンラインで気軽に情報交換できるのはとても良いなと思っています。

とはいえ、話す内容の密度が薄いと貴重な時間がもったいないので、事前にアジェンダをやりとりして、お互い有意義な時間にできればと思っています!

スナックミー のカジュアル面談もぜひ!

そんなわけでスナックミー でもMeetyを始めました。

今のところ下の1件ですが、こんな人の話が聞きたい、こんな話が聞きたいなどあれば社内で共有して随時メンバーや話せるネタも増やしていければなと思っています。コメントでも、Meetyでもぜひご意見ください!

meety.net

最後に

そんなスナックミーではもりもりコードを改善し、開発していきたいバックエンドエンジニア、テックリードを募集中です。 採用の最新情報はこちらにありますので、ご興味ある方はご確認ください!

engineers.snaq.me

開発プロセスの分析・課題解決でVSMが役に立った話

こんにちは!スナックミーでPM兼エンジニアをやっている渡邉(nabepiyo)です。

スナックミーに限らず、これまで開発する中で、「この機能が使われていないのはなんで?」、「この機能リリースしたけど要望と違っていたよ」、「この機能リリースまでに思ったより時間がかかる」という出来事に遭遇することがありました。

今年の1〜3月にかけてVSM (Value Stream Mapping)を使って、開発プロセスの課題を可視化したり、解決に関する取り組みをやって、徐々に改善できてきたのでそんなお話をご紹介したいと思います。

VSM(Value Stream Mapping)について

youtu.be

こちらの動画を何度も見て学ばせていただきました! めちゃくちゃわかりやすいのでオススメです!

ではでは、どんなことをやってきたのかお伝えしたいと思います。

課題解決までのプロセス

1. 開発のツールや手順をVSMに書き出します

VSMを書くツールはdiagrams.netを使用しました。

スナックミーのとあるチームでは開発の際にZenHub、GitHub、Docker、Ruby on RailsAWS(細かい部分は割愛)を使っているので、こうしたツール群をVSMにプロットします。

VSMを書いてみるとわかるのですが、それぞれの手続きでLT(リードタイム), PT(プロセスタイム)を出すところが大変でした。特にGitHubのそれぞれのPRごとにレビュー完了までの時間を取得するところ。。。

※ 実はAPIで抽出することもできるのですがVSMを作成したのが初めてだったので、まずは生のデータを見ながら手を動かす選択をしていました。結果的にこの行動が意味を持ちます。

所々カスタマイズしたスクラムで開発しており、ストーリーポイントごとに開発にかかる時間や、レビューが完了するまでの時間やSR(手戻りが発生する割合)が異なるので、違いがある部分は別のマップに切り出して作成しました。

2. 結果を分析してみます

今回は、VSMを書いたことで、

  1. 要件定義までのLTが長いこと
  2. QA、Stage/QAまでのLTが長いこと
  3. ストーリーポイントが大きいものはPRを上げてからQAで差し戻しが発生する割合が高いこと
  4. CIで時間がかかっていること

などなど他にもいろいろと改善したくなるポイントが浮かび上がりました。

生のデータを見たことで、この時はこんな出来事があったな(障害対応していたな等)と思い出すことができ、一概に全てこの結果が悪いまたは改善の余地があるとは言い切れないものもあるとわかりました。

3. 改善案を検討します

レトロスペクティブでVSMを見て、チームでなぜこうした結果になるんだろうと話し合い、解決策を考えました。 実際に改善につながっていくブレストなのでここはチーム全員の士気も上がります🔥

細かな部分まではお伝えできないのですが、例えば、上の2.は急ぎのPRなのかどうかが不明確であったり、日々バーンダウンチャートを見てチームの進捗を追うことができていないという課題が隠れていてLTが長くなっていました。

そこで、日々10分程度のデイリースクラムを取り入れてみたところQA、Stage/QAのLTが半分以下になりました🙌(出社時間が異なるため、それまでやっていませんでした。。)

意外と簡単にできることで改善インパクトが大きいコスパの良い取り組みの1つのご紹介でした。

まとめ

VSMはどこのプロセスを改善すればどれぐらいのインパクトが出るか判断することにも使えます。

開発生産性の向上にはまだまだ伸びしろがありますが、数字が見えてなくて改善してもインパクトが小さなものを優先度高くやるような無駄打ちをすることがなくなるので、効率も上がって良い試みだったと感じています。

そんなスナックミーではもりもりコードを改善し、開発していきたいテックリード(バックエンド)を募集中です。 ご興味のある方はぜひこちらからご応募ください。

engineers.snaq.me

クリエイティブチームとの継続的なリリースフローの実践

こんにちは!SRE を担当している多田です(@tada_infra).

先日,lp.snaq.me のデザインがリニューアルしました✨ lp.snaq.me

このサイトの継続的なリリースを行う上で,キャンペーンを打ったりするためクリエイティブチームが作ったコンテンツを差し替えが頻繁に発生します.そこで,非エンジニアのメンバーと共同でのリリースフローを作った話をこの記事で紹介します.

従来の課題感

これまでの課題感として話を聞く限りメンバーの間で次のものがありました.

  • クリエイティブチームからコンテンツの入れ替えのやり方が不明なためエンジニアチームへの都度作業依頼が発生している
    • 上記の依頼に対して心理的に申し訳なさを感じていた
  • エンジニアチームとしても可能であればコンテンツの入れ替えをクリエイティブチームに実施できるようにフローを作りたい

上記の課題感からデザインリニューアルのタイミングでリリースフローを作ろうと動きました.

リリースフローの構築

リリースフローの構築にあたってはクリエイティブ側を中心に弊社の中では従来の取り組みとは異なったアプローチを取り入れてもらいました.

GitHub の使い方レクチャー

GitHub でコンテンツをアップロードしてもらって,ステージで確認し本番リリースするというフローを作りたかったので,クリエイティブチームのメンバーに GitHub のレクチャーを行いました.担当者の端末で Git と Visual Studio Code を入れてもらい,チュートリアルを作っていたので一緒に辿って練習を行いました.Git の環境作りにあたっては Progate さんのコンテンツを参照させていただきました.

prog-8.com

コンテンツアップロードの手順

次に,コンテンツのアップロードの手順をまとめ,一緒にアップロードと GitHub の PR を出してみるところまでを辿りました.PR をマージし,デプロイするのはエンジニアの仕事なのでここまでのフローを辿ることで,クリエイティブチームのメンバーからも「これならできそう」という感想をもらえました.また,その日のうちにコンテンツ追加の PR をあげてもらえてすぐにフローを実践してくれたおかげで早々に業務フローに載せていくこともできました.

手順の画面抜粋版 f:id:sadayoshi_tada:20210531171717p:plain

まとめ

新デザインになった LP の継続的なリリースフローをクリエイティブチームと共同で行っている話を書いてきました.分離していたオペレーションが GitHub 上のコミュニケーションで完結するようになり,双方の負担が軽減できたと思います.他にも適用範囲を広げられる余地があるので改善を一緒にやっていければと思います.

最後に

そんなスナックミーではもりもりコードを改善し、開発していきたいバックエンドエンジニア、テックリードを募集中です。 採用の最新情報はこちらにありますので、ご興味ある方はご確認ください!

engineers.snaq.me

サービススケールに対応していくための既存アーキテクチャ再構成の取り組み

こんにちは!SRE を担当している多田です(@tada_infra).

お客様のおかげで snaq.me はサービス開始から5年が経ちました.これからもサービスのスケールに合わせてシステム側もその変化に対応していけるように既存システムの課題から構成を見直し,改善を試みたのでその模様をこの記事でお伝えしていきます.

prtimes.jp

既存アーキテクチャにおける課題

弊社のシステム基盤は AWS を採用しておりその上で様々なシステムが稼働しています.これまではお客様への迅速なサービス提供を最優先に取り組んできてアーキテクチャの改善は後手になっていたと思います.私が専任で AWS 周りを管理していく立場で昨年入社し,改めて稼働しているシステムの設定を見た時にいくつかの課題があると感じました.今回は構成変更に伴う部分を抜粋して列挙しますが,大きく2点です.

課題1 VPC にパブリックサブネットしかない

EC2,ECS,RDS,ElastiCache,Lambda,Batch,ELB といった VPC 内に展開しているリソースを配置しているネットワークセグメントがパブリックサブネットでサブネットはそれしかありませんでした.ELB はインターネットから直接アクセスを受けるのでいいのですが,それ以外のリソースは直接インターネットからのアクセスを受けないためパブリックサブネットに配置しておく必要はなかったです.この状態のままリソースが増え続けていたので今後もこのままだと懸念を抱えたまま管理することになるため,本来配置しておくべきネットワークセグメントに移動したいという課題感を持ちました.

改善前の AWS 構成イメージ f:id:sadayoshi_tada:20210324175631p:plain

課題2 セキュリティグループの設定の問題

次の課題はセキュリティグループの設定です.セキュリティグループの設定で2つの課題を抱えていました.1つ目は下記のようにインバウンドで受け付けるのがプロトコルALLだったり,通信元の制御として 0.0.0.0/0 が EC2,RDS の設定で定義されていたままでした.セキュリティグループのインバウンドで受け付けるのにこの定義は広範過ぎるかつセキュリティ的にも突かれてしまう危険性を孕んでいる状態でした.

あるセキュリティグループのインバウンドルールのイメージ

セキュリティグループのインバウンドプロトコル IPアドレス範囲
ALL 0.0.0.0/0
HTTP 0.0.0.0/0
HTTPS 0.0.0.0/0
カスタムTCP 0.0.0.0/0

2つ目の課題は上記のようなセキュリティグループが複数のサーバーに跨って設定されていました.例えば,EC2 のセキュリティグループが Lambda,RDS などといった関連ではないリソース間で使いまわされていました.不要なポート開放となるため最低限なポート開放にできるよう1つ目の課題と合わせて解消していく必要があると課題と認識しました.

アーキテクチャの見直しと変更

上記のようなネットワーク設定に起因する課題感からアーキテクチャを見直して変更を加えていきました.

1. プラベートネットワークセグメントの追加

まずはコンピューティングリソースやデータベース郡をプライベートサブネットに移動させたいと思い,サブネットを追加していくことにしました.加えてプライベートサブネットに移動することに伴いインターネットへの疎通のための経路として NAT GatewayVPC エンドポイントを作ってサービス間通信が継続できるような見直しをかけていきました.見直し後の結果のアーキテクチャイメージが下の図になります.これでパブリックにおいていたリソースをプライベートに配置しなおせました.

改善後の AWS 構成イメージ f:id:sadayoshi_tada:20210324185315p:plain

合わせてプライベートサブネットに EC2 も移動したことに伴いこれまでは SSH での接続だったところを Session Manager での接続に全移行しています.また,開発における開発者からのDB への接続は AWS Client VPN 経由でプライベートサブネットの Aurora に繋げるように変更しています.

2. セキュリティグループの作り直しと最適化

セキュリティグループの改善としてサーバーごとにセキュリティグループ定義を作り直して付け直していきました.AWS のサービス間通信はセキュリティグループの ID 同士でインバウンドトラフィックで絞るということもルール化していきました.

改善後の EC2 のインバウンドルールのイメージ

セキュリティグループのインバウンドプロトコル IPアドレス範囲
HTTP sg-xxxxxxxxxxxxxxxx(ELB のセキュリティグループ ID)

3. 変更の伴う箇所におけるルールをドキュメント化

そして,私が変更をかけた部分について考えをドキュメント化して共有するようにしていきました.私の頭の中にあるだけでは今後メンバーが増えた時に変更をかける時に私がボトルネックになってしまって進めるスピードが落ちてしまうのではないかという懸念から考えを文書化していきました.画像は今回の変更に関わるネットワークのルールを書いたページの抜粋部分ですが,これに限らず今後も設計や運用の考えをドキュメント化していきます.

f:id:sadayoshi_tada:20210326111630p:plain

まとめ

ネットワーク設定に関わる課題感から既存本番システムのアーキテクチャ変更に伴う取り組みをまとめました.個人的には DB のサブネット移行と切り替えのタイミングはドキドキが止まらず,終わった後も数日間業務が止まらないかソワソワしていました.この点,予め影響範囲の確認や取り進め方の相談など CTO 三好のサポートがあり危機的な業務停止はなく動いています.この取り組みでネットワーク周りやアーキテクチャの見直しを図れましたが,他にも課題はあるのでカイゼンをしてよりよいシステムの形を目指していきます.

最後に

そんなスナックミーではもりもりコードを改善し、開発していきたいバックエンドエンジニア、テックリードを募集中です。 採用の最新情報はこちらにありますので、ご興味ある方はご確認ください!

engineers.snaq.me

『JAWS DAYS 2021 - re:Connect -』でシステムリリースフローの刷新の取り組みを話してきた

こんにちは!SRE を担当している多田です(@tada_infra).

3/20 開催の「JAWS DAYS 2021 - re:Connect -」にて「スタートアップ企業での散乱したシステムリリースフローをととのえる話」というタイトルでオンライン登壇させていただきました.開発者が安心かつスムーズなリリースフローを作り、開発生産性を向上させたいと言う課題感からリリースフロー刷新に取り組んだお話をしました.この記事で発表を振り返ってきます.

jawsdays2021.jaws-ug.jp

発表資料

発表資料はこちらです.

発表の振り返り

発表した取り組みはリリース周りでまだ仕組み化されてなかったり,複雑になっていることで開発のやりづらさがあるのではないかという課題感や開発サイドへのヒアリングから刷新をしていくことにしました.

改善に向けての取り組みはいくつかの記事でも紹介しておりましたが,GitHub Actions を中心にした形に変えていき,GitHub を見ればリリースに関する設定もわかるし開発者も慣れているツールだから最悪自分がいなくなってもリリースが止まることはないだろうとも思い,採用していきました.また,慣れているからこそ GitHub Actions の処理がうまくいかない時は助言もくれたりしてくれています.

関連記事

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

sadayoshi-tada.hatenablog.com

システムリリースの部分で課題に感じたところの刷新をしていけたのですが,デプロイしているコードの中にはテストが十分に書けてなかったりしてリリースフローに組み込めてなかったり,発表の中で触れたまとまったコマンドスクリプトがうまくいかない事象が発生し始めたので原因究明して改善していかないといけなかったりと課題が残っているのを潰してよりよい仕組みに育てていければと思います.とはいえ,開発者からはいいリアクションをもらっているのはありがたいことです.

質問への回答

発表に対するツイートで反応くださった方ありがとうございました! 拙い発表においてよかったとリアクションをいただけたりして大変ありがたかったです🙇‍♂️ Twitter で質問いただいていたことについて回答させていただきます.

Q. デプロイのスクリプトがサーバーによって異なるのはなぜか?

デプロイスクリプトがサーバーごとに違うことについて質問いただいていました.ヒアリングの時に判明したのがリリースの対象サーバーにコードを git pull する処理やミドルウェアの再起動などといった処理は共通しているのですが,Railsdb:migrate 処理が1台のサーバーだけで実行するようにしているため特定のサーバーのみは処理が現状異なっています.

Q. DB は1つなのか?

今後の改善で別れる場合もあるのですが,DB は現状1つです.

Q. どのタイミングで GitHub Actions を実行しているのか?

GitHub Actions ですが,EC2 のシステムはプルリクマージ後に指定した時間に Run Command を走らせる設定を定義できるように設定していくようにしています.Lambda/Step Functions は2つのタイミングで走っててプルリクが上がってきたタイミングで差分検出した結果を一時的に S3 に入れるのと,マージ後にデプロイする処理が走っています.

まとめ

登壇の振り返りや質問いただいたことを書いてみました.いつもは JAWS DAYS は見るだけな参加を数年続けてきて CFP を出したのは二回目で登壇の機会は初めていただけたので大変ありがたかったです! 登壇者として準備にあたりリハーサルや,配信環境,PR,マイクを送っていただいたりと運営の皆様の手厚いサポートや熱量を非常に感じたイベントでした.また登壇できるように AWS の使い込んで発表していければと思います.ありがとうございました!!

元記事

元記事はこちらです.

最後に

そんなスナックミーではもりもりコードを改善し、開発していきたいバックエンドエンジニア、テックリードを募集中です。 採用の最新情報はこちらにありますので、ご興味ある方はご確認ください!

engineers.snaq.me