Classi開発者ブログ

教育プラットフォーム「Classi」を開発・運営するClassi株式会社の開発者ブログです。

S3上のログデータをBigQueryにニアリアルタイム連携する基盤を作った話

こんにちは、データプラットフォームチームの鳥山(id: to_lz1)とマイン(id: manhnguyen1998)です。

Classiでは、AWS上にあるサービスが出力したログをBigQueryに連携するプロダクト「Seneka」を開発し*1、社内の開発者・分析者に役立ててもらっています。

ログの連携はこれまでバッチ処理で行っていたのですが、この夏に技術的なチャレンジも兼ねてニアリアルタイムでの連携が出来るように移行しました。そこで、この記事で移行前後の構成と、移行時に気をつけたことについて、紹介できればと思います。

Senekaのそれまでの構成

改善方法を議論する前に、まずは従来の構成について簡単に紹介します。

バッチ処理を軸にしたSenekaの旧構成

  • アプリケーションまたはロードバランサーからS3にログファイルがアップロードされる
  • Cloud Composerで毎時実行されるDAGにより、以下の処理を実行
    • Storage Transfer ServiceでS3からGoogle Cloud Storage(以下、GCS)へデータを転送
    • GCSからStorage Write APIを使ってBigQuery上の一時テーブルにデータをInsert
    • 一時テーブルのデータとデータレイクのテーブルとをマージ

従来の構成が完全に悪いわけではありませんが、毎時定期的に実行されるため、開発者はログの反映まで最大60分程度待つ必要がありました。

この構成のままでも、単純にバッチの実行頻度を上げればリアルタイム性を上げられます。しかし、それまでの作りの関係上、ファイルによっては何度も無駄に取り込みが行われてしまうといった問題がありました。このように、バッチ処理のアプローチのままではコスト面でも実行時間面でも限界があるため、イベントドリブンの構成にチャレンジしてみる価値は十分にあると判断しました。

Senekaの新しい構成

新しい構成は以下のようなものです。

イベントドリブンの処理を軸にしたSenekaの新構成

  • アプリケーションまたはロードバランサーからS3にログファイルがアップロードされる
  • S3にファイルが置かれた時点でPutObjectイベントが発生し、SQSに通知が送られる
  • GCSにファイルが置かれた時点でFinalizedイベントが発行され、それがPub/SubにPublishされる
  • Pub/SubトリガーによってCloud Functions*2が起動される
    • BigQueryへのInsertの方式は従来と同様

結果

ログがBigQueryでクエリできるようになるまで、従来は最大60分程度かかっていましたが、新しい構成では数分でクエリ可能になりました。

今回、効果を正確に把握するために、あるELBの1日分のログを対象に「BigQueryに連携されるまでどれくらいの時間がかかったのか」を集計してみました。

あるELBログがBigQueryに連携されるまでの秒数を示したヒストグラム

上記から、最大6分未満でログが連携される世界になった、と言えそうです。すべてのログを調べたわけではありませんが、ECSサービスを含めた他のいくつかのログに関しても概ね同様の結果となっていました。

また、イベントドリブン化によってコストが増えることもなく、逆に約10%削減することができました。

移行前後のCloud Billing Reportのキャプチャ

21日はリリース前、22日-25日の間は検証期間で一時的にコストが増加しました(後述します)が、チューニング後の26日に本番リリースして以降はコストが削減出来ています。

工夫した点

移行においては以下のようなことを工夫しました。

Design Docによる認識共有

Classiには、Design Docを書く文化があります。

今回の移行で実際に作成したDesign Doc

実装に取りかかる前にしっかりと調査を行い、その調査結果をもとにシステムを設計しました。提案のメリット・デメリットを明確にしたうえで、チーム内で意見を共有し、方針を確定してから実装に移るという流れです。

また、選定する技術については、以下の観点で調査・検討をしました。

サービスごとのクォータ・上限

クラウドサービスにはしばしば上限があります。システムの要求に対して、この上限を超えた場合に問題が生じる可能性があるため、将来的にこの上限を超える可能性があるかどうかを予測してサービスを選びます。例えば、Pub/SubトリガーのCloud Functionsの最大実行時間は9分です。もしこの9分を超える場合にどう対応するかなど、こうした上限を常に考慮しています。

サービスごとのコスト体系や無料枠

これは非常に重要なポイントです。選んだサービスのコストプランがどのようになっているか、また、どのようにコストを削減できるかを検討する必要があります。例えば、Cloud Functionsは月に200万リクエストまでは無料なので、Classiの規模であればイベントドリブンで実装してもコストを抑えることができると判断しました。

段階的な移行

新しい構成へ一度に移行するのはリスクが高いため、段階的に移行を進めました。

まず、検証のためにStaging環境で一部のバケットに対して新しい構成を適用し、影響を確認しました。検証中に、BigQueryのスキャンコストが高くなる現象が起きました。Staging環境でもそれまでと比べて数倍になっており、このまま本番環境に移行すると、1日数TB〜数十TBものスキャンが発生する可能性があると予想しました。

調査の結果、1日あたり24回のバッチからイベントドリブンの処理に移行したことで、テーブルへの書き込み頻度が大幅に増加しており、クエリの数が1日あたり数万件に達することがわかりました。

従来のInsert処理は、Delete -> Insert の流れで行われており、この構成には以下のメリットがありました。

  • データ取り込みの冪等性(Idempotency)を維持できる
  • 既存のファイルが編集された場合でも再取り込みが可能

しかし、レコードをDeleteするときにどうしても走査が発生してしまい、それがスキャン量の高騰の主要因になっていました。今回の要件ではアプリケーションログが取り込み対象であるため、既存のファイルが編集される可能性は極めて低いといえます。レコードが所属するファイルの存在を確認するだけで十分であるため、より単純なInsert処理に移行しても問題ないと結論付けました。

本番環境に適用する際は、データの挿入先をテスト用のデータセットに変更し、旧構成と新構成でデータ内容に差異がないかを確認しました。差分がないことが確認できた後、安全に切り替えを行い、本番環境に移行しました。

段階的に移行を進めた結果、コストの問題や本番環境でしかわからないキャパシティの問題(後述します)にも、焦らず対処できるようになりました。

リリース前後に見つかった課題への対応

段階的に対応を進める中で、スキャン量以外にもいくつか問題が見つかり、さらなる改善が必要でした。

コストチューニング

本番環境でテスト用データセットへの挿入を稼働させた直後、ログの生成頻度が予想以上に高く、コストも非常に高くなってしまいました。先ほどのグラフで発生していたコストの一時的な山は、このときに発生したものです。

移行前後のCloud Billing Reportのキャプチャ(再掲)

分析の結果、以下の3つの問題が見つかりました。

