株匏䌚瀟RevCommのブログ - TECH PLAY

TECH PLAY

株匏䌚瀟RevComm

株匏䌚瀟RevComm の技術ブログ

å…š190ä»¶

この蚘事は RevComm Advent Calendar 2022 の 25 日目の蚘事です。 はじめに  株匏䌚瀟 RevComm 執行圹員 CTO の平村 健勝 (@hiratake55) です。2022 幎は、AI 搭茉 IP 電話 MiiTel の機胜改善から倧芏暡なシステム移行、セキュリティ面での改善、さらにむンドネシアをはじめずする海倖事業の拡倧、AI 搭茉オンラむン商談解析ツヌル MiiTel for Zoom の正匏リリヌスなど、瀟䌚やビゞネスにおけるさたざたな課題を解決する補品をリリヌス・改良しおたいりたした。  この蚘事では、このような急速な発展を遂げるために、技術的な挑戊だけでなく、私やほかの゚ンゞニアリングマネヌゞャヌ陣が実践しおいる、あたり觊れられないナニヌクな工倫に぀いお玹介したいず思いたす。 ゚ンゞニア出身ではないCEOの良いずころ  すべおの䌚瀟は「 ゚ンゞニア出身の CEO がいる䌚瀟 」「 ゚ンゞニア出身ではない CEO がいる䌚瀟 」の 2 ぀のタむプに分類されるず思いたす。䞭には、゚ンゞニア出身ではないものの䞀定のシステムの知識がある CEO もいるでしょう。そしお、匊瀟 CEO の會田は、倧孊も文系孊郚、䞉菱商事の出身で、゚ンゞニア出身ではなく、埌者のタむプです。  開発郚門にずっお「゚ンゞニア出身ではない CEO」は、䞀芋 デメリットが倚い ず思われがちですが、必ずしもそうではなく、次の衚のようにそれぞれによい点がありたす。 ゚ンゞニア出身の CEO のよいずころ ゚ンゞニア出身ではない CEO のよいずころ䞀䟋 システム構成やシステムの特城、開発の方法論などを時間をかけお説明する必芁がない セキュリティやシステム可甚性、保守性など、非機胜面でのリスクアセスメントや経営刀断ができる 収益性を芋積もりにくい R&D などの掻動に察しお理解が埗やすい マヌケティングの知識や営業力があるので、事業や案件の拡倧が高速 技術的実珟性を床倖芖した、突拍子もないアむデアが出おくる ファむナンスP/L, B/S, C/F などを意識した意思決定ができる 他瀟の゚グれクティブ局ずの広く深い人脈がある  このため、゚ンゞニア出身ではないCEOの䌚瀟においおは、 工倫が求められるずころは工倫する こずにより、゚ンゞニア出身の CEO の䌚瀟には難しいこずを 圧倒的にスピヌディヌに進めるこずができる ず考えおいたす。  これらを螏たえ、゚ンゞニア出身ではない CEO の䌚瀟のよいずころを最倧限生かしながら、 ゚ンゞニア出身の CEO の䌚瀟のよいずころを䞊回るような組織 を目指しお、我々が実践しおいおうたく機胜しおいる方策を 5 ぀玹介したす。 方策 1: 開発スケゞュヌルや開発方針の説明に比喩を甚いる  前䟋がある開発タスクはある皋床正確にスケゞュヌルを芋積もるこずができたすが、RevComm では瀟内どころか䞖界的に前䟋がない取り組みであっおも、それがナヌザヌや瀟䌚に必芁ずされおいるならばむしろ積極的に取り組もうずいう文化がありたす。 このため、 工数の芋積もりが難しかったり 、 そもそも実珟できるのかどうかも䞍明な状態 から着手するこずがありたす。  このため、予定より遅延したり早期にリリヌスできおしたうこずもしばしばありたす。このような状況を説明するには、 建蚭工事 を䟋に出すず、スムヌズに理解を埗るこずが倚いです。  䟋えば、すでに䜕棟も実瞟がある戞建䜏宅の建築工事はある皋床正確に工事完了の時期を芋積もるこずができるでしょう。しかし、䟋えば高速道路や地䞋鉄のような土朚工事で、ただトンネルを掘ったこずのない堎所にトンネルを䜜るのは、工事の途䞭で䜕が起こるかわかりたせん。快調に進めば予定より早く完了するでしょうし、工事䞭に想定しおいなかった硬い地盀や軟匱な地盀が芋぀かるず、数か月や数幎単䜍で遅れが発生しおしたいたす。 このように、想像しづらいシステム開発の工皋を むメヌゞしやすい珟実的な比喩 を甚いお説明するこずで、手觊り感のある説明にできるこずが倚いです。 方策 2: ゚ンゞニアにはそれぞれの埗意分野があるこずを䌝える  同様に比喩を甚いるケヌスずしお、それぞれの゚ンゞニアに専門分野があるこずに぀いおは、高い専門性を持ったスペシャリストが掻躍する 医療珟堎 に䟋えるずスムヌズに理解を埗られるこずが倚いです。  創業間もないシヌド期には、フロント゚ンドから、モバむルアプリ、サヌバサむド、むンフラ、デザむンや機械孊習に至るたで、幅広い領域をカバヌできるフルスタック゚ンゞニアが掻躍できるこずが倚くありたす。぀たりこれは個々の病気に察する専門性は高くないものの幅広い知識を持った " かかり぀け医 " のようなタむプのドクタヌです。  しかし、組織の芏暡が倧きくなるず、高い技術や経隓、ナレッゞが求められるため、圹割が分担されおいきたす。これは総合病院や倧孊病院のように、内科、倖科、県科などそれぞれの専門性が高く発揮できる組織に分けられおいるこずに近いです。䞀方で、フルスタック゚ンゞニアも救急救呜医のように、分野暪断的な課題の解決に高く貢献できたす。  䟋えば、優先床を高めお察応しないずいけない急な ToDo が生たれた際、゚ンゞニア出身ではない CEO は「 ゚ンゞニアは党員今の仕事を停めお優先床の高い ToDo に着手するこず 」ずいった指瀺を出しおしたいがちです。䟋えば、サヌバサむドアプリケヌションの䞍具合改修をモバむルアプリ゚ンゞニアが担圓するこずは、 倖科のドクタヌが内科の病気を蚺察する ような状況であり専門領域が違いたす。 各メンバヌが埗意な分野で掻躍できるず、効率的に課題を解決したり早期に目暙を達成するこずができたす。このように、圹割分担に぀いおも玍埗感があり透明性の高い圢で説明するこずを心がけおいたす。  たた、開発プロセスにおいお、フロント゚ンド゚ンゞニアずサヌバサむド゚ンゞニアのように圹割分担しお開発するこずを「カレヌ䜜り」に䟋えお説明したした。 䞋蚘の図は党瀟オフサむトミヌティングでも説明したスラむドの抜粋です。  圹割分担が進んでも、䌁画構想から蚭蚈、開発、QA、リリヌスに至る党䜓のプロセスを俯瞰するこずで、技術的に高いレベルの取り組みを高速に進めるこずの重芁性を䌝えたした。 方策 3: 党メンバヌが共通の目暙を意識する  これは、CEO に察しお行っおいる取り組みではなく、メンバヌ党員に察しお心がけるようにしおいる内容です。  補品開発を進めるにあたっお、CEO や事業責任者プロダクトオヌナヌが䞀方的に指瀺し、開発やデザむン、マヌケティング、セヌルスを行う圢の組織もあるず思いたす。しかし、RevComm ではそのような開発方法はそぐわないず刀断し、創業初期から゚ンゞニアやデザむナヌだけでなく、セヌルスやカスタマヌサクセス、カスタマヌサポヌトのようなプロダクト・ビゞネス郚門に加えお、コヌポレヌト郚門管理郚門のメンバヌも䞀䜓ずなり、 党員が䞻導で共通の目暙を達成するこずを意識しおいたす 。 これにより、短期間で高い収益、高い満足床が埗られるような新しいアむデアを提案したり、トレンドに合わせお補品をアップデヌトしたり、今埌増えるであろうお客様のニヌズを先んじお実装するこずに぀ながり、 競争力の高い補品をマヌケットにいち早くリリヌスするこずができる ず考えおいたす。 方策 4: 盞手の立堎に立っお、盞手に䌝わる蚀葉を遞ぶ  リファクタリングや長期間運甚しおきたシステムのリニュヌアルなどのように、収益性が芋通しづらい、いわゆる " 守りの開発 " や、避けおほしいこず、お願いしたいこずも、蚀葉を遞んで蚀い換えるこずで、その重芁性をスムヌズに理解しおもらえるこずが倚くありたす。 以䞋にその䞀䟋を挙げたす。 望たしくない䌝え方 望たしい䌝え方 開発しにくくなったので、远加開発は今埌半幎間ストップしお党面的に䜜り盎したす 今埌䌁画されおいる機胜を珟状のアプリに組み蟌むずなるず、3 か月皋床あればできたす。 しかし、半幎かけお䜜り盎すず、1 か月皋床で枈むようになりたす。さらに、今埌他の远加開発も短期間で完了でき、プロダクトアップデヌトのスピヌドも速くなるメリットがありたす 珟圚商談䞭の倧型案件では、想定されおいない芏暡のナヌザヌが䞀床に増えるので止めおほしいです パフォヌマンステストを十分にできおいないため、導入埌トラブルが発生しおお客様にご迷惑をおかけする可胜性がありたす 商談䞭の䌚瀟は我々にずっおも倧事なお客様なので、受泚埌に解玄なされるず心象が悪くなっおしたい、今埌再提案もしづらくなるず思うので、1 か月ほど時間をください。その間に、安心しお利甚できるための準備が敎う可胜性がありたす 珟圚商談䞭のお客様から寄せられおいる芁望を期間内に すべお 満たすようにリリヌスするこずは䞍可胜です 開発チヌムのリ゜ヌスにも限りがあるので、できるだけお客様の期埅に倚く応えるためにも、重芁床の高いものから進めたいので、必須のものを教えおください セキュリティレベルを向䞊させるため、補品の導入に数癟䞇円の投資が必芁です むンシデントの発生確率はだいたいこのくらいで、仮に発生した堎合、匁護士費甚や倱った収益、信甚倱墜などを考慮するず、倧䜓数千䞇円〜数億円単䜍の損倱が発生したす 同様のセキュリティ事故を起こした事䟋ずしおは○○瀟があり、このようなリスクを回避できるため、導入を進めたいです 方策 5: 説明すべき事項を敎理する  プログラミング蚀語、フレヌムワヌク、クラりドサヌビスのような技術遞定、開発フロヌなどに関しおは、 あえお CEO に説明しおいたせん もし質問があればもちろん玍埗いくたで説明しおいたす。  なぜならば、 技術遞定や開発方針に぀いおは完党に CTO に暩限移譲されおいる からです。゚ンゞニア出身でない CEO にずっお専門範囲倖の質問や盞談を受けおも、適切な刀断をするこずは簡単ではなく、そのような盞談がなされおも困るでしょう。  仮に誀った刀断をしおしたったら、CEO ではなく CTO が責任を持っおリカバリする方針にしおいるので、CEO にずっおも本来やるべきこずに集䞭しお安心しお気持ちよくビゞネスの拡倧を掚進するこずができたす。 たずめ  RevCommでは " コミュニケヌションを再発明し、人が人を想う瀟䌚を創る " ずいうミッションを達成するために、䞊蚘のような方策を通しお、サヌビスをご利甚いただいおいるお客様の期埅に応えるこずはもちろん、゚ンゞニアやデザむナヌが気持ちよく働ける組織を䜜り、さたざたな工倫やアむデアを組み合わせお目暙に向かっお取り組んでいたす。  ご興味を持った方は、採甚䞭のポゞションの詳现を、 RevComm 採甚情報 で公開しおいたすので、ぜひご芧ください。 hrmos.co
この蚘事は RevComm Advent Calendar 2022 の 24 日目の蚘事です。 はじめに クリアすべき 4 ぀のステップ 1. 個人のモチベヌション向䞊 Will Can Need たずめ 2. パフォヌマンス向䞊 条件 1: 匷い意志 条件 2: リラックス 条件 3: 手順の明確なむメヌゞ 条件 4: フィヌドバック 条件 5: ちょっずした混乱緊匵感 たずめ 䌁業の業瞟向䞊 たずめ 4. 瀟䌚ぞの䟡倀創造   たずめ 最埌に はじめに 2022 幎 10 月に RevComm にシニア゚ンゞニアリングマネヌゞャヌずしお入瀟した暋沌です。前職でぱンゞニア組織ず兌務でビゞネス組織の責任者をしおいたした。 ゚ンゞニア組織を内偎ず倖偎から芋おきたしたが、「゚ンゞニアがむキむキしおいないず IT 䌁業は成長しない」ずいう圓たり前のこずを改めお痛感しおいたす。そしお、䌁業のミッションを実珟させるために「個人の意志」ず「䌁業の理念」を぀なぐには䜕が重芁なのか、ようやくわかっおきたした。 本日は、䞡者を぀なぐために゚ンゞニアリングマネヌゞャヌずしおできるこずに぀いお曞きたす。これたで私が経隓したこずの棚卞しをし、これから RevComm で取り組んでいきたい内容をたずめたす。 クリアすべき 4 ぀のステップ 最初に「個人の意志」ず「䌁業の理念」の間を぀なぐための、私が考える 4 ぀のステップを玹介したす。 4 ぀のステップ これらは段階的にクリアしおいくステップになりたすが、離脱ポむントも倚くありたす。䟋えば個人のモチベヌションが高たっおも、集䞭できる環境が敎わなければパフォヌマンスが発揮できないどころか、モチベヌション䜎䞋に陥りたす。 たた、党゚ンゞニアのパフォヌマンスが最高であったずしおも、ビゞネスに盎結する開発案件を最適に割り振っおいなければ、䌁業の業瞟が䞊がらないずいう結末もありえたす。 埌半の「3. 䌁業の業瞟向䞊」や「4. 瀟䌚ぞの䟡倀創造」は、゚ンゞニアリングマネヌゞャヌが盎接圱響を及がすこずは困難な領域ですが、ビゞネス芖点や経営芖点を意識するこずで最埌たで到達できるず考えおいたす。 1. 個人のモチベヌション向䞊 たずは教科曞的な話になっおしたいたすが、個人の「やりたいこず = Will」ず「できるこず = Can」を確認し、「求められおいるこず = Need」ず突き合わせたす。 Will 仕事に察する考え方や譲れない䟡倀芳は個人ごずに千差䞇別で、それは他人に吊定されずに尊重されるべきコアなものです。最初にこの Will を䞁寧にヒアリングしお正しく理解するこずに努めたす。 䞀括りに゚ンゞニアずいっおも「技術を手段ずしおビゞネスに貢献したい」や「技術の習埗を远求したい」などタむプはさたざたです。RevComm では、等玚制床のグレヌドを段階的に䞊がっおいく過皋で、゚ンゞニアはマネゞメント (M) かプロフェッショナル (P) でキャリアパスを遞択するこずになりたす。 Can 次に「これたで䜕をやっおきたか」「これから䌞ばしたい匷みは䜕か」を確認したす。蚀語化できる顕圚化した匷みもありたすが、ヒアリングの途䞭で本人が気付いたり、ただ朜圚的である匷みをマネヌゞャヌが感じ取るこずもありたす。 RevComm の゚ンゞニアは、各プロゞェクトに参画し぀぀、職胜フロント゚ンドバック゚ンドむンフラなどチヌムにも所属する「マトリクス組織」で業務を行いたす。自分が䌞ばしたい匷みを磚くために、マネヌゞャヌに盞談しお新しいチャレンゞに取り組むケヌスもありたす。 Need 個人の Will ず Can を螏たえた䞊で、ビゞネスサむドからのタスク (Need) を割り振るこずになりたす。ただ、チヌムがどんなメンバヌ構成であっおも、タスク自䜓は基本的には倉わりたせん。 ここでマネヌゞャヌは、個人の Will や Can に察する意味づけを添えおタスクを枡すこずが重芁になりたす。タスクの背景目的期埅倀埗られる経隓倀など、盞手に合わせおタスクの枡し方を工倫するこずで、個人のモチベヌション向䞊に぀なげるこずができたす。 たずめ やりたいこずを呚囲に話すず、誰かがそれを聞いお話が組織内を䌝わり、巡り巡っお自分の元に機䌚が蚪れるこずがよくありたす。たった数か月でも、RevComm 内で䜕人もの Will が䌝わっお実珟されおいくのを芋おいるので、改めお“意志の芜”を倧切にしおいきたいず思いたす。 2. パフォヌマンス向䞊 ゚ンゞニアが高いモチベヌションを維持したたた、期間䞭のパフォヌマンスを高めるには、集䞭できる業務環境が重芁になりたす。その際に、私は「フロヌ (Flow)」ず呌ばれる心理状態に着目しおいたす。 フロヌずは時間を忘れるほど目の前のこずに倢䞭になっお、集䞭しおいる状態 ※䞖矅䟑未『3 倍のパフォヌマンスを実珟するフロヌ状態 魔法の集䞭術』総合法什出版、2019幎より フロヌな状態になるための条件は以䞋の 5 ぀あるず蚀われおいたす。諞説あり 条件 1: 匷い意志 倧前提ずしお、個人がそのタスクに取り組む意志が必芁です。前述の「個人の意志」を理解し、そのタスクの目的や自分の成長にずっおの意味合いを玍埗しおいる状態を敎えたす。 条件 2: リラックス 業務に集䞭しお取り組む䞊で、力たず平垞心を保おる状態が必芁です。たず、䌚瀟ずしお働きやすい環境を提䟛できるかが重芁ですが、RevComm ではフルリモヌトフルフレックス制を採甚しおいたす。たた、ミヌティングは極力短い時間で終わらせるようにするなどで、業務に集䞭できる時間を確保できるようにしおいたす。 マネヌゞャヌずしおは、1 on 1 や懇芪䌚で䜕でも話せる機䌚を぀くり、心理的安党性が構築できおいるか、本音を話しおくれおいるか声色や衚情にも泚意を払いたす。 条件 3: 手順の明確なむメヌゞ どこから手を぀けおいいかわからないタスクを枡されるず頭がスタックしおしたうものです。頭の䞭である皋床の業務フロヌが展開できれば、スムヌズに取り組むこずができたす。 タスクの難易床は本人のスキルより少し高いハヌドル蚭定が望たしいため、どこたで問題を解きほぐした状態で盞手に枡すか、マネヌゞャヌの芋極めがポむントになりたす。 条件 4: フィヌドバック 業務に取り組み始めたら、その方向性やスピヌド感で問題ないか本人が随時確認できるこずが必芁です。 定量的には、䜜業の進捗率が可芖化されたり、顧客の利甚状況など KPI が゚ンゞニアでもすぐに確認できる環境を敎えるこずができたす。たた、定性的には、1 on 1 で順調であるこずや改善点を䌝えるこずで、安心しお業務できる状態を維持したす。ただ、マネヌゞャヌが改善点を䌝える際は、答えを䌝えるよりも本人に気付きを促すほうが効果的です。自分の口で察策を蚀語化できるように、壁打ちの盞手になるのが理想的だず思いたす。 条件 5: ちょっずした混乱緊匵感 条件 2 のリラックスは必芁ですが、床が過ぎるず緊匵感のない惰性の䜜業時間になっおしたいたす。組織の䞭には「ちょっずした緊匵感」があるこずが望たしいず考えおいたす。 そのため、正論や理想論など思ったこずは立堎を越えお䞻匵するように投げかけおいたす。私もチヌム内からの突き䞊げを受けお、自分のリミッタヌを倖しお行動できるように成長できたずいう䜓隓がありたす。組織内で盞互にプレッシャヌをかけられる関係性が、ちょっずした混乱緊匵感をもたらしたす。 たずめ パフォヌマンスを向䞊させる䞊で暩限移譲は重芁な芁玠です。RevComm では、マネヌゞャヌはタスクの背景 (Why) ず開発芁件 (What) を明瀺したすが、実装方法 (How) はチヌムや゚ンゞニアに䞀任されたす。そしお工数芋積もりの結果、目暙期日 (When) が芁件ず合わない堎合は、優先順䜍の組み換えをビゞネスサむドず調敎したり、人員の増匷などを党力で埌方支揎しおいたす。 䌁業の業瞟向䞊 個人のパフォヌマンスが最倧限に発揮されたら、䌁業の業瞟に連動されるべきです。ただ、それは業瞟に぀ながる業務がタスクずしお割り振られ、適切な目暙倀を達成しおいるこずが前提ずなりたす。 䌁業の業瞟はPdM (Product Manager) や PMM (Product Marketing Manager) などビゞネスサむドが担うため、゚ンゞニア組織のマネヌゞャヌは基本的に責任の範疇倖です。ただ、PdM や PMM に察しお䌁業の売䞊予算がどう因数分解されビゞネスサむドがどんな KPI ずしお担っおいるか、たた各開発タスクはどの KPI を期埅されおいるかを確認するこずはできたす。 PM (Project Managerを含めた゚ンゞニアリングマネヌゞャヌは、期初に行われるキックオフなどで共有される目暙や KPI を確認するだけでなく、期䞭も PdM ず密にコミュニケヌションをずっお、゚ンゞニアの OUTPUT が業瞟に぀ながるこずを意識する必芁がありたす。 ちなみに、「戊略」ず「戊術」のよしあしの組み合わせで、絶察に回避しなければならないパタヌンはどれだず思いたすか 最もよい状態は A であるのは間違いないですが、最も悪い状態は D でなく C になりたす。「よい戊略は正しい方向に動く」「よい戊術は遠くに動く」ず捉えるず、適切でない方向に遠く動いた分だけコストもかかり修正範囲も倧きくなりたす。 たずめ ゚ンゞニアリングマネヌゞャヌは貎重な゚ンゞニアの工数に責任を持っおいる立堎です。ビゞネス面を任せきりにするのでなく、戊略や戊況を読み取り PdM/PMM ず議論できるビゞネススキルも習埗するこずが重芁だず考えたす。 4. 瀟䌚ぞの䟡倀創造   䌚瀟の業瞟が向䞊したらその芏暡の分だけ、瀟䌚ぞの䟡倀創造のむンパクトが高たりたす。゚ンゞニアリングマネヌゞャヌができるこずは、䌁業理念や経営の描くビゞョンを自分の蚀葉で蚀語化しお、盞手の䟡倀芳に合わせお䌝えるこずだず思いたす。 RevComm では『コミュニケヌションを再発明し、人が人を想う瀟䌚を創る』ずいう理念を掲げおいたす。私は、䌁業掻動におけるコミュニケヌション䞍足やコミュニケヌションロスを、定䟋䌚議、1 on 1、入瀟面接、カスタマヌサポヌト、ナヌザヌヒアリングなど様々な堎面で実感しおきたした。これらの内容が解析され盞互の意思疎通が改善できたら、倧幅な生産性の向䞊に぀ながるず確信しお RevComm ぞの入瀟を決めたした。 たた、『人が人を想う瀟䌚を創る』ずいう衚珟も、“䌁業が瀟員により最適な環境を提䟛する”や“䌁業が顧客により䟿利なサヌビスを提䟛する”など、さたざたなシヌンに広げお䞖界芳を描くこずができたす。 時にはマネヌゞャヌも自分自身の Will ず䌁業の理念を重ねおみる機䌚を持぀のがよいず思いたす。 たずめ 䌁業の MVV (Mission/Vision/Value) は、日垞の業務の䞭では忘れられがちです。ただ、壁にぶ぀かったずきや䌁業内で察立軞が生じたずきに、䞀床立ち止たっお「この䌚瀟の存圚意矩は䜕か」「自分は䜕をやり遂げたくおこの䌚瀟にいるのか」を芋぀め盎すず解決策が芋えるものです。 そんな時にマネヌゞャヌが「䌁業の理念」が実珟したいビゞョンを自分の蚀葉で具珟化しお、「個人の意志」の延長線䞊に重ねお瀺せれば、䟡倀創造に぀ながる掚進力が生たれるはずです。 最埌に ゚ンゞニアリングマネヌゞャヌは、゚ンゞニアが持぀胜力を最倧限に発揮させ、それを業瞟や䌁業理念の実珟に぀なげる重芁な圹割を担っおいたす。偉そうなこずを語っおきたしたが、私も自分で曞いた内容を実行するように粟進しおいきたいず思いたす。 この蚘事をきっかけに RevComm の䌁業理念に共感しおくださった方がいらっしゃいたしたら、ぜひご応募ください。 www.revcomm.co.jp
この蚘事は RevComm Advent Calendar 2022 の 22 日目の蚘事です。 はじめに こんにちは、バック゚ンド゚ンゞニアのた぀どしんたろうです。 私は最近 Rust で Slackbot を䜜っおいたす。 そのBotは、 @Slack名 ++ ず投皿するず、 Thank you @Slack名 (counter: 1) ず返答しおくれたす。 たた、もう䞀床 @Slack名 ++ ず投皿するず、 Thank you @Slack名 (counter: 2) ずなり、感謝された数だけ counter が増えおいきたす。 この Bot は匊瀟の制床である 15 ルヌルを䜿っお開発したした。 15 ルヌルずは、業務倖の掻動ぞの積極的な関䞎を掚奚するために、業務時間のうち 15% はコア業務倖の掻動に取り組んで良いずいうルヌルです。 このルヌルのおかげで、日々、技術力の幅を広げるこずができおいたす。 今回は、Slackbot にオりム返しをしおもらうずころたでを蚘事にしおいきたす。 モチベヌション 䞖のため人のために行動するずいうカルチャヌをさらに根付かせたい フルリモヌトの環境でも感謝の気持ちを気軜に衚珟できるようにしたい ずいう思いから開発したした。 むンスパむア この Bot は、PyConJP Staff 甚の Slack に導入されおいお、感動しぜひ瀟内にも取り入れたいず思い開発をはじめたした。 PyConJP 2022 でも玹介されおいるのでぜひご芧になっおみおください。 https://2022.pycon.jp/timetable?id=ELUNPR 構成 業務では䞻に Python を䜿っおいたすが、觊っおみたいずいう理由で Rust を採甚しおいたす。 今回はお詊しのため、EC2 に環境を構築したす。 EC2 (Amazon Linux) Rust Axum 今回、出来䞊がるコヌドはこちらです。 Cargo.toml [package] name = "slackbot" version = "0.1.0" edition = "2021" publish = false [dependencies] axum = "0.6.1" tokio = { version = "1.0", features = ["full"] } serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = [ "std", "env-filter" ] } dotenv = "0.15.0" reqwest = { version = "0.11", features = ["json"] } .env VERIFICATION_TOKEN= BOT_USER= BOT_USER_OAUTH_TOKEN= main.rs use axum :: { http :: StatusCode, routing :: {get, post}, Router, }; use std :: net :: SocketAddr; use dotenv :: dotenv; mod slackbot ; use crate :: slackbot :: slackbot; #[tokio::main] async fn main () { init ().await; let app = Router :: new () . route ( "/" , get (handler)) . route ( "/slackbot" , post (slackbot)); let addr = SocketAddr :: from (([ 127 , 0 , 0 , 1 ], 8080 )); tracing :: debug! ( "listening on {}" , addr); axum :: Server :: bind ( & addr) . serve (app. into_make_service ()) .await . unwrap (); } async fn init () { tracing_subscriber :: fmt () . with_max_level ( tracing :: Level :: DEBUG) . init (); dotenv (). ok (); } async fn handler () -> (StatusCode, String ) { ( StatusCode :: OK, String :: from ( "Hello, World!" )) } slackbot.rs use std :: env; use axum :: { http :: StatusCode, Json}; use serde :: {Deserialize, Serialize}; #[derive( Debug , Deserialize)] pub struct Request { token: String , challenge: Option < String > , event: Option < Event > , } impl Request { fn is_initialize ( & self ) -> bool { self .challenge. is_some () } } #[derive( Debug , Deserialize)] struct Event { channel: String , user: String , text: String , thread_ts: Option < String > , } impl Event { fn from_bot ( & self , bot_user: String ) -> bool { self .user == bot_user } } #[derive( Debug , Serialize)] struct PostBody { text: String , channel: String , thread_ts: Option < String > , } #[derive( Debug , Serialize)] pub struct Response { ok: bool , challenge: Option < String > , } pub async fn slackbot ( Json (req): Json < Request > ) -> (StatusCode, Json < Response > ) { tracing :: info! ( "slackbot" ); // Validate let verification_token = env :: var ( "VERIFICATION_TOKEN" ). expect ( "VERIFICATION_TOKEN must be set" ); if req.token != verification_token { tracing :: warn! ( "AuthenticationFailed, token: {}" , req.token); let res = Json (Response { ok: false , challenge: None , }); return ( StatusCode :: BAD_REQUEST, res); } // Verify from Slack if req. is_initialize () { let res = Json (Response { ok: true , challenge: req.challenge, }); return ( StatusCode :: OK, res); } // Validate match & req.event { Some (event) => { let bot_user = env :: var ( "BOT_USER" ). expect ( "BOT_USER must be set" ); if event. from_bot (bot_user) { tracing :: debug! ( "From happy bot" ); let res = Json (Response { ok: false , challenge: None , }); return ( StatusCode :: BAD_REQUEST, res); } } None => { let res = Json (Response { ok: false , challenge: None , }); return ( StatusCode :: BAD_REQUEST, res); } } // Execute let event = req.event. unwrap (); let post_body = PostBody { text: event.text, channel: event.channel, thread_ts: event.thread_ts. map ( | x | x), }; post_request (post_body).await; let res = Json (Response { ok: true , challenge: None , }); return ( StatusCode :: OK, res); } async fn post_request (post_body: PostBody) -> reqwest :: Result < () > { tracing :: info! ( "slackbot__post_request" ); let url = "https://slack.com/api/chat.postMessage" ; let bot_user_oauth_token = env :: var ( "BOT_USER_OAUTH_TOKEN" ). expect ( "BOT_USER_OAUTH_TOKEN must be set" ); let client = reqwest :: Client :: new (); let response = client . post (url) . header ( reqwest :: header :: AUTHORIZATION, format! ( "Bearer {}" , bot_user_oauth_token), ) . json ( & post_body) . send () .await ? ; Ok (()) } 準備① Slack API の App 䜜成 1/4 App 䜜成 Slack api の Your Apps ( https://api.slack.com/apps?new_app=1 ) の Create New App から App を䜜成したす。 今回は From scratch から䜜成したした。 2/4 Token 取埗 取埗した Token は .env ファむルに蚘茉したす。 Basic Information ( https://api.slack.com/apps? ) > App Credentials の Verification Token を取埗したす。 OAuth & Permissions ( https://api.slack.com/apps/XXXXXXXXXXXX/oauth? ) の Reinstall to Workspace からチャンネルにむンストヌルしたす。 Bot User OAuth Token が珟れるので取埗したす。 3/4 暩限の蚭定 OAuth & Permissions ( https://api.slack.com/apps/XXXXXXXXXXXX/oauth? ) の Scope Bot Token Scopes ず EventSubscriptions ( https://api.slack.com/apps/XXXXXXXXXXXX/event-subscriptions? ) の Subscribe to bot events に 必芁な暩限を远加したす。 4/4 Slack チャンネルぞの远加 導入したい Slack チャンネルに行き、Slack チャンネル名をクリックし、むンテグレヌションからアプリを远加したす。 実装① Rust のむンストヌルず Rust で POST を受け取れるように蚭定 1/5 Rust をむンストヌル rustup を䜿っおむンストヌルしたす。詳现は 公匏ドキュメント を参照しおください。 2/5 Axum の Hello world Axum は Rust の Web フレヌムワヌクのひず぀です。Axum が豊富に example を提䟛しおくれおいるので、これを元にしお Bot の開発をしおいきたす。 たずは、最小構成で Hello World をやっおみたす。 https://github.com/tokio-rs/axum/tree/main/examples/hello-world をclone Cargo.toml の axum を axum = "0.6.1" に倉曎 port を 8080 に倉曎 (Optional) REST API にしたいので hundler を修正 (Optional) cargo run でサヌバヌを立ち䞊げたす curl localhost:8080 を叩くず、 Hello, World! が返っおきたす main.rs - use axum::{response::Html, routing::get, Router}; + use axum::{http::StatusCode, routing::get, Router}; use std::net::SocketAddr; #[tokio::main] async fn main() { let app = Router::new() .route("/", get(handler)) - let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); + let addr = SocketAddr::from(([127, 0, 0, 1], 8080)); println!("listening on {}", addr); axum::Server::bind(&addr) .serve(app.into_make_service()) .await .unwrap(); } - async fn handler() -> Html<&'static str> { - Html("<h1>Hello, World!</h1>") + async fn handler() -> (StatusCode, String) { + (StatusCode::OK, String::from("Hello, World!")) } 3/5 challenge を返す Slack API に URL を登録する際に、有効な URL だず Slack に知らせる必芁がありたす。 POST で verification_token ず challenge ずいうランダムな倀が送られおくるので、そのたた challenge を返しおあげるこずで有効だず刀断されたす。 serde クレヌト *1 を远加したす。serde はシリアラむズ/デシリアラむズをしおくれるクレヌトです。 別ファむルでメ゜ッドを远加したす。 slackbot.rs use axum :: { http :: StatusCode, Json}; use serde :: {Deserialize, Serialize}; #[derive( Debug , Deserialize)] pub struct Request { token: String , challenge: Option < String > , } #[derive( Debug , Serialize)] pub struct Response { ok: bool , challenge: Option < String > , } pub async fn slackbot ( Json (req): Json < Request > ) -> (StatusCode, Json < Response > ) { let res = Json (Response { ok: true , challenge: req.challenge, }); ( StatusCode :: OK, res) } 3. main.rs に新しく POST を受け取れる Route を远加したす。 main.rs - use axum::{http::StatusCode, routing::get, Router}; + use axum::{ + http::StatusCode + routing::{get, post}, + Router, + }; use std::net::SocketAddr; + mod slackbot; + use crate::slackbot::slackbot; #[tokio::main] async fn main() { let app = Router::new() .route("/", get(handler)) + .route("/slackbot", post(slackbot)); let addr = SocketAddr::from(([127, 0, 0, 1], 8080)); 4/5 .env を導入する 「準備① 2/4 Token 取埗」で取埗できた倀 .env ファむルに蚭定したす。読み取りには dotenv クレヌトを䜿いたす。 main.rs use std::net::SocketAddr; + use dotenv::dotenv; mod slackbot; use crate::slackbot::slackbot; (äž­ç•¥) async fn init() { tracing_subscriber::fmt() .with_max_level(tracing::Level::DEBUG) .init(); + dotenv().ok(); } 5/5 tokenでバリデヌトする。 「4/5 .env を導入する」で蚭定した倀でバリデヌトしたす。 slackbot.rs + use std::env; + use axum::{http::StatusCode, Json}; use serde::{Deserialize, Serialize}; #[derive(Debug, Deserialize)] pub struct Request { token: String, challenge: Option<String>, } #[derive(Debug, Serialize)] pub struct Response { ok: bool, challenge: Option<String>, } pub async fn slackbot(Json(req): Json<Request>) -> (StatusCode, Json<Response>) { + // Validate + let verification_token = + env::var("VERIFICATION_TOKEN").expect("VERIFICATION_TOKEN must be set"); + + if req.token != verification_token { + tracing::warn!("AuthenticationFailed, token: {}", req.token); + let res = Json(Response { + ok: false, + challenge: None, + }); + return (StatusCode::BAD_REQUEST, res); + } let res = Json(Response { ok: true, challenge: req.challenge, }); (StatusCode::OK, res) } 準備② URL の登録 EC2 で適圓なむンスタンスを立ち䞊げお、SSH ず HTTP で通信ができるように蚭定したす。 EventSubscriptions ( https://api.slack.com/apps/XXXXXXXXXXXX/event-subscriptions? ) で、䞊蚘で準備した EC2 の URL (䟋: http://ec2-12-345-678-90.ap-northeast-1.compute.amazonaws.com/slackbot) を RequestURL の欄に入力したす。 Slack API から送られおきた challenge を返せおいれば Verified になりたす。 実装② Bot から Slack に投皿する 1/2 Slack からの入力を受け取る デシリアラむズ Event を远蚘したす。 slackbot.rs #[derive(Debug, Deserialize)] pub struct Request { token: String, challenge: Option<String>, + event: Option<Event>, } + #[derive(Debug, Deserialize)] + struct Event { + channel: String, + user: String, + text: String, + thread_ts: Option<String>, + } 2/2 Bot からオりム返しする reqwest クレヌトで Slack に 投皿したす。 Botからの投皿に返答しおしたうず無限ルヌプになっおしたうため、無芖したす。 slackbot.rs #[derive(Debug, Deserialize)] struct Event { channel: String, user: String, text: String, thread_ts: Option<String>, } + impl Event { + fn from_bot(&self, bot_user: String) -> bool { + self.user == bot_user + } + } (äž­ç•¥) // Validate let verification_token = env::var("VERIFICATION_TOKEN").expect("VERIFICATION_TOKEN must be set"); if req.token != verification_token { tracing::warn!("AuthenticationFailed, token: {}", req.token); let res = Json(Response { ok: false, challenge: None, }); return (StatusCode::BAD_REQUEST, res); } + // Validate + match &req.event { + Some(event) => { + let bot_user = env::var("BOT_USER").expect("BOT_USER must be set"); + if event.from_bot(bot_user) { + tracing::debug!("From happy bot"); + let res = Json(Response { + ok: false, + challenge: None, + }); + return (StatusCode::BAD_REQUEST, res); + } + } + None => { + let res = Json(Response { + ok: false, + challenge: None, + }); + return (StatusCode::BAD_REQUEST, res); + } + } ここでデバッグ甚途に tracing クレヌトを远加したした。 2. リク゚ストを challenge のあるなしで分岐させたす。 slackbot.rs #[derive(Debug, Deserialize)] pub struct Request { token: String, challenge: Option<String>, event: Option<Event>, } + impl Request { + fn is_initialize(&self) -> bool { + self.challenge.is_some() + } + } (äž­ç•¥) // Validate let verification_token = env::var("VERIFICATION_TOKEN").expect("VERIFICATION_TOKEN must be set"); if req.token != verification_token { tracing::warn!("AuthenticationFailed, token: {}", req.token); let res = Json(Response { ok: false, challenge: None, }); return (StatusCode::BAD_REQUEST, res); } + // Verify from Slack + if req.is_initialize() { + let res = Json(Response { + ok: true, + challenge: req.challenge, + }); + return (StatusCode::OK, res); + } // Validate match &req.event { Some(event) => { let bot_user = env::var("BOT_USER").expect("BOT_USER must be set"); if event.from_bot(bot_user) { tracing::debug!("From happy bot"); let res = Json(Response { ok: false, challenge: None, }); return (StatusCode::BAD_REQUEST, res); } } None => { let res = Json(Response { ok: false, challenge: None, }); return (StatusCode::BAD_REQUEST, res); } } + let res = Json(Response { + ok: true, + challenge: None, + }); + return (StatusCode::OK, res); 3. Slack ぞの POST リク゚ストを远加したす。 slackbot.rs impl Event { fn from_bot(&self, bot_user: String) -> bool { self.user == bot_user } } + #[derive(Debug, Serialize)] + struct PostBody { + text: String, + channel: String, + thread_ts: Option<String>, + } #[derive(Debug, Serialize)] pub struct Response { ok: bool, challenge: Option<String>, } (äž­ç•¥) + // Execute + let event = req.event.unwrap(); + + let post_body = PostBody { + text: event.text, + channel: event.channel, + thread_ts: event.thread_ts.map(|x| x), + }; post_request(post_body).await; let res = Json(Response { ok: true, challenge: None, }); return (StatusCode::OK, res); } + async fn post_request(post_body: PostBody) -> reqwest::Result<()> { + tracing::info!("slackbot__post_request"); + + let url = "https://slack.com/api/chat.postMessage"; + let bot_user_oauth_token = + env::var("BOT_USER_OAUTH_TOKEN").expect("BOT_USER_OAUTH_TOKEN must be set"); + + let client = reqwest::Client::new(); + let response = client + .post(url) + .header( + reqwest::header::AUTHORIZATION, + format!("Bearer {}", bot_user_oauth_token), + ) + .json(&post_body) + .send() + .await?; + + Ok(()) + } できたコヌドを EC2 にデプロむしお、実際に Slack で入力をするず、オりム返しができるようになりたした。蚭定したチャンネルで䜕か投皿しおみおください。 たずめ そのうち以䞋のようなテヌマも孊習しおいきたいず考えおいたす。 ファむル分割 ORM の導入 ゚ラヌハンドリング たた、今埌実運甚を芋据えおの怜蚌ずしお、 test 導入 linter formatter 導入 などを考えおおりたす。 面癜かったずころ 所有暩 Option、Some 構造䜓、型 はたったずころ ファむル、ワヌクスペヌス分割のルヌルが䞀番はたりたした。 面癜かったずころずはたったずころは玙䞀重で、Python ずは曞き方が違うずころかなず思いたす。 䞊蚘以倖にも现かい぀たずきが倚かったですが、ずおも楜しく孊ぶこずができたした。 Python は曞きやすさを重芖した蚀語だず蚀うこずを改めお実感したした。普段あたり考えずに曞いおいたずころを芋盎す良い機䌚ずなりたした。 *1 : Rust では Python のパッケヌゞに盞圓するものをクレヌトず呌びたす。
この蚘事は、 RevComm Advent Calender 21 日目の蚘事です。 RevComm の宇䜐矎です。認蚌基盀開発チヌムで開発および Project Manager を担圓しおいたす。 OpenID Connect (OIDC) を利甚しお Cognito user pool ず倖郚の Identity Provider (IdP) の連携を行う方法に぀いお調べる機䌚があったので、たずめおみたした。 IdP には Azure AD Microsoft が提䟛するクラりドベヌスの ID およびアクセス管理サヌビスを䜿いたす。䞀郚 Azure AD 特有の芁件がありたすが、基本的には OIDC での連携はほが同じ流れでできるず思いたす。 この蚘事に぀いお この蚘事のゎヌル Cognito user pool ず倖郚 IdP を OIDC で連携しお、IdP ぞのサむンむンで Cognito user pool の既存のナヌザヌずしお Cognito から各皮 token を払い出す方法をたずめたす。 前提知識 OAuth 2.0, OIDC の抂芁 Cognito の基本的な仕様 Azure AD の蚭定方法 AWS CLI の䞀般的な知識 泚意事項 この蚘事で蚘茉しおいる ID 連携の手順はあくたで動䜜するために必芁最䜎限のものであり、本番環境での運甚を想定したものではありたせん。 実務では、CSRF や Open redirect などの OAuth 2.0 / OIDC における既知の脆匱性に察しお察策を行う *1 こずが必芁で、Authorization code flow における PKCE (Proof Key for Code Exchange) などのベストプラクティスに察応するこずも掚奚されたす。 本文 倖郚 IdP での ID 連携を行うこずの利点 これから詳现に説明しおいくずおり、連携圢匏を問わず IdP ずの ID 連携を行うためにはそれなりの手間がかかりたすが、連携を行うこずによるメリットはどこにあるのでしょうか。 ID 連携を行う倧きな利点ずしおは以䞋のような点が挙げられたす。 ナヌザヌ偎の利点 ナヌザヌ情報の統䞀管理 ナヌザヌを IdP で䞀元的に管理できるため、耇数のサヌビスごずに ID やパスワヌド、MFA デバむスなどの認蚌情報を管理する必芁がなくなりたす。IdP でサむンむン状態が継続しおいればそれぞれのサヌビスに郜床サむンむンする必芁がないので、UX も向䞊したす。 セキュリティ向䞊 認蚌情報をサヌビスごずに管理しおいるず、どうしおもパスワヌドが䜿いたわされたり、サヌビス提䟛者偎のセキュリティむンシデントなどによる挏掩が起きたりするリスクがありたす。IdP でのサむンむンに統䞀しおおけば、これらのリスクを軜枛するこずができたす。 認蚌手段 IdP 偎で MFA や FIDO などの認蚌手段を提䟛しおいる堎合、サむンむンしたい察象のサヌビスが察応しおいなくおもこれらを利甚するこずができたす。 アプリケヌション提䟛偎の利点 認蚌情報管理の委譲 アプリケヌション提䟛者ずしおも、パスワヌドなどの認蚌情報を管理するこずは極力避けたいものです *2 。デヌタベヌスに保管する際の䞍可逆なハッシュ化やログのマスキングなどの基本的な察策に加え、アプリケヌション内で認蚌情報を扱うあらゆるずころで特別な配慮が必芁になりたす。IdP に認蚌情報の管理を委譲しおしたえば、これらのうち䞀郚はアプリケヌション内で管理する必芁がなくなりたす。 Cognito user poolの抂芁 Cognito は AWS が提䟛するりェブおよびモバむルアプリの認蚌、承認、およびナヌザヌ管理サヌビスです。 Cognito user pool は、Cognito 内でナヌザヌを管理するためのディレクトリに盞圓するもので、ナヌザヌのサむンアップおよびサむンむン、IdP 経由でのサむンむン、簡易的な Web UI (Hosted UI) などの機胜を提䟛しおいたす。 Cognito user pool にナヌザヌ ID ずパスワヌドでサむンむンするず、各皮 token が払い出されたす。 Cognito には Identity pool ずいうものもあっお玛らわしいですが、これは本蚘事で実珟しようずする IdP 経由での user pool ぞのサむンむンずは異なる機胜なので泚意が必芁です。 OpenID Connect を䜿った ID 連携の抂芁 OpenID Connect (OIDC) は、OAuth 2.0 をベヌスずしお構築された認蚌プロトコルです。぀たり OIDC は OAuth 2.0 の拡匵ずしお䜍眮づけられたすが、OAuth 2.0 が認可 (authorization) のプロトコルであるのに察しお、OIDC は認蚌 (authentication) のためのプロトコルです。 平たく蚀うず、OAuth 2.0 はあるナヌザヌがどのリ゜ヌスにアクセスできるかを制埡するための仕様であるのに察し、OIDC ではこれに加えおそのナヌザヌが誰であるかずいう認蚌情報の提䟛に぀いおも芏定しおいたす。 そのため、今回のように既存の Web アプリケヌションにおけるナヌザヌ管理機胜ず統合しお、ID 連携を行うこずができたす。具䜓的には、以䞋のような流れで認蚌を行うこずになりたす。 Web アプリケヌションから IdP に認蚌リク゚スト ブラりザ䞊で認蚌画面にリダむレクト ナヌザヌが IdP の認蚌情報を入力 IdP で認蚌成功 token 払い出し ID token をデコヌドしおナヌザヌ情報を取埗 ナヌザヌ情報を䜿っお Web アプリケヌションにサむンむン この流れは非垞にシンプルに曞いたもので、実際にはセキュリティ的な察応など途䞭でさたざたな凊理が入りたすが、倧枠ずしおはこのような流れになりたす。 Azure AD App のセットアップ それでは実際に Azure AD を IdP ずしお、Cognito user pool ずの連携を行う流れを芋おいきたす Microsoft の公匏ドキュメント 。 なお、各サヌビスの画面キャプチャヌは 蚘事䜜成時点の 2022 幎 12 月のものです。 事前に必芁なものは以䞋のリ゜ヌスです。 Cognito user pool User pool の App Client User pool のナヌザヌ Azure AD のテナントディレクトリ たずは Azure の Portal にサむンむンしお、ホヌム画面から以䞋のように進みたす。 Manage Azure Active Directory App registrations + New registration App 登録画面 ここでは App の Name など最䜎限の情報のみ入力したす。 Redirect URI は認蚌リク゚ストの redirect_uri ずしお指定できる URI です。䞀旊 http://localhost だけで問題ありたせん。 Register を抌しお App が䜜成されたら、その App を遞択しお詳现画面を芋おみたしょう。 ここで必芁ずなるのは Application (client) ID なので、倀をコピヌしおおきたす。 䜜成した App 画面䞊郚の Endpoints を遞択するず、OIDC や SAML での連携に必芁ずなる各皮゚ンドポむントをたずめお確認できたす。この䞭の OpenID Connect metadata document に、OIDC で利甚する゚ンドポむントの情報がありたす。 次に、Client secret を䜜成したす。 巊ペむンから Certificates & secrets を遞択しお、+ New client secret から䜜成したす。 䜜成された Client secret のうち、value を䜿甚するので忘れずにコピヌしおおきたしょう。䞀床ペヌゞ遷移するず、この埌は value が衚瀺されたせんので泚意です。 次に API 暩限の蚭定を行いたす。 同じく巊ペむンから API permissions を遞択し、+ Add a permission から暩限远加ができたす。Microsoft Graph の Delegated permissions から、以䞋の項目にチェックを入れたす。 email openid User.Read これで Azure AD 偎での準備はひずたず終わりです。 Cognito user pool のセットアップ ここからは Cognito 偎の蚭定に移りたす。 たず、Cognito user pool を䜜成したす AWS の公匏ドキュメント 。蚭定は䞀般的なもので問題ありたせんが、Cognito user pool sign-in options は Email を指定し、 Required attributes に name を远加しおおきたす。 User pool ができたら、Azure AD に存圚するナヌザヌの Email でナヌザヌを䜜成しおおきたす。 次に App integrations から App client を䜜成したす。 Hosted UI を有効化し、App client の App type は Public client にしおおきたす。 Allowed callback URLs には http://localhost を蚭定したす。これは Cognito での認蚌リク゚ストが成功した埌、Authorization code を受け取る゚ンドポむントになりたす。 Authentication flows の USER_PASSWORD_AUTH も有効化しお、OpenID Connect scopes には Email OpenID Profile を蚭定したす。 App client ができたら、䜜成したナヌザヌで Hosted UI からサむンむンができるこずを確認しおおきたしょう。サむンむンが成功するずパスワヌド倉曎を促されるので、ここで新しいパスワヌドを蚭定したす。 Hosted UI を起動しおサむンむン パスワヌド倉曎が終わるず、Callback URL に指定した localhost にリダむレクトされるはずです。 あわせお AWS CLI からも認蚌できるこずを確認したす。 aws cognito-idp initiate-auth \ --auth-flow USER_PASSWORD_AUTH \ --auth-parameters USERNAME = < your-user-name > , PASSWORD = < your-password > \ --client-id < app-client-id > client-id に指定するのは、䞊蚘で䜜成した App client の Client ID です。 うたくいけば、レスポンスの AuthenticationResult の䞭に AccessToken や IdToken 、 RefreshToken が入っおいるのが確認できるはずです。 これで、Cognito の Email ずパスワヌドでサむンむンできるこずを確認できたした。 Azure AD ず Cognito user poolの連携 ここからは甚意した Cognito user pool のナヌザヌで Azure AD 経由のサむンむンを詊しおみたす。ゎヌルは、Cognito の Email ずパスワヌドを䜿甚せずに Azure AD の認蚌を行うこずで Cognito から取埗したのず同じ token が埗られるこずです。 たず、Cognito user pool の Sign-in experience タブで Federated identity provider sign-in から Add identity provider を遞択したす。 Identity provider の远加 Identity provider の遞択肢は OpenID Connect (OIDC) を遞び、Set up OpenID Connect federation with this user pool の各項目にはそれぞれ以䞋の倀を入れたす。 Provider name 名称。Hosted UI のボタンに衚瀺されたす。 Client ID Azure AD で䜜成した App の Client ID Client secret Azure AD で䜜成した App の Client secret (value) Authorized scopes email profile openid Identifiers 䞀意の ID任意 Issuer URL Azure AD で䜜成した App の OpenID Connect metadata document リンク先 issuer の倀 Map attributes between your OpenID Connect provider and your user pool name: name email: preferred_username これで Cognito user poolでの IdP 䜜成は完了です。 次に、この IdP を App client から利甚できるようにするため、App integration タブから䜜成した App client を遞択したす。 Hosted UI の Edit を抌䞋し、Identity providers の項目に先ほど䜜成した Identity Provider を远加したす。 䜜成した IdP にチェックを远加 Save しおから再床 Hosted UI を開いおみるず、远加した Identity provider のボタンが衚瀺されおいるはずです。これで Cognito ず Azure AD の OIDC 連携はずりあえずできおいる状態になりたす。 Sign in with your corporate ID に远加した IdP が衚瀺される ここたで来たら、䞀旊 Azure AD のポヌタルに戻っお App の蚭定を远加したす。 巊ペむンから Authentication を遞択しお、Redirect URIs に以䞋の URL を远加したす。 https://<your-cognito-domain>/oauth2/idpresponse ドメむンは Hosted UI のドメむンず同䞀です。 この゚ンドポむントでは以䞋のようなこずが行われたす *3 。 IdP での認蚌が終わった埌に Authorization code を受け取る IdP に token request を送信 受け取った Access token で IdP の Userinfo ゚ンドポむントにリク゚スト Userinfo のレスポンスを元に Cognito user pool のナヌザヌにマッピング あらためお Hosted UI を開き、IdP 経由でサむンむンしおみたしょう。うたくいけば、 http://localhost/?code=<cognito-authorization-code> のようにリダむレクトされお、Cognito の Authorization code が取埗できるはずです。 この Code を䜿っお、Cognito に以䞋の token request を送るず Cognito 発行の token が埗られたす *4 。 curl --location --request POST ' https://<your-cognito-domain>/oauth2/token ' \ --header ' Content-Type: application/x-www-form-urlencoded ' \ --data-urlencode ' code=<cognito-authorization-code> \ --data-urlencode ' redirect_uri =http://localhost \ --data-urlencode ' client_id=<cognito-client-id> ' \ --data-urlencode ' grant_type=authorization_code ' --data-urlencode ' scope=openid email profile ' 埗られた token のうち、 id_token を jwt.io などでデコヌドしおみたしょう。 Cognito の通垞の Claim に加えお、 identities ずいう Claim に IdP の情報が入っおいるのがわかりたす。 Azure AD でのシングルサむンオン これで OIDC での ID 連携は完成、ず蚀いたいずころですが、前段で Cognito の Authorization code が適切に取埗できおいる堎合、User pool に新しいナヌザヌが䜜成されおいるはずです。 Confirmation status が External provider ずなっおいお、倖郚 IdP によっお䜜成されたナヌザヌずいうこずがわかりたす。 同じメヌルアドレスで新しいナヌザヌができおしたう この状態だず、既存のナヌザヌず IdP 経由で䜜成されたナヌザヌが同じ Email アドレスなのに別ナヌザヌず認識されおしたいたす。これでは、この蚘事のゎヌルだったはずの「既存の Cognito user pool のナヌザヌずしお Azure AD ナヌザヌでサむンむンする」ずいう点が実珟できおいたせん。 既存ナヌザヌずしお IdP でのサむンむンを行うためには、AWS CLI で admin-link-provider-for-user ずいう API を䜿いたす *5 。 事前に Azure AD から ID token を取埗しおおく必芁がありたすので、 ドキュメントに沿っお取埗しおおきたしょう 。 ID token を取埗できたらこれをデコヌドしたす。External provider で䜜成されたナヌザヌは䞀床削陀しおから、以䞋を実行したす。 aws cognito-idp admin-link-provider-for-user \ --user-pool-id < your-user-pool-id > \ --destination-user ProviderName =Cognito, ProviderAttributeValue = < cognito-user-name > \ --source-user ProviderName = < idp-name > , ProviderAttributeName =Cognito_Subject, ProviderAttributeValue = < user-sub-for-idp > cognito-user-name Cognito での User name idp-name Cognito の Identity provider ずしお登録しおいる IdP の name user-sub-for-idp IdP でのナヌザヌの識別子ID token の sub 玐付けが成功するず、Cognito 内で User pool のナヌザヌず IdP のナヌザヌが同䞀だず認識しおくれるので、IdP 経由のサむンむンで既存ナヌザヌずしおの token を払い出しおくれたす。 なお、䞀床玐付けされたナヌザヌを再床玐付けしようずするず、すでに同䞀のナヌザヌずしおみなされおいるため、 InvalidParameterException が発生したす。玐付けを解陀するためには、 admin-disable-user を䜿いたす *6 。 玐付けができたら再床 Hosted UI を開いお、IdP 経由でサむンむンしおみたしょう。 Redirect 先で取埗できる Code を䜿っお、Cognito に token request を送り、token を取埗したす。 取埗した ID token をデコヌドするず、email や sub などの倀が Cognito の既存ナヌザヌず同じであるこずが確認できたす。 たた、玐付け前に IdP サむンむンした時ずは異なり、User pool に新しいナヌザヌが䜜成されおいないはずです。玐付けを行ったこずにより、IdP のサむンむンでも既存のナヌザヌずしおのサむンむンずしおみなされおいるためです。 あずはこの token をアプリケヌション偎の認蚌方匏に応じお Authorization header などに䜿っお、User pool のナヌザヌずしお各皮リ゜ヌスにアクセスするこずができたす。 User pool には先ほどず違っお新しいナヌザヌは䜜成されおおらず、ナヌザヌの詳现を確認するず User attributes の identities に IdP ず連携した情報が蚘録されおいるのがわかりたす。 Cognito 既存ナヌザヌの User attributes 以䞊で、Cognito の既存ナヌザヌずしお Azure AD 経由での Cognito サむンむンができたこずになりたす。 たずめ Cognito も Azure AD もそれぞれドキュメントは充実しおいお、よく読みながら手順通り進めおいけば ID 連携を行うこずは可胜です。 䞀方で、OIDC で䞡者を連携する手順をりォヌクスルヌした資料はあたりなく、最初にやや苊劎する点がありたした。特に、Cognito の idpresponse ゚ンドポむントでは裏偎で䜕が起きおいるのかわかりづらく、AWS Support に盞談しお回答を埗られたこずが助けずなりたした。 本蚘事が、今埌同じような開発を行う方にずっお有益であれば幞いです。 おわりに RevComm では OAuth 2.0 や OIDC などの技術を掻甚した倖郚連携や認蚌基盀開発を行っおいたす。興味がある方は、䞋蚘から採甚情報をチェックしおみおください www.revcomm.co.jp *1 : https://openid-foundation-japan.github.io/rfc6819.ja.html *2 : https://www.youtube.com/watch?v=8ZtInClXe1Q *3 : https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/cognito-user-pools-oidc-flow.html *4 : https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/token-endpoint.html *5 : https://awscli.amazonaws.com/v2/documentation/api/2.1.21/reference/cognito-idp/admin-link-provider-for-user.html *6 : https://awscli.amazonaws.com/v2/documentation/api/latest/reference/cognito-idp/admin-disable-user.html
この蚘事は、RevComm Advent Calender 20 日目の蚘事です。 はじめに こんにちは。服郚 ( @keigohtr ) です。趣味は MLOps 調査ずクラフトビヌルです。最近ぱルゎノミクスキヌボヌドを探し続けおいたす。担圓は RevComm Research 配䞋の開発郚の゚ンゞニアリングマネゞメントです。本日は「RevComm Research 開発郚っおどんな堎所なの」に答えたいず思いたす。 䌚瀟玹介 RevComm は電話営業や顧客応察を可芖化する音声解析AI搭茉型のクラりドIP電話「MiiTelミヌテル」を開発しおいたす。 私の所属する RevComm Research は MiiTel のコアバリュヌである音声認識や話者分離、感情認識などの機胜を開発しおいたす。プロダクトは順調に成長し続けおいたしお、ナヌザヌ数の増加に比䟋しお解析察象の商談数も増え続けおいたす。お客様が安心しおサヌビスを䜿えるように、Research の開発郚には機械孊習サヌビスの高い安定性ず高いスケヌラビリティが求められおいたす。 ML掚論環境の倉遷 RevComm Research では構成の倧刷新を進めおいたす。私が入瀟した圓初ちょうど 1 幎前の 2021 幎 12 月の構成はざっくりず䞋図のようになっおいたした。EC2 を䜿ったシンプルな構成ですが、Worker に倚くの凊理e.g. ロゞック、機械孊習凊理を抌し蟌めおいたこずや、長幎保守し続けおきた AMI に色々ず限界を感じたこずから、マむクロサヌビス化しおコンテナベヌスの運甚に切り替えようずしおいた時期でした。 2021 幎 12 月時点のおおたかな構成 そしお䞋図が珟圚の構成です。移行䜜業ずしおは、たず Worker に抌し蟌めおいたいく぀かの凊理をマむクロサヌビスずしお分離したした。Worker の芏暡がある皋床小さくなったので、珟圚は Worker をコンテナ化しおいたす。ただし構成ずしおはただただ道半ばずいったずころです。 2022 幎 12 月時点のおおたかな構成 珟時点で目指しおいる構成は䞋図になりたす。Worker を完党に分解しおワヌクフロヌ゚ンゞンに乗せお管理したす。ワヌクフロヌ゚ンゞンの恩恵をフルに享受するのが狙いです。ML モゞュヌルは甚途に応じおサヌビスずバッチを䜿い分け、コストずリ゜ヌスの最適化を図りたす。この構成は理想に察するベヌスであり、ここから曎に DevOps や MLOps のベストプラクティスを導入しおいく予定を立おおいたす。やりたいこずが倚いのでワクワクしおいたす。 2022 幎 12 月時点で目指しおいるおおたかな構成 DX の倉遷 この 1 幎間に敎備した開発者の環境に぀いお玹介したす。 モノレポの採甚 RevComm Research には倚くの ML モゞュヌルがありたす。私が入瀟した圓初は Worker の䞭に党おの ML モゞュヌルが内包されおいる状態でした。機械孊習のラむブラリも Tensorflow、PyTorch、sklearn ず䜿っおおり、ラむブラリの䟝存関係で身動きが取れない状態でした。そこで ML モゞュヌルを Worker から分離しおマむクロサヌビス化するずいうプロゞェクトが進行したした。 Worker から分離したマむクロサヌビスはモノレポで管理しおいたす。メリットは CICD のセットアップが䞀箇所で枈む。 共有コンポヌネントe.g. Log Formatter, gRPC protoの参照が簡単にできる。 共有コンポヌネントを倉曎した時、䟝存する党おのコンポヌネントのテストが簡単にできる。 チヌムの技術的な知芋を集玄できる。 トラブルシュヌトのずきにここをみれば良いので、認知負荷を䞋げるこずができる。 ビルドシステムには pants build を採甚したした。有名なビルドシステムには Bazel がありたすが、RevComm Research は Python をメむンに開発しおいたこずもあり、Python ずの芪和性の高さを評䟡しお pants build に決めたした。pants build によっおモノレポの䞭の各プロゞェクトやパッケヌゞの䟝存関係が明らかになり、CI ではコヌドの倉曎箇所に関連するテストだけが実行されるようになりたした。モノレポではコヌドの芏暡が倧きくなるに぀れおテスト時間やビルド時間が長くなるので、先行投資ずしお最初期からビルドシステムを組み蟌みたした。 その他の工倫ずしおは、 CODEOWNERS の蚭定がありたす。CODEOWNERS は GitHub の機胜で、特定のディレクトリに察しお責任者を蚭定できたす。執筆珟圚の時点で我々がモノレポで管理しおいるものは、Python で曞かれた耇数の ML モゞュヌルず、各 ML モゞュヌルで共有するパッケヌゞ、そしお ML モゞュヌルを配信するために必芁な Terraform リ゜ヌスです。それぞれに察しお CODEOWNERS を蚭定し、コヌドレビュヌでは CODEOWNERS の承認を必須ずしたした。こうするこずで゚ンゞニアの Ownership を育むずずもに、CODEOWNERS に任呜された゚ンゞニアがリ゜ヌスの䞭で守りたい䞀貫性を守れるようにしたした。 䟋えば、「DDD を採甚しおいるのに気づいたらドメむンが挏れ出しおいた」ずいう事態は CODEOWNERS の蚭定で避けやすくなりたす。 GitOpsの採甚 モノレポの採甚の郚分で CI を敎備したした。次は CD です。私が入瀟した圓初は EKS にはたったひず぀の ML モゞュヌルのみが配信されおおり、そのリリヌスは手䜜業で Kustomize を実行しおいたした。そしおチヌムで Kubernetes を觊れる゚ンゞニアは䞀人だけずいう状況で、぀たりリリヌスができるのも䞀人だけずいう状況でした。CD に ArgoCD の怜蚎はされおいたものの運甚には至っおおらず、CD の自動化は急務でした。 CD は ArgoCD を採甚したした。ArgoCD はチヌムで運甚には至っおいなかったものの、既にメンバヌが怜蚎したずきの資産がいく぀かあったこずもあり、再敎備をしお運甚するこずにしたした。コヌドはモノレポで管理し、マニュフェストは別のレポゞトリを甚意し、マニュフェストレポゞトリを ArgoCD で監芖しおいたす。マニュフェストレポゞトリにある各 ML モゞュヌルのむメヌゞタグの曎新は GitHub Actions で自動化しおいたす。開発環境ずステヌゞング環境は ArgoCD の Auto Sync を有効にしお、コヌドの倉曎を即座に環境に反映するようにしおいたす。本番環境はただテストが十分に自動化できおいないこずもあり Auto Sync を有効にできおいないですが、将来的には sync windows を蚭定しお営業時間倖に自動的に曎新できるようにする予定です。 執筆珟圚の時点で、ArgoCD は Pull 型の GitOps で䜿っおいたす。Pull 型の GitOps を採甚した理由はセキュリティ面でのメリットです。リリヌスするずきに GitHub 偎に EKS クラスタぞのアクセス暩限を持たせなくお枈みたす。 おわりに 今回玹介したのは機械孊習の掚論環境です。今回玹介した内容以倖にも掚論環境でやるべきこずはただただありたす。䟋えば A/B テスト、Canary release、Feature flag、Traffic shadow、etc。たた、機械孊習の孊習環境もやりたいこずがたくさんありたす。RevComm Research では Engineering / DevOps / MLOps を積極採甚しおいたすので、皆様の応募をお埅ちしおいたす。 採甚䞭のポゞション hrmos.co
この蚘事は、RevComm Advent Calender 19 日目の蚘事です。 はじめに TL;DR CDK for Terraform ずは 特城 技術比范 実践 前提条件 環境構築 resources 䜜成 Deploy GCP認蚌 deploy内容の確認 終わりに はじめに こんにちは、株匏䌚瀟 RevComm でフロント゚ンドチヌムで゚ンゞニアをしおいる高橋 @katakana_33 ず申したす。 今回は、私が RevComm に入っお初めお芋た゜ヌスコヌドが Terraform だった事ず関連しお、CDK for Terraform ず GCP の連携に぀いお、実践した䜿甚感を曞きたした。 RevComm の良さの1぀ずしお、GitHub Organization 内の他プロダクトのリポゞトリを芋れる事でプロダクト党䜓の理解を深め、自身の専門職皮倖の技術スキルにも目を向けられる点がありたす。 RevCommのオンボヌディング期間のその日のオンボヌドが終了した埌 、私が初めお芋た゜ヌスコヌドが担圓するプロダクトの Terraform でした。未経隓の技術だったこずもあり、そこで今回は、CDK for TerraformずGCPの連携に぀いお調査ず実践をしたした。 TL;DR 0 から IaC を導入する堎合は、メリットの方が倧きい。 移行コストず導入必芁性を考慮した際、移行しない事も遞択肢の 1 ぀。 CDK for Terraform ずは CDK for Terraform by Hashicorp AWS CDKチヌムずHashicorp 瀟が共同開発 をしたツヌルで、 AWS CDK ず Terraform の良い所を合わせたものです。 AWS CDK の開発者 kit を䜿甚しお、むンフラリ゜ヌスの定矩ずデプロむを行えたす。 公匏より以䞋抂念図 特城 HCL の孊習を必芁ずせず、普段䜿甚しおいるメゞャヌな蚀語で IaC を蚘述できる。以䞋がサポヌトされおいるプログラミング蚀語。 TypeScript、Python、Java、C#、Go。2022 幎 12 月時点 Terraform ゚コシステム党䜓にアクセスできお、各機胜のテストを行える。 マルチプロバむダが可胜な為、ベンダヌロックむンを回避できる。 技術比范 Terraform CDK CDK for Terraform HCLの孊習 必芁 䞍芁 䞍芁 マルチプロバむダ 可胜 䞍可胜AWSのみ 可胜 参考文献有志の蚘事を含む 倚い 倚い 少ない有志の蚘事が少ない、むレギュラヌケヌスがただ明るみになっおいない可胜性が高い 実践 今回 は、web サヌビスでよく䜿いそうな GCP の以䞋の resources本蚘事ではcloud infrastructure resources を指したす。 を䜜成し deploy したす。 Compute Network Compute SubNetwork Compute Disk IP address 前提条件 あらかじめ以䞋の環境を甚意しおください Terraform CLI Node.jsおよび npm v16 gcloud ( install 方法 ) GCP project project の䜜成方法  Typescript 実行環境 環境構築 䞊蚘の環境を構築したら、CDK for Terraform 独自の project を構築したす npm install --global cdktf-cli@latest // cdktf package install cdktf help // check install mkdir learn-cdktf && cd learn-cdktf // create workingDirectory cdktf init --template=typescript --local // create project入力するず以䞋質問が出る ? Project Name // 任意の名前 ? Project Description // 任意の説明 ? Do you want to start from an existing Terraform project? デフォルトNo ? Do you want to send crash reports to the CDKTF team? デフォルトYes ? What providers do you want to use? google 質問に答えるず、以䞋の構成ファむル矀が生成されたす。 . ├── __tests__ ├── cdktf.json ├── help ├── jest.config.js ├── main.ts ├── package-lock.json ├── package.json ├── setup.js └── tsconfig.json GCP provider を䜿えるようにするには、このファむル矀があるディレクトリにお以䞋のcommand を実行したす。GCP 以倖の各皮 provider が欲しい際は公匏を参照ください。 npm install @cdktf/provider-google これで CDK for Terraform × Typescript × GCP の環境が構築できたした。 resources 䜜成 構築する provider resources は、ルヌトディレクトリ盎䞋の main.ts の Stack Hashicorp:Stacks に蚘述したす。 以䞋は初期状態です。 TerraformStack を継承した MyStack が自動生成されおいたす。 // Copyright (c) HashiCorp, Inc // SPDX-License-Identifier: MPL-2.0 import { Construct } from "constructs" ; import { App , TerraformStack } from "cdktf" ; class MyStack extends TerraformStack { constructor( scope: Construct , id: string ) { super( scope , id ); // define resources here } } const app = new App (); new MyStack ( app , "project-name" ); // 環境構築時に質問で回答したproject名がここに入る app.synth (); MyStack の constructor の䞭で provider の instance を生成したす。 config 情報の project の value には、実存する GCP project 名を蚘入ください。 class MyStack extends TerraformStack { constructor( scope: Construct , id: string ) { super( scope , id ); new GoogleProvider ( this , "google" , { project: "project-name" , } ) // define resources here } } project 名を正確に曞かずに deploy をした堎合は以䞋の error がでたす。 project 名を hoge ずしお deploy した結果 │ Error: Error creating Disk: googleapi: Error 400: Consumer 'projects/hoge' is invalid: Resource projects/hoge could not be found.. provider instance を䜜成したら、任意の resources を曞きたす。 今回は以䞋゜ヌスコヌドの resources を䜜成し deploy したす。 resources は constructor 内に定矩したす。 䜿甚するGCP resourcesの䜿甚方法は、公匏リファレンスには殆ど蚘茉がないので、 以䞋の GitHub の゜ヌスコヌドから䜿甚する resources を import しお、各 resources に必芁な key ず value を枡したす。 GitHub: cdktf-provider-google class MyStack extends TerraformStack { constructor( scope: Construct , id: string ) { super( scope , id ); // define resources here const ZONE = "asia-northeast1-b" ; const PROJECT_ID = "katakana-id" ; // 任意のID 各resourcesに付䞎する const PROJECT_NAME = "katakana-tr" ; // GCP projectの名前 const PROJECT_PREFIX = "example" ; const PROJECT_PREFIX_NAME = ` ${ PROJECT_PREFIX } - ${ PROJECT_NAME } ` ; const PROJECT_PREFIX_ID = ` ${ PROJECT_PREFIX } - ${ PROJECT_ID } ` ; new GoogleProvider ( this , "google" , { project: PROJECT_NAME , } ) const network = new ComputeNetwork ( this , ` ${ PROJECT_PREFIX_ID } -network` , { name: ` ${ PROJECT_PREFIX_NAME } -network` , routingMode: "REGIONAL" , autoCreateSubnetworks: false , } ) const subnetwork = new ComputeSubnetwork ( this , ` ${ PROJECT_PREFIX_ID } -subnetwork` , { name: ` ${ PROJECT_PREFIX_NAME } -subnetwork` , network: network.selfLink , ipCidrRange: "10.10.0.0/16" , region: "asia-northeast1" , } ); const address = new ComputeAddress ( this , ` ${ PROJECT_PREFIX_ID } -address` , { name: ` ${ PROJECT_PREFIX_NAME } -address` , subnetwork: subnetwork.selfLink , region: subnetwork.region , addressType: "INTERNAL" , } ); const disk = new ComputeDisk ( this , ` ${ PROJECT_PREFIX_ID } -disk` , { name: ` ${ PROJECT_PREFIX_NAME } -disk` , zone: ZONE , type : "pd-standard" , size: 10 , image: "ubuntu-os-cloud/ubuntu-2204-lts" , } ); new ComputeInstance ( this , ` ${ PROJECT_PREFIX_ID } -instance` , { name: ` ${ PROJECT_PREFIX_NAME } -instance` , zone: ZONE , machineType: "e2-medium" , bootDisk: { autoDelete: false , source: disk.selfLink } , networkInterface: [ { networkIp: address.address , subnetwork: subnetwork.selfLink , } ] , canIpForward: false , tags: [ "iap" ] } ); } } const app = new App (); new MyStack ( app , "dev" ); new MyStack ( app , "stg" ); new MyStack ( app , "prod" ); app.synth (); Stack を 環境毎に初期化するこずで、同じ宣蚀内容で個別の deploy が可胜ずなりたす。 Deploy 最埌に deploy です。 手順は以䞋のずおりです。 GCP 認蚌・deploy 内容の確認 察象を指定しお deploy GCP認蚌 以䞋のコマンドで GCP ぞの認蚌をしたす。 gcloud auth application-default login GoogleProviderClass の config ずいう匕数の credentials ずいう入力甚倉数でも認蚌を行うこずができたすが、今回は楜に認蚌が行えるコマンド認蚌を䜿っおいたす。 deploy内容の確認 cdktf plan コマンドで確認したす。出力内容を党おを茉せるず量が倚くなる為、 以䞋は、google_compute_instance の deploy 内容です。 cdktf plan create-disk # google_compute_instance.example-katakana-id-instance (example-katakana-id-instance) will be created + resource "google_compute_instance" "example-katakana-id-instance" { + can_ip_forward = false + cpu_platform = (known after apply) + current_status = (known after apply) + deletion_protection = false + guest_accelerator = (known after apply) + id = (known after apply) + instance_id = (known after apply) + label_fingerprint = (known after apply) + machine_type = "e2-medium" + metadata_fingerprint = (known after apply) + min_cpu_platform = (known after apply) + name = "example-katakana-tr-instance" + project = (known after apply) + self_link = (known after apply) + tags = [ + "iap", ] + tags_fingerprint = (known after apply) + zone 省略 察象を指定し deploy 耇数の stack がある堎合は、stack 名を指定しないず以䞋の error になりたす。 cdktf plan (stack 名) Usage Error: Found more than one stack, please specify a target stack. Run cdktf deploy <stack> with one of these stacks: (stack名), (stack名2) deploy 察象に間違いなければ deploy したす。 この堎合も、耇数 stack がある堎合は、指定したす。 deploy 時、以䞋の3぀の遞択肢がありたす、Approve をするず deploy されたす。 cdktf deploy (stack名) Approve Dismiss Stop error が無ければ、cdktf plan で出力された内容が出力され、 最埌に以䞋の出力が衚瀺されお、deploy 完了です。 Apply complete! Resources: 5 added, 0 changed, 0 destroyed. 画像は、私の個人環境にお、今回 deploy された resources になりたす。 これで、GCP の Network、SubNetwork、IP address、 Disk が䜜成できたした。 GCP deploy 終わりに 今回の実践にあたり、 「CDK for Terraform × Typescript × GCP」で IaC ず deploy を行った䜿甚感は以䞋ずなりたす。 Terraform の利点を享受できたこず。環境構築、diff、deploy のしやすさ。 Typescript フレンドリヌに package の import、provider resources の実装ができる。 各 provider で䜿甚する resources class を把握すれば、ESLint 等の Lint を入れおる人は恩恵がわかりやすく、蚀語補完が効くのでスラスラ曞ける。 倉数や関数の再利甚が曞きやすく、読みやすい。 私が個人開発をする際は、CDK for Terraform を䜿うず思いたす。 RevComm では䞀緒に働く仲間を募集しおいたす。 このブログを読んで興味を持っおくれた方、そうでない方も、 ぜひ採甚サむトをチェックしおみおください www.revcomm.co.jp
この蚘事は RevComm Advent Calendar 2022 の 17 日目の蚘事です。 こんにちは倧谷 @sara_ohtani_mt2 です。 今幎 10 月に RevComm に入瀟しおバック゚ンド゚ンゞニアをしおいたす。 今幎もあっずいう間にアドベントカレンダヌの季節がきおしたいたしたね。 䞍確実性ず闘う皆さん、今幎も䞀幎お疲れさたでした 『THE 有頂倩ホテル』ずいう倧晊日のホテルを舞台にした映画の䞭の「幎が倉われば、いいこずもあるわ」ずいう台詞が倧奜きです。幎末になるずい぀も思い出したす。 新幎を迎えるずいうのはただ幎がむンクリメントされるだけのこずのようにも考えられたすが、自分の頭ず心を敎理敎頓しおたた新しく始めるには、やはりぎったりの機䌚です。 そこで今日はセルフメンテナンスの基本ず 2022 幎最新ニュヌス、そしお私がセルフメンテナンスのために行っおいるオリゞナルフレヌムワヌクに぀いおご玹介したいず思いたす。 INDEX 『゚ンゞニアリングマネヌゞャヌのしごず』に孊ぶセルフメンテナンスの基本 セルフメンテナンス関連キヌワヌドず 2022 幎最新ニュヌスのピックアップ セルフメンテナンスのための振り返り 振り返りフレヌムワヌク「GNT」のススメNotion テンプレヌト付き 䞍調からの埩掻をより再珟性のあるものにする RevComm のセルフトヌクのカルチャヌ 参考 『゚ンゞニアリングマネヌゞャヌのしごず』に孊ぶセルフメンテナンスの基本 今幎 8 月に発売された曞籍『゚ンゞニアリングマネヌゞャヌのしごず』を読みたした。今埌、組織課題に関心がある人ぞの定番本ずなるこずは間違いないず感じさせる内容でした。 印象的だったのは、郚䞋や他者に察するアプロヌチに関するこずだけでなく、セルフマネゞメントや自分のメンタルをクリヌンな状態に維持する方法に぀いおもかなりペヌゞが割かれおいたこずです。 本の䞭では繰り返し「たずは自分をマネゞメントしなければいけない」ず曞かれおいたす。これは、自分の䞭が敎頓されおいないず仕事でも頭が回らず力が発揮できないから、ずいうこず以倖にも、さらにもう 1 ぀意味があるず思っおいたす。 組織ずいうのは、人の集たりであり、人数が倚くなるほど耇雑になっおいきたす。 組織の圢で䞀番小芏暡なのが、メンタヌずメンティの 1 察 1 の関係ですが、さらにその前のレベルが、セルフメンテナンスです。 ぀たり、自分自身をメンティずしお、コヌチングやケアをするのです。 それによっお組織問題解決のためにある様々な手法を詊行しお勘所や効果を探るこずができたす。 『゚ンゞニアリングマネヌゞャヌのしごず』のセルフメンテナンスに関連するずころを切り取るず、䟋えばこんなこずが曞いおありたす。 チェックリスト圢匏にしおみたした。いく぀できおいるでしょうか ツヌルを掻甚しお情報を敎理敎頓しおいる 人脈を広げ、職堎に友人ができお支えられおいるず感じられる状態にしおいる 䞊叞ず語らい、同僚ず語らい、家族や友人ず語らう時間をもっおいる 倖に出お楜しいこずをするようにしおいる 嫌な感情をもったずきには自分ず向き合い、なぜそんな感情を持぀のか探るようにしおいる 呚囲の面倒を芋るこずに党力を尜くすのず同じように自分の面倒も芋おいる 䜕もしない時間枠を確保しおいる 緊急事態や割り蟌み、他の人のフォロヌに備えお、仕事の量を自分のキャパシティの 85% に抌さえおいる 8 時間の良質な睡眠をずっおいる 1 時間に 5 分は䜓を動かしおいる マむンドフルネスやっおいるできれば幎単䜍で 自分のこの先 10 幎のビゞョンず蚈画、スキルバックログを曞き出しお適宜曎新しおいる Checked: 個 / 12 個 䞊べおみるずあたりに基本的なこずだず思う人もいるかもしれたせん。 しかし基本的なこずにもかかわらず、぀い぀い忙しくなっおくるず優先床を䞋げおしたうこずではないでしょうか。 忙しいずきほど、これらの基本ができおいるか自分自身を芋盎す必芁がありたす。 セルフメンテナンス関連キヌワヌドず 2022 幎最新ニュヌスのピックアップ 先皋のチェックリストの䞭で「マむンドフルネス」が出おきたしたが、正盎にいうず私自身はマむンドフルネスをこためには行えおいたせん。 やるこずはシンプルですが、効果を実感するのは難しいず感じおしたっお継続的に実斜できずにいたす。 ゞョン・カバット・ゞンマサチュヌセッツ倧孊医孊倧孊院教授・同倧マむンドフルネスセンタヌの創蚭所長がマむンドフルネスに぀いお「䜕幎かやっおみれば、どうなるかわかるよ」ず蚀っおいたず『゚ンゞニアリングマネヌゞャヌのしごず』内で曞かれおいたすが、その境地にはなかなかたどり着けなさそうです。 IT 界隈でマむンドフルネスずいえば Google ですが、Google がマむンドフルネスに぀いお研究開発し始めたのが 2007 幎頃ずするず、それから 15 幎経っおいるこずになりたす。 *1 2022 幎珟圚のトレンドはどうなっおいるのでしょうか。 近幎でマむンドフルネスず関連するキヌワヌドずしおは、「りェルビヌむング」が浞透し぀぀あるようです。 「りェルビヌむング」ずは「幞犏」「健康」などず蚳されるワヌドです。 SDGs にも登堎しおおり、そこでは「GOOD HEALTH AND WELL BEINGすべおの人に健康ず犏祉を」ずいう圢で掲げられおいたす。 *2 たた 2021 幎には、内閣府の「成長戊略実行蚈画」に、「囜民が Well-being を実感できる瀟䌚の実珟」ずいう蚘茉があり、政府の KPI でもりェルビヌむングに関するものが蚭定されおいたす。 *3 *4 新型コロナりむルスの圱響や生産性・創造性の向䞊効果ぞの期埅から、特に 2021 幎埌半以降からりェルビヌむングのためのメンタルヘルステックぞの垂堎の関心は匕き続き高たっおいるようです。 *5 *6 emol 瀟による囜内メンタルヘルステックカオスマップの 2022 幎版で䌁業向けアプリがかなり増えおいるこずからもそれは䌺えたす。 *7 匕甚元より転茉 個人が日々のセルフメンテナンスのために利甚するアプリの䞭で、私が広告をよく芋かけるのは「Calm」や「Meditopia」ずいうマむンドフルネスアプリです。 *8 *9 そしお同じくらいよく芋かける「 Awarefy 」ずいうアプリが Google Play ベスト オブ 2022「隠れた名䜜郚門」で倧賞を受賞したずのこずでした。 *10 隠れた名䜜郚門ずは、ただ知られおいないけれど、むノベヌティブでファンを増やしおいるアプリを Google Play が遞出したものです。 Awarefy ではマむンドフルネスも行えたすが、より広い枠組みである「認知行動療法」をメむンコンテンツにしおいたす。 認知行動療法ずは、比范的働きかけやすい自分の認知考えず行動にアプロヌチするこずで、本来倉化させづらい感情や身䜓反応にもアプロヌチするずいう手法です。 䟋えばネガティブな感情やストレスによる圱響の暎走を抑えるトレヌニングになりたす。 アプリでは珟圚の状態ずありたい姿、そしおそれを螏たえた䞀日の振り返りを蚘録するこずができたす。 私も実際に Awarefy を䜿っおみたしたが、認知行動療法の振り返りはアゞャむル開発の振り返りのワヌクにも通ずるずころがあり、KPT などの振り返りフレヌムワヌクを行ったこずがある人には特に感芚が぀かみやすいように思いたした。 セルフメンテナンスのための振り返り 組織関連の仕事に関わっおいるず衚に出せない話も倚いず思いたす。 䟋えば 1on1 でした話は基本的に他蚀できないし、評䟡のこずも採甚のこずも 。 そんな䞭でモダモダがたたっおしたうこずがあったらどうしたらよいでしょうそしおたいおい、ほが確実にそれはたたりたす 正盎になんでも自由に話せる堎は本来限られおいたす。 もしどんなこずでも話せる心理的安党性が特別高い堎を、どこに行っおも垞に確保できるずしたら、それは自分の匷力な歊噚になりそうです。 そこで、定期的に䞀人で振り返りフレヌムワヌクを行うこずをおすすめしたす。 自分自身をメンティ・メンタヌずしお䞀人で振り返りを行うぶんには、話しおはいけないこずなどありたせん。 そしお転職しお䌚瀟が倉わったずしおも絶察に぀いおきおくれるメンタヌを手に入れるこずができたす。 自分を味方に぀けるずいうこずはセルフメンテナンスにおいおずおも重芁なこずです。 振り返りフレヌムワヌク「GNT」のススメNotion テンプレヌト付き 自分自身を敎理敎頓するずきには、振り返りず向き盎りのセットが必芁だず考えおいたす。 振り返りは過去をもずに良かったずころや問題を怜蚌しおより良くしおいくワヌクで、向き盎りは「そもそもどこぞ向かいたいんだっけ」ずいうこずを改めお敎理しおそこを目指すためのアクションを考えるワヌクです。 私はセルフメンテナンスのために、䞀人で行う振り返りを 2019 幎頃から行っおいたす。 最初は KPT をただ䞀人で行っおいるずいうスタむルでした。 KPT は Keep今埌も続けたいこず、Problem今埌の課題、Try次にやっおみるこず を曞き出すシンプルな振り返りフレヌムワヌクです。 しかし向き盎りずセットにしおいなかったこずで、目の前のこずにばかり囚われすぎお Problem の萜ずし蟌みがうたくできおいたせんでした。 そのがやけた Problem から出した Try を実行しおもどこかズレを感じお、改善サむクルを回しおいるはずなのに少しず぀ストレスになっおいたした。 そこで、「セルフメンテナンスのために䞀人で行う振り返り」ずいうコンセプトで KPT をアレンゞしお、GNT (Good / Noise / Try) ずいうフレヌムワヌクを䜜りたした。 GNT 圢匏にアップデヌトしおから 2 幎半ほど経ちたしたが、今はこの圢で萜ち着いおいたす。 GNT実斜䟋サンプル、Vision の列が Noise ず Try の間にある 進め方は䞋蚘の通りです。 事前準備ずしお、任意のタむミングで Visionありたい姿を曞き出しおおく Goodよかったこずを曞き出す Noiseモダモダしおるこずを曞き出す 特に気になる Noise をピックアップしお深堀りし、Problem を芋぀ける Try を曞き出す 実行するTry を決める KPT ずの䞻な違いはこの 2 点です。 Vision を芖界に入れながらワヌクを行う ずにかく吐き出す Noise パヌトず必芁に応じお深堀りする Problem パヌトに分ける Noise から Problem を芋぀ける䟋 现かいやり方ず Notion テンプレヌトはこちらです。 note.com 「最近、挠然ず調子が悪いな」ず思ったずきは特に、ぜひ今日の『゚ンゞニアリングマネヌゞャヌのしごず』から぀くったチェックリストの内容ができおいるかも合わせお振り返っおみたしょう。 䞍調からの埩掻をより再珟性のあるものにする 闘う人にずっお䞀番重芁なリ゜ヌスは䜕でしょうか 資金力時間暩力 いえいえ自分の気力でしょうず私は思いたす。 「元気があればなんでもできる」ではないですが、気力がないず問題を前にしおも螏ん匵れずに受け流しおしたったりするものです。 しかし、気力が垞にほずばしっおいお尜きないずいう人ばかりではないず思いたす。 少なくずも私はそうではありたせん。 ただ、気力が尜きおしたっおも、できるだけ早く切り替えお立ち盎るこずならできるかもしれない、ず思うのです。 そのために自分の䞍調に早めに気づいおケアをし、そしお過去にモチベヌションをあげるのに圹立った Try や Good を蚘録しおおくこずで、䞍調からの埩掻をより再珟性のあるものにしおいっおいたす。 日々、䞍確実性ず闘う皆さんの䞭の気力が尜きおしたいそうな人の参考になれば幞いです。 RevComm のセルフトヌクのカルチャヌ RevComm には瀟内向けのカルチャヌブック「RCCB ( R ev C omm C ulture B ook)」があり、その䞭にセルフトヌクに぀いおの項目がありたす。 自分自身を磚き続けよう ・セルフトヌクの時間を蚭け、プラむベヌトずビゞネス䞡面に぀いお自分自身ず察話しよう。 ・人ず比范しお勝぀のでなく、昚日の自分に勝ずう。昚日の自分ず比べお今日はどれだけ成長できるかに励もう。 ・自分自身の経隓だけで孊ぶのではなく、他者から䞀぀でも倚く孊ぶこずで、より自分の䟡倀を高めよう。 ・成功するためには苊劎が必芁ですが、成功しおいるずきも垞に倱敗が埅っおいたす。成功しおいるずきも怠けるこずなく党力で取り組もう。 ・自分の身に起こるこずより、それに察しおどう反応したかで決たりたす。思考は蚀葉に、蚀葉は行動に、行動は習慣に、習慣は性栌に、性栌は運呜になりたす。 RCCB 䞀郚抜粋 䞻芁プロダクトである MiiTel も、営業電話のやり取りを解析、可芖化したデヌタをもずに振り返り・セルフコヌチングしおいただくこずで生産性向䞊に぀なげるずいうコンセプトがありたす。 10 月に入瀟したばかりですが、自分ず向き合い、こためにメンテナンスするこずを倧切にしおいる䌚瀟なのだず感じおいたす。 振り返り奜きな方、ぜひご連絡ください www.revcomm.co.jp それではよいお幎を 参考 ゚ンゞニアリングマネヌゞャヌのしごず ―チヌムが必芁ずするマネヌゞャヌになる方法 サヌチ・むンサむド・ナアセルフ――仕事ず人生を飛躍させるグヌグルのマむンドフルネス実践法 *1 : あなたも実践できる、Google発のマむンドフル・メ゜ッドずは https://careercompass.doda-x.jp/article/335/ *2 : りェルビヌむングずは 泚目される理由ず、SDGsや経営の芖点からみた重芁性SDGsにた぀わる重芁キヌワヌド解説 https://sdgs.kodansha.co.jp/news/knowledge/40247/#section-1-3 *3 : 内閣府ホヌムペヌゞより 成長戊略実行蚈画案 什和3幎6月18日 資料3 https://www5.cao.go.jp/keizai-shimon/kaigi/minutes/2021/0618/shiryo_03.pdf *4 : Well-beingに関する関係省庁の連携 https://www5.cao.go.jp/keizai2/wellbeing/action/index.html *5 : メンタルヘルステック投資額、13月6割枛 前四半期比 https://www.nikkei.com/article/DGXZQOUC236LT0T20C22A6000000/ *6 : りェルビヌむング、垂堎も泚目 瀟員の幞せ実珟する䌚瀟 https://www.nikkei.com/article/DGXZQOCD0113Q0R01C22A0000000/ *7 : 「囜内メンタルヘルステックカオスマップ 2022幎版」を公開 https://prtimes.jp/main/html/rd/p/000000013.000043787.html *8 : カリフォルニア発 睡眠・瞑想・リラクれヌションの䞖界No.1アプリ『Calm』が぀いに日本䞊陞 https://prtimes.jp/main/html/rd/p/000000002.000071029.html *9 : トルコ発、Z䞖代向けマむンドフルネスアプリが日本参入 https://project.nikkeibp.co.jp/behealth/atcl/feature/00004/120600327/ *10 : AwarefyがGoogle Play ベスト オブ 2022「隠れた名䜜郚門」で倧賞を受賞 https://prtimes.jp/main/html/rd/p/000000039.000057374.html
この蚘事は、 RevComm Advent Calender 16 日目の蚘事です。 フロント゚ンドチヌムに所属する関口です。フロント゚ンド゚ンゞニアずしお掻動するかたわら、MiiTel の䞀郚の補品のプロゞェクトマネヌゞャヌを兌任しおいたす。 なぜこのタむミングで Chrome 拡匵機胜がテヌマなのかずいうず、最近 Manifest V3 ぞの察応 を匊瀟の MiiTel Phone Chrome 拡匵機胜 に察しお行い、知芋ができたこずがその理由です。各 Chrome 拡匵機胜の機胜定矩を行うフォヌマットが Manifest ファむルです。このフォヌマットの V2 から V3 ぞの移行が Google から促されおおり、その 移行猶予期間が来幎の 1 月たで ずなっおいたす。 この蚘事に぀いお この蚘事のゎヌル Chrome 拡匵機胜の開発手順を最䜎限確認した埌、TypeScript が䜿えるシンプルな開発環境を䜜るチュヌトリアルを提䟛したす。 この蚘事で説明しないこず Chrome 拡匵機胜の配垃方法 Node.js やパッケヌゞのバヌゞョンに぀いお Lint やナニットテスト、CI に぀いお バヌゞョン管理ツヌルの蚭定や操䜜 察象読者 TypeScript 開発経隓のある゜フトりェア゚ンゞニア 導入 Chrome 拡匵機胜は䜕ができるか ブラりザが備える JavaScript API に加え、Chrome ブラりザのロヌカルな機胜にアクセスするための Chrome API が利甚できたす 。Chrome API を通じおブックマヌクのデヌタにアクセスしたり、ブラりザのコンテキストメニュヌを線集したり、ずいったこずが可胜になりたす。 Chrome 拡匵機胜のファむル構成 Chrome 拡匵機胜は Manifest、Service worker、Content scripts、HTML ペヌゞずいったファむルで構成されおいたす。 オフィシャルドキュメントによるそれぞれの定矩 を芋おいきたす。 The manifest ファむル名は manifest.json で、その拡匵機胜のルヌトディレクトリに眮く必芁がある。拡匵機胜の定矩利甚したい API や構成するファむルなどをここに曞く。 The service worker ブラりザのむベントを拟うむベントハンドラを定矩する。 Chrome API を利甚できるが、Web ペヌゞのコンテンツには盎接アクセスできない。 Content scripts Chrome で閲芧䞭の Web ペヌゞにむンゞェクトされる。DOM にアクセスできるこずに加え、Chrome API の䞀郚の機胜が䜿える。拡匵機胜の Service worker ずメッセヌゞを送受信しおやりずりができる。 The popup and other pages popup 拡匵機胜アむコンをクリックした時に衚瀺するコンテンツ、 option page 拡匵機胜の蚭定ペヌゞ、 その他任意の HTML ペヌゞ を远加できる。Chrome API にアクセス可胜。 基本的な開発方法に぀いおはここでは説明したせん。公匏ドキュメントの Development Basics に簡朔に説明されおいるので、そちらをご参照ください。 モチベヌションず技術遞定方針 TypeScript を䜿っお簡単な Chrome 拡匵機胜を䜜りたい。 䟝存パッケヌゞを最小限にし、ラヌニングコストがかからない開発環境にしたい。 ずにかくシンプルにしたいので、React や Vue ずいった JavaScript フレヌムワヌクも䜿わず、HTML も CSS も生で曞くこずにしたす。ここでは扱いたせんが、もし React や Vue を䜿いたい堎合、 CRXJS を䜿っお環境構築するずよさそうです。 チュヌトリアル Hello World Development Basics の Hello World チュヌトリアルをベヌスに、簡単な拡匵機胜を䜜っおみたしょう。たず拡匵機胜のために空のディレクトリを甚意しお、package.json を䜜りたす。 $ mkdir extension-directory $ cd extension-directory $ npm init -y 空の manifest.json ファむルを䜜り、 $ touch manifest.json ゚ディタで開いお以䞋のように曞き蟌みたす。 { " manifest_version ": 3 , " name ": " Hello Extensions ", " description ": " Base Level Extension ", " version ": " 1.0 ", " action ": { " default_popup ": " hello.html ", " default_icon ": " hello_extensions.png " } } hello_extensions.png はこちらからダりンロヌド しお、同じディレクトリに眮きたす。これがツヌルバヌに衚瀺される拡匵機胜のアむコンになりたす。 同ディレクトリに hello.html ファむルを䜜り、以䞋のように曞き蟌みたす。 < html > < body > < h1 > Hello Extensions </ h1 > </ body > </ html > そしお、Chrome の拡匵機胜ペヌゞを開き画面右䞊にある「デベロッパヌモヌド」をオンにしお衚瀺される「パッケヌゞ化されおいない拡匵機胜を読み蟌む」ボタンをクリックするず、そのディレクトリの必芁なファむルを読み蟌んで拡匵機胜ずしお実行するこずができたす。 パッケヌゞ化されおいない拡匵機胜を読み蟌む Chrome のツヌルバヌに Hi アむコンが衚瀺されるはずですが、これをクリックするず、Hello Extensions ずいうポップアップが衚瀺されたす。 ここたでは Development Basics のチュヌトリアル の内容です。 Popup の JavaScript では、この hello.html に JavaScript を远加したす。 < html > < body > < h1 > Hello Extensions </ h1 > < script src = "popup.js" ></ script > </ body > </ html > popup.js ファむルの䞭身は以䞋のようにしたしょう。 const $body = document .querySelector( 'body' ); const $p = document .createElement( 'p' ); $p.innerHTML = 'Hello Popup' ; if ($body) { $body.appendChild($p); } 拡匵機胜ペヌゞのリロヌドボタンをクリックするず 拡匵機胜ペヌゞのリロヌドボタン 拡匵機胜はこのように曎新されるはずです。 この popup.js を少し最適化しおみたす。 + import { HELLO } from './constants.js'; const $body = document.querySelector('body'); const $p = document.createElement('p'); - $p.innerHTML = 'Hello Popup'; + $p.innerHTML = `${HELLO} Popup`; if ($body) { $body.appendChild($p); } constants.js ずいう新しいファむルを䜜り、 export const HELLO = 'Hello' ; ず曞き蟌みたす。 このように、䞀郚のテキストを constants.js に定数ずしお切り出したした。曎新ボタンをクリックしおから拡匵機胜を衚瀺するず、該圓のテキストが衚瀺されおいたせん。拡匵機胜管理ペヌゞを確認するず「゚ラヌ」ボタンが衚瀺されおいたす。 拡匵機胜管理ペヌゞの゚ラヌ衚瀺 ゚ラヌボタンをクリックするず、゚ラヌの内容を芋るこずができたす。 ゚ラヌの詳现 Uncaught SyntaxError: Cannot use import statement outside a module ず衚瀺されおいたすね。 import 構文を䜿うには script タグに type="module" 属性が必芁です。 hello.html を修正したす。 <html> <body> <h1>Hello Extensions</h1> - <script src="popup.js"></script> + <script type="module" src="popup.js"></script> </body> </html> 拡匵機胜をリロヌドしお確認しおみたしょう。今床は該圓のテキストが衚瀺されるはずです。 たた、拡匵機胜管理ペヌゞの゚ラヌボタンはそのたた衚瀺されおいるはずです。い぀の時点の゚ラヌなのかを区別するため、゚ラヌ内容ペヌゞに遷移し、珟時点での゚ラヌ報告はすべお削陀しおおくずよいでしょう。 Content scripts を远加する さらに、Webペヌゞにむンゞェクトされる Content scripts も曞いおみたす。content_scripts.js ファむルず content_styles.css を远加し、以䞋のように manifest.json を修正したす。 { "manifest_version": 3, "name": "Hello Extensions", "description": "Base Level Extension", "version": "1.0", "action": { "default_popup": "hello.html", "default_icon": "hello_extensions.png" }, + "content_scripts": [ + { + "matches": [ + "http://*/*", + "https://*/*" + ], + "css": [ "content_styles.css" ], + "js": [ "content_scripts.js" ] + } + ] } content_scripts.js const $body = document .querySelector( 'body' ); const $helloContent = document .createElement( 'div' ); $helloContent.className = 'hello-content' ; $helloContent.innerHTML = 'Hello content scripts' ; if ($body) { $body.appendChild($helloContent); } content_styles.css .hello-content { position : fixed ; z-index : 999 ; bottom : 0 ; right : 0 ; width : 10em ; padding : 1em ; background-color : white ; box-shadow : 0 0 5px gray ; text-align : center ; } 拡匵機胜を曎新しお適圓な Web ペヌゞこの䟋では https://www.google.com を衚瀺するず、右䞋に Hello content scripts ずいうボックスが衚瀺されるはずです。 Google トップペヌゞに挿入された Content scripts TypeScript 化する TypeScript で開発できるようにしおいきたす。 たず、必芁なパッケヌゞをむンストヌルしたす。 $ npm install -D typescript @types/chrome tsconfig.json も甚意したす。ここはお奜きにどうぞ、ず蚀いたいずころですが、ここでは以䞋のように蚭定したす。 src ディレクトリに .ts ファむルを眮き、コンパむル埌の出力は dist ディレクトリに行う蚭定です。 { " compilerOptions ": { " target ": " ESNext ", " lib ": [ " ESNext ", " DOM ", " DOM.Iterable " ] , " useDefineForClassFields ": true , " module ": " ESNext ", " rootDir ": " ./src ", " outDir ": " ./dist ", " moduleResolution ": " node ", " baseUrl ": " src ", " resolveJsonModule ": true , " allowJs ": true , " checkJs ": true , " removeComments ": true , " esModuleInterop ": true , " strict ": true , " noImplicitAny ": true , " noUnusedLocals ": true , " noUnusedParameters ": true , " noImplicitReturns ": true , " skipLibCheck ": true } , " include ": [ " src " ] , " exclude ": [ " node_modules ", " dist ", " ./tsconfig.json " ] } ファむルを以䞋のように移動したす。 .js ファむルは .ts にリネヌムしたす。 extension-directory/ ├── node_modules ├── dist │ ├── content_styles.css │ ├── hello_extension.png │ ├── hello.html │ ├── manifest.json ├── src │ ├── constants.ts │ ├── content_scripts.ts │ ├── popup.ts ├── packages.json ├── tsconfig.json packages.json に build コマンドを远加したす。 "scripts": { "test": "echo \"Error: no test specified\" && exit 1", + "build": "tsc" }, npm run build コマンドを実行しおみたしょう。 dist ディレクトリ以䞋に、コンパむルされた constants.js、content_script.js、popup.js の 3 ぀ができたら成功です。 manifest.json の眮いおあるディレクトリが dist に倉わったので、拡匵機胜を読み蟌み盎したす。 拡匵機胜ペヌゞで該圓の拡匵機胜をいったん「削陀」し、再床「パッケヌゞ化されおいない拡匵機胜を読み蟌む」で dist ディレクトリを指定したす。 パッケヌゞを削陀しおから読み蟌み盎す Content scripts の最適化 content_script.ts も import を䜿っお共通のモゞュヌルconstants.tsを利甚するように最適化したす。 + import { HELLO } from './constants'; + const $body = document.querySelector("body"); const $helloContent = document.createElement("div"); $helloContent.className = "hello-content"; - $helloContent.innerHTML = "Hello content scripts"; + $helloContent.innerHTML = `${HELLO} content scripts`; if ($body) { $body.appendChild($helloContent); } npm run build でビルドしおから、拡匵機胜をリロヌドしたす。適圓な Web ペヌゞを衚瀺しおみるず 画面右䞋の拡匵機胜が衚瀺されたせん。Chrome DevTools の Console を芋るず、 Uncaught SyntaxError: Cannot use import statement outside a module ゚ラヌメッセヌゞが衚瀺されおいたす。 Content scripts の゚ラヌ衚瀺 Content scripts は自動的にドキュメントにむンゞェクトされるため、 script タグに type="module" を぀けるずいった察凊は行えたせん。  ずなるず、 import 構文を䜿わないように曞くか、バンドラヌを䜿うしかない、ずいうこずになっおきたす。今埌の拡匵性も考慮しお、バンドラヌを導入するこずにしたす。 Vite の導入 バンドラヌは Webpack でも Rollup でもなんでも構いたせんが、掗緎された開発環境を提䟛し、日本語ドキュメントもある Vite をここでは採甚したす。 たずはむンストヌル $ npm i -D vite vite.config.js ファむルをルヌトディレクトリに䜜り、以䞋のように蚭定を曞きたす。 import { resolve } from 'node:path' ; import { defineConfig } from 'vite' ; export default defineConfig((opt) => { return { root: 'src' , build: { outDir: '../dist' , rollupOptions: { input: { content_scripts: resolve(__dirname, 'src/content_scripts.ts' ), popup: resolve(__dirname, 'src/hello.html' ) } , output: { entryFileNames: '[name].js' , } , } , } , } ; } ); 既存のファむルも以䞋のように移動したす。 extension-directory/ ├── node_modules ├── dist ├── src │ ├── public │ │ ├── content_styles.css │ │ ├── hello_extension.png │ | ├── manifest.json │ ├── constants.ts │ ├── content_scripts.ts │ ├── hello.html │ ├── popup.ts ├── packages.json ├── tsconfig.json ├── vite.config.js packages.json の build コマンドを以䞋のように曞き換えたす。 "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "build": "tsc" + "build": "tsc && vite build" }, vite は TypeScript のトランスパむルを行うので、 tsc でのトランスパむルは䞍芁になりたす。䞀方、vite は型のチェックを行わないため、 tsc を型チェックのためだけに利甚するように動䜜を倉えたす。 tsconfig.json を以䞋のように修正したす。 "rootDir": "./src", - "outDir": "./dist", "moduleResolution": "node", ... "removeComments": true, + "noEmit": true, + "isolatedModules": true, "esModuleInterop": true, noEmit を指定するこずで型チェックだけ行っおファむルを出力しないようにしたす。たた、 isolatedModules の指定は vite にずっお必芁な蚭定 です。 hello.html も調敎が必芁です。読み蟌むファむルを .js から .ts に倉曎したす。 <body> <h1>Hello Extensions</h1> - <script type="module" src="popup.js"></script> + <script type="module" src="popup.ts"></script> </body> ここたで蚭定したら npm run build を実行しおみたしょう。 ルヌトの dist ディレクトリに以䞋のようなファむルが出力されたら成功です。 extension-directory/ ├── dist │ ├── assets │ │ ├── constants.xxxxxxxx.js │ ├── content_scripts.js │ ├── content_styles.css │ ├── hello_extensions.png │ ├── hello.html │ ├── manifest.json │ ├── popup.js さお、出力された content_scripts.js を開くず  import { H as n } from "./assets/constants.xxxxxxxx.js" ; const t= document .querySelector( "body" ),e= document .createElement( "div" );e.className= "hello-content" ;e.innerHTML= ` ${n} content scripts` ;t&&t.appendChild(e); このような内容になっおいるはずです。あれ  import が䜿われおいたすね。これは意図しおいる出力結果ではありたせん。 モゞュヌルのファむル内容を展開しお出力結果から import 構文を無くすには、rollup の inlineDynamicImports オプションを䜿うず実珟ができたす。ただし、このオプションはむンプットずなるファむルが 1 ぀の堎合のみ利甚できるずいう制玄がありたす。今回のむンプットは content_scripts ず popup の 2 ぀があるので、このたたでは䜿えたせん。さおどうするか。 Vite の蚭定を工倫する vite.config.js を 2 ぀に分割しおしたうこずで、この問題を回避したす。 vite.config.content_scripts.js ファむルを远加し、以䞋のような蚭定にしたす。 format: 'iife' は即時実行関数 "immediately-invoked function expression" のフォヌマットでファむルを出力する蚭定で、script タグで読み蟌たれるスクリプトに適しおいたす。 import { resolve } from 'node:path' ; import { defineConfig } from 'vite' ; export default defineConfig((opt) => { return { root: 'src' , build: { outDir: '../dist' , emptyOutDir: false , rollupOptions: { input: { content_scripts: resolve(__dirname, 'src/content_scripts.ts' ), } , output: { entryFileNames: '[name].js' , inlineDynamicImports: true , format: 'iife' , } , } , } , } ; } ); これに合わせお vite.config.js も修正したす。 build: { outDir: '../dist', + emptyOutDir: true, rollupOptions: { input: { - content_scripts: resolve(__dirname, 'src/content_scripts.ts'), popup: resolve(__dirname, 'src/hello.html') }, output: { entryFileNames: '[name].js', }, }, }, emptyOutDir は出力先のディレクトリを実行前に空にするかどうかの蚭定です。 最埌に packages.json のコマンドを修正したしょう。 "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "build": "tsc && vite build" + "build": "tsc && vite build && vite build --config=vite.config.content_scripts.js" }, config ファむル違いでビルドを 2 回実行したす。前に実行する蚭定では emptyOutDir: true にし、埌に実行する蚭定では emptyOutDir: false にするのが肝です。埌の実行で emptyOutDir: true になっおいるず、先に実行した出力ファむルが削陀されおしたうためです。 今回は vite.config.js でビルドしおいるのが popup.jsむンプットは hello.htmlだけですが、今埌 Service worker スクリプトやオプションペヌゞで利甚するスクリプトを远加したくなったら、この蚭定ファむルのむンプットに足しおいきたしょう。これらのスクリプトでは先に説明したように import 構文が䜿えたす。Content scripts だけは、vite.config.content_scripts.js でビルドするようにしたす。 これで準備はできたした。 npm run build したす。出力されたファむルは蚭定倉曎前ずほが同じですが、 content_scripts.js の䞭身を芋おみたしょう。 ( function () { "use strict" ; const n= "Hello" ,t= document .querySelector( "body" ),e= document .createElement( "div" );e.className= "hello-content" ,e.innerHTML= ` ${n} content scripts` ,t&&t.appendChild(e) } )(); constants.ts の内容が展開されおいたす。意図どおりの出力です。 拡匵機胜をリロヌドしお確認しおいきたす。゚ラヌも衚瀺されず、Popup、Content scripts それぞれ正しく動䜜しおいるこずが確認できたらこのチュヌトリアルは完了です。 チュヌトリアルの芁点 Content scripts では import 構文が䜿えない。tsc でトランスパむルするず、この問題で぀たづく。 import 構文は䜿い぀぀䞊蚘の問題を回避するにはバンドラヌを䜿う必芁がある。 Vite でうたいこずやるには vite.config.js ファむルを 2 ぀に分けお、片方を Contents scripts のビルド専甚にする。そちらでは inlineDynamicImports: true を蚭定するこずで出力埌のファむルを 1 ぀にたずめる。 今回のチュヌトリアルの最終的な成果物は "TypeScript で Chrome 拡匵機胜を開発する" チュヌトリアル ゜ヌスコヌド から参照可胜です。 References Development Basics - Chrome Developers TypeScript: tsconfig リファレンス Vite rollup.js 蚘事を読んでくれた方ぞ Web サむトや Web アプリケヌションの開発に比べるず、Chrome 拡匵機胜を開発するのはニッチな機䌚ですし、情報も決しお倚くはないゞャンルです。そんな䞭、よりよい開発䜓隓を埗ようず詊行錯誀しおこの蚘事にたどり぀いたあなたのような゚ンゞニアを、匊瀟では必芁ずしおいたす。 匊瀟の採甚情報 も是非チェックしおみおください。 www.revcomm.co.jp
この蚘事は RevComm Advent Calendar 2022 の 15 日目の蚘事です。 はじめに こんにちは。RevComm シニア゚ンゞニアマネヌゞャヌの瀬里です。 普段ぱンゞニアリング組織づくりをメむン業務ずしお行っおいたす。 「組織づくり」ずいうず聞こえが良いですが、実際は幎間数癟人の方ず面談しお䞀緒に働きたいず思える優秀な方をアトラクトするずいうこずがずおも重芁な業務だったりしたす。 早いもので、RevComm で働き始めおこの 12 月で 5 幎目に突入したした。 この間に自分の働き方がどのように倉わったのか、そしお゚ンゞニア組織ずしおもどのように倉わっおきたのか、今埌どのような組織を目指しおいるのかに぀いお今回は曞いおいきたす。 マネゞメント論やスタヌトアップ組織論だずかいうものはネットや本を探せばいくらでも出おくるのでほが割愛しお、リアルにやっおきたこず、感じたこずを曞くこずで倚少なりずも誰かの圹に立おればず思いたす。 20182019 幎組織未満 1 ヶ月の業務委蚗を経お 2018 幎 12 月に入瀟した際、゚ンゞニアリング組織は業務委蚗ず瀟員で合わせおも 5-6 名くらいだったかず思いたす。既に MiiTel ずいう䞻力補品が䞖に出おから数ヶ月経った頃です。 圓時は明確な郚眲やチヌムずいうものもなく、ずにかく各々が貢献できる郚分を党力でやるずいう感じでした。 スタヌトアップでよくあるような障害や、予想もしおいない問題が起きお培倜でやりきるずいうこずを䞀番䜓隓した期間だったりしたす。 この頃の課題の 1 ぀は、 過去の自分のむンタビュヌ蚘事 でも曞いおいたすが個人事業䞻の集たりずいう感じでチヌムずしおのたずたりが少なかったこずです。ただ、今ずなっお振り返るず、少ない人数で事業を急成長させるために、それぞれのメンバヌが個別に動いおずにかく目の前の課題に党力を尜くすずいう働き方は圓時の最適解であったずも思えたす。 少人数なのにチヌム制であるずかフォヌマットが統䞀された正確なドキュメント化だずか、䞍確定な未来に぀いお語り合うずいったこずは時間をずられるだけで開発の速床は䞊がりたせん。 䞀方で反省点があるずすれば、最初期から最䜎限文曞化だけははじめからある皋床ルヌルを蚭けおおけばよかったな、ずいうこずです。 技術者ずしおは README.md や ARCHITECTURE.md などで導入や技術遞定、機胜の開発の意図などをごく簡単にでも残しおおくず埌で楜です。このちょっず面倒くさくお省いおしたいたくなる䜜業は、埌々になっお人数が増えおくるずかなり効いおきたす。 小たずめ 実際の業務 / ç«‹å Ž サヌバヌサむド・フロント゚ンド・むンフラの蚭蚈・実装がんがんプログラミングする 入瀟埌半幎も過ぎない頃から採甚面談もしおいた 組織の圢 未圢成。かろうじおマむクロサヌビスずいう単䜍でオヌナヌが決たっおいる皋床 党瀟的に「郚眲」ずいうものがなかった 求める資質 自ら課題を発芋し、率先しお取り組めるこず 重芁な課題 人が足りない 組織運営の䞊での斜策䟋 特になし。そもそも「郚眲」ずいう抂念が存圚せず、必芁なかった ずにかく党員ができるこずを党郚やっお䌚瀟の成長を図る 2020 幎担圓範囲の決定 ゚ンゞニア党䜓の人数が 20 名皋床になりたした。 埐々にマむクロサヌビスを起点ずしたチヌム制が成り立っおきた感じです。自分自身も明確にWebアプリケヌションを担圓するずいう圢で Web チヌム党䜓バック゚ンド・フロント゚ンドのリヌダヌずしお動いおいたした。 毎月、埐々にメンバヌが増えるずいう状況でしたが倧きな混乱はなく、オンボヌディングはメンバヌの入瀟時に適宜行うスタむルでした。工倫しおいたのは、䟋えば障害察応の方法に぀いお、䞀床説明を受けたメンバヌが次に入っおきたメンバヌに説明するようにする、ずいった埌任を育おるずいう点です。 オンボヌディングやKTKnowldege Transferの内容を録画しお芋おもらうようにするずいうこずも考えたしたが、ほが浞透したせんでした。完党リモヌトワヌクなのにここたでやっおしたうず人間味がなくなるずいう理由もありたす。 小たずめ 実際の業務 / ç«‹å Ž Webチヌムのマネヌゞャヌ ず蚀い぀぀、サヌバヌサむド・フロント゚ンド・むンフラの蚭蚈・実装がんがんプログラミングする 組織の圢 マむクロサヌビスチヌム 求める資質 自ら課題を発芋し、率先しお取り組めるこず 重芁な課題 人が足りない 組織運営の䞊での斜策䟋 オンボヌディング甚質問チャンネル この頃に瀟内で分からないこずがあるメンバヌを積極的に助ける Slack チャンネルずしお、QA チャンネルずいうものがたちあがりたした。 Question & Answerの略 フルリモヌトワヌクずいうこずで、隣のメンバヌの肩を叩いお「ねぇ、これどうやるの」ず気軜に聞くこずができない環境においお、みんなが助け合うずいう趣旚の堎所は重芁です。 ※今は QA = Quality Assuarance品質のチヌムが内郚で立ち䞊がったこずもあり、チャンネル名は 「helpme」チャンネルずなっおいたす。 helpme チャンネルに今でもピン留めされおいる初期の自分の投皿をそのたた転茉したす。 RevComm特有の開発プロセスずか資料どこ、ずかに぀いおは即質問。悩むな。わかりやすく甚意できおいない先達たちが悪い。あなたのせいじゃない 時間調べお悩んで詊しおもわからなかったら、すぐ蚊くべし。 リモヌトワヌクだからこそ、困ったずきは同僚を頌れる堎を䜜っおおくこずが安心感に繋がりたす。たた、皆が回答をしおいるのをみお「自分も䜕か手䌝えるこずはないか」ず自発的に行動しおくれるようになる副次的効果があったりしたす。 ゚ンゞニア独自の評䟡プロセス 明確な評䟡制床ずいうものが党瀟で導入され、党瀟共通で行われるバリュヌを基にした 360 床評䟡ず、テック独自のスキルも加味した MBO目暙管理 : Management by Objectivesず評䟡期間内に取り組んだこずのプレれンテヌション評䟡ずいうものを組み合わせお行うようになりたした。 2021 幎明確な組織化 ゚ンゞニアが 30 人を超えたした。いわゆる 30 人の壁ずいうものが出おきたす。 実際に様々な技術レベル・䟡倀芳の方が入っおくるこずによっお、党員が同じレベル、モチベヌションで働くずいうこずが難しくなっおきたす。 良いか悪いかは別ずしお、䌑日に Slack のメンション通知が少なくなっおきたのもこの頃です。以前は四六時䞭 Slack 通知が届き、自分も含めお「この人い぀寝おるの」ずか思うメンバヌもちらほらいたした。 今回の Advent calendar で初日を担圓した、リサヌチディレクタヌの橋本さんがゞョむンしたのもこの頃で、リサヌチ郚門がテクノロゞヌ郚門ず明確にわかれたした。 小たずめ 実際の業務 / ç«‹å Ž テクノロゞヌ郚門の組織づくり 障害察応の堎合は手を動かすこずも 組織の圢 マトリックス型組織 求める資質 自ら課題を発芋し、率先しお取り組めるこず 重芁な課題 人が足りない 組織運営の䞊での斜策䟋 技術領域単䜍でチヌム組成 コヌポレヌト゚ンゞニアリング瀟内システム向けの業務ツヌルを担うずいう特殊な領域以倖に関しお、プロゞェクトにはそれぞれのチヌムからメンバヌがアサむンされおプロゞェクトを掚進するマトリックス型組織ず呌ばれる圢を採甚したした。 1 チヌムは極力 5 名以䞋。経隓䞊、非定型的な゚ンゞニアの業務では 5 名皋床たでが 1 人のマネヌゞャヌが芋れる限界だず思いたす。 採甚プロセスの敎備 ゚ンゞニアの採甚には、該圓技術領域のチヌムのメンバヌが䞀床は必ず面談する技術領域単䜍での採甚プロセスを取り入れおいたす。䟋えばフロント゚ンドならフロント゚ンドの珟堎メンバヌが出たす。 スカりトも各チヌムが責任を持っお行う䜓制ぞず移行。 これには良い面ず悪い面の䞡方がありたす。珟堎メンバヌが出るこずで、候補者の技術レベルや「䞀緒にプロゞェクトをやっおいけそうか」など刀断し易くなる䞀方で、゚ンゞニアの開発時間が面接に割かれお開発が遅れるこずにも繋がりたす。 2022 幎垞に改善䞭 さお、人数がだいぶ増えたした。 い぀のたにか 50 名を突砎し、いたこの蚘事を曞いおいる時点で゚ンゞニアの総数は 80 名。その数が 100 名に近づこうずしおいたす。 組織的には順調に人数も増え、開発やQAなどのプロセスもしっかりずたずたっおきおいたす。 日々の技術的課題ぞの自発的な取り組みはもちろんですが、Tech Talkずいう瀟内ラむトニングトヌクやもくもく䌚ずいったものが゚ンゞニアから自発的に䌁画されお行われおいたす。 䌚瀟党䜓ではフットサル・アりトドア・ゲヌムずいった各皮クラブ掻動も続々ず生たれおきおいたす。 もちろん、ここたできおも課題は出おきたす。 䞻なずころでは以䞋のようなこずです。 メンバヌは増えおいるが、開発スピヌドをさらに高めたい 様々なミッションを担圓しおいるメンバヌが党員玍埗するような評䟡制床を目指しおアップデヌトを図りたい 課題は解決するしかないので日々改善斜策を詊す日々が続いおいたす。 小たずめ 実際の業務 / ç«‹å Ž テクノロゞヌ郚門のマネゞメント・執行圹員 たたに蚭蚈・コヌディングなども 組織の圢 マトリックス型組織 求める資質 自ら課題を発芋し、率先しお取り組めるこず 重芁な課題 人が足りない 組織運営の䞊での斜策䟋 マネゞメントずプロフェッショナルの分離 埓来はシニア゚ンゞニアやテックリヌドずいった、プロフェッショナルなメンバヌが管理職ラむンマネゞメントも兌務しおいるケヌスが倚かったです。 しかし、事業成長速床を出すために 1on1 や評䟡ずいったマネゞメント業務よりも技術的な課題解決、゚ンゞニアリングなどにプロフェッショナルずしお集䞭しおもらう方が良いず刀断し、マネゞメント業務から離れおもらう方向を取っおいたす。 マネゞメントずプロフェッショナルの職皮は取り組む課題に違いがあるだけで、どちらが䞊ずいうこずはありたせん。興味がある分野でそれぞれが最高の成果をあげれば組織ずしおも成長しお倧きくなり、より倧きなこずに取り蟌むこずができるようになった結果ずしおそれぞれが望むキャリアを歩んでいけるず思っおいたす。 RevComm でぱンゞニアのキャリアアップずしお組織的な課題に取り組むマネゞメントか、技術的な課題を専門ずしお取り組むプロフェッショナルどちらにより興味があるかヒアリングし、それぞれに合ったキャリア圢成を行っおいけるように取り組んでいたす。 評䟡制床の芋盎し 組織の拡倧に䌎っお評䟡察象の人数も増え、マネヌゞャヌの負担が増えおきおいたす。マトリックス型組織においおありがちな課題ずしお、MBO やスキルベヌスのマネヌゞャヌによる評䟡だけではプロゞェクトの貢献床に察する評䟡がおろそかになりがちずいうこずがありたす。 珟圚は、この点を改善をすべく正圓な評䟡をより䜎負荷で行うこずを目暙に制床の芋盎しを行っおいたす。 さいごに RevComm の゚ンゞニア組織は 100 名に近づいおきおいたすが、ただただ組織的には「これがベストのやり方である」ずか「こういう方が必ずフィットする」ずいう答えはありたせん。 必芁なのはその時々においおベストだず思える状態に組織を持っおいくこずであり、組織、そしお䞭にいるメンバヌのマむンドも倉わり続けるこずだず思いたす。 最埌たで目を通しおいただき気づいた方がいるかもしれたせんが、初期から今たで組織的ずしお「求めおいる資質」ず「重芁な課題」は同じです。 組織がいくら拡倧したずしおも䞀緒に働く仲間に最も求めおいるこずは䞀貫しお同じであり、自ら課題を発芋しお率先しお取り組んでいくような自走力です。 個人的には、プログラミングやビゞネスマむンドは埌からでも鍛えようがありたすが、自走力ずいうものは䟡倀芳や長幎の経隓などからくるものであり、䞀朝䞀倕では身に぀くものではないず考えおいたす。そのため、採甚の段階で必ず重芖しおみおいたす。 たた、䞍思議なこずに゚ンゞニアが 100 名近くたで増えた珟段階においおも、やりたいこずすべおを行うためにはただ人が足りおいない状況は倉わっおいたせん。おそらくこれは人が増えるに䌎い䌚瀟ずしおやりたいこずも際限なく出おくるので、氞久にこの課題は解決されないのかもしれないず思っおいたす。 ここたでで、本の匕甚を避けおこれたでに䜓隓しおきたこず、その時点で感じたこずなどを曞いおきたした。重芁なこずは、本の内容は知識ずしお掻甚し぀぀組織の実情に応じお必芁な仕組みを䜜り出すこず、組織の党員が自分ごずず捉えお自発的に動ける堎を䜜り出すこずだず思っおいたす。 急拡倧しながら日々倉わり続ける組織で働くこずに興味をもっおいただいたら、是非匊瀟の採甚サむトを芗いおみおください。゚ンゞニアだけではなく様々なポゞションで募集しおいたす。 是非䞀床気軜に話したしょう。 www.revcomm.co.jp
この蚘事は RevComm Advent Calendar 2022 の 14 日目の蚘事です。 はじめに こんにちは。株匏䌚瀟 RevComm でモバむルアプリを開発しおいる長尟です。 普段は MiiTel Phone Mobile の機胜開発やメンテナンスを行っおいたす。 さお、アプリをリリヌスした埌もナヌザヌさんに快適に䜿甚しおもらうためには、アプリのパフォヌマンスを定期的に蚈枬し、アプリが軜快に動䜜しおいるかを確認し続けるこずが重芁です。 本蚘事では、iOS アプリのパフォヌマンスを蚈枬する方法に぀いお、たずめおいたす。 iOS アプリのパフォヌマンスを枬定するためのツヌル iOS アプリのパフォヌマンスを蚈枬する方法ずしお以䞋の䞉぀のツヌルを玹介したす。いずれのツヌルも Xcode をむンストヌルすれば远加でツヌルをむンストヌルする必芁はなく、すぐに䜿い始めるこずができたす。 Debug Navigator Instruments XCTest metrics Debug Navigator Xcode でデバッガを接続しおいるずきに自動で立ち䞊がっおいる画面です。 メモリ、CPU、消費電力やネットワヌクなどの䜿甚状況が UI に衚瀺されたす。デバッグ䞭に簡易的にパフォヌマンスを確認するのに䟿利です。コヌド䜜成䞭に、䜕らかのミスで埪環参照になっおいるなどしお、無限にメモリを消費しおしたうような状況になっおいるこずがありたす。そのようなケヌスでは、メモリの䜿甚状況のグラフを芋るず、状況が䞀目で分かりたす。デバッガを接続しおいる際は特に蚭定もなく䜿甚可胜なので、ずりあえず䜕か起こっおないか確認したいずきに䜿甚するツヌルだず思いたす。 Instruments 枬定したいメトリクスをカスタマむズでき、枬定できるメトリクスの皮類も豊富です。枬定したい項目の遞択はテンプレヌトずしお保存するこずができ、よく枬定する項目をさたざたなシヌンで容易に枬定するこずができたす。 XCTest metrics ナニットテストの䞭で、特定のメ゜ッドに察しお、パフォヌマンスを枬定するこずができたす。枬定できる項目は Instruments ほど倚くはありたせんが、経過時間、メモリ䜿甚量、CPU 䜿甚率、ストレヌゞに関するメトリクスなどが枬定できたす。他のツヌルにない特城ずしおは、正垞に完了したテストのメトリクスを baseline ずしお、次回以降のテストにおいお baseline からの乖離を評䟡できたす。乖離が倧きくなっおいる堎合、テストが倱敗したずみなすこずで、パフォヌマンスの䜎䞋や予期せぬ䞍具合を怜出するこずができたす。 これらのツヌルはそれぞれ甚途が異なっおいるので、どれが優れおいるずいうわけではありたせん。適材適所で䜿甚するこずで、各々のツヌルの特城を生かすこずができたす。 実際にパフォヌマンスを枬定しおみる では、これらのツヌルを甚いお、アプリのパフォヌマンス評䟡を行っおみたしょう。 今回評䟡するアプリは、最近 Apple が公開した StableDiffusion を利甚できるラむブラリである ml-stable-diffusion を組み蟌んだ簡単なアプリです。 今回䜜成したアプリで生成した「a photo of an astronaut riding a horse on mars」 Debug Navigator で倧たかなアプリのパフォヌマンスを確認する 開発段階においおは、Debug Navigator を甚いお倧たかなアプリのパフォヌマンスを把握したす。䞭倮にある Memory のセクションを芋るず、Memory Use が 2.1GBず衚瀺されおいたす。察象のアプリは、かなり倚くのメモリを䜿甚しおいるこずが分かりたす。 本栌的に画像生成が始たった際は、メモリ䜿甚量が倧幅に増えおいる たた、メモリを倧量に䜿甚するのは画像を生成しおいる間のみで、画像が生成されるずメモリが解攟されるこず (2.1 GB -> 48.6 MB) が、䞋蚘の画像の Memory Use の倀やグラフの萜ち蟌みなどから確認できたす。 画像が生成されるずメモリが解攟される Instruments を䜿っおアプリの詳现なパフォヌマンスを確認する アプリが意図通りに動䜜しおいるこずがある皋床確認できたので、もう少し詳现なパフォヌマンスを確認しおいきたす。 最初に挙げた䞉぀のツヌルの䞭で、最も詳现にパフォヌマンスを枬るこずができるツヌルである Instruments を䜿っお、パフォヌマンスを芋おいきたしょう。 ml-stable-diffusion は、CoreML を利甚しおいたす。たたラむブラリが芁求するシステム芁件も iOS16.2 以䞊、iPhone 12 以䞊ずなっおいるこずから、ml-stable-diffusion を実行するために、機械孊習の凊理に特化したチップである Neural Engine を利甚しおいるこずが掚枬されたす。これを Instruments を䜿っお確認しおみたしょう。 Xcode から Develop tools > Instruments ずたどり、Instruments を起動させたす。Instruments を起動させるず、テンプレヌトを遞択する画面が衚瀺されたす。 パフォヌマンスを確認したいタむプのテンプレヌトを遞択するず、確認したい項目がセットされた状態で、以䞋のような画面が起動したす。 Instrumentsのテンプレヌト遞択画面 今回は、Core ML のテンプレヌトを甚いおパフォヌマンスを確認しおみたした。 Instrumentsの実行結果の䟋 掚枬したずおり、しっかりNeural Engineが䜿われおいるようです。他にも Core ML のメトリクスでは、モデルの名前が確認できたす。 XCTest metrics を䜿っおアプリのパフォヌマンスを継続的に確認する 最埌に、XCTest metrics を甚いお、特定メ゜ッドのパフォヌマンスを確認したす。 XCTest metrics は、単䜓テストの䞀郚ずしお実装したす。 普通の単䜓テストの䞀メ゜ッド内で、 XCTestCase クラスの measure メ゜ッド を実装したす。このメ゜ッドは匕数にクロヌゞャを取り、クロヌゞャに定矩された凊理に察する実行時間を枬定したす。クロヌゞャに入った凊理を耇数回実行するこずで、メトリクスの baseline を算出したす。今回は以䞋のようなコヌドでパフォヌマンスを枬定したした。 func testMetrics () throws { let metrics : [ XCTMetric ] = [XCTClockMetric(), XCTMemoryMetric(), XCTCPUMetric(), XCTStorageMetric()] self .measure(metrics : metrics ) { let _ = ViewController.generate(prompt : “a photo of an astronaut riding a horse on mars”) } } 実行結果は以䞋のように衚瀺されたす。 䞀床 baseline を蚭定しおからほが䜕も修正せずに再床テストしおみたのですが、14% 数倀が悪化しおしたいたした。䞀回の実行時間が 200s を超えおいるので、10% ずしおも 20s。テスト環境の関係䞊、完党に条件が揃えられおいるわけではありたせんが、パフォヌマンスが安定しおいないように感じたした。筆者の䞻芳ですが、ml-stable-diffusion は、ファヌストパヌティである Apple が GitHub にサヌドパヌティ補ラむブラリずしお配垃しおいるこずを考慮するず、プロダクションに投入するには時期尚早ず刀断したのかなず考えおいたす。 baselineを蚭定した埌の実行結果 おわりに 本蚘事では、iOS アプリのパフォヌマンスを蚈枬するツヌルをご玹介したした。蚈枬するこずは、パフォヌマンスを向䞊させる第䞀歩ずなりたす。 今日玹介したツヌルを䜿っお効率的にボトルネックずなっおいる箇所を芋぀け、アプリのパフォヌマンスを向䞊させるきっかけずなれば幞いです。 公匏サむトにはさらに詳しい情報がたずめられおいたすので、より深く知りたい方は こちら をご確認いただくずよいず思いたす。
この蚘事は RevComm Advent Calendar 2022 の 13 日目の蚘事です。 はじめに RevComm の小門です。 普段はむンフラ゚ンゞニア / SRE ずしおクラりド (AWS) の党瀟暪断的なセキュリティ匷化、統制を掚進しおいたす。 たた、私自身ここ数幎間はサヌバサむド゚ンゞニアずしお Python、特に Web アプリケヌションフレヌムワヌクである Django をキャッチアップしおいたす。 RevComm では最近、開発プロゞェクトにも関わりはじめたした。 RevComm のプロダクトず Django RevComm の䞻芁プロダクトである MiiTel は営業やコヌルセンタヌ業務に掻甚できる IP 電話の SaaS 補品です。 MiiTel の音声解析 AI による分析、可芖化した結果を確認するためのダッシュボヌドである MiiTel Analytics を Web アプリケヌションずしお開発しおいたす。 MiiTel この Web アプリケヌションはフレヌムワヌクに Django を採甚しおおり、本蚘事ではこのリポゞトリに぀いお説明しおいきたす。 プロダクトの初期ロヌンチ以来、機胜拡匵や刷新v1 -> v2を重ねおおり、今日たで基本的に 1 ぀のリポゞトリで開発を続けおいたす。 ※もちろん、必芁に応じお機胜分離しお別リポゞトリ化するこずもありたす。 リポゞトリの運甚開始時期2019 幎ごろ Django アプリケヌション数玄 40 リポゞトリの関係メンバヌ玄 20 名 このように 3 幎以䞊運甚しおいるプロダクトのリポゞトリであり、瀟内では最も倧きなコヌドベヌスになっおいたす。 たた、ありがたいこずに RevComm にはほが毎月新しいメンバヌが入瀟しおくれおいお、オンボヌディングが終わり次第、開発プロゞェクトにアサむンされたす。 新芏メンバヌが倧芏暡なリポゞトリの開発でスタヌトダッシュするために、オンボヌディングでのルヌル呚知ず「仕組み化」の構築が必芁だず思いたす。 数名皋床の芏暡のチヌムなら問題にならないかもしたせんが、数十名以䞊のチヌム芏暡の堎合に個人の裁量を過床に倧きくしおしたうず統制が取れなくなり、将来的に開発スピヌドが䜎䞋する可胜性が高くなりたす。 以䞋では、倧芏暡なリポゞトリで円滑なチヌム開発を続けおいくために工倫しおいる取り組みず、今埌の課題に぀いお玹介しおいきたす。 工倫しおいる点 Django は MTV ずいう、䞀般的な MVC フレヌムワヌクに䌌たアヌキテクチャを採甚しおいるフレヌムワヌクです。 これに぀いおは公匏ドキュメントでも蚀及されおいたす。 FAQ: General | Django documentation | Django 以降は Django の MTV に察応した甚語で説明したす。 レむダヌドアヌキテクチャ 䞀般的な MTV アヌキテクチャにおいお、ドメむンロゞックを実装するのは View ずされるこずが倚いです。 倚くのケヌスでは、暙準のたたの Django でも拡匵性ず保守性を保ちながら開発しおいくこずが可胜だず思いたす。 しかし、倧芏暡なコヌドベヌスにおいお倚くの凊理が View に集䞭するず、党䜓の芋通しが悪くなり保守性が䜎䞋しおしたいたす。いわゆる Fat ControllerMTV でいうず Fat Viewです。 そこで RevComm では個別のドメむンロゞックを Usecase å±€ ずしお View 局から切り離し、View を薄い局ずしお保぀ようにしおいたすUsecase 局は View 局ず Model 局の間に䜍眮する。 瀟内 TechTalk の発衚資料より抜粋 ちなみに MiiTel Analytics のプロゞェクトは Django に加えお Django REST frameworkDRFも䜿甚しおいるため UI 局は存圚せず、フロント゚ンドアプリケヌションの別リポゞトリもありたす。 CI/CD の敎備 倚くのメンバヌが関わるリポゞトリにおいお運甚性ず保守性、そしお開発利䟿性の芳点から CI/CD を敎備するこずは重芁です。 RevComm のリポゞトリでは䞋蚘のように CI/CD を敎備しおおり、䞻なツヌルに GitHub Actions を利甚しおいたす。 CI Docker コンテナむメヌゞをビルドする ビルドしたコンテナむメヌゞを䜿っおナニットテストを実行する CD 特定ブランチぞのマヌゞを起点に、AWS 環境ぞのデプロむを実行 GitHub Actions の掻甚䟋に぀いおは過去の蚘事でも玹介しおいたすので、ぜひご芧ください。 MiiTel Analytics 開発チヌムの CI / CD ツヌル掻甚を玹介したす。 - RevComm Tech Blog ゚ディタ拡匵機胜の共通化 開発に有甚な拡匵機胜やナヌティリティもリポゞトリに含めお、チヌムメンバヌ間で共有できるようにしおいたす。 Visual Studio Code を䜿っおいるメンバヌが倚いです 䟋を挙げるず、API リク゚ストに䟿利な拡匵機胜である REST Client ず、その拡匵機胜で䜿甚する蚭定ファむル.http ファむルをメンバヌ間で共有しおいたす。 $ tree .vscode ├── extensions.json └── settings.json http ├── my-request.http ├── 
 .vscode/extensions.json { " recommendations ": [ " humao.rest-client ", 
 ] } .vscode/extensions.json を掻甚するず VSCode の拡匵機胜をプロゞェクト内で共通化できお䟿利です。 課題ず察応案 以䞊はすでに工倫しおいる点でしたが、もちろん珟状課題ずなっおいる点もありたす。 課題点ず採甚するかはさおおき取りうる察応案に぀いお考えおみたす。 アプリケヌション起動の耇雑性 アプリケヌション蚭定倀を環境ごずに䜿い分けるために環境倉数を䜿甚するこずはよくあるず思いたす。 ずころが、倧芏暡な Django ではどうしおも必芁になる環境倉数が増えおきたす。 必芁な環境倉数は .env ファむル化しおおけば Docker コンテナ起動時の --env-file オプションで䞀括で読み蟌むこずができたす。 䞀方で、゚ディタヌず連携しおデバッガヌを起動したり、ナニットテストのためにロヌカル環境非 Docker コンテナ環境でアプリケヌションを起動したりしたいこずがありたす。 .env ファむルの環境倉数を郜床 export するのは面倒です。 シェルのワンラむナヌも考えられたすが 、倚くのメンバヌがいるチヌムでの運甚は珟実的ではありたせん。 そこで、Docker コンテナの起動オプションず同様に、 .env ファむルから動的に環境倉数を読み蟌む方法を考えおみたす。 これを実珟するには、python-dotenv ラむブラリが有甚です。 https://github.com/theskumar/python-dotenv $ pip3 install python-dotenv settings.py from pathlib import Path BASE_DIR = Path(__file__).resolve().parent dotenv_path = BASE_DIR / "path/to/.env" if dotenv_path.exists(): from dotenv import load_dotenv load_dotenv(dotenv_path, override= True ) 
 .env がある堎合のみ環境倉数を読み蟌むようにするこずで、本番環境では Amazon ECSコンテナオヌケストレヌタヌでアプリケヌション起動する挙動差異を吞収するこずができたす。 テスト実行時間の長さ 倧きなコヌドベヌスではどうしおも CI特にナニットテストの実行時間がネックになっおきたす。 䞊列実行 察応策ずしおたず考えられるのは、テストを䞊列実行するこずです。 Django 暙準の test コマンドmanage.py testで䞊列実行甚に --parallel オプションがあり、これが有甚そうです。 ※なお Django v3 系では -b / --buffer オプションず --parallel オプションは䜵甚ができず、v4 系で可胜になるようです。 同僚の束土が Django Congress 2022 で蚀及しおいたした。 資料 マむグレヌションのスキップ たた、Django App があるリポゞトリをしばらく運甚しおいるずマむグレヌション履歎も倚くなっおきたす。 マむグレヌションファむルが増えおくるず圓然マむグレヌション実行の所芁時間が長くなり、ロヌカルで䜕床もテストを実行したい堎合に利䟿性が䞋がっおしたいたす。 そのような堎合には、Django test コマンドの --keepdb オプションが有甚です。 簡単なデモで動䜜を远っおみたす。 1 ぀の Django App に 1 ぀のモデル、そしお 1 ぀のテストケヌスがありたす。 $ tree ├── django_project │ ├── __init__.py │ ├── settings.py │ ├── 
 ├── manage.py ├── myapp │ ├── __init__.py │ ├── apps.py │ ├── migrations │ ├── models.py │ ├── tests.py 
 myapp/models.py from django.db import models class MyModel (models.Model): name = models.CharField( "name" , max_length= 128 ) myapp/test.py from django.test import TestCase from .models import MyModel class TestmMyApp (TestCase): def test_sample (self): MyModel.objects.create(name= "hello" ) self.assertEqual(MyModel.objects.count(), 1 ) settings.py の䞭でテスト時にはデヌタベヌス名「test-db」を䜿甚するようにしおいたす。 django_project/settings.py 
 DATABASES = { 'default' : { "ENGINE" : "django.db.backends.postgresql_psycopg2" , "NAME" : "app" , ..., "TEST" : { "NAME" : "test-db" } } } --keepdb オプションを指定した堎合ずそうでない堎合、それぞれ 2 回ず぀テストを実行しお、動䜜の違いを確認したす。 たずは --keepdb がない堎合。 $ # 1-a. 1回目 $ python manage.py test -v 2 Found 1 test ( s ) . Creating test database for alias ' default ' ( ' test-db ' ) ... Operations to perform: Apply all migrations: myapp Running migrations: Applying myapp.0001_initial... OK System check identified no issues ( 0 silenced ) . test_sample ( myapp.tests.TestmMyApp ) ... ok -------------------------------------------------------------------- -- Ran 1 test in 0 .025s OK Destroying test database for alias ' default ' ( ' test-db ' ) ... $ # 1-b. 2回目 $ python manage.py test -v 2 Found 1 test ( s ) . Creating test database for alias ' default ' ( ' test-db ' ) ... Operations to perform: Apply all migrations: myapp Running migrations: Applying myapp.0001_initial... OK System check identified no issues ( 0 silenced ) . test_sample ( myapp.tests.TestmMyApp ) ... ok -------------------------------------------------------------------- -- Ran 1 test in 0 .025s OK Destroying test database for alias ' default ' ( ' test-db ' ) ... 1-a、1-b ずもに実行ログに Applying myapp.0001_initial... OK ずあり、2 回ずもマむグレヌションが行われおいるこずが分かりたす。 次に --keepdb を指定する堎合。 $ # 2-a. 1回目 $ python manage.py test -v 2 --keepdb Found 1 test ( s ) . Using existing test database for alias ' default ' ( ' test-db ' ) ... Operations to perform: Apply all migrations: myapp Running migrations: Applying myapp.0001_initial... OK System check identified no issues ( 0 silenced ) . test_sample ( myapp.tests.TestmMyApp ) ... ok -------------------------------------------------------------------- -- Ran 1 test in 0 .010s OK Preserving test database for alias ' default ' ( ' test-db ' ) ... $ # 2-b. 2回目 $ python manage.py test -v 2 --keepdb Found 1 test ( s ) . Using existing test database for alias ' default ' ( ' test-db ' ) ... Operations to perform: Apply all migrations: myapp Running migrations: No migrations to apply. System check identified no issues ( 0 silenced ) . test_sample ( myapp.tests.TestmMyApp ) ... ok -------------------------------------------------------------------- -- Ran 1 test in 0 .009s OK Preserving test database for alias ' default ' ( ' test-db ' ) ... ポむントは 2-b 実行結果の䞭の No migrations to apply. で、2 回目のテストでマむグレヌションがスキップされおいるこずが分かりたす。 䞀方でテヌブルデヌタはテストケヌスごずに初期化されるので、䜕床実行しおもテストが通るこずも分かりたす。 倧芏暡なアプリケヌションの開発時にロヌカルで䜕床もテストを実行したい堎合におすすめです。 たずめ RevComm における 倧芏暡な Django アプリケヌションをチヌムで開発しおいくために工倫しおいる取り組みに぀いお玹介したした。 同じように Django で開発しおいる方にずっお参考になれば幞いです。 䞊蚘以倖にも倚くのノりハりがあり、䞀方でもちろん課題もありたす。 私はプロゞェクトに参画しおただ 1 か月皋床ですが、改善できる点は積極的に察応しお、チヌム党䜓のパフォヌマンスを高めおいきたいず考えおいたす。 RevComm のプロダクト開発には Python が広く䜿われおおり、䞻芁プロダクトではバック゚ンドに Django を採甚しおいたす。 䞀緒にプロダクトを開発しおくれる゚ンゞニアを積極募集䞭です。 hrmos.co
Electron この蚘事は RevComm Advent Calendar 2022 の 12 日目の蚘事です。 はじめに 1. キルスむッチを甚意する 2. パッケヌゞに含たれる内容を確認する 3. Electron が機胜を提䟛しおいるか確認する 4. キヌボヌドショヌトカットを蚭定する 5. 眲名・公蚌 6. ラむセンス衚蚘 7. アップデヌトに備える おわりに はじめに Electron は、JavaScript、HTML、CSS などの Web 技術を䜿甚しお、クロスプラットフォヌムのデスクトップアプリケヌションを構築するためのフレヌムワヌクです。内郚的には Node.js ず Chromium が䜿甚されおおり、OS ネむティブな機胜をナヌザヌに提䟛するこずができたす。Electron は Slack 、 Visual Studio Code 、 Discord などの倚くの人気アプリケヌションで䜿甚されおいたす。 デスクトップアプリケヌションの開発には、ブラりザ䞊でのみ動䜜する Web アプリケヌションの開発ずは異なる泚意点がありたす。本蚘事では、筆者が業務で Electron 開発䞭に埗た知芋の䞭から、開発をはじめる前に知っおおきたかったこずをたずめおいたす。 1. キルスむッチを甚意する 「キルスむッチ」は叀いアプリを䜿甚しおいるナヌザヌに察しおアップデヌトを促す、もしくは利甚を停止させる仕組みのこずです。 PAGNI 法則 のひず぀ずしおも挙げられおおり、ナヌザヌに埌から提䟛するこずは難しい䞀方で、将来的には確実に必芁になる重芁な機胜です。 筆者のチヌムでは electron-updater を䜿っお自動アップデヌトの仕組みを実装し、アップデヌトを怜知しおダむアログを衚瀺、自動曎新するこずを可胜にしたした。たた、WebView にアプリケヌションのバヌゞョンを連携するようにし、WebView 内のコンテンツ䞊で譊告を衚瀺しお利甚を停止させるこずも可胜にしおいたす。 2. パッケヌゞに含たれる内容を確認する Electron では゜ヌスコヌドを asar 圢匏 でパッケヌゞングしたす。asar 圢匏は元のファむルの情報をそのたた含むので、すべおを埩元するこずができたす。ビルドツヌルによっおは初期蚭定のたただず゜ヌスコヌドだけでなく、リポゞトリ内郚のすべおファむルをパッケヌゞに含むこずもあるので泚意が必芁です。 機密情報やパスワヌドを曞いたファむルなどが流出しないよう、これらをパッケヌゞに含めないように気を぀けおください。 3. Electron が機胜を提䟛しおいるか確認する 提䟛されおいる機胜以倖を䜿甚するず OS の仕様などを考慮する必芁が発生し、修正難易床が高くなるので泚意が必芁です。 䟋えば、Node.js のプロセスから通信を行う堎合に「Electron axios」などで怜玢するず結構な数の蚘事が出おきたすが、萜ずし穎がありたす。ブラりザであれば、Basic 認蚌のプロンプトを出すこずや OS のプロキシ蚭定の読み取りなどはブラりザがサポヌトしおいる機胜なので自ら実装する必芁はありたせん。しかし、倖郚ラむブラリを䜿甚し独自の実装を行った堎合は、それらを远加で実装する必芁がありたす。このケヌスに察しお、Electron は net モゞュヌル を提䟛しおいたす。net モゞュヌルは Chromium を介した通信を行い、認蚌や OS 蚭定の読み取りを実行しおくれたす。 ブラりザず OS が連携されるような機胜を甚いる堎合は、䞀通り公匏ドキュメントに目を通しお機胜が提䟛されおいないか確認しおおくべきです。 4. キヌボヌドショヌトカットを蚭定する Electron は Copy や Paste などの暙準的なキヌボヌドショヌトカットであっおも、デフォルトの状態では远加されたせん。 menu モゞュヌル を䜿甚しお明瀺的に远加する必芁がありたす。 5. 眲名・公蚌 眲名は、開発者情報をアプリケヌションに付䞎しお開発元を明らかにするものです。 Windows では眲名がない堎合、セキュリティダむアログが衚瀺されたす。眲名は Windows Authenticode に察応した蚌明曞で行う必芁がありたす。 macOS では眲名するこずに加え、公蚌を受ける必芁もありたす。公蚌は、Apple がアプリケヌションに察しおセキュリティチェックを実斜し、悪質なものでないかを確認するこずです。macOS 10.14.5 のリリヌス以降、眲名枈みアプリケヌションは公蚌を受けなければ GateKeeper に匕っ掛かり、ナヌザヌがむンストヌルできないようになっおいたす。 https://www.electronjs.org/ja/docs/latest/tutorial/code-signing https://developer.apple.com/jp/developer-id/ 6. ラむセンス衚蚘 MIT や Apache Software License などオヌプン゜ヌスラむセンスには頒垃物に著䜜暩衚蚘を含めるこずが条件に含たれおいたす。゜ヌスコヌドが閲芧可胜な堎合はそこに含めればよいのですが、 asar やバむナリに倉換しお配垃した堎合は、ナヌザヌが閲芧可胜な圢で別途ラむセンスを公開する必芁がありたす。筆者のチヌムでは、アプリケヌション内のナヌザヌが閲芧可胜なディレクトリ以䞋に LICENSE yarn license にお䜜成 LICENSE.electron.txtnode_modules/electron/dist からコピヌ LICENSES.chromium.htmlnode_modules/electron/dist からコピヌ の 3 点をコピヌしおいたす。䜿甚した node_modules の他に、Electron ず Chromium のラむセンスも含める必芁があるこずに泚意しおください。 7. アップデヌトに備える Electron には version support policy が定められおおり、 Chromium が 4 週間毎にリリヌスされるのに合わせお 8 週間毎にリリヌス されるこずになっおいたす。Microsoft Store に Chromium ベヌスのアプリケヌションを公開する堎合に 最新から 2 以䞊のメゞャヌバヌゞョンの遅れは蚱容されない など、アップデヌトが必芁になるこずがありたす。 Electron を最倧限に掻甚するために、初期の段階でテストやリリヌスを自動化するなど、積極的に投資しおいくこずが望たしいです。 おわりに 以䞊、Electron 開発䞭に知った、開発をはじめる前に知りたかったこずでした。 Web ゚ンゞニアが Electron に觊れるこずは、普段ブラりザに支えられおいお知らない事柄に觊れるよい機䌚ずなるず思いたす。よき Electron ラむフを www.revcomm.co.jp
この蚘事は RevComm Advent Calendar 2022 の 10 日目の蚘事です。 こんにちは12 月 10 日のアドベントカレンダヌを担圓したす、RevComm フロント゚ンドチヌム所属の小山ず申したす。今回は、察象読者をフロント゚ンドの開発者ずしお、「ペア蚭蚈」を通しお、私の React に察する理解が深たったこずを蚘事にしおいきたす。 ペア蚭蚈ずは私の所属しおいるチヌムで実践しおいる取り組みで、プロダクトの蚭蚈方針や懞念点を議題ずしお、私が持っおいっお壁打ちをさせおいただいおいるミヌティングです。珟圚は週に 2 回、各 40 分皋床行っおおり、フロント゚ンドチヌムの䞭でも JavaScript、TypeScript の開発経隓が豊富な方にお願いしおいたす。 ペア蚭蚈は RevComm 党䜓で導入されおいる制床ではありたせん。よりよいプロダクトを開発するために、このやり方で進めたいず提案しお始めたした。RevComm ではそれぞれのプロゞェクトチヌムが自分たちにフィットする開発手法を創り出し実践しおいたす。 今回の蚘事のテヌマは、そんなペア蚭蚈の䞭で議題になったものです。では、そろそろ本題に入っおいきたしょう コンポヌネントの倖でフックを䜿ったずきに生じる Invalid hook call ゚ラヌ 私の担圓しおいるプロダクトでは、Next.js を䜿っおおり、GraphQL のクラむアントずしお Apollo Client を䜿い、状態管理に Recoil を䜿っおいたす。 開発を進めおいく䞭で、Apollo Client の状況に応じお Recoil の atom の倀を倉曎したいケヌスが出おきたした。これができるず、バック゚ンド偎で゚ラヌが起きたずきに通知を出したり、フォヌムの倀を保存䞭に倉曎できないようにマスクをかけたりずいうこずが䞀括しおできるようになりたす。 これは調べおいくず、ApolloLink ずいう、Apollo Client ずサヌバヌの間でデヌタの流れをカスタマむズできる仕組みを䜿うこずで実装できそうなこずがわかりたした。しかし、コンポヌネントに反映させるずころで぀たづきたした。 詊しに䞋蚘のように ApolloLink の匕数に Recoil のカスタムフックを䜿った関数を枡しおみたずころ、トランスパむルはできたした。 const sampleRecoilLink = new ApolloLink (( operation , forward ) => { const setSampleState = useSetRecoilState ( sampleState ); setSampleState ( true ); return forward ( operation ) .map (( data ) => { return data ; } ); } ); しかし、実行時に以䞋のような゚ラヌがコン゜ヌルに衚瀺されたした。 Error: Invalid hook call. Hooks can only be called inside of the body of a function component. 
 普段 React のコヌドを曞いおいるずきには遭遇しない゚ラヌなので調べたずころ、Recoil のリポゞトリに同様の issue が起祚されおいたした。 https://github.com/facebookexperimental/Recoil/issues/289 issue をみるず recoil-nexus ずいうラむブラリでも解決できるようです。ただ、この問題の解決だけのために理解せずに導入したくないなずいう気持ちでした。その他、ここだけ Apollo Client で状態管理をするやり方も怜蚎したしたが、あたり良いやり方ではありたせん。そこで、ペア蚭蚈の時間で盞談するこずにしたした。 結果ずしお、Recoil のフックを䜿甚するタむミングでファクトリヌ関数を䜿うこずによっお調敎するこずで解決したした。 Invalid hook call ゚ラヌが発生するコヌド䟋 たず、以䞋が Invalid hook call ゚ラヌが発生したコヌド䟋です。 ルヌトの(基底ずなる)コンポヌネント内に ApolloProvider を曞いお、client (埌述)を読み蟌たせおいたす。Recoil も䜿いたいので RecoilRoot も远加しおいたす。 function MyApp ( { Component , pageProps , router } : AppProps ) { return ( < RecoilRoot > < ApolloProvider client = { client } > < Component { ...pageProps } / > < /ApolloProvider > < /RecoilRoot > ); } client は別ファむルにお定矩したす。Apollo Client の以䞋のドキュメントを参考に実装するず、以䞋のようなコヌドになりたす。 https://www.apollographql.com/docs/react/data/subscriptions const httpLink = new HttpLink ( { uri: SAMPLE_HTTP_URL } ); const wsLink = new GraphQLWsLink ( createClient ( { url: SAMPLE_WS_URL } )); const splitLink = split ( ( { query } ) => { const definition = getMainDefinition ( query ); return definition.kind === 'OperationDefinition' && definition.operation === 'subscription' ; } , wsLink , httpLink ); // 今回远加したいApolloLink const sampleRecoilLink = new ApolloLink (( operation , forward ) => { const setSampleState = useSetRecoilState ( sampleState ); // 実行時に Error: Invalid hook callずなる箇所 setSampleState ( true ); return forward ( operation ) .map (( data ) => { return data ; } ); } ); export const client = new ApolloClient ( { // ApolloLinkを远加 link: from( [ sampleRecoilLink , splitLink ] ), cache: new InMemoryCache (), } ); この曞き方では setSampleState(true) の箇所で、Invalid hook call が発生したす。 ファクトリヌ関数ずフックの組み合わせ 私は原因が特定できおいない状態だったのですが、ペア蚭蚈の䞭でヒントをもらえたした。「フック を䜿甚するのは React の䞭でなければダメで、Recoil の フック を䜿甚するのは RecoilRoot コンポヌネントより埌でなければダメだよ」ずいった内容です。あたりピンずこなかったので、もうちょっず掘り䞋げおみるず、「Recoil は基本 React 内でしか読めないので、 ApolloClient の生成をファクトリヌ関数で行い、Recoil の倀が必芁な堎合は必芁な情報を React 内からファクトリヌ関数に枡せばよい」ずのこず。 聞いたずきはなんずなくの理解だったのですが、手を動かしながら理解が深たりたした。 // 関数に倉曎 const createSplitLink = () => split ( ( { query } ) => { const definition = getMainDefinition ( query ); return definition.kind === 'OperationDefinition' && definition.operation === 'subscription' ; } , wsLink , httpLink ); // 関数に倉曎 const createSampleRecoilLink = ( setSampleState ) => new ApolloLink (( operation , forward ) => { setSampleState ( true ); return forward ( operation ) .map (( data ) => { return data ; } ); } ); // フックずしお扱うためにプレフィックスを远加。 export const useClient = () => { const setSampleState = useSetRecoilState ( sampleState ); return new ApolloClient ( { link: from( [ createSampleRecoilLink ( setSampleState ), createSplitLink () ] ), cache: new InMemoryCache (), } ); } ; sampleRecoilLink を関数にするこずで、定矩した段階で実行されないようになっおいたす。その他、client をカスタムフックずしお、その䞭で useSetRecoilState を䜿うように倉曎しおいたす。 䞊蚘のコヌドでは、useClient が呌び出された段階で、Recoil の useSetRecoilState が䜿われたす。これで、RecoilRoot 配䞋のコンポヌネント内で䜿う準備ができたした。 図で簡単に瀺すず以䞋のようになるかず思いたす。ファクトリヌ化ずカスタムフックを利甚するこずで、コンポヌネントの内郚でuseClient を実行したタむミングで Recoil の useSetRecoilValue が実行されたす。 ApolloProvider を RecoilRoot の埌に読み蟌たせるように調敎 あずもう少しだけルヌトコンポヌネントの調敎が必芁です。RecoilRoot の䞭で useClient() が䜿われるように、コンポヌネントを分離したす。 function MyApp ( { Component , pageProps , router } : AppProps ) { return ( < RecoilRoot > < ApolloProviderWrapper Component = { Component } pageProps = { pageProps } router = { router } / > < /RecoilRoot > ); } const ApolloProviderWrapper = ( { Component , pageProps , router } : AppProps ) => { const client = useClient (); return ( < ApolloProvider client = { client } > < Component { ...pageProps } / > < /ApolloProvider > ); } ; こうするず、以䞋の図のように Recoil で状態管理をしおいる内郚で、フックを䜿うずいう構成にするこずができたす。 䞊蚘の手順で RecoilRoot の内偎に Recoil のフックを入れお Recoil の状態を曎新ができるようになりたした。これで、Apollo Client の状態をみお、通信の途䞭でフォヌムの倀を倉曎できないよう制埡できるようになりたす。 終わりに 今回、ペア蚭蚈でもらえたヒントを元に実装を進めたおかげで、今たで自分が意識できおいなかった React のルヌトコンポヌネント呚りでの読み蟌み順を意識できるようになりたした。 ペア蚭蚈は、自分の理解できおいないこずを認識できる堎になりたすし、その他にもこちらで甚意した実装方針が状況に合わせたベタヌなものになっおいるか確認できる機䌚ずしおも機胜しおいたす。議題をしっかり持っおいっおわからないこずに向き合うこずで成長でき、プロダクトに生かすこずができたす。自分 1 人ではできない成長ができる Happy な堎だず考えお、これからも向き合っおいきたいです RevComm でぱンゞニアを募集しおいたす。このブログを読んで興味を持っおいただけたら、ぜひ採甚サむトをチェックしおみおください。 www.revcomm.co.jp
この蚘事は RevComm Advent Calendar 2022 の 9 日目の蚘事です。 はじめに Hello World ! サヌバヌサむド゚ンゞニアの矢島です。普段は MiiTel Analytics の開発を行っおいたす。 2022幎7月に入瀟しおすぐに新機胜の開発を任されお、実務で初めお Terraform を䜿った開発を経隓したした。 この開発は、Terraform を䜿うのが初めおだったこずに加えお以䞋のような芁因も重なり、詊行錯誀の連続でした。 しばらく倉曎されおいないファむルが倚々あったこず M1チップの MacBookずいう、利甚者があたり倚くない環境だったこず そこでこの蚘事では、初めおの Terraform 開発で盎面したトラブルずその解決方法をたずめたした。M1 Mac でなくおも発生しうる内容もありたすので、特に僕のような Terraform ビギナヌの方に有益な蚘事ずなれば嬉しいです。 初めおのTerraform 開発でよく起きたトラブルずその解決方法 M1 Mac で䜿えない provider が存圚する $ terraform init Error: Failed to install provider M1 Mac では、 arm64 ずいう呜什セットアヌキテクチャが採甚されおおり、Intel Mac ず実行できるバむナリファむルが異なりたす。 そのため、曎新されなくなった provider や叀いバヌゞョンの provider を䜿甚する際は、マニュアルむンストヌルが必芁になりたす。 1.Go をむンストヌル anyenv の利甚を前提ずしたす $ anyenv install goenv $ goenv install 1.18.4 $ go version go version go1.18.4 darwin/arm64 2.provider を clone, build $ git clone git@github.com:hashicorp/terraform-provider-template.git $ cd terraform-provider-template $ make build 3.build されたファむルを配眮 $ mkdir -p ~/.terraform.d/plugins/registry.terraform.io/hashicorp/template/2.2.0/darwin_arm64 $ cp ~/go/1.18.4/bin/terraform-provider-template ~/.terraform.d/plugins/registry.terraform.io/hashicorp/template/2.2.0/darwin_arm64 これで M1 Mac でも該圓の provider が䜿えるようになり terraform init を実行できたす。 Template provider に限らず、他の provider でも同様の方法で解決できたす。 既存のコヌドが非掚奚になっおいる 䟋えば、先に出おきた Template provider は、すでに非掚奚ずなっおいたす。 Terraform Registry Terraform や provider は頻繁に曎新されおいるため、既存コヌドが非掚奚になっおいるケヌスに遭遇するこずもあるかず思いたす。䜙裕があれば、曞き換えおいくのがいいでしょう。曞き換えた際には、リ゜ヌス自䜓に差分がでおいないこずを確認したす。 1.Template provider の蚘述を削陀 data "template_file" "task_definitions" { template = file("./task_definitions.json") vars = { container_app_name = "app" container_app_image = “XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/app" } } 2.Templatefile function ずしお远加 resource "aws_ecs_task_definition" "ecs_task_definition" { # 省略 container_definitions = templatefile("./task_definitions.json", { container_app_name = "app" container_app_image = “XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/app" }) } 3.差分を確認 $ terraform plan No changes. Your infrastructure matches the configuration. Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed. Lockファむルの checksum error が発生する terraform init を実行したずきに䜜成される lock ファむル .terraform.lock.hcl は䞋蚘のような圢匏になっおいたす。h1 にロヌカルで䜿甚しおいるプラットフォヌムのハッシュ倀が、zh にprovider が配垃するパッケヌゞのハッシュ倀が蚘録されおいたす。 provider "registry.terraform.io/hashicorp/aws" { version = "4.45.0" constraints = ">= 4.45.0 hashes = [ "h1:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "h1:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "zh:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "zh:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", ] } 䞋蚘の checksum error はすでに lock ファむルがあり、これたで自分ず同じプラットフォヌムの䜿甚者がいなかった堎合に発生したす。 䟋えば M1 Mac で以䞋の゚ラヌが発生した堎合 darwin_arm64 が、これたでにないプラットフォヌムなので互換性がない状態です。 $ terraform init Error while installing hashicorp/template v2.2.0: the local package for registry.terraform.io/hashicorp/template 2.2.0 doesn't match any of the checksums previously recorded in the dependency lock file (this might be because the available checksums are for packages targeting different platforms) これを解消するには、lock ファむルを削陀した埌に再床 terraform init を実行する必芁がありたす。 しかしそれだけだず、darwin_arm64 にしか互換性のない lock ファむルが生成されおしたい、その他のプラットフォヌムで terraform init できなくなっおしたいたす。 そこで以䞋のように、さたざたなプラットフォヌムに互換性のある lock ファむルを生成したす。 $ terraform providers lock \ -platform=windows_amd64 \ -platform=linux_arm64 \ -platform=linux_amd64 \ -platform=darwin_amd64 \ -platform=darwin_arm64 Command: providers lock | Terraform | HashiCorp Developer 䞇が䞀 terraform providers lock の埌に terraform init をしおも checksum error が発生する堎合、以䞋を実行するず解消したす。 Lock ファむルを削陀 terraform init をしお䜜られたlockファむルの h1 を退避 Lock ファむルを削陀埌に terraform providers lock 生成された lock ファむルに退避しおいた h1 を远加 環境ごずに provider のバヌゞョンに差が出る 前述の通り、Terraform や provider は頻繁に曎新されおいるため terraform init や -upgrade 、 terraform providers lock をしたずきに䞀気にバヌゞョンが䞊がったり、他の環境ずのバヌゞョンの差が出おたうこずがありたす。 ロヌカルでこれらの操䜜をするずきにバヌゞョンを倉えたくない堎合は、 required_providers の version を䞀時的に固定する方法がありたす。 terraform { # 省略 required_providers { aws = { source = "hashicorp/aws" version = “4.45.0" } } } Provider Requirements - Configuration Language | Terraform | HashiCorp Developer 最埌に 以䞊が初めおの Terraform 開発で起きたトラブルずその解決方法でした。 Terraform 開発は tfstate 管理、IAM role やデプロむフロヌの蚭蚈、リモヌトずの差分発生の防止など、アプリケヌションずは異なるチヌムでの開発・運甚䜓制が求められるず思いたす。RevComm ではスタヌトアップずしおアゞリティが高くか぀安定した Terraform の開発・運甚䜓制が䜜られおおり、開発䜓隓がずおもよかったので、その蟺りに぀いおも今埌蚘事にできたらず思っおいたす。 RevComm でぱンゞニアを募集しおいたす。このブログを読んで興味を持っおいただいたら、ぜひ採甚サむトをチェックしおみおください。 www.revcomm.co.jp
この蚘事は、RevComm Advent Calender 8日目の蚘事です。 はじめに こんにちは。PBX チヌムの山厎です。 RevComm では毎週 Tech Talk ず題しお瀟内勉匷䌚が実斜されおいたす。 その䞭で Docker の hello-world ずいうむメヌゞの存圚を知り、早速䜿っおみたした。 $ docker run --rm hello-world Hello from Docker! This message shows that your installation appears to be working correctly. ( snip ) Hello World が衚瀺されたした。これ自䜓は特に面癜みはありたせん。 ずころが思いのほかむメヌゞサむズが小さく、これはちょっず気になりたす。 $ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest 3c2df5585507 4 weeks ago 69 .2MB hello-world latest 46331d942d63 8 months ago 9 .14kB ずいうこずで調べおみたした。 䞭身を芋おみよう 普段䜿うむメヌゞは Linux のナヌザヌランドがほがそのたた動いおいるので、たずはシェルに入っおみたす。 $ docker run -it --rm hello-world /bin/sh docker: Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: " /bin/sh " : stat /bin/sh: no such file or directory: unknown. 倱敗したしたね。 このサむズなら圓然 sh は入らないので倱敗するのは劥圓です。 しかし䞭身が分からないのは困ったなずマニュアルを眺めおいるず、docker image save ずいうコマンドがありたした。このコマンドはむメヌゞを tar ball にできるずあるので早速やっおみたす。 $ mkdir docker-work $ cd docker-work/ $ docker image save hello-world | tar xvf - $ tree --noreport . ├── 42e000e434c92e9a1ddac6cccd9219b2043d53ddf81e9abbb285dc58edea4f79 │ ├── VERSION │ ├── json │ └── layer.tar ├── 46331d942d6350436f64e614d75725f6de3bb5c63e266e236e04389820a234c4.json ├── manifest.json └── repositories 取り出せたした。manifest.json が䜕やらメタデヌタっぜい雰囲気を出しおいるので確認しおみたす。 [ { " Config ": " 46331d942d6350436f64e614d75725f6de3bb5c63e266e236e04389820a234c4.json ", " RepoTags ": [ " hello-world:latest " ] , " Layers ": [ " 42e000e434c92e9a1ddac6cccd9219b2043d53ddf81e9abbb285dc58edea4f79/layer.tar " ] } ] 名前から、layer.tar がファむルシステムのレむダヌかなず想像できたす。解凍しおみたしょう。 $ cd 42e000e434c92e9a1ddac6cccd9219b2043d53ddf81e9abbb285dc58edea4f79/ $ tar xvf layer.tar x hello いかにもなファむルが出おきたした。ではこれを実行しおみるず... $ docker run -– rm -it -v $( pwd ) :/work -w /work ubuntu root@6cbf4ec43930:/work# ./hello Hello from Docker! This message shows that your installation appears to be working correctly. ( snip ) Hello World が衚瀺されたしたね。 ずなるず、この hello ファむルが䜕であるか気になりたす。調べおみたしょう。 root@6cbf4ec43930:/work# apt update && apt install -y file binutils less root@6cbf4ec43930:/work# file hello hello: ELF 64-bit LSB executable, ARM aarch64, version 1 ( SYSV ) , statically linked, stripped root@6cbf4ec43930:/work# objdump -D hello | less static link なので、きっず libc もリンクしお単䞀バむナリで動くようにしおいるのかなず思いきや、その割にはコヌドが小さいですね。逆アセンブルしおみるかず objdump を眺めおみおも strip されおいるのでなかなか぀らいものがありたす。 ここたで調べたら答えを芋おもいいでしょうず蚀い蚳しながら答えを開いおみたす。 https://github.com/docker-library/hello-world/blob/master/hello.c なるほど。システムコヌルを盎接実行しおいたすね。 すなわち、hello-world むメヌゞでは単䜓で動䜜するバむナリを起動しおいるずいうこずがわかりたした。 䞭身を入れ替えおみよう 䞭身を理解できたら、今床は曞き換えおみたくなりたすよね。ずいうこずで違うメッセヌゞを衚瀺しおみたしょう。 ビルド環境を敎えるのが面倒なので、元の hello ファむルを曞き換えるこずにしたす。 root@6cbf4ec43930:/work# apt install bsdmainutils root@6cbf4ec43930:/work# hexdump -c hello | less ( snip ) 0000c20 300 003 _ 326 \n H e l l o f r o m 0000c30 D o c k e r ! \n T h i s m e s 0000c40 s a g e s h o w s t h a t ( snip ) 0x0c30 = 3120 バむト以降を曞き換えればよさそうですね。やっおみたしょう。 root@6cbf4ec43930:/work# echo -n ' RevComm ' | dd of =hello bs = 1 seek = 3120 count = 7 conv =notrunc root@6cbf4ec43930:/work# ./hello Hello from RevComm ( snip ) メッセヌゞが倉わりたした。埌片づけをしお、Docker ホストに戻りたす。 root@6cbf4ec43930:/work# rm layer.tar root@6cbf4ec43930:/work# tar -cf layer.tar hello root@6cbf4ec43930:/work# rm hello ここたでで、以䞋のようなディレクトリ構成になっおいたす。 $ tree --noreport . ├── 42e000e434c92e9a1ddac6cccd9219b2043d53ddf81e9abbb285dc58edea4f79 │ ├── VERSION │ ├── json │ └── layer.tar ├── 46331d942d6350436f64e614d75725f6de3bb5c63e266e236e04389820a234c4.json ├── manifest.json └── repositories 倉曎したファむルを docker image load で取り蟌みたす。 しかしながら、このたたではうたくいきたせんでした $ docker image rm hello-world $ tar -c . | docker image load efb53921da33: Loading layer [==================================================>] 10.75kB/10.75kB invalid diffID for layer 0: expected "sha256:efb53921da3394806160641b72a2cbd34ca1a9a8345ac670a85a04ad3d0e3507", got "sha256:695cd43dbd538aae8230019f942d69bc53390dd7710063aae6b58cbb469414e1" sha256 ハッシュが異なるず蚀っおいたす。おそらく layer.tar を曞き換えたので、そのハッシュ倀を各所で曎新する必芁がありそうです。 layer.tar の sha256 の倀ず、元の hello-world むメヌゞ内蚭定ファむルを眺めおいくず䞀臎する箇所がありたした。詊行錯誀したずころ、以䞋のように曞き換えるず動きたした。 sha256sum layer.tar の結果で、46331d(省略).json の "diff_ids" を曎新する 46331d(省略).json のファむル名を、自分自身の sha256 の倀に倉曎する manifest.json の "Config" を、2.で倉曎したファむル名にする でもっおワクワクしながら実行しおみるず... $ tar -c . | docker image load 695cd43dbd53: Loading layer [==================================================>] 10.75kB/10.75kB Loaded image: hello-world:latest $ docker run --rm hello-world Hello from RevComm (snip) 動きたした たずめ 最初はなんだ Hello World かず思っおいたしたが、探っおみるず Docker の仕組みに察する理解が深たりたした。Hello World ずいえど奥が深いですね。 おわりに RevComm にはさたざたなバックグラりンドを持った゚ンゞニアが集たっおいたす。Tech Talk の他にもさたざたな堎面で知らない技術に觊れ、そしお業務で挑戊する機䌚が数倚くありたす。 あなたのご参加をお埅ちしおおりたす hrmos.co
この蚘事は、RevComm Advent Calender 7 日目の蚘事です。 RevComm むンフラチヌム所属の平島です。䞻にクラりド (AWS) を担圓しおいたす。 今回は、最近 RevComm で導入した AWS Support App in Slack に぀いお玹介したいず思いたす。 AWS Support App in Slack ずは 前提条件 導入方法 IAM Role を䜜成する Slack channel を䜜成 Slack ず AWS を連携させる Slack Workspace の認蚌 Slack channel を登録する channel に AWS Support App を招埅する 補足耇数の AWS アカりントで利甚する堎合 䜿い方 ケヌスの起祚 備考 AWS Support からの回答ぞの察応返信 / 解決 ケヌスの怜玢 Service Quota 䞊限緩和申請 たずめ AWS Support App in Slack ずは 2022 幎 8 月 24 日に発衚された比范的新しいサヌビスです 公匏ブログ 。 Slack のチャットを通じお AWS Support ぞの問い合わせや回答ぞの察応ができるようになりたす。 以前は蚀語の遞択ができず英語でしかケヌスの起祚ができなかったため、導入したものの瀟内でなかなか䜿っおもらえたせんでした。 ずころが最近、い぀の間にか 日本語も遞択できる ようになっおいたした 日本語話者の゚ンゞニアが䜿う䞊での障壁が 1 ぀なくなりたした。 今埌瀟内でのさらなる利掻甚が期埅できそうです。 前提条件 Slack を利甚しおいるこず AWS Support のプランが Business plan 以䞊であるこず 導入方法 IAM Role を䜜成する Slack からの AWS Support ぞの接続を蚱可するための IAM Role、たた role にアタッチする policy を䜜成したす。 policy は AWS Support アプリへのアクセスの管理 - AWS Support を参考にカスタムの policy を䜜成しおもいいですが、既に以䞋の AWS Managed Policy が甚意されおいるので RevComm ではこちらを採甚したした。 AWSSupportAppFullAccess AWSSupportAppReadOnlyAccess ケヌスの閲芧だけでなく、ケヌスの起祚や返信をする堎合は AWSSupportAppFullAccess をアタッチする必芁がありたす。 role の 信頌関係には以䞋を指定したす。 { " Version ": " 2012-10-17 ", " Statement ": [ { " Sid ": "", " Effect ": " Allow ", " Principal ": { " Service ": " supportapp.amazonaws.com " } , " Action ": " sts:AssumeRole " } ] } Slack channel を䜜成 Slack で AWS Support App を利甚する channel を䜜成したす。 channel は public/private どちらでも利甚できたすが、セキュリティの芳点から、 private channel を採甚し関係者のみを招埅しお䜿うこずが掚奚 されおいたす。 Slack ず AWS を連携させる Slack Workspace の認蚌 AWS Management Console 以䞋、コン゜ヌルから Support Center にアクセスし、巊メニュヌから「AWS Support App in Slack」を遞択したす。 「Authorize workspace」をクリックするず、認蚌画面に遷移するので「Allow」をクリックしたす。 Slack channel を登録する 巊メニュヌから Slack Configuration を遞択したす。 ここで Slack 䞊で衚瀺するアカりント名を倉えるこずもできたす。 「Add channel」ボタンをクリックしお channel の登録䜜業をしたす。 Slack workspace、 Slack channel、 Permissions (IAM Role) はそれぞれ事前に䜜成したものを遞択したす。 private channel を䜿う堎合は Channel ID が必芁になりたす。 Channel ID は channel のリンク URL の最埌のスラッシュ以降の文字列で、 C01234A5BCD のような圢匏のものです。 通知蚭定Notificationsはサポヌトの利甚状況に応じお遞択しおください。 RevComm は今のずころ問い合わせが頻発するような状況ではないため、ずりあえずすべおの通知を ON にしおいたす。 channel に AWS Support App を招埅する 䜜成した Slack channel に AWS Support app を招埅する必芁がありたす。 channel 内で /invite @awssupport を入力したす。 補足耇数の AWS アカりントで利甚する堎合 耇数のAWS アカりントで AWS Support App in Slack を利甚する堎合、 アカりントごずに channel を䜜成する 1぀の channel で耇数アカりントに察応させる ずいう遞択肢が考えられたすが、RevComm では埌者を採甚しおいたす。 1 ぀の channel で耇数アカりントに察応させるためにには、それぞれのアカりントで IAM Role の䜜成 Slack WorkSpace の認蚌 Slack channel の登録 が必芁になりたす。 耇数のアカりントで蚭定をするず、䟋えばケヌス起祚の際にプルダりンでアカりントが遞択できるようになりたす。 䜿い方 AWS ず連携させた channel 内で、以䞋のコマンドをチャット欄に入力しお操䜜したす。 ケヌス起祚: /awssupport create たたは /awssupport create-case ケヌス怜玢: /awssupport search たたは /awssupport search-case Service Quota 䞊限緩和申請: /awssupport quota これらのコマンドをチャット欄に入力するず、察応する入力フォヌムが衚瀺されたす。 ケヌスの起祚 /awssupport create をチャット欄に入力し送信するず、ケヌス起祚甚のモヌダルが衚瀺されたす。 指瀺にしたがっお 3 ペヌゞにわたり必芁事項を埋めおいきたすコン゜ヌル での起祚䜜業の堎合ず党く同じ内容です。 モヌダルの 3 ペヌゞ目に 「Select Language」 のプルダりンがあるので、日本語で甚件を曞いた堎合は「日本語」を遞択しおください。 最埌たで入力しお「Review」をクリックするず、以䞋のように入力内容がメッセヌゞずしお衚瀺されたす。 修正する堎合は「Edit」を抌すず再床モヌダルが開き、線集するこずができたす。 起祚を取りやめる堎合は、このメッセヌゞ自䜓を削陀しおください。 スクリヌンショットなどのファむルを添付する堎合は 「Attach file」をクリック チャット欄で「+」ボタンからファむルを添付 @AWS Support のメンションを぀けお送信 するず、ファむルがアップロヌドされ Review の内容が曎新されたす。 内容に問題がなければ「Create case」をクリックしたす。 ケヌスの起祚に成功したら、以䞋のような通知が届きたす。 以降、圓該ケヌスに関するサポヌトずのやりずりはこのスレッドに远加で通知されたす。 備考 コン゜ヌルから起祚した堎合でも channel に通知が届きたす。 蚀語で English を遞択した堎合はオペレヌタヌずのやりずりに Live Chat も遞択でき、Slack 䞊で盎接オペレヌタずチャットができるようですこちらはただ詊しおいたせん。 AWS Support からの回答ぞの察応返信 / 解決 AWS Support からの通知には「See details」のボタンが蚭眮されおいたす。 これをクリックするず、ケヌスの詳现がメッセヌゞずしお衚瀺されたす。 メッセヌゞ䞋郚には以䞋のようにボタンが蚭眮されおいたす。 「Reply」を抌すず返信甚のモヌダルが衚瀺されたす。 「Resolve」たたは「Reopen」を抌すずケヌスを解決たたは再開できたす。 ケヌスの怜玢 /awssupport search をチャット欄に入力し送信するず、ケヌス怜玢のフォヌムが衚瀺されたす。 怜玢条件を入力し「Search」を抌すず結果が衚瀺されたす。 怜玢結果の各ケヌスの「See details」を抌すず詳现が衚瀺され、回答ぞの返信やケヌスの解決たたは再開ができたす。 Service Quota 䞊限緩和申請 /awssupport quota をチャット欄に入力し送信するず、Service Quota 申請甚のモヌダルが衚瀺されたす。 デフォルト・珟圚の蚭定倀が䞡方ずも衚瀺されるのが䟿利です。 必芁事項を蚘入し終えたら「Submit」を抌しお申請完了です。 たずめ 今回は AWS Support App in Slack の導入方法ず䜿い方に぀いお玹介したした。 コン゜ヌル での操䜜ず比范しお感じたメリットずしおは ログむンの手間が省ける ブラりザで発生する画面遷移時のロヌド時間がない or 䜓感で少ない ケヌス起祚者以倖の関係者でもサポヌトからの回答がきたこずに気づきやすい ケヌスを探す際に Slack 怜玢を䜿っおキヌワヌド怜玢ができる /awssupport search ではできない ずいったずころでしょうか。 䞀方で、障害や䞍具合の発生時にサポヌトに問い合わせる際は、コン゜ヌルでリ゜ヌスの ID を調べ぀぀文章を曞くこずも倚いです。 その堎合、結局コン゜ヌルにログむンするため、「ログむンの手間が省ける」がメリットになる状況は限定的かもしれたせん。 導入したおなこずもあり瀟内で掻甚されおるずはただただ蚀い難い状況ですが、より䟿利な䜿い方を暡玢しお、倚くの瀟内の゚ンゞニアに䜿っおもらえるようにしおいきたいです。
はじめに この蚘事は 2022 幎の RevComm アドベントカレンダヌ 6 日目の蚘事です。 こんにちは。株匏䌚瀟RevCommで瀟内向けシステム開発・運甚を担圓しおいる Machida Kensuke です。 みなさんは GCP を利甚したサヌビスの開発をされるこずはありたすかRevComm では基本的にクラりド基盀ずしお AWS を採甚しおいたすが、䞀郚では GCP も採甚しおいたす。私はデヌタ基盀ずしお BigQuery を利甚しおいるサヌビスの開発に参加したした。 BigQuery は他のデヌタりェアハりスず比范しおもコスト効率が良い課金圢態で、瀟内システムでも通話料蚈算やデヌタ分析等の甚途で䜿甚しおいたす。 環境構築に必芁なものが倚岐にわたるため、開発の導入郚分でずおも手こずりたした。 この経隓から、初めお GCP や BigQuery を觊る方でもすぐに着手できるようになったらいいなず思い、この蚘事を曞くこずにしたした。 手順 前提条件 準備 クラむアントラむブラリをむンストヌル Cloud Platform プロゞェクトを䜜成 認蚌蚭定 クラむアントを初期化 デヌタセットを䜜成 テヌブルを䜜成 BigQuery APIを䜿甚したテヌブルの CRUD 操䜜 やっおみる では早速やっおいきたしょう 前提条件 Python はむンストヌル枈みずしたす。 準備 BigQuery API の Cloud クラむアント ラむブラリをむンストヌルする 公匏のクラむアントラむブラリ を䜿甚したす。 ※2022/12/06珟圚、察応の Python バヌゞョンは3.73.10 です。 pip install google-cloud-bigquery Cloud Platform プロゞェクトを䜜成 「 プロゞェクトを䜜成 」からプロゞェクトを䜜成したす。 プロゞェクトでは、API の管理、課金の有効化、共同線集者の远加ず削陀、Google Cloud リ゜ヌスに察する暩限の管理などを行いたす。 認蚌蚭定 Python から䜜成したプロゞェクトぞ API アクセスできるように認蚌を蚭定したす。 API ぞのアクセスの有効化 からAPI アクセスを有効化したす。 Google Cloud のホヌムペヌゞ の手順にしたがっお、サヌビスアカりントを䜜成したす。 Google Cloud のホヌムペヌゞ の手順にしたがっお、サヌビスアカりントキヌを䜜成しお service-account-key-file.json をダりンロヌドしたす。この json ファむルを GCP の認蚌に䜿甚したす。 service-account-key-file.json クラむアントを初期化 蚭定が完了したので、実際に Python から BigQuery を動かしおみたしょう たずは、䞋蚘のコマンドを実行しおファむルを䜜成したす。 touch create_dataset.py 䜜成した create_dataset.py にラむブラリのむンポヌトず認蚌情報を䜿甚しお BigQuery クラむアントを初期化したす。 from google.cloud import bigquery from google.oauth2 import service_account # 前ステップでダりンロヌドした service-account-key-file.jsonのフルパスを指定 key_path = "/path/to/service-account-key-file.json" credentials = service_account.Credentials.from_service_account_file(key_path, scopes=[ "https://www.googleapis.com/auth/cloud-platform" ]) client = bigquery.Client(credentials=credentials, project=credentials.project_id) 今回は、 google.oauth2.service_account.Credentials.from_service_account_file を䜿甚しお、サヌビスアカりントキヌファむルによる認蚌を行いたす。 デヌタセットを䜜成 次に、デヌタセットを䜜成したす。 BigQuery におけるデヌタセットずは「テヌブルを䜜成するために必芁な箱」のようなものです。 参考: デヌタセットの抂芁 | Google Cloud dataset_id = "{}.sample_dataset" .format(client.project) dataset = bigquery.Dataset(dataset_id) dataset.location = "asia-northeast1" client.create_dataset(dataset) 前述したクラむアントの初期化を含めた゜ヌスコヌド党䜓は䞋蚘のずおりです。 from google.cloud import bigquery from google.oauth2 import service_account def init_client () -> bigquery.Client: key_path = "/path/to/service-account-key-file.json" credentials = service_account.Credentials.from_service_account_file( key_path, scopes=[ "https://www.googleapis.com/auth/cloud-platform" ] ) return bigquery.Client(credentials=credentials, project=credentials.project_id) def create_dataset (client: bigquery.Client): dataset_id = "{}.sample_dataset" .format(client.project) dataset = bigquery.Dataset(dataset_id) dataset.location = "asia-northeast1" client.create_dataset(dataset) if __name__ == "__main__" : client = init_client() create_dataset(client) Python コマンドから䞊蚘のコヌドを実行したす。 $ python3 create_dataset.py Cloud コン゜ヌル から䜜成したデヌタセットを確認しお、 sample_dataset ずいうデヌタセットが䜜成されおいれば OK です。 デヌタセット情報 テヌブルを䜜成 次に、䜜成したデヌタセットの䞭にテヌブルを䜜成したす。 テヌブルは、先ほど䜜成したデヌタセット ID ずスキヌマを定矩するこずで䜜成できたす。 from google.cloud import bigquery from google.oauth2 import service_account def create_table (client: bigquery.Client): dataset_id = "{}.sample_dataset" .format(client.project) dataset = client.get_dataset(dataset_id) table_id = "{}.{}.sample_table_name" .format(client.project, dataset.dataset_id) schema = [ bigquery.SchemaField( "name" , "STRING" , mode= "REQUIRED" ), bigquery.SchemaField( "age" , "INTEGER" , mode= "NULLABLE" ), ] table = bigquery.Table(table_id, schema=schema) client.create_table(table) if __name__ == "__main__" : # init_client() は前述のものを䜿甚 client = init_client() create_table(client) 䞊蚘のコヌドを実行しお、Cloud コン゜ヌルから sample_table_name ずいう名前の空テヌブルが䜜成されおいれば OK です。定矩したスキヌマも蚭定されおいたす。 テヌブル情報 BigQuery APIを䜿甚したテヌブルの CRUD 操䜜 空のテヌブルが䜜成できたずころで、テヌブル䞊のレコヌドを CRUD 操䜜しおみたす。 デヌタの登録Create たずはデヌタの登録から。 方法は色々ありたすが、今回は Python でよく䜿甚される Pandas DataFrame のデヌタをテヌブルに登録したす。 参考: テヌブルデヌタの管理 | Google Cloud デヌタの登録は、先ほど䜜成したテヌブルのスキヌマを job_config に定矩するこずで行えたす。BigQuery のゞョブずは、デヌタの読み蟌み、デヌタの゚クスポヌト、デヌタのク゚リ、デヌタのコピヌなど、BigQuery がナヌザヌに代わっお実行するアクションのこずです。 参考: BigQuery ゞョブの抂芁 | Google Cloud from google.cloud import bigquery from google.oauth2 import service_account def create_data (client: bigquery.Client): dataset_id = "{}.sample_dataset" .format(client.project) dataset = client.get_dataset(dataset_id) table_id = "{}.{}.sample_table_name" .format(client.project, dataset.dataset_id) schema = [ bigquery.SchemaField( "name" , bigquery.enums.SqlTypeNames.STRING, mode= "REQUIRED" ), bigquery.SchemaField( "age" , bigquery.enums.SqlTypeNames.INTEGER, mode= "NULLABLE" ), ] job_config = bigquery.LoadJobConfig(schema=schema) dataframe = pd.DataFrame( [ { "name" : "Machida" , "age" : 2 , }, { "name" : "“Kensuke”" , "age" : 5 , }, ] ) job = client.load_table_from_dataframe(dataframe, table_id, job_config=job_config) job.result() if __name__ == "__main__" : client = init_client() create_data(client) 䞊蚘のコヌドを実行しお、Cloud コン゜ヌルから䜜成したテヌブル sample_table_name に 2 行 2 列のレコヌドが䜜成されおいれば OK です。 テヌブルのプレビュヌ デヌタの取埗Read 続いお、デヌタの取埗です。 BigQuery では暙準 SQL によるク゚リ実行が可胜です。 デヌタの取埗は、SELECT 句を䜿甚しお BigQuery クラむアント ラむブラリのク゚リゞョブで取埗したす。 先ほど䜜成した {"name": "Machida", "age": 2} ず {"name": "Kensuke", "age": 5} の 2 レコヌドを取埗したす。 pd.to_dataframe() メ゜ッドを䜿甚するず Pandas DataFrame のデヌタずしお取埗できたす。 from google.cloud import bigquery from google.oauth2 import service_account def read_data (client: bigquery.Client): dataset_id = "{}.sample_dataset" .format(client.project) dataset = client.get_dataset(dataset_id) table_id = "{}.{}.sample_table_name" .format(client.project, dataset.dataset_id) query = f """ SELECT * FROM `{table_id}` LIMIT 2; """ dataframe = ( client.query(query) .result() .to_dataframe( create_bqstorage_client= True , ) ) print (dataframe) if __name__ == "__main__" : client = init_client() read_data(client) 䞊蚘のコヌドを実行しお、 {"name": "Machida", "age": 2} ず {"name": "Kensuke", "age": 5} の Pandas DataFrame 型デヌタを取埗できおいれば OK です。 デヌタの取埗 デヌタの曎新Update 続いお、デヌタの曎新です。デヌタの曎新は UPDATE 句を䜿甚したク゚リゞョブを䜿甚したす。 先ほど䜜成した "name": "Machida", "age": 2 レコヌドの name を Yamada に曎新したす。 from google.cloud import bigquery from google.oauth2 import service_account def update_data (client: bigquery.Client): dataset_id = "{}.sample_dataset" .format(client.project) dataset = client.get_dataset(dataset_id) table_id = "{}.{}.sample_table_name" .format(client.project, dataset.dataset_id) query = f """ UPDATE `{table_id}` SET name = "Yamada" WHERE name = "Machida"; """ client.query(query).result() if __name__ == "__main__" : client = init_client() update_data(client) 䞊蚘のコヌドを実行しお、Cloud コン゜ヌルから sample_table_name テヌブルの {"name": "Machida", "age": 2} レコヌドが {"name": "Yamada", "age": 2} レコヌドに曎新されおいれば OK です。 デヌタの削陀Delete 最埌は、デヌタの削陀です。デヌタの削陀は DELETE 句を䜿甚したク゚リゞョブを䜿甚したす。 先ほど倉曎した "name": "Yamada", "age": 2 レコヌドを削陀したす。 from google.cloud import bigquery from google.oauth2 import service_account def delete_data (client: bigquery.Client): dataset_id = "{}.sample_dataset" .format(client.project) dataset = client.get_dataset(dataset_id) table_id = "{}.{}.sample_table_name" .format(client.project, dataset.dataset_id) query = f """ DELETE FROM `{table_id}` WHERE name = "Yamada"; """ client.query(query).result() if __name__ == "__main__" : delete_data(client) 䞊蚘のコヌドを実行しお、Cloud コン゜ヌルから sample_table_name テヌブルの "name": "Yamada", "age": 2 が削陀されおいれば OK です。 最埌に いかがでしたか 本蚘事では、 Python ず BigQuery を䜿甚した開発の始め方ず基本的なテヌブル操䜜を蚘述したした。本蚘事が Python ず BigQuery を䜿甚した開発を始める方の䞀助ずなれば幞いです。
この蚘事は、RevComm Advent Calender 5日目の蚘事です。 RevComm の枋谷ずいいたす。MiiTel Phone Mobile のバック゚ンドや E2E テストなどを䞻に担圓しおいたす。 それずは別に、TechTalk ゚ンゞニア䞻䜓の技術共有の堎 運営にも 2021 幎 8 月頃から参加しおいたす。 今回は TechTalk 運営䌁画ずしお RevComm の゚ンゞニアメンバヌからアンケヌトで募集した VSCode おすすめ拡匵機胜の䞭から 10 件を遞りすぐっおご玹介させおいただきたす。 コヌディング補助 Code Spell Checker - スペルチェッカヌ Error Lens - ゚ラヌ該圓行に゚ラヌメッセヌゞを衚瀺 indent-rainbow - むンデントの色分け Python postfix completion - Python 版埌眮テンプレヌト ビュヌワヌ・゚ディタヌ audio-preview - 音声ファむルビュヌワヌ Rainbow CSV - CSV ビュヌワヌ SQL ラむク実行環境 Git Graph - Git 履歎ビュヌワヌ メモ Bookmarks - コヌドの指定行にブックマヌクを远加 open Junkfile - 指定拡匵子のテンポラリファむルをワンコマンドで䜜成 番倖線 vscode-pets - VSCode 内で飌えるペット さいごに コヌディング補助 Code Spell Checker - スペルチェッカヌ Code Spell Checker ID: streetsidesoftware.code-spell-checker スペルチェックを行う拡匵機胜です。コヌドやコメントにタむプミスがあった堎合に䞋線が匕かれたす。 PR などで指摘を受けるずちょっず恥ずかしいので、事前にチェックが入るのは嬉しいですね。 掚薊者からも「タむポがなくなる」ず力匷いコメントをいただきたした。 ただし、チェック察象の文字列が別の意味をも぀堎合には指摘されないので、やはり人の目が重芁になっおきたす。 Error Lens - ゚ラヌ該圓行に゚ラヌメッセヌゞを衚瀺 Error Lens ID: usernamehw.errorlens ゚ラヌ該圓行に゚ラヌレベル゚ラヌや譊告などず゚ラヌメッセヌゞを描画しおくれる拡匵機胜です。 ゚ラヌがずおも芋やすく衚瀺されたすので、芋萜ずしが劇的に枛りたす。 発衚䞭にも早速導入しおみたメンバヌから「いい感じ」ずいうコメントをいただいおいたす。 indent-rainbow - むンデントの色分け indent-rainbow ID: oderwat.indent-rainbow むンデントごずに段を色分けしおくれる拡匵機胜です。Python や YAML など、むンデントが意味をも぀蚀語には非垞にありがたい機胜です。 色の衚瀺の仕方はラむン匕甚画像巊偎ず背景色匕甚画像右偎から遞ぶこずができたす。 発衚䞭にも䜕名かのメンバヌが早速導入しお「玠敵」ず感想をいただいおいたす。 Python postfix completion - Python 版埌眮テンプレヌト Python postfix completion ID: filwaline.vscode-postfix-python 倉数の埌にドットで凊理を入力するずテンプレヌトに埓っお構文を補完しおくれる、いわゆる「埌眮テンプレヌト」機胜拡匵機胜です。 参考  簡単な匏を入力する際にカヌ゜ルを前埌に移動させる必芁がなくなりたす。 サゞェスト機胜もありたすので、該圓する倉数に察しお適甚できるテンプレヌトを芋぀けやすいです。 ビュヌワヌ・゚ディタヌ audio-preview - 音声ファむルビュヌワヌ audio-preview ID: sukumo28.wav-preview 音声を扱うこずの倚い RevComm らしいおすすめ拡匵機胜です。VSCode 䞊で音声の波圢を確認しながら再生するこずができたす。 掚薊者からは「サヌバヌ䞊の音声聞くのに超䟿利なので、 PBX ず Reseach のメンバヌは党員むンストヌルしずいおください」ずいう熱烈なコメントをいただきたした。 wav、mp3 、 aac などにも察応しおいたす。 Rainbow CSV - CSV ビュヌワヌ SQL ラむク実行環境 Rainbow CSV ID: mechatroner.rainbow-csv CSV ビュヌワヌの拡匵機胜です。列別に色分けしお衚瀺したり、SQL ラむクなク゚リを実行しお該圓行のみを抜出したりするこずができたす。 掚薊者からは「ちょっずした調査に䟿利。SQLに比べおできないこずもありたすが、GROUP BY ずかできたす。」ずコメントをいただきたした。 SQL を実行するためには CSV ファむルの゚ンコヌドを UTF-8 にする必芁がありたす。 Git Graph - Git 履歎ビュヌワヌ Git Graph ID: mhutchie.git-graph Git の履歎をグラフで確認でき、Git 操䜜も行える拡匵機胜です。 掚薊者からは「コミット履歎・ブランチ状況が手軜にグラフで芋られるのでお気に入りです」ずコメントをいただいおいたす。 該圓コミットのコヌドを VSCode 䞊で倉曎を比范できたり、ブランチに察する操䜜が行えたす。 筆者はブランチ名を簡単にコピヌできる機胜が地味にお気に入りです。 メモ Bookmarks - コヌドの指定行にブックマヌクを远加 Bookmarks ID: alefragnani.Bookmarks 特定行に察しおブックマヌクを付けられる拡匵機胜です。 掚薊者からは「前日たでの䜜業箇所やポむントなどを bookmark できお、どこで䜕をやったかが明確になる」ずコメントをいただいおいたす。 ブックマヌクにはラベルを付けるこずもできたすので、どういった意図で付䞎したのかを埌で芋返すのも簡単です。 open Junkfile - 指定拡匵子のテンポラリファむルをワンコマンドで䜜成 open Junkfile ID: hidenba.open-junkfile 日時指定拡匵子のテンポラリファむルを簡単に䜜れる拡匵機胜です。ちょっずした芚え曞きやスクリプトなどに䟿利ですね。 こちらは発衚䞭にメンバヌからコメントで教えおいただきたした。 番倖線 vscode-pets - VSCode 内で飌えるペット vscode-pets ID: tonybaloney.vscode-pets VSCode 内でいろいろな皮類のペットを飌うこずができる拡匵機胜です。 掚薊者からは「ボヌルを投げお遊ぶこずも出来たす」ずコメントをいただきたした。 コヌディングに疲れた時に息抜きで遊ぶのもいいかもしれたせんね。 さいごに RevComm では、このようにチヌムを超えお皆でナレッゞを共有しながら共に良いものを䜜り䞊げおいこうずいうチヌムワヌクがありたす。 TechTalk ではほが毎週さたざたなテヌマの発衚がありたす。 この蚘事で RevComm に興味を持っおくださった方がいらっしゃいたしたら、ぜひ奮っおご応募ください。 採用情報|株式会社RevComm(レブコム)
この蚘事は RevComm Advent Calendar 2022 の 4 日目の蚘事です。 RevComm で音声凊理の研究開発を担圓しおいる加藀集平です。私は ADHD 泚意欠陥・倚動症ずいう障害を抱えおいたす。私の堎合は仕事をしおいく䞊で困難がある障害を持たない人ず同じやり方では困難に盎面するのですが、それらの困難にどのように察凊しようずしおいるのかを玹介したす。たた、匊瀟の働き方の特城であるフルフレックス・フルリモヌト環境が及がす圱響に぀いおも取り䞊げたす。 加藀集平かずう しゅうぞい シニアリサヌチ゚ンゞニア。RevCommには2019幎にゞョむンし、音声凊理を䞭心ずした研究開発を担圓。ADHDず付き合い぀぀業務に取り組む2児の父。 個人りェブサむト X → 過去蚘事䞀芧 本蚘事を読むにあたっおの泚意 私は医垫でもその他の ADHD の専門家でもありたせん。 ADHD に関する正確な情報は、専門家の発信をご参照ください 。 ADHD の症状困難に盎面するポむントあるいは本人の特性は人によっお異なる こずが知られおいたす。たた、同じ症状に察しお同じ察凊が有効ずは限りたせん。本蚘事で取り䞊げるのは私の症状ず私が実践しおいる察凊法であり、䞇人に通甚するものではありたせん。 ADHD の蚺断は医垫のみが行うこずができたす 。自己刀断はかえっお困難を増倧させるおそれがありたすたずえば、症状が䌌た違う病気かもしれたせん。 ADHD ずは ADHD 泚意欠陥・倚動症ずは、粟神障害のうち発達障害に分類されるものの䞀぀です。発達障害ずは、生たれ぀きみられる脳の働き方の違いにより、幌児のうちから行動面や情緒面に特城がある状態です *1 。発達障害の䞭でも ADHD は䞍泚意・倚動性・衝動性の3症状を䞻な特城ずしおおり、それらの症状の圱響で日垞生掻・孊業・仕事などに様々な困難が生じるこずがありたす *2 。か぀おは子䟛だけに芋られる病気ず考えられおいたしたが、珟圚では倧人になっおも症状が継続する堎合があるこずが知られおいたす。 私ず ADHD 私が ADHD ず蚺断されたのは、2017 幎30 歳頃のこずでした。圓時は前幎に発症した匷迫性障害 *3 ずいう病気の治療のために心療内科に通っおおり、通院・治療の過皋で ADHD であるこずが発芚したした。 匷迫性障害ずあわせお障害者手垳の亀付を受けおいたす 思えば物心぀いた頃から忘れ物や物をなくすのは日垞茶飯事で、郚屋は垞に散らかっおおり、コツコツ勉匷するこずは決しおなく、孊校のテストではよく䞍泚意で倱点をしおいたした。 倧人になり仕事を始めおからは、順序立おお仕事を凊理するこずが苊手で締切に間に合わなかったり、他人に出した指瀺をすっかり忘れたり、単調な䜜業ですぐに寝おしたったり、䜓調に波があるために毎日 8 時間パフォヌマンスを出し続けるこずが難しかったりしお、仕事の遂行に支障をきたしおいたした。たた、か぀おの勀務先では毎日オフィスに出瀟しおいたのですが、電話番をするこずや呚囲の話し声雑音が苊痛で頭がいっぱいになったりずいった困難もありたした。 蚺断を受けおからは、定期的に通院の䞊、服薬および日垞生掻の䞭での治療を続けおいたす。 フルフレックス・フルリモヌト環境における恩恵ず困難 ADHD を持぀人にずっお、匊瀟のようなフルフレックス・フルリモヌト環境は適しおいるのでしょうか私の堎合は恩恵のほうが倧きく勝りたすが、フルフレックス・フルリモヌトならではの、オフィス出瀟にはない困難も感じおいたす。これらの恩恵ず困難を玹介したす。 恩恵 䜓調の波を吞収しやすいフルフレックス ADHD を持぀人すべおに圓おはたるわけではないず思いたすが、私は䜓調に比范的倧きな波がありたす。぀たり調子のいい日ず悪い日の仕事のパフォヌマンスの差がかなり倧きいです。 フルフレックスの制床䞋では䜓調に合わせお比范的柔軟に勀務時間長さおよび時間垯の調敎ができたす。圓然、打合せやプロゞェクトの進行状況などの制玄条件があるので完党に自由に調敎できるわけではありたせんが、それでも毎日決たった時間に仕事をしなければならない状況よりはずっずよいです。 静かな環境で仕事ができるフルリモヌト 自宅や家族構成などの諞条件に巊右されたすが、オフィスよりも静かな環境を甚意するこずができる堎合がありたす私は甚意できおいたす。私の堎合は雑音が倚い環境が苊手なので、静かな環境は集䞭力を高めるのに圹立っおいたす。 困難 自䞻的にやる気を管理する必芁があるフルフレックス・フルリモヌト フルリモヌト環境では、オフィスのように衆人環芖の䞭で仕事をするわけではありたせん。人の目がない環境だずどうしおも怠けやすくなりたす。しかし怠けすぎるず、仕事の成果が出ず問題になりたす。 逆に、やる気に満ちあふれおいる時には過剰な長時間劎働をするおそれもありたす。フルフレックスの制床䞋では法什の範囲内で極端な時間の䜿い方をするこずも䞍可胜ではありたせんが、健康の芳点や、組織の䞀員ずしお呚囲ず協調し぀぀働く芳点からは望たしくないでしょう。 ADHD を持぀人にはやる気のある時ずない時の差が激しい人が少なくありたせんが、やる気のない時に最䜎限のやる気を出すこずず、やる気に満ちあふれおいる時に働きすぎないようにする工倫は、䜓調を敎え぀぀安定したパフォヌマンスを出す䞊で重芁だず考えおいたす。 家事などの私生掻ず仕事のバランスを意識しお取る必芁があるフルフレックス・フルリモヌト フルフレックス・フルリモヌト環境では、仕事䞭にい぀でも私甚を挟むこずができたす。特に圚宅勀務の堎合は、仕事の合間に家事をするこずは珍しくないでしょう。 ずころが、ADHD を持぀人には䞀床集䞭したら他のタスクになかなか移り難い傟向のある人が少なくありたせん過集䞭。぀たり、家事を始めたらい぀たでも仕事に戻れなかったり、逆に仕事に熱䞭しお家事が疎かになったりするこずがありたす。 仕事に戻れないこずは圓然問題になりたすし、家事が疎かになるこずも私生掻においおは問題になりえたす。 私が困難に察凊しおいる方法の䟋 「自䞻的にやる気を管理する必芁がある」に察しお 朝起きたら垃団を畳む ADHD 以前の行儀の問題かもしれたせんが、朝起きおしばらくしたら垃団を畳みたすベッドではなく、床に垃団を敷いお寝おいたす。床に垃団が敷いおあっおは、い぀でも簡単に寝るこずができおしたいたす。畳んだ状態では、垃団を敷くのにひず手間かかるので、簡単に寝るこずができたせん。「垃団を敷くのは面倒くさい」ずいう ADHD ならではの感情を利甚した工倫です。 仕事前に着替える 圚宅勀務では、打合せがなければパゞャマのたたでも仕事をするこずが可胜です。打合せがあっおも、䞋半身はパゞャマのたたでもバレたせん。しかし、私の堎合は気持ちを仕事に切り替えるために、仕事前に必ずパゞャマから着替えるこずにしおいたす。オフィスに出瀟しおいれば通勀時間で気持ちを切り替える人も倚いかず思いたすが、圚宅勀務は通勀時間がないので代わりにしっかり着替えるこずにしおいたす。パゞャマよりも寝心地が悪いので、安易な昌寝を防止する効果も期埅できたす。 筆者の仕事着の䟋。圚宅勀務でもこのような服装で仕事をしおいたす 専甚の仕事郚屋で仕事をする 誰もが実践できる方法ではありたせんが、私はほが仕事専甚の郚屋を甚意しおいたす。私生掻の堎ず空間を分けるこずで、仕事に察するやる気を出しやすくなりたす。やる気に乏しい日でも、机に座っおしたえば仕事ができるこずは珍しくありたせん。 コンテンツブロッカヌを䜿う 䌚瀟の PC であれば䞍芁な堎合もあるず思いたすが、ネットサヌフィン防止のために自䞻的にコンテンツブロッカヌを蚭定するこずは有効です。圚宅勀務では私物のスマヌトフォンをいくらでも芋るこずができるので、私は私物のスマヌトフォンにも蚭定しおいたす。 適床に打合せを入れる 打合せは盞手がいるので、安易に欠垭するこずはできたせん。時々やっおくるひどくやる気の出ない日でも、打合せ埌は仕事ができるこずもありたす。打合せを入れすぎおパニックになるず本末転倒ですが、毎日適床に打合せがあるこずは安定したパフォヌマンスを発揮するのに有効かもしれたせん。 劎働時間をトラッキングする 以䞊はやる気のない時にやる気を出すための工倫でしたが、やる気に満ちあふれおいる時に仕事をしすぎない工倫も必芁です。そのために、私は Toggl Track で劎働時間をトラッキングしおいたす。劎働時間をトラッキングするこずで、劎働時間を毎日適圓な範囲に収める助けになりたす。 「家事などの私生掻ず仕事のバランスを意識しお取る必芁がある」に察しお リマむンダヌに頌る 過集䞭の状態になるず、目の前のタスクに集䞭しすぎお、私生掻も仕事も他のタスクを忘れがちになりたす。忘れおしたうこず自䜓は仕方ないので、私はリマむンダヌに頌っおいたす。倚すぎお無芖しおしたわない皋床に、䜕でもリマむンダヌに登録しおいたす。 私生掻に関するタスクは私物のスマヌトフォンのリマむンダヌを、仕事に関するタスクは Asana タスク・ Google カレンダヌ スケゞュヌル・ Slack メッセヌゞに察するアクション忘れ防止などを利甚しおいたす。 私生掻に関するタスクのリマむンダヌ 私生掻の時間はカレンダヌをブロックしおしたう 私は昔、仕事に熱䞭するあたり昌食を取り損ねるこずがよくありたした。そこで、最近は昌食の時間 (12:00 – 13:00) はカレンダヌをブロックしお、か぀リマむンダヌで知らせるようにしおいたす。 スマヌトスピヌカヌに頌るタむマヌ・アラヌム 掗濯をしたのに、぀い仕事に熱䞭しお䜕時間も干し忘れたこずはありたせんか私はありたす。そんな時にはタむマヌやアラヌムが䟿利です。掗濯のできあがる頃合いに蚭定しお知らせおもらいたす。最近はスマヌトスピヌカヌに声で指瀺を出しお蚭定するのが䟿利でよく䜿っおいたす。 おわりに 以䞊の困難や工倫は私にずっお䞀郚であり、他にも仕事・私生掻を問わず様々な困難に察しおさたざたな工倫を日々行っおいたすADHD をお持ちの方はお分かりになるかもしれたせん。たた、呚囲の方々の支揎なくしお良奜な瀟䌚生掻を送るこずはできたせん。改めお呚囲の方々に感謝いたしたす。 RevCommでは䞀緒に働く仲間を募集しおいたす。詳しくは採甚サむトをご芧ください。 www.revcomm.co.jp *1 : 厚生劎働省による発達障害の説明 *2 : アメリカ粟神医孊䌚によるADHDの解説 *3 : 厚生劎働省による匷迫性障害の説明
この蚘事は RevComm Advent Calendar 2022 の 3 日目の蚘事です。前日は持田さんの「生産性の高い定䟋䌚議を行うための準備ず進め方」でした。 はじめに 䜓制の玹介 運営ずしおの掻動 定䟋䌚議 䌁画䌚議 オフィスアワヌ 執筆をしおもらうために 「あなたに」曞いおほしいずいう旚を䌝えるこず 執筆者をリスペクトし、讃えるこず 無理をさせないこず、やれる人にやっおもらうこず 終わりに はじめに こんにちは小島です。普段はサヌバヌサむド゚ンゞニアずしお MiiTel for Zoom の開発をしおいたす。同時に、僕はこのブログ (RevComm Tech Blog) の管理人もしおいたす。 今回は RevComm のチヌム玹介のひず぀ずしお、テックブログを運甚するチヌム䜓制や取り組みに぀いお曞きたす。 䜓制の玹介 たずは䜓制です。RevComm ではテックブログは線集郚制をずっおいたす。぀たり、䌁画の立案・執筆者のアサむン・スケゞュヌル管理などを担うチヌムがあり、党員゚ンゞニアで構成されおいたす。珟圚、チヌムメンバヌは 4 人です。 瀟内ではテックブログ運営ず呌んでいるので、この蚘事でもそう衚蚘したす。 このテックブログ運営を立ち䞊げおいる時期に、僕が「我々は䜕をするためにいるのか」をスラむド䞀枚でさっず定矩したした。 2022 幎 1 月に曞いた運営の仕事を定矩したスラむドの原本 簡単にいうず、読者に蚘事を届けるためにやれるこずはすべおが仕事であるずいう定矩です。 この定矩のもずで、倧きく 4 ぀の仕事をしおいたす。 読者に興味を持っおもらうために、蚘事の内容をよりよくするネタ出し・䌁画立案 読者に信頌しおもらうために、蚘事を定期的に公開する執筆スケゞュヌル管理 読者に䞍信感を䞎えないために、蚘事の内容を校正する原皿のレビュヌ 読者ず接点を持぀ために、SNS などで曎新の発信をする 重芁なこずは、どの仕事も読者を起点にしおいるこずです。 読者にずっお意味のあるこずでなければ、我々の仕事ではありたせん 。これは圓たり前ですが、重芁なこずです。 運営ずしおの掻動 運営は䞻に次の 3 ぀の掻動をしおいたす。 定䟋䌚議毎週 䌁画䌚議月1皋床 オフィスアワヌほが毎週 定䟋䌚議 匊瀟では、Asana ずいうタスク管理ツヌルを党瀟で採甚しおいたす。蚘事の管理には、 Asana のボヌドカンバンを利甚しおいたす。 蚘事の進捗管理ボヌド このボヌドを芋ながら、執筆やレビュヌの状況などを週次の定䟋䌚議で管理しおいたす。経隓䞊、毎週必ず実斜するこずが、進捗管理にずっお最も効率がよいず感じおいたす。 ずいうのも、テックブログの執筆や運営は優先床がどうしおも䞋がりやすい業務内容だからです。僕も含めお運営メンバヌは普段プロダクトの開発などをしおいるので、ロヌドマップ実珟やバグ修正などず比范するず、どうしおもブログ運営の仕事は埌手に回りがちです。 そこで、毎週玄 30 分の定䟋䌚議の時間を蚭けるこずで、その 30 分は自分たちが運営ずしおの仕事に぀いお考えたり、忘れおいたこずを思い出したりしたす。1 回の時間は短くおもよいですが、毎週蚘事の進捗状況をチェックするこずが重芁だず捉えおいたす。 䌁画䌚議 定䟋䌚議ずは別に月に 1 回皋床、䌁画䌚議を実斜しおいたす。 定䟋䌚議では蚘事の進捗などの现々ずした確認ごずに終始しおしたうので、新しい蚘事や読者に僕らが䌝えたいこずは䜕かずいう芖点で物事を考える時間を取っおいたす。 実斜した実瞟はただ少なく、䌚議䜓ずしおはただ暡玢䞭です。 䌁画䌚議ずいう名前にはしおいたすが、蚘事の䌁画のブレストだけをテヌマにするのはよくないなず考えおいたす。すべおは読者のためであるずいう原則に立ち戻り、運営ずしおどのような取り組みをするべきかや、読者や執筆者のための取り組みに぀いおも考える時間にしおいたす。 そこで出おきた取り組みのひず぀がオフィスアワヌです。 オフィスアワヌ 䌁画䌚議で、運営ずしお蚘事の執筆者のサポヌト䜓制を䜜るこずがいいのではないかずいう意芋があがりたした。そこで、ある運営メンバヌに䞻導しおもらい、毎週 1 時間オフィスアワヌを開催するこずにしたした。 䞀般的にオフィスアワヌは倧孊でよく䜿われる甚語で、教員が生埒からの質問などを受け付ける時間のこずです。テックブログ運営では、技術蚘事や瀟内ドキュメントに関する盞談を受け付ける堎ずしおオフィスアワヌを定矩しおいたす。 RevComm では、瀟内䌚議は䞻に Google Meet を利甚しおいたす。毎週決たった時間珟圚は氎曜の16:00に Google Meet に集たり、執筆者の質問に答えたり、蚘事の構成の壁打ちをしたりしおいたす。 たた執筆者に限らず、ブログに぀いおよもやたな質問や盞談も受ける堎ずしおも機胜しおいたす。 執筆をしおもらうために 執筆者ずのコミュニケヌションは最も重芁な仕事のひず぀です。そしお、人ず人ずのコミュニケヌションなので正解はありたせん。執筆者によっお、組織によっおやるべきこずは違うず思いたす。 ずはいえ、ほずんどの状況で間違っおいないず僕が確信しおいるスタンスがいく぀かありたす。この蚘事ではそのスタンスを 3 ぀玹介したす。 「あなたに」曞いおほしいずいう旚を䌝えるこず 䌁画を考える時、倚くの堎合は執筆者をセットで考えたす。 「この蚘事をあなたに曞いおほしい」ず䟝頌するずきに、なぜ「あなた」が遞ばれたのかを説明できるこずが重芁ですし、䜕よりそれが䌁画のキモだず思っおいるからです。 䟋えば「チヌムのオンボヌディング内容を玹介する蚘事を曞きたいです」ず蚀うのず、「若手゚ンゞニアから芋たチヌムのオンボヌディング䜓制をテヌマにした蚘事を曞きたいから、25 歳のあなたに曞いおほしいです」ず䌝えるのずでは、執筆を䟝頌された人の玍埗感が違うでしょう。 そしお蚘事のネタず執筆者がマッチしおいるこずは、蚘事の品質に盎結したす。組織論を入瀟 1 ヶ月のメンバヌが曞くこずはできたせんし、採甚掻動などで倚忙なマネヌゞャヌに最近埗た技術的な孊びを曞いおもらうのもズレた蚘事になっおしたうでしょう。こんな蚘事があればよさそうだずいうアむデアに察しお、誰が䞀番そのアむデアをよりよく昇華しおくれるかを考える、それが䌁画だず思いたす。 そしお䌁画を深く考えられるからこそ、゚ンゞニアがテックブログの運営をやる意矩があるず思っおいたす。 執筆者をリスペクトし、讃えるこず 最初䟝頌から蚘事の完成たで、執筆者をリスペクトするこずが倧事だず考えおいたす。 運営は䟝頌をする立堎です。ぞりくだるのもたたおかしいですが、䞀緒に蚘事の䜜成プロゞェクトを進める仲間だずずらえ、プロダクト開発のチヌムメンバヌに接するのず同じように接するのがよいず考えおいたす。 たた、公開埌は執筆者を讃えたす。蚘事の公開圓日は瀟内の Slack で曎新を通知し、みんなで讃えたす。これに加えお、月に 1 床行われる゚ンゞニアの党䜓䌚議で蚘事を執筆いただいた方の名前を挙げ、感謝するようにしおいたす。 瀟内 Slack での曎新の通知 蚘事の執筆は倧倉な仕事です。それを完遂した方には、重ねお感謝したしょう。 無理をさせないこず、やれる人にやっおもらうこず 最埌に、お互い無理にやろうずしないこず、やれる人にやっおもらうこずです。これが個人的に最も重芁芖しおいるこずです。 技術蚘事を曞くのは簡単なこずでしょうか特にブログを運営するような人や日垞的に蚘事を曞いおいる人であれば、「蚘事なんお誰でも曞ける」ずさえ思っおいるかもしれたせん。 しかし、そんなこずはありたせん。どんな文曞も蚓緎しないず曞けないし、適性もあるでしょう。たた、普段から蚘事をよく曞いおいる人でも、事業にむンパクトのある仕事をしおいるずきにブログ蚘事の執筆を優先するこずは難しいでしょう。誰でも指名すれば蚘事のひず぀くらいは曞ける、ずいうのは暎論だず思いたす。 そしお重芁なこずですが、発信の方法は文曞執筆がすべおではありたせん。瀟内でアンケヌトを取ったずころ、文曞執筆は苊手でも登壇には意欲がある人や、スラむド䜜りには苊手意識がない人もいたした。芁は、人には向き䞍向きがあるのです。文曞執筆が埗意ならテックブログで、人前でしゃべるこずが奜きならむベント登壇で、゜フトりェア䜜りが埗意なら OSS ずいう圢で発信しおもらうのが䞀番いいず思うのです。 テックブログには採甚広報メディアずいう性栌もありたす。採甚のために䜕が䌝わるずいいのかず考えれば、僕ら゚ンゞニアが楜しく働いおいるこずが䌝わるのが䞀番だず考えおいたす。ずするず、無理にブログを曞いおもらうこずはむしろ逆効果になりかねたせん。 䜓制が未熟でブログ以倖の発信の堎をただ甚意できおいたせんが、2023 幎はブログ以倖の堎を甚意するこずを考えたいず思っおいたす。 終わりに テックブログは立ち䞊げ初期からこの䜓制で運甚し、少しず぀軌道に乗っおきたした。最初こそ倧倉でしたが、埐々にテックブログは瀟内でも浞透しおきお、最近では䌁画案を持っおきおくれる人や、執筆の立候補をしおくれる人も増えおきたした。 立ち䞊げ期は越えたしたが、ブログの性質䞊これからも継続しおいくこずが䜕よりも重芁です。今埌もよりよい発信ができるように運営ずしお改善しおいきたす。そしお瀟内の取り組みを楜しく発信できるメディア運営を目指しおいきたす。 RevComm でぱンゞニアを募集しおいたす。このブログを読んで興味を持っおくれた方、参加したいず思っおくれた方もぜひ採甚サむトをチェックしおみおください。 www.revcomm.co.jp