こんにちは、ぐるなびWebアプリの予約サービスフロントエンドの芹澤です。
2021年に新卒としてぐるなびに入社し、2年目になります。
ぐるなびでは、定期的にAWSの勉強会や技術共有会などを企画して、開発部全体としてクラウド化を推進しています。
私が所属しているフロントエンドのユニットでもクラウド化を推進していて、これまでにいくつかのオンプレ環境をAWSへ移行しました。
今回はフロントエンド内のレビュー確認時に使う環境をクラウド化したので、そちらを事例として紹介させていただきます。
実際に行ったクラウド化の内容
レビュー者が動作やデザインを確認するためにブランチを落とす手間を省く目的で運用されています。
基本的にはビルドされた静的資材をアップしているだけなので、上の画像のような『S3 + CloudFront + α』というシンプルな構成に落ち着きました。
S3
ビルドされた静的資材を置くためにS3に格納しています。
S3とはAmazon Simple Storage Serviceの略で、データを格納するためのストレージサービスです。今回のようにHTMLやCSS、JavaScriptのみであればS3単体で静的ホスティングサービスとして利用することが可能で、他の用途としてはデータのバックアップ/復元やアーカイブなども利用可能です。
上図の赤点線のように、S3に置いてある静的資材は設定次第ではダイレクトにアクセスできてしまいます。 ですが今回CloudFrontを使用して、S3側でOAI(Origin Access Identity)を利用しているので赤点線の経路は許可せず、緑色のCloudFrontを経由した経路しかアクセスできません。
また、利便性を考えてGit のPush時に自動的にS3へbuild生成物をアップするようにしました。
上図青線の経路のように、User(開発者)がGitLabへPushするとGitLab上のCIが動いてAWS CLIからS3へアップロードされます。
# S3にデプロイ before_script: - export AWS_ACCESS_KEY_ID=$TEST_FRONTEND_AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY=$TEST_FRONTEND_AWS_SECRET_ACCESS_KEY - export AWS_DEFAULT_REGION=$REGION script: - aws s3 rm s3://$S3_BACKET_NAME/$CI_PROJECT_NAME/$CI_COMMIT_BRANCH --recursive --quiet - aws s3 sync ./build s3://$S3_BACKET_NAME/$CI_PROJECT_NAME/$CI_COMMIT_BRANCH --quiet - aws cloudfront create-invalidation --distribution-id $CLOUDFRONT_DISTRIBUTION_ID --paths "/$CI_PROJECT_NAME/*"
CloudFront
S3単体でもウェブサイトエンドポイントとして使用(Webサイトのような運用)することができますが、ウェブサイトエンドポイントとしてS3を使用する場合のみHTTPS通信を使用できません。
(REST APIエンドポイントとして利用した場合には問題なくHTTPS通信が可能です。)
なのでCloudFrontにACM(AWS Certificate Manager)で発行した証明書を設定して解決しています。
ACMを利用することでSSL通信が可能となります。
また、WAFを使うことで社内IPのみのアクセスに限定できるため利用しています。
クラウド化する前の状態
今回のフロントエンド環境クラウド化の目的は、チームのクラウド知識向上が目的でした。
クラウド化する前の私とチームの状態はというと、以下の通りでした。
AWS経験ゼロからのスタート
AWSに対する当初のイメージは、『AWS = バックエンドやインフラが触るもの』という印象があり興味はありませんでした。
(のちにCloudFrontやLambdaなど、フロントエンドでも触る機会のあるサービスがあることを知りました)
それゆえに、会議でAWSの話題があったとしてもAWSサービスの役割はおろか、EC2などのサービス名もわからない状態だったので会議の内容を理解することが難しい状況でした。
チーム内のAWS知識に幅があった
私のいるチームはフロントエンドのみで構成されています。
その中でAWSの知見がある人は少なく、AWSに関するタスクは知見者にアサインされるというサイクルによってチーム内の知識の差は広がっていく一方でした。
そのようなサイクルになってしまった原因として考えられるのが、今まではAWSに関するチーム内のタスクが『緊急性が高い』『重要性が高い』ものばかりで初心者が足を踏み入れにくい印象でした。
クラウド化をして変わったこと
ですが今回は『チーム内で使う開発環境をAWS化する』という、どちらかというと緊急度、重要度ともに低いタスクなのでチーム内のAWS初心者でも手をつけやすいものでした。
具体的には、あまりAWSを触ったことのないメンバーが技術の選定から実装を行い、社内のAWSサポートチームの方たちにセキュリティの観点での構築方法などを教えていただき、実装したものをチームメンバーにレビューしてもらうような体制でした。
そのようにして今回のクラウド化を行ったことによって、以下のような利点がありました。
チーム内のAWS知識の底上げ
前述したとおり、チーム内でAWSに関して知見者と未経験者で知識の差がとてもありましたが、今回知識のあまりないメンバーが主導してクラウド化を行ってその差が縮まりました。
それによって、AWS関連のタスクを固定メンバーに負担させることがある程度緩和されました。
個人としても理解度向上
個人としても、AWSに関する理解が深まり視野が広まりました。
自社サービスの全体像も今まではフロントエンドの範囲しか理解できていませんでしたが、インフラで何がどんな用途で使われているのか理解することができました。
また今回、AWSのさまざまな機能を知ることができ、業務での技術選択の幅が広がりました。
今までは『AWS = バックエンド、インフラが触るもの』という勝手なイメージを持っていましたが、実際に触ってみてフロントエンドが関与した方が良い部分もあることを理解しました。
フロントエンドだからAWSは知らなくても良いのではなく、ある程度周りの知識も入れておくとサービスの全体像を理解しやすく、エラー時の問題範囲切り分けがしやすくなったなど業務に活かす場面も多々ありました。
これからの展望
フロントエンド環境のクラウド化の実装は完了しましたが、運用保守についてはまだ改善すべき点はあります。
現状ブランチ全てをS3上にあげていますが、運用しつつコストを見て対象を絞ることを検討したりCI/CDのフローを見直すことも課題として残っています。
また、インフラ環境をコード化できる AWS CDK でコードを再利用し類似した環境の構築スピードを上げたり、CodePipeline を使ったCI/CDにして他のAWSサービスと連携するなど、運用を効率化できる便利なサービスがいくつかあります。そういったものを活用した改善を行いながら、これからもAWSに触れて行きたいと思っています。