(1) スケーリング不足でリトライが頻発していた問題

最初に設定していたCloud Functionsのスケール上限を超えるリクエストが発生してしまい、リトライが大量発生したためにコストが増大していました。このため、Cloud Functionsのスケール上限を以下の通り増やしました。

  • インスタンスのメモリの使用率はまだ25%程度だったため、同時実行数を2に増やし、1つのインスタンスで2つのリクエストを処理できるようにした
  • 最大インスタンス数を300に拡大した

この対応により、スケールの問題は解決できました。

(2) GCSのClass A操作数が多く課金が増加した問題

Cloud Billingのレポートを見ると、Cloud Storage ClassA OperationというSKUがコストの一因になっていました。

ドキュメントを確認すると、storage.objects.list というAPIの呼び出しがClass A操作に含まれており、コード内で listObjects メソッドを使用していることと関連していそうでした。

そもそも listObjects を使っていたのは、毎時のバッチで処理していた頃には1回の実行で複数のログファイルを処理する可能性があったためです。

今回は既存のコードを Functions Framework でラップすることで開発を省力化していました。そのため、かつて必要だった listObjects を呼び出す処理が残ったままとなり、これが無駄に動き続けていたのです。最終的に、該当の処理を getObject に変更し、無事にコストを削減できました。

(3) Data Lineage APIの課金が増加した問題

Data Lineage は Dataplex の一機能で便利なサービスですが、ログ連携用のプロジェクトにおいてはほとんど使用しておらず、また一時テーブルを大量に作る関係でコストが無視できない水準まで増加していました。利用を止めることで発生するデメリットもなかったため、APIを無効化してコストを削減しました。


上記の対応により、最終的に一日あたりのコストを移行前よりも低く抑えることができました。

メモリリーク解消

リリースしてから4日後、突然「Out Of Memory」というエラーが発生しました。メモリの使用状況を確認したところ、メモリが段階的に増加していることがわかり、メモリリークの問題が考えられました。

メモリリークが発生した当時のメモリ利用状況

Goのpprofを使用してメモリ利用を分析した結果、解放されていないBigQueryのgRPCクライアントが見つかりました。そのクライアントを解放することで問題を解決しました。

リーク箇所の修正リリース以後は、メモリの使用状況やインスタンス台数が安定することを確認できました。

まとめ

以上、アプリケーションログの連携基盤にイベントドリブンの転送を用い、連携速度を大幅に向上させた話をお届けしました。

リアルタイムでログを分析したい、という要望は一般的なもので、これを可能にするソリューションは数多くあります。近い将来では、例えば BigQuery Omni のようなサービスやプロダクトも試す余地があると考えています*3

BigQuery Omni を使用すると、BigLake テーブルを使用して、Amazon Simple Storage Service(Amazon S3)または Azure Blob Storage に保存されたデータに対して BigQuery 分析を実行できます。

BigQuery Omniに限らず、昨今登場してきているサービスは 「そもそもデータ転送をしない」 や、 「自前で仕組みを作る手間が要らない」 という方向性を指向しているように思います。

これは非常に大事な考え方です。データ基盤の開発と運用そのものに工数を使うよりも、貯めたデータを使ってどうやって価値を生み出すかという部分にフォーカスできた方がエンジニア組織としてのインパクトは大きくなるからです。

しかしながら、こうして自前で仕組みを設計・実装・運用することから得られる学びは大きく、そのことがまたインパクトを生み出すための力になるという側面もあるでしょう。

旧来のログ連携基盤による毎時の連携でも、「ものすごく困っている!絶対に数分で連携してほしい!」という声はなかったわけですが、この伸びしろにあえて挑んでみて得られた学びは大きく、また最終的にも成功を収める事ができました。事業インパクトを直接生み出す「攻め」でもなく、データ基盤の安定を図る「守り」でもなく、技術的な新しさを取り入れるチャレンジをする「遊び」として、個人的には非常に良い取り組みだったと思っています。

We are Hiring!

最後に取り上げた「攻めと守り、そして遊び」は、私たちデータプラットフォームチームが属するプラットフォーム部の今期テーマでもあります。

部長であるlacolacoと1on1をしていて出てきたフレーズなのですが、自分もとても気に入っており今季だけと言わずエンジニアリングをするに当たってずっと大切にしたい三要素です。

末筆となりますが、そんな「攻めと守り、そして遊び」の鼎立に挑むエンジニア組織で一緒に働きたい仲間を募集中です!少しでも気になった方は、以下求人からご応募・カジュアル面談の申し込みをお待ちしております。

hrmos.co

*1: Classiのデータ関連システムには、哲学者の名前をつける慣習があります。 ref: https://tech.classi.jp/entry/2021/05/31/120000

*2: Google Cloudから2024-08-22にCloud Run Functionsへのリブランディングが発表されましたが、本記事中では Cloud Functions と呼称します

*3:クエリパフォーマンスの懸念や、Order By句の使用等に関する様々な制限、またそもそもまだ東京リージョンに来ていないといったいろいろな制約から、今回はまだ時期尚早であろうと判断しました

SRE留学体験記(第5期生)

こんにちは、学習PMF部でエンジニアをしている辻です。 私は2023年12月から2024年5月までSRE留学という社内制度を利用して、SREチームに期間限定で所属していました。
SRE留学とは?や、第1期生、2期生、3期生の体験記はこちらをご覧ください。 tech.classi.jp tech.classi.jp tech.classi.jp

留学を志望した理由

SRE留学をする以前は主にCALEというシステムの開発・運用を担当しており、その中でパフォーマンス改善やSLI/SLOの設定、Toil削減などに取り組んだことで、SREに興味を持ちました。
SREの活動に必要なAWSの知識やTerraformの知識、Classi全体のシステムの知識などを獲得して、学習トレーニングやCALEといったシステムでの開発や運用に活かせることを期待しました。また、SREチームに参加することで、単一のチームやシステムに関わるだけでは得られない視点を獲得できるとも考えました。

留学中にできたこと

基本的に、やりたいことをやらせてもらえる環境なので、留学中にしかできないことや学びになることを実施しました。日常的なタスクとして、SRE宛に来るTerraformのレビューや依頼の対応は行っていましたが、私が実施した代表的なタスクを2つ紹介します。

学習トレーニングのSLI/SLOの設定

CALEというシステムのSLI/SLOの設定を行った経験から、学習トレーニングでもSLI/SLOを設定したいと思いました。SRE留学前からSREチームでは学習トレーニングにSLI/SLOを設定することが計画されており、参加させてもらいました。
SREチームのid:ut61zさんと一緒に取り組むことで安心感があり、またSLO本読書会もこのタイミングで開催され、非常に有意義でした。学習トレーニングチームの方々と話し合いながら設定を決め、id:ut61zさんにも多く相談しました。設定後、このSLOの値を基に改善の議論が発生しており、今後もSREチームと連携しながら改善を続けていきたいと思います。

Opsサーバリプレイス

このタスクはチームで行いましたが、私は主にAnsibleの記述、CI/CDの構築、起動方法の設計・実装を担当しました。Opsサーバとはいわゆる踏み台サーバのことで、検証環境、本番環境でなんらかのオペレーションを実行するために利用しています。既存のOpsサーバはitamaeでプロビジョニングされているのですが、Classiではそのリポジトリのメンテナンスが不十分だったり、EC2関連のシステムの関心が入り混じったリポジトリからOpsサーバの関心の分離をしたいという意図があったため、AnsibleとPackerを用いて作り直しました。
既存のOpsサーバでは、起動方法にAuto Scalingグループを使っていましたが、デタッチ忘れやタグの付け忘れ、Opsサーバの消し忘れや立ち上げが手間などの課題がありました。
そのため、新しいOpsサーバの起動方法はChatOpsを採用し、AWS Chatbotを使ってより簡単に立ち上げることができ、管理しやすいようにしました。

ChatOpsの構成図

起動と削除をSlack上で行えるようにしたことで、管理が容易になり、履歴も残るため、既存のOpsサーバでの起動方法の課題も解決しました。
このリプレイスのタスクで学習した許可セットなど、SRE留学中に、普段の業務ではあまり触らないところも触ることができ、勉強になりました。SRE留学から戻った後もこれらの知識は活きてくると思います。

これらのタスク以外にも、構成図の作成、Sandboxリソース作成の通知、GithubActionsの導入、証明書の更新など、SRE留学をしていなければ経験できなかったタスクを多く経験し、多くの学びがありました。

良かったこと

普段の業務では、あまり触れることのない部分に触れた

具体的には以下の機能などです。

  • SCPを含んだAWS Organization
  • IAM Identity Center
  • IR購入に関するあれこれ

SRE留学では、SREチームと同等の権限を持ってSREとして業務を行うので、普段では触れない部分に触れることができるのは、SRE留学の良いところだと思いました。

コードレビューを通してClassiのシステムへの理解とAWS・Terraformの理解が深まった

SREチームの朝会では、SREチーム宛に来たTerraformのプルリクエストをレビューするのですが、その中で出てきたわからないことはその場でSREの方に聞くことができるので、すごく勉強になり、レビューを行う過程で、Classiの全体のサービスやそのシステム構成をある程度把握することができました。
また、留学前は自身のチームの範囲のAWSサービスやそのTerraformコードの部分しか理解していませんでしたが、Classi全体で使われているAWSやTerraformへの理解も深まりました。

難しかったこと

横断的な動きができなかった

留学生の振り返りでよくこの点が挙げられていますが、他のチームから寄せられる質問への対応やプラットフォームに関することに積極的に関わっていくことができませんでした。「こういった場合どうしたらいいですか?」という質問がSRE宛のメンションで来ても、知識が必要ということと、SRE留学生としての立場では意思決定が難しく感じる面があり、あまり関与していくことができませんでした。

今後

ClassiのSREチームはプラットフォーム部のチームなので、直接的なSREingをプロダクトに対して行うというよりはプロダクトチームへのSREingの支援という側面が強いです。留学期間中に特定のプロダクトに対する直接的なSREingはあまりできませんでしたが、プラットフォーム部のSREチームに留学したことで、今まであまり触ってこなかった技術などに触れられてとても充実したSRE留学でした。SRE留学からプロダクトチームへ戻ったときに、その経験を活かし、よりアプリケーションの近くでSREingを実践していき、SREチームと連携しながら取り組んでいきたいと考えています。

詳解Terraform読書会を実施しました

こんにちは。プロダクト本部プラットフォーム部SREチームの id:ut61z です。 SREチームが主体となって書籍『詳解 Terraform 第3版』(以後、詳解Terraform)の読書会を社内で実施しました。

www.oreilly.co.jp

どう進めたか、実施してみた感想や反響、学んだことをご紹介しようと思います。

なお、過去にもSREチームが開催した読書会を実施しているので、よければこちらもご覧ください。

tech.classi.jp

詳解 Terraform 第3版について

詳解TerraformはTerraformについて体系的に学べる一冊で、サンプルコードとともにハンズオン形式でAWSのリソースを構築しながら学ぶことができます。

Terraformの実装方法、操作方法、注意点、特徴など全体像を把握するにはとてもよい書籍だと思います。

全体の構成については以下のようになっています。

  • 1章: 従来のプロビジョニングツールとの違いと、インフラストラクチャを取り巻く環境の遷移とともにツールがどのように移り変わってきたかの紹介から始まり、IaCの利点やなぜTerraformを使うかについて解説がなされます
  • 2章: AWSを用いたハンズオン形式でのTerraformの操作方法・定義の仕方についての紹介パートが続きます。EC2 1台で稼働する素朴なWebサーバ構築から始まり、徐々に周辺リソースを追加していくことで可用性の高いスケーラブルなWebシステムを構築することを目指します。Application Load Balancer、Listener、Listener Rule、Target Group、AutoScaling Group、EC2を用いた基本的な構成のWebシステムを理解することができます
  • 3~7章: TerraformのState、Module、ループや条件分岐など動的なTerraformリソースの記述の仕方など、Terraformに搭載されている様々な機能について紹介され、やや応用的な使い方・記述の仕方について知ることができます
  • 8~9章: 本番環境の構築にあたっての注意点、テストについて紹介されています
  • 10章: チームでTerraformを運用するにあたっての勘所やデプロイワークフローの構築について触れ、組織へTerraformを導入・定着させていくための戦略についても紹介されています

なぜ詳解Terraform読書会を実施したか

ClassiではほとんどすべてのインフラリソースをTerraformで管理していて、SREチームだけでなくプロダクトチームのエンジニアもインフラリソースの構築・運用を行っています。

しかし、エンジニア全員がTerraformを用いたインフラリソース構築経験があるわけではなく、スキルやレベルにばらつきがあるのも事実です。

それを踏まえ、主に下記2点を期待して読書会を実施しました。

  • インフラストラクチャ、Terraformに対してとっつきにくさを感じているエンジニアの心理的ハードルを少しでも下げ、興味を持ってもらうこと
  • エンジニア組織全体のTerraformスキルのボトムアップを図り、より開発効率を上げること

どのように進めたか

週1回のペースで1章ずつ読み進めました。 担当者は1章分の要約と感想を前半30分で発表し、後半30分でその章について参加者全員でディスカッションを行うという形式で読書会を実施しました。

今回の読書会において工夫した点は、SREチームのメンバーが各章のまとめにコメントを加えて、実際のClassiでの運用はどうしているかをコラムとして追加した点が挙げられます。

座学的な読書会にとどめず、実践的にClassiでTerraformを書くならどうすればよいかをイメージしやすいようにし、普段の業務との接続を試みました。

記述したコラムの例

実際にやってみて

あくまで読書会として書籍を読み進めることをスコープとしていたので、主催者としてはAWSにリソースを構築することまでは参加者に強要はしなかったのですが、結果的には参加者の多くが実際に手を動かしてリソースの構築を行い学習を進めていました。

Terraformを触っている参加者であっても、ゼロからインフラリソースを構築する体験は普段の業務ではなかなか味わえないので、ハンズオンを進めながらシンプルなシステム構築を行い、改めてAWSやClassiのシステム構成への理解が深まったという感想もありました。

特に理解が深まった点として挙げられていたのは、Terraformのロックの仕組みや、Stateファイルの位置づけや特徴などについてでした。 「Stateファイルには秘匿すべき情報が平文で書き込まれてしまうので注意すべき」など、これだけは抑えておこうという知識が参加者にインプットされたのも、実務に直結する知識として今後活きてきそうだという感触を得ました。

他にも、Terraformを組織にどのように導入するかについて言及されている章では、新しい技術を組織に提案・導入・定着させていくための戦略が記されていて、Terraformに限らず応用が効きそうだという感想もあり、思わぬ収穫があったメンバーもいたようでした。

一方で、どんな読書会でも起きがちな問題ではありますが、回を重ねるごとに中だるみをして参加者のモチベーションが低下し、参加を見送る機会が増えたという意見もありました。 中間ふりかえりの回を挟んだり、途中で改めて目次を眺めてこの章は実務でどう役立つかなど、現在地の確認をしてモチベーションを維持するなどのアイディアが出ました。

ふりかえりの様子

中だるみを解消するためのアクションとして、今後の読書会に取り入れていきたいです。

SREチームによるコラムも好評で、Classiではこうしているという現状を共有することで、ハンズオン内容が普段触っているリソースやTerraformのソースコードと直結し、読書会の満足度を高めることに貢献できました。

以下に読書会後のアンケート結果を添付します。

参加者にとって有益だったことがうかがえますね。

少し余談になりますが、Classiでは読書会が常に開催されているので、各読書会の知見が集まり、読書会が洗練されていくのを感じました。

今回の読書会も読了後全体を通してのふりかえりを行うことで、どんな学びを得られたかを言語化し、各々の実務にどう接続するかを考える機会を設けることで、もう一歩踏み込んだ学びの機会になったことを実感しています。

フルサイクルエンジニアを目指して

Classiでは、開発から運用まで一環して行えるフルサイクルエンジニア*1であろう、ということをエンジニアの共通認識として持っています。

今回の読書会はその一助になったのではないでしょうか。 改めて、開発から運用までなんでもやりたいという方にとってはとてもよい環境だと感じました。

ピンと来た方がいらっしゃれば、ぜひカジュアル面談等気軽に問い合わせてみていただけるとうれしいです。

hrmos.co

SREチームもメンバー募集中です。こちらもご興味ある方はぜひお問い合わせください。

hrmos.co

最後まで読んでいただきありがとうございました。

なれる!データエンジニア

はじめに

こんにちは。データプラットフォームチームのマイン(id:manhnguyen1998)です。

2024年1月からデータエンジニア留学(第1期)という制度を利用して、データプラットフォームチームに配属されています。第1期生として、このデータエンジニア留学制度について、自分の経験をもとに紹介したいと思います。

データエンジニア制度とは

データエンジニア留学制度は基本的にSRE留学と同じですが、留学先はデータプラットフォームチームです。SRE留学に関する記事はいくつかありますのでご覧ください。

tech.classi.jp tech.classi.jp tech.classi.jp

なぜ留学したのか?

もともとバックエンドエンジニアとしてRailsのアプリケーション開発を行っていましたが、ある時社内のBigQueryでデータを見る機会がありました。どうやってRDSからBigQueryまでデータが反映されるのかに興味を持ち、データエンジニアの仕事に興味を持つようになりました。

その時、データエンジニア留学制度の告知があり、不安もありましたが、チャンスを逃すまいと留学を希望しました。

自分と同じようにデータエンジニアに興味を持っているけれど、不安でチャレンジしない方もいると思います。この記事で「誰でもできるよ!」ということを伝えたいです。

データエンジニアの仕事とは?

データエンジニアの仕事は、データ活用の基盤を作ることです。具体的にはデータの収集、処理、保存、提供などがあります。

Classiでは主に以下のようなことを行います。

  • 他チームのデータ活用の支援、相談、作業依頼

  • 改善活動

また、データエンジニアが使用するツールや技術はBigQuery、dbt、Cloud Composerなどがあります。

他チームのデータ活用の支援、相談、作業依頼

データ基盤は社内の多くのメンバーが利用しており、さまざまな意思決定を支えるシステムとなっています。そのため、データを活用する上で、データ基盤に対してもさまざまな要望があります

  • マーケティングチームは顧客の利用状況を把握するためにダッシュボードを作成したい
  • プロダクトチームがリリースした機能の効果測定をしたいが、方法がわからないので相談したい
  • データサイエンティストがデータ分析のためにデータセットを準備したい
  • データ活用に関するアドバイスやベストプラクティスを共有して欲しい

などの要望です。このような相談に対してエンジニアとして意見を出し、他チームの開発をサポートしていました。

改善活動

データ基盤の改善もデータエンジニアの重要な業務の一つです。データ基盤は膨大なデータを扱うシステムであり、うまく改善しないとデータの提供もできないことがあったり、コストも高くなることがあります。

改善活動として、私が対応したものは以下のようなものがありました。

  • データパイプラインをCloud Composer (Airflow) からdbtに移行する
  • データの品質を監視する環境の整備
  • コスト削減
  • 不要なリソースの削除

留学中にやったこと

BigQueryに抽出されたデータの欠損検知

データ基盤の毎日のデータ抽出には欠損リスクがありますが、欠損がある場合、これまで気付くことができませんでした。そこで、欠損を発見しやすくするための改善に取り組みました。

BigQueryに保存されたテーブルのレコード数の推移の異常を検知し、欠損など急な変化を検知できるようにしました。例えば、特にアクションがないにもかかわらず、レコード数が急激に増減する場合、データの欠損や何らかのミスが発生した可能性があります。逆に、繁忙期におけるデータの推移を監視することで、利用状況を把握することもできます。

Design

開発したSlack通知

通知の例

Tableau

TableのView

ダッシュボード機能のETLのdbtへの移行と改善

ダッシュボード機能のETLは元々Cloud Composerで直接クエリを実行してデータを管理していましたが、管理が難しかったため、dbtに移行しました。dbtに移行することで、データの処理や管理が容易になり、データに関する説明も整理することができました。

この機能は管理職が利用し、学校全体に関する統計情報を閲覧するため、その重要性が非常に高く、データに誤りがあると重大な影響を及ぼす可能性があります。そのため、dbtに切り替える前に、移行前後の差分確認をしっかり行い、慎重に対応しました。しかし、確認不足の部分があり、学校IDをクラスタキーとして使用することを忘れてしまったため、リリース直後に課金が増加してしまいました。この経験から、コストに対する理解を深めることができました。

このコストの問題を認識した上で、ダッシュボード機能のETLを見直す機会があり、毎日のスキャン量を約85%削減することができました。 ダッシュボード機能のクエリでは学校IDをクラスタキーとして使用していました。しかし、クラスタはクエリごとにスキャン量が異なり、効率的な測定が難しいという課題がありました。そこで、調査の結果、学校IDの空間でパーティションを使用することにより、スキャン量を削減することができました

GCPコストの削減

メタデータシステムPlatoをクローズ、dbtに移行

Platoは以前ブログでも紹介したメタデータ管理システムです。

tech.classi.jp

当時、メタデータの普及に重要な功績を残してくれたシステムでしたが、近年では運用コストが上がり、手間も増えたため、別の仕組みに移行するモチベーションがありました。

この対応により運用作業が減少し、毎月のGCPコストも削減することができました。既存のメタデータもdbt docsに移行でき、社内でのdbt docsの存在を改めて認識させることができて良かったです。

dbtに関しては下記の記事をご覧ください

tech.classi.jp

dbt docsの例

dbt docs画面

RedashのCloudSQLのPostgreSQLを9から15にバージョンアップ

データベースのメジャーバージョンアップデートは初めての経験だったので、最初から調査し、ダウンタイムを短くするための計画を立てました。作業自体は非常に勉強になりました。今回は20分以内に作業を終え、ダウンタイムを短く抑えることができてよかったです。

Slackでやり取りました

勉強になったこと

留学中に学んだことは技術に限らず、以下の点が特に勉強になりました。

分析力

データから仮説を立て、それをもとに結論や次のアクションを提案することができました。少しずつですが、分析について学ぶことができました。

チーム間コミュニケーション

留学の目標の一つはチーム間で協力することでした。自分のタスクに関わるだけでなく、SRE、マーケ、開発チームなど他のチームとも関わり、情報共有やコミュニケーションが必要でした。

「how」より「why」の考え方

以前はタスクに直接飛び込むことが多く、その理由がわからないまま適当な解決方法を出すことがありました。今回の留学で、「なぜ」そのタスクが必要なのか、誰がその成果を求めているのかを十分に理解した上で、適切な提案をすることが大切だと学びました。

難しかったこと

知識の広さ

データエンジニアは多くのチームと関わるため、求められるスキルは多岐にわたります。インフラ管理の知識、データ管理の知識、開発スキル、マーケ側とのコミュニケーション能力など、広い範囲で深く理解する必要があります。

横断的な振る舞い、考え方の難しさ

データプラットフォームチームは他のチームをサポートすることが多く、横断的な振る舞いや考え方が求められます。しかし、留学中はチーム課題に集中しすぎて、データエンジニアとして他チームをアドバイスして支援することが難しかったです。

あなたもできる!

データエンジニアは魅力的な仕事ですが、チャレンジも多いです。しかし、難しいからといってできないわけではありません。もともと何もわからなかった自分ができたので、誰でもできると思います。日々の仕事でスキルを磨き、必ず達成できます。

まずは小さなプロジェクトから始めましょう。このアプローチは、少ないリスクで新しいスキルを試し、成長するための確かなステップです。例えば、データエンジニアとして初めてのプロジェクトとして、日々のログデータから特定の指標を抽出するタスクを考えてみましょう。このプロジェクトでは、SQLクエリを使用してデータを加工し、分析結果をダッシュボードで可視化することが目標です。小規模なデータセットと少ないリソースで取り組むことで、自分のアイデアを具体的な成果物に変えるプロセスを学ぶことができます。

さらに、タスクを進めながら、メンターやチームに積極的に質問し、理解を深めましょう。この過程で、ソフトスキルも成長し、データエンジニアとしてのスキルだけでなく、チーム全体での協力や連携能力も養われます。チーム内だけでなく、インフラチームなど他の部門の意見も積極的に取り入れて、より良い成果を目指しましょう。

最後に

データエンジニアというキャリアは挑戦と学びの機会に満ちています。最初は不安でしたが、一歩踏み出すことで多くのスキルと知識を得ることができました。他チームとの協力や支援を通じて自分の成長を実感しています。

データエンジニアを目指す皆さんにも、その一歩を踏み出してほしいと思います。初めは難しく感じるかもしれませんが、挑戦し続けることで必ず成長できます。その過程で得た知識やスキルは、今後のキャリアに大いに役立ちます。

Classiのデータエンジニアに興味を持った方は下記をご覧ください

hrmos.co

Classiのエンジニア2名が RubyKaigi 2024 に参加しました

はじめに

こんにちは、エンジニアの id:kiryuanzu です! 今回の記事は 5月15日(水)から 5月17日(金)の3日間を通して開催された RubyKaigi 2024 の参加レポートです。

rubykaigi.org

弊社からは 2名のエンジニアが参加しました。本記事では各メンバーによる参加レポートをお送りします。

id:kiryuanzu の参加レポート

改めて今回の RubyKaigi 2024 に参加してきた id:kiryuanzu です。
自分自身は学生の頃(2017年)からほぼ毎年参加していますが、弊社のメンバーと参加するのは RubyKaigi 2022 以来で 2年振り 2回目となりました。

tech.classi.jp

前回と同じく初参加のメンバーにもできる限り楽しんでもらえるように意識しつつ、自分もたくさんインプットできるように心がけて過ごすようにしました。

発表の感想

Community-driven RBS repository (pockeさん)

Rubyの型情報を収集するOSSリポジトリである gem_rbs_collection の運用についての発表でした。
GitHub Actions のワークフローの仕組みを使いつつメンテナのレビューに依存しない運用に切り替えていった話について紹介されており、筆者もここ最近の業務で GitHub Actions を使って運用フローの効率化について考えていたため、とても親近感が沸く内容でした。
OSSリポジトリの場合、様々な人がコントリビューターとして関わる際に開発の効率性とセキュリティのリスクの双方を気にしつつ運用フローを考える必要があるのが難しいポイントだなと思いました。

発表が終わった後、早速ワークフローのコードを見に行ったのですが、ワークフロー内で呼び出すスクリプトを全部 Ruby で書いている点に強い Ruby愛を感じました。

github.com

スライド内でも「It uses Ruby scripts Because I love Ruby」と言及されていますね。

Adding Security to Microcontroller Ruby (sylph01さん)

PicoRuby に暗号機能を実装する話についての発表でした。
現地では英語発表で分からない部分も多かったのですが、とても楽しそうに話されている姿が印象に残っていました。その後、るびま(Rubyist Magazine)で日本語版が公開されていて改めて発表の内容について知ることができました。

magazine.rubyist.net

記事中の「Ruby での真のIoT」という表現がかなり印象的で、今後もまだまだやれることがありそうな雰囲気を感じました。

実際の IoT 環境ではこれらの違ったスペックを持つハードウェアは協調して動作させるので、PicoRuby が WiFi に繋がるようになったことで、「Ruby での真の IoT」は現実に近づいたといってよいでしょう。IoT に関するプロトコルは数多く存在しており、これらを PicoRuby で扱えるようにすることで、Ruby での IoT の可能性は広がっていくものと考えられます。このことから、Ruby での IoT は「ブルーオーシャン」であるといえます。コミュニティは皆さんのコントリビュートをお待ちしています。

自分は PicoRuby 自体書いたことがなかったのですが、他の発表でも多く言及されていたトピックの一つで「なんだかみんな楽しそうにやってていいな……」と思い会期終了後にRassberry Pi Pico W を購入しました。
まずは以下の記事を見ながらLチカチャレンジしてみようと思います。(この記事の執筆者の hasumikin さんは PicoRuby/R2P2 の開発者かつ今年の RubyKaigi のスピーカーの方です)

shimane.monstar-lab.com

発表以外で印象に残ったこと

会期中の社外の方々との交流についてはいもりさんのパートでたくさん取り上げているので、id:kiryuanzu のパートでは RubyKaigi に絡めて行われた社内での活動についてピックアップします。

今回の現地参加組はいもりさんと私の2人だけでしたが、社内の Slack で #spot-rubykaigi-2024 チャンネルを作って、会社のメンバーに向けて発表の感想や現地での出来事をその都度発信するようにしました。
今回は現地参加されなかった方々も、発表の解説ツイートや私たちの発言に対して反応してくださり一緒に楽しむことができました。

社内slack での様子

また、今年の4月から株式会社万葉から参画し、tetoru チームで関わってくださっている櫻井さんも RubyKaigi に参加されていました。
イベント直前に社内で企画した予習会では、初参加の人向けの RubyKaigi の楽しみ方についてお話ししていただき、会期中にも交流の機会をたくさん作っていただきました。
会期中は Classi Tシャツも着てくださっていたのが大変嬉しかったです。なんとよく見ると名札の方にも tetoru のロゴを手書きで描いてくださっています。

RubyKaigiが終わってすぐのタイミングで、会期中に印象に残ったことについて語る会も実施しました。
筆者が「パーサーについてみんなどうやってインプットしてるんだろう……」とぼやいた際に、同僚の方から「まずはインタプリタの作り方の第二部まで読むのがおすすめです」とアドバイスをもらい読むことにしました。紙の本を購入したところですが、中々の分厚さにびっくりしています。

(当時の会話をメモした社内esaを一部抜粋)

そのようにして、現地参加組とリモートで見守ってくれたメンバーの間で交流を深めつつ一緒に RubyKaigi の空気感を楽しむことができました。
来年はもっと多くのメンバーに現地参加してもらえるよう社内での発信を続けていきたいです。

いもりの参加レポート

2024年4月に新卒入社したいもりです!

今回、ありがたいことに新卒研修期間中にRubyKaigiへ参加する機会をいただきました。 ところが当時私のRuby学習歴はたったの4日…

そんな人間のレポートとなっています。生暖かい目でご覧ください。

参加しての感想・交流について

第一印象として、とにかく新参者に優しいコミュニティでした!

交流の場として、日中はRubyKaigiで知り合った人と一緒に昼食を食べたり、夜には多くの交流の場が設けられていたのでそちらに参加したりしました。
その場では初学者でも非常に温かく出迎えてくださり「今日の発表は何が印象に残った?」「普段はどんな研修を受けているの?」など、私の目線で会話に加えていただいたことが本当にありがたかったです。

登壇者の方ともお話しする機会に恵まれ、RubyKaigiの沿革や、登壇者ならではの苦労などを話していただきました。
特に「自分が発表している時間の発表を聞きに行きたいんだ!」という一言は忘れられません。

また、私は現在フィヨルドブートキャンプにて研修しているのですが、同じフィヨルド生の方とも交流できました。
研修で使っている『ゼロからわかる Ruby 超入門』の著者であり、Classiの新卒研修の設計に携わられていたigaigaさんとも快くお話ししていただき、サインもいただきました。大事にします!

発表

全体として、登壇者の方々が「この技術はこの方の登壇を聞けばより詳しいことがわかる 」と、他の方の発表を引用し合っているのが非常に印象的でした。

これは本当に素晴らしいことだと思います。Rubyコミッターの方々が互いを知り、また信用していないとできない引用だと思います。 改めてRubyコミュニティの活発さを感じ取った瞬間でした。

ここでは特に印象に残った発表3つについて、簡単ではありますが感想を書かせていただきます。

Writing Weird Code

初日トップバッターのキーノートの登壇です。 正直なところ、この発表がなければ私はRubyKaigiを楽しめていなかったかもしれません。それくらい衝撃的で感銘を受けた発表でした。

内容としては、irbで奇妙なコードを書くというものです。その奇妙さが本当に強烈でした。

これは紹介された一例ですが、irb上でコードのクラゲが泳ぎ、マウスでクリックするとそれに反応して変形するという内容です。

この発表では、この他にも視覚的に楽しむことができる奇妙なコードが合計で6つ用意されており、そのどれもが本当に衝撃的でした。

肝心の実装についての説明はあまりに高度な内容で、会場含め「…?なるほど…ね?」という反応にならざるを得ませんでしたが、irbすごい!これから使っていこう!と思えた発表でした。

Cross-platform mruby on Sega Dreamcast and Nintendo Wii

こちらは1日目午後の登壇でした。内容としては、mrubyを用いてNintendo WiiとDreamcastのクロスプラットフォームを作成するというものでした。

この方の発表はとてもゲーム製品への愛が伝わってくる内容で、ゲームコントローラーがいわゆるスライドポインターの働きをしており、登壇中は軽快にWiiコントローラーを振っていました。また、Tシャツが非常に個性的でした。

この発表で驚いたのは、最初はまた個性的だと思っていた発表スライドが、実は起動したゲーム内でテキストを表示させていたことでした。

発表の後半ではDreamcastを起動していたのですが、先ほどまで見ていた全く同じテキストが、Dreamcastのフォントで表示されていることに気づいた時は鳥肌が立ちました。

Ruby Committers and the World

こちらは3日目最初のRubyコミッター同士の対話形式登壇でした。 内容としては、2日目深夜にRuby3.4.0-preview1がリリースされたこと、そしてこれからのRubyについて議論するという内容で、活発に意見が交わされていました。

この対談で印象的だったのは、コミッターの方が現在検討しているRBSの文法について、参加者がどちらを好むか多数決で世論調査を行ったことでした。
この多数決が将来のRBS文法を決めるものになるかもしれないと思うと、Rubyコミュニティに少し関わることができて嬉しかったです。

また、対談は日本語と英語の二か国語で実施されたのですが、途中からMatzさんによる同時翻訳が始まったのが面白くもあり、非常にありがたかったです。

まとめ

今回、先輩の id:kiryuanzuさんを通して多くのRubyistの方とお話しさせていただきました。貴重な交流の時間、本当にありがとうございました。

また、株式会社万葉から参画しClassiに携わっていただいている櫻井さん、社内から後押ししてくれたClassiメンバーの皆さん、RubyKaigiを運営していただいたスタッフの皆さん、その他ランチや飲み会の場で交流をしていただいた方々に深く御礼申し上げます。

次回は愛媛県松山市開催ということで、関西在住の私にとっては比較的好立地なこともあり、ぜひ参加したいです。

これからもRubyコミュニティに関わっていき、一人前のRubyistを目指します!

おわりに

以上、Classi メンバーの感想レポートをお届けしました! 今回の RubyKaigi での経験を経て普段の業務や趣味の開発を頑張っていこうという気持ちを改めて持てました。

RubyKaigiの翌週には Classiオフィスで開催された shinjuku.rb #92 ではいもりさんが「RubyKaigi 2024 行ってきたレポ」というタイトルでLT発表をされていました。

tech.classi.jp

このように早速コミュニティ活動へと飛び込んでいく姿を見せており、RubyKaigi での経験が後押しになったとしたら嬉しい限りです。

来年の4月には愛媛県松山市で RubyKaigi 2025 が開催されます。その時に向けて日々の生活の中で学びを重ねつつ、今回よりも更に RubyKaigi という非日常の場を楽しめるようになりたいです。

来年もまた RubyKaigi でお会いしましょう!

Strict CSP を Content Security Policy Level 3 に対応したブラウザに絞って適用する

こんにちは、プロダクト本部エンジニアの中村 (kozy4324) です。

現在 Classi が提供している Web サービスでは Content Security Policy を導入しています。その導入時の話は以下の記事で紹介させてもらいました。

今回の記事では、運用を続けていく中でわかったことや出てきた課題、またそれらを踏まえて現在どういった CSP のポリシーで運用を行っているのか紹介します。

オリジンの許可リストをベースにしたポリシー

導入時の記事でも紹介している通り、運用開始時のポリシーは以下のようなものでした。

Content-Security-Policy:
  default-src 'self';
  script-src  example.com 'sha256-xxx' 'nonce-hogehoge111';
  style-src   example2.com 'sha256-yyy';

ベースは ’self’ (文書が提供されたオリジンと同一オリジンのリソースを許可する)とホスト名による許可リスト方式で、特定のインラインコードやインラインスタイルを追加で許可したい場合にハッシュ値や nonce を追加しています。

最初はできる限り厳格な規格に沿ってポリシーを設定、違反レポートを確認しながら必要に応じてポリシーを追加、もしくは無害と判断できるものは無視するという運用ルールとしていました。

出てきた課題1: オリジンの許可リストベースでは攻撃とは見なせない違反レポートが雑多に出てくる

上記ポリシーで運用を始めたところ、すぐに多くの違反レポートが日々あがってくる状況になりました。ところがそのほとんどがブラウザ拡張機能や 3rd party 製の何かによる img や style 、script の挿入に見受けられ、総合的にみて「攻撃とは見なせない」という判断になるものばかりでした。

Sentryに収集された実際の違反レポートの一部

違反レポート自体にはそれほど多くの情報は含まれておらず、頻度やブラウザの分布なども確認しながら一つ一つ丁寧に調査していく必要があります。新しいレポートが発生するたびに調査対応していくと運用負荷は大きなものになっていきました。

Strict CSP をベースにしたポリシーへの変更

オリジンの許可リスト方式で厳密に制限して運用していくのは運用負荷が大きいということが分かりました。また許可リスト方式では CSP バイパスの問題も指摘されています。なので方針を変更し、nonce + strict-dynamic による Strict CSP をベースにしたポリシーとすることにしました。Strict CSP では XSS に対する防御に重点を置き、基本的にはスクリプトに対してのみ制御を行います。XSS に対して効果の薄いスクリプト以外のリソースには制御を行わないため、スクリプト以外で発生する雑多な違反レポートが抑止されることを期待しました。

Strict CSP をベースにしたポリシーは以下のようになります。

Content-Security-Policy:
  object-src 'none';
  script-src 'nonce-{random}' 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' https: http:;
  base-uri   'none';
  report-uri https://your-report-collector.example.com/

この設定内容は、例えば strict-dynamic をサポートしていないブラウザでのフォールバックが含まれています。 Strict CSP のページでも説明がなされていますが、より詳しく整理したものが以下です。

  • CSP Level 3 まで対応しているブラウザの場合
    • 'nonce-{random}' が採用されるので 'unsafe-inline' は無視される
    • 'strict-dynamic' が採用されるので https: http: は無視される
    • よって nonce + strict-dynamic で許可されたスクリプトだけが実行される
  • CSP Level 2 まで対応しているブラウザの場合
    • 'nonce-{random}' が採用されるので 'unsafe-inline' は無視される
    • 'strict-dynamic' が解釈できないので https: http: が採用される
    • よって nonce で許可されたインラインスクリプトと外部スクリプトだけが実行される
    • nonce が付与されないインラインスクリプトは実行が制限される
  • CSP Level 1 まで対応しているブラウザの場合
    • 'nonce-{random}' が解釈できないので 'unsafe-inline' が採用される
    • 'strict-dynamic' が解釈できないので https: http: が採用される
    • CSPによる実行制限はない(保護されない)
  • CSPに対応していないブラウザの場合
    • CSPヘッダは何も作用しない
    • CSPによる実行制限はない(保護されない)

出てきた課題2: Strict CSP ベースでは一部ブラウザで Google Tag Manager による違反レポートが発生する

Classi サービスでは Google Tag Manager を利用している箇所がいくつかあり、Google Tag Manager が動的に追加するスクリプトで違反レポートが発生しました。これは一部のブラウザのみで発生し、確認したところ CSP Level 2 まで対応しているブラウザ、2024年5月時点では iOS 14.x〜15.3 の Mobile Safari が該当しました。Classi サービスにおいてまだ一定数のアクセスがある状態です。

CSP Level 2 まで対応しているブラウザでは strict-dynamic は解釈されないため、動的に追加するスクリプトの実行を許可するには nonce を付与する必要があります。 Google Tag Manager のガイドに nonce 対応バージョンの言及があるので、この nonce 対応バージョンとすることで問題なく CSP の実行許可がなされると思われましたが、一つ落とし穴がありました。Google Tag Manager の「カスタム HTML 」で追加されるスクリプトタグには nonce を付与することができませんでした。補足として Google Tag Manager 上で「 document.write をサポートする」というオプションを有効にすることで nonce を付与することは可能になりますが、 Classi での利用方法的にこのオプションを有効にすることもできませんでした。

CSPで制御されるスクリプトの種類とディレクティブの整理

ここまでに遭遇した課題をうまく回避できる CSP 設定はないものかと思い、スクリプトの種類とディレクティブについて整理をしてみました。

種類 具体例 制御ディレクティブ ‘self’ と host-source による許可 nonce による許可 strict-dynamicによる許可
外部スクリプト <script src="outer.js"></script> script-src-elem できる できる できる
インラインスクリプト <script>alert(1)</script> script-src-elem できない できる できる
インラインイベントハンドラー <a onclick="alert('clicked')">link</a> script-src-attr できない できない できない
JavaScript URL <a href="javascript:void(0);">link</a> script-src-elem できない できない できない

a タグの href 属性に設定する javascript: で始まるスクリプト記述は script-src-attr ではなく script-src-elem で制御されるというのは押さえておきたいポイントです。

またこの整理の中で strict-dynamic 以外に script-src-elem と script-src-attr の両ディレクティブについても CSP Level 3 からの機能であることに気づきました。 CSP Level 3 に対応していないブラウザではこれらのディレクティブは単純に無視されます。

Strict CSP を CSP Level 3 に対応したブラウザに絞って適用する

上記の整理を行うことで、以下の CSP 設定を導き出すことができました。

Content-Security-Policy:
  object-src      'none';
  script-src      'report-sample' 'unsafe-inline' 'unsafe-eval' https: http:;
  script-src-elem 'report-sample' 'nonce-xxxxx' 'strict-dynamic';
  script-src-attr 'report-sample' 'none';
  base-uri        'none';
  report-uri      https://your-report-collector.example.com/;

この設定における整理は以下の通りです。

  • CSP Level 3 まで対応しているブラウザの場合
    • script-src-elem, script-src-attr によって Strict CSP と同等の効果が得られる
  • CSP Level 2 / CSP Level 1 まで対応しているブラウザの場合
    • script-src-elem, script-src-attr は無視され script-src のみが採用される
    • CSP による実行制限はない(保護されない)

Classiの運用ポリシーとしてインラインイベントハンドラーで違反となるスクリプトについては極力インラインスクリプト形式にリファクタリングをするべきとしています。リファクタリングが妥当でない場合と JavaScript URL については unsafe-hashes で許可をすることも認めており、 script-src-elem と script-src-attr の適切な方にそれぞれ hash を追加していくことになります。最終的には以下のような設定例になっていきます。

Content-Security-Policy:
  object-src      'none';
  script-src      'report-sample' 'unsafe-inline' 'unsafe-eval' https: http:;
  script-src-elem 'report-sample' 'nonce-xxxxx' 'strict-dynamic' 'unsafe-hashes' 'sha256-xxxxxx';
  script-src-attr 'report-sample' 'unsafe-hashes' 'sha256-xxxxxx';
  base-uri        'none';
  report-uri      https://your-report-collector.example.com/;

まとめ

この CSP 運用を続けていく中でわかったことは以下の通りです。

  • オリジンの許可リストベースではレポート運用負荷が高くなり、CSP バイパスという問題も含めると費用対効果の観点では微妙と判断せざるを得ない
  • Strict CSP ベースで Google Tag Manager を利用している場合に、一部ブラウザでの違反レポートが抑止できない問題が発生しうる

CSP のディレクティブを整理することで、 CSP Level 3 に対応したブラウザに限定されますが適切な設定方法が見出せました。行き詰まった時は一度立ち止まって仕様や実装状況を整理することも大事だということを痛感しました。

現在、 Strict CSP をベースにした前述のポリシーで数週間運用をしていますが、違反レポートのノイズも少なく運用負荷も気になるレベルではありません。 Report Only で運用をしていましたが、一部ページでは Report Only も解除し、実際に不正なスクリプト実行には CSP によるブロックがかかる状態にも問題なく移行できています。 CSP の適用範囲を広げ、よりセキュリティ強度の高い設定を目指していくのが次の目標です。

今後も CSP に関わる運用が続いていきますので、また共有できる事例があれば紹介したいと思います。読んでいただきありがとうございました。

Shinjuku.rb#92をClassiで開催しました

ソフトウェアエンジニア&Shinjuku.rbオーガナイザーの onigra です。5/31にClassiオフィスにてShinjuku.rbを開催いたしました。足元の悪い中ご参加くださった方々、本当にありがとうございました。

Shinjuku.rb とは、新宿周辺のRuby技術者たちが気軽に集まるコミュニティです。 ミートアップでは一方的な発表のみならず、ディスカッションを通じたインタラクションを大事にしているのが特徴の1つです。

今回の開催にあたり、同じくShinjuku.rbオーガナイザーである yuki3738さんが所属する 株式会社mov様より、フード&ドリンクスポンサーの協賛をいただきました。mov様は先日のRubyKaigi2024でもAfter Party Sponsorを行なっており、お世話になった方も多いと思います。心より感謝申し上げます。

Classiのエンジニアメンバーも設営兼ねて数名参加したのですが、今回、千葉県教育委員会から研修でお越しの小川先生がShinjuku.rbに興味をお持ちでしたので、参加いただきました。現役の学校の先生がプログラミングコミュニティに参加するのは珍しい機会だと思いますので、Classiらしさを出せたと思っています。

また、LTにはClassiメンバーのkozy4324さんと2024年新卒の伊森さんが参加してくれました。伊森さんは新卒らしからぬ小慣れた調子で発表しており、驚きました。

DevTools と デバッグ と 私(kozy4324

RubyKaigi行ってきたよレポ(いもり)

Shinjuku.rbはこれからも新宿界隈のRubyコミュニティを盛り上げていきたいと思います! 次回開催の際は是非お越しください!

© 2020 Classi Corp.