TECH PLAY

ニフティ株式会社

ニフティ株式会社 の技術ブログ

487

概要・はじめに こんにちは。2023年9月にエンジニアとして中途入社した細野です。 社内では、会員システムグループでニフティポイントクラブの開発を担当しています。 この記事では、ニフティへ入社して感じたギャップや、会社や配属先のチームの特徴などについて紹介させていただきます。 簡単な自己紹介 前職では、SIerエンジニアとして約2年半勤務しておりました。 React、Rails、AWSの技術を中心に、複数案件の開発に携わらせていただき、その中で、案件内の開発リーダーや、新人エンジニアの育成などを担当していました。 ニフティへの入社の決め手は、IT転職サイトのカジュアル面談を通して、ニフティのサービスや社員に魅力を感じた為です。カジュアル面談後、ご縁があって、昨年ニフティへ中途入社しました。 ニフティポイントクラブの簡単な紹介 「ニフティポイントクラブ」は、運営実績20年以上、累計会員数330万人以上のポイントサイトで、普段のネットでのお買い物をニフティポイントクラブ経由で利用することでポイントを貯めることができ、貯めたポイントは現金や電子マネー、インターネット回線使用料に交換することで、お客さまの生活をもっとお得にできるサービスです。 詳細については、 「ニフティポイントまるわかりガイド」 を良ければご覧ください。 開発環境/技術 ニフティポイントクラブでは以下の技術を使用しています。 クラウド:AWS、ニフクラ 仮想化環境:Vagrant、Docker DB:Oracle、PostgreSQL OS:CentOS 言語:Ruby、TypeScript フレームワーク:Ruby on Rails、Vue.js(Vue3) 構成管理:Terraform、Itamae バージョン管理:Git、GitHub、GitLab チームでは、フロントエンド担当やバックエンド担当などで分業せず、チーム全体で臨機応変に開発しています。 ニフティで働いてみて感じたギャップ [1] 想像以上にスクラム開発が中心であること 今まではウォーターフォール寄りの開発が多かった事もあり、ニフティでは、スクラム開発の文化がとても根付いているように感じました。 前職でも開発スケジュールの作成、定例MTG(進捗共有・振り返り)などは実施していましたが、スクラム開発で言うところのベロシティ(チームの平均的な速度や作業量の指標)を測ったり、チーム全員で計画を立てるという活動などは、あまり取り入れられていなかったように思います。 ニフティでは、 「スクラムガイド」 を参考に、積極的にスクラム開発を導入している為、スプリントプランニング、スプリントレビュー、レトロスペクティブなど、各スクラムイベントを通して、チーム全員でスクラム開発をしているという実感が強いです。 [2] 社内イベントが多く、学びや交流の場が多いこと ニフティでは、社内交流会や勉強会が活発に開催されています。私も、DDD(ドメイン駆動開発)ギルドに入り、社内勉強会の運営に携わらせていただきました。 私たちのチームでは、DDDの書籍出版や勉強会等で有名な外部講師の方を招き、ドメインの設計やコーディングの配信する勉強会を開催しました。こちらは後日ブログにアップされる予定です。 他チームのイベントの例としては、AWS、Azure、GCPの3つのクラウドサービスについてハンズオン形式の勉強会や、社内システムのドメイン勉強会など、定期的に様々なイベントが企画されています。 また、学びの場だけでなく、チームや全社の交流会イベントも定期的に開催されていたりします。勿論強制参加とかではありません。 [3] たくさんのシステムの開発・運用を経験できること 配属直後にオリエンテーションと一緒にオンボーディング資料を共有頂いたのですが、最初は社内用語を含めた大量のドメイン知識と、システムアーキテクチャの複雑さに対して、理解が全然追いつきませんでした。 社内用語は、Notion QAを使用したり、チームメンバーから教えて頂くことで、自然と慣れていきました。 システムの理解については、まだ全体的に理解が浅いと感じています。 レガシーシステムでは良くある話なのかも知れませんが、ブラックボックス化されてしまっている仕様や処理が所々あり、 「エンジニアに与える認知負荷の高さ」 が開発チームの大きな課題の1つだと捉えています。 現在は、DDD(ドメイン駆動開発)やDaC(Document as Code)などのプラクティスを通して、チーム全体で積極的にアイディアを出しながら、改善活動に取り込み始めています。 ポイント開発チームの主な作業 ポイント開発チームでは、主に以下に関する作業を行ってます。 [1] 事業開発 ビジネスサイド側の依頼内容に沿った開発行います。依頼内容には、1人月を超えるような規模の新規機能の開発や既存機能の改修を進めていきます。 開発物としては、ユーザー向けの機能追加が多い印象です。 [2] システム部開発 こちらはシステムの課題に沿った開発を行います。例としては、システムのモダナイゼーションやコストカットの為の開発などがあげられます。 DB移行やライブラリのバージョンアップ、サーバーの棚卸など内部的にシステムを作り替えたり、コストカット施策の立案〜開発までを進めていきます。 [3] 運用保守 基本的には1人月の範囲で収まる規模の既存機能の改修やパッチ適用の他、問い合わせに依頼が上がった場合の既存機能の調査対応などを行います。 おわりに この記事では、私がニフティへ中途入社して感じたギャップや会社やチームの特徴などについて紹介させて頂きました。 最初は覚える事のボリュームの多さや、チームメンバーの活躍する姿を目の当たりにして「本当にやっていけるかな?」と何度も思ったりしました。 ただそんな中でも、周りの方に支えられ、少しずつチームに貢献出来るようになってきているように感じます。仕事において「何をやるか」も大切ですが、「誰とやるか」はそれ以上に大切な要素だと言えるのではないでしょうか。 そしてニフティには、知識、経験共に「この人と一緒に働きたい」と思えるような人が多いように感じました。 現場の技術的負債も多く、大変だと感じる面もありますが、システムのモダナイゼーションを進める事で得られる経験は、とても良い経験になると思っています。 私自身もいち早く皆さんのお手本社員になれるように、今後もスキルを磨き続けていきたいと思います。 もしニフティの開発に興味頂いた方は、以下リンクよりお気軽にご連絡ください。 ニフティでは、 さまざまなプロダクトへ挑戦する エンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトより お気軽にご連絡ください! ニフティ株式会社採用情報 カジュアル面談も随時受付中! ニフティに興味をお持ちの方は キャリア登録をぜひお願いいたします! キャリア登録 connpassでニフティグループに 参加いただくと イベントの お知らせが届きます! connpassで ニフティグループに参加する
アバター
はじめに こんにちは。たかたかと申します。 私は23卒で入社したのですが、社会人一年目ももうすぐ終わりそうな時期に差し掛かっており、時が経つのは早いなぁと思うばかりです。(年齢的には若い筈なのに) さて、私はジョブローテーション最後の配属先である、サービスインフラチームで活動をしていました。 ここでは、ニフティのシングルサインオンや会員管理データベースなど、ニフティのサービスを裏から支えるシステムの運用に携わりました。( こちら に詳しく書かれている記事があるので、興味がある方は参考にしてみてください) その中で特定の条件にマッチした会員データを抽出する機会があり、状況に応じてSQLを考えたりする必要がありました。 私は情報系の勉強はしてきたつもりではいましたが、SQL自体あまり触った経験がなく、この際ある程度マスターしてしまおうということで学習をしたりしていました。 こんな感じの事やってました〜というのを、内容を会社的に問題にならないように改変した上で問題形式にしてみたので、皆さんも考えてみてください。 では問題です 問題1 同じ誕生日の人が身近にいると親近感が湧く方ですか?一種の仲間意識が芽生えたりしますか? ということで、1980-01-01以降の日付で、誕生日毎にカウントを出力するSQLを書いてください。 出力例 birthday | count ------------+------- 1988-03-15 | 4 1990-08-25 | 1 1995-07-09 | 1 1985-04-12 | 1 テーブル例 person_id name birthday 1 takeshi 1985-04-12 2 yumi 1990-08-25 3 hiroshi 1975-11-30 4 sachiko 1988-03-15 5 sacchan 1988-03-15 6 hamako 1988-03-15 7 momoko 1988-03-15 8 kenji 1995-07-09 persons テーブル 解答例 SELECT birthday, COUNT(*) as count FROM persons WHERE birthday >= '1980-01-01' GROUP BY birthday; 余談 COUNT(*)とCOUNT(Primary Key)とCOUNT(1)のどれが一番処理速度が早いかという議論がたまに行われていたりします。調べてみたところ、Primary Keyが良いだったり、どれもそんなに変わらないよと言われていたりします。ケースバイケースかもしれませんが、どれが一番最適なのか考えてみると良いかもしれませんね。 問題2 私はtakeshiさんの誕生日を盛大に祝いたいと考えています。 しかし私はtakeshiさんの食べ物の好みを知らず、このままだと喜んでいただけないでしょう。 そこであなたにはtakeshiさんの好きな食べ物を抽出するSQLの作成をお願いしたいです。 出力例 person_name | favorite_food -------------+--------------- takeshi | Ramen takeshi | Pizza テーブル例 person_id name birthday 1 takeshi 1985-04-12 2 yumi 1990-08-25 3 hiroshi 1975-11-30 4 sachiko 1988-03-15 5 sacchan 1988-03-15 6 hamako 1988-03-15 7 momoko 1988-03-15 8 kenji 1995-07-09 persons テーブル food_id food_name 1 りんご 2 ぶどう 3 カレー 4 おにぎり foods テーブル food_id person_id 1 1 3 2 2 3 1 4 favorite_foods テーブル 解答例 SELECT p.name as person_name, f.food_name as favorite_food FROM persons p INNER JOIN favorite_foods ff ON p.person_id = ff.person_id INNER JOIN foods f ON ff.food_id = f.food_id WHERE p.name = 'takeshi'; 余談 join句辺りは昔の私には何が何だかよく分からない文法でしたね。 left joinやright joinの内容を理解できず頭を抱えていました。 問題3 会社名と学校名をまとめて表示したいのに、別々のテーブルに保存されています。 schoolsテーブルとcompaniesテーブルのnameを合体させたデータを抽出するSQLを作成してください。 出力例 name ----------- xxcompany wwschool wwcompany xxschool bbschool aaschool ooschool aacompany テーブル例 school_id school_name 1 ooschool 2 xxschool 3 wwschool 4 aaschool 5 bbschool schools テーブル company_id company_name 1 xxcompany 2 wwcompany 3 aacompany companies テーブル 解答例 SELECT school_name as name FROM schools UNION SELECT company_name as name FROM companies; 余談 union句の存在を知った時、こんなこともできるのかと衝撃が走りましたね。 最後に いかがでしたでしょうか? SQLは、抽出方法ならまだしも、速度や可読性などを考え始めるとまた奥の深い世界なのかなぁと思います。 それでは、またどこかで会いましょう! ニフティでは、 さまざまなプロダクトへ挑戦する エンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトより お気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering connpassでニフティグループに 参加いただくと イベントの お知らせが届きます! connpassで ニフティグループに参加する
アバター
参加登録はこちらから (connpass)スクラムマスターによるチーム改善LT! ニフティのスクラムトーク vol 2 イベント概要 NIFTY Tech Talkは、ニフティ株式会社の社員が主催するトークイベントです。 本イベントでは、ニフティグループの社員が業務を通じて学んだことを発信しています! テーマ NIFTY Tech Talkでスクラムにテーマを絞った「ニフティのスクラムトーク」シリーズが始まりました。 今回はVol 2となります。 チーム改善に取り組んだこと かんばんの戦略 認知負荷 過去のニフティのスクラムトークはこちら スクラムマスターの技を磨く! ニフティのスクラムトーク vol 1 / 動画 ( Youtube ) 開催概要 日程:3月26日(火)19:00〜20:00 会場:ニフティ株式会社 オンライン参加の方 YouTube Liveで配信 こんな方におすすめ スクラムマスターの経験がある方 チームの改善に興味がある方 タイムテーブル 時間 コンテンツ 18:30 – 19:00 開場 19:00 – 19:10 オープニング 19:10 – 19:30 LT1: チーム力を高めるスクラム実践法:カンバン公開と課題攻略について 19:30 – 19:50 LT2: スクラムチームと認知負荷 19:50 – 20:00 クロージング 登壇者プロフィール 添野 翔太(登壇者) ニフティ株式会社 会員システムグループ 第1開発チーム 新卒入社7年目。@niftyトップページやニフティゲームズの開発・運用を担当し、日々スクラムマスターとして奮闘しています。また最近はマルチクラウドを題材にした社内研修の講師や運営も務めています。 清水 利音(登壇者) ニフティ株式会社 基幹システムグループ サービスインフラチーム 新卒入社7年目。シングルサインオンシステムのスクラムマスターとして刷新・開発・運用などの活動をしています。 ニフティグループでは一緒に働く仲間を募集中です 新卒採用、キャリア採用を実施しています。ぜひ リクルートサイト をご覧ください。 ニフティエンジニアが業務で学んだことやイベント情報を エンジニアブログ にて発信しています! ニフティエンジニアのX(旧Twitter)アカウント NIFTY Tech Talkのことや、ニフティのエンジニアの活動を発信していきます。 NIFTYDevelopers アンチハラスメントポリシー 私たちは下記のような事柄に関わらずすべての参加者にとって安全で歓迎されるような場を作ることに努めます。 社会的あるいは法的な性、性自認、性表現(外見の性)、性指向 年齢、障がい、容姿、体格 人種、民族、宗教(無宗教を含む) 技術の選択 そして下記のようなハラスメント行為をいかなる形であっても決して許容しません。 不適切な画像、動画、録音の再生(性的な画像など) 発表や他のイベントに対する妨害行為 これらに限らない性的嫌がらせ 登壇者、主催スタッフもこのポリシーの対象となります。 ハラスメント行為をやめるように指示された場合、直ちに従うことが求められます。ルールを守らない参加者は、主催者の判断により、退場処分や今後のイベントに聴講者、登壇者、スタッフとして関わることを禁止します。 もしハラスメントを受けていると感じたり、他の誰かがハラスメントされていることに気がついた場合、または他に何かお困りのことがあれば、すぐにご連絡ください。 ※本文章はKotlinFest Code of Conductとして公開された文章( https://github.com/KotlinFest/KotlinFest2018/blob/master/CODE-OF-CONDUCT.md )を元に派生しています。 ※本文章はCreative Commons Zero ライセンス( https://creativecommons.org/publicdomain/zero/1.0/ ) で公開されています。
アバター
NIFTY Tech Talkは、ニフティ株式会社の社員が主催するトークイベントです。 ニフティグループの社員が業務を通じて学んだことを発信しています! スクラムにテーマを絞ったシリーズとして、「ニフティのスクラムトーク」を開催しています。 隔月での開催を予定しています。 connpassでNIFTYグループのメンバー登録をしていただくと、次回以降のイベント情報を受け取ることができます。 connpass: NIFTY Developers NIFTY Tech Talk ニフティのスクラムトーク 【2024/01/30】 スクラムマスターの技を磨く! ニフティのスクラムトーク vol 1 【2024/03/26】 スクラムマスターによるチーム改善LT! ニフティのスクラムトーク vol 2 【2024/05/28】 TBD ニフティのスクラムトーク vol 3 【2024/07/23】 TBD ニフティのスクラムトーク vol 4 【2024/09/24】 TBD ニフティのスクラムトーク vol 5 【2024/11/26】 TBD ニフティのスクラムトーク vol 6
アバター
はじめに まだギリギリ新卒1年目の中井改めstatiolakeです。エンジニアブログでは Rust関連の投稿 をさせていただいたりしていますが、改めましてRust大好きマンです。よろしくお願いします。 さて、実は私もこのたびのエンジニア定例合宿に参加させていただき、チーム†skyscraper†としてオリンピックを盛り上げるサービスを作るなどしました。チーム内では私はバックエンド開発グループ(総勢1名)に所属していました。せっかくなので、記憶が新しいうちに(といっても一ヶ月は経ってしまったのですが)どういう感じだったのかをつらつらと書き残しておこうかと思います。 エンジニア定例合宿ってなんぞ? †skyscraper†って誰? という方は、以下の投稿を先にご覧ください! エンジニア定例とは: https://engineering.nifty.co.jp/blog/25125 †skyscraper†の制作物: https://engineering.nifty.co.jp/blog/25226 チームの開発体制について 改めて、私たちのチームの開発物の構成はこのようになっていました。 フロントエンドにSvelteを採用し、バックエンドにはRustを採用しています。Rust側がAPIを提供し、フロントからはそれを呼び出してJSONでレスポンスを受けるという構造です。 ふたを開けてみると、他のチームではこのように明確にフロントエンドとバックエンドを分離しているところはなかったように思います。確かにツールや言語も増えますし、APIのインターフェースなど、短期的には考えることが少し増えますよね。そういう意味では、この構成でハッカソンを走りきれたことには達成感もあります。ただ、開発中も完成しない危機感を感じることは全くありませんでした。それはフロントエンドチームの技術力の高さと、実際に走りきるための色々な工夫があったからこそだと思っています。 フロントエンドチームの技術力の高さ まず最初に断っておきたいのは、これから書き残す諸々の工夫がしっかり効果を発揮したのはフロントエンドチームの技術力の高さゆえです。バックエンド側として私が決めたAPIの仕様をいい感じにエスパーして勝手に使ってくれましたし、APIの新しい実装が出来上がったときもすぐチェックしてもらえました。とにかく余裕をもって作業を進めてくれましたおかげで、バックエンド側も次へ次へとスムーズに進んでいきました。これめちゃくちゃやりやすかったです。ありがとうございます。 走り切るための工夫 さて、 チーム側の参加記 では、次の点を開発における工夫に挙げさせてもらいました。 フロントエンドとバックエンドを効率よく完全に分業する。 フロントエンド側のUXにかなりの比重を置き、粗の少ないユーザー体験を作る。 「最低限の機能」を十分小さく定義し、動作する状態をキープしながら拡張を続ける。 この記事では、1つ目の「効率よく完全に分業する」点、そして3つ目の「動作する状態をキープしながら拡張を続ける」点について、自分が考えたことだったり貢献した部分だったりを書き残そうと思います。2つ目の部分は走り切るための工夫というよりはクオリティのための工夫で、少しでも理想形に近い完成度でゴールするためという意味合いが強いためです。 ちなみに、ここでいう最低限の機能というのは「デモで動作が破綻しない程度にとりあえず動く状態のもの」という意味合いです。例えばデモでちゃんとしたものに見えるとか、はたまたお客様へのリリースに耐える品質であるとか、そういう「担保したい品質のボーダーライン」的な意味では考えていませんでした。むしろ完全に開発の都合側の概念で、短期間の開発で品質を最大化するために、1ステップ1ステップのギャップを最小化しようとした、という意味で捉えていただけると幸いです。 工夫1: 完成像の雰囲気と開発の流れを全員が完全に理解しておく これはまあ合宿が始まる前の話ですが、事前のアイデア出しの段階で3人の中の完成像を完全に一致させるように話し合いを重ねました。合わせて全体の開発の流れも全員で共有していました。以下はその話し合い中のメモです。 求める機能全体をいい感じの小さい機能に分割し、実装優先順位を決めて番号を振りました。当日は番号順にできるところまで進めるという方針を取りました。実際に進んだのは4まで、5がベータ版として実装されていたくらいです。でも、仮に最初から4まで一気に完成させようとしていたら多分うまくいかなかったと思います。見せられるものがなくて焦ってしまったり、進捗が合わなくてつなぎこみに失敗したりするからです。 そして、機能を分割した後に、各機能の具体的な内容をすり合わせていきました。遷移はこんな感じ、画面構成はこんな感じで、こういう機能は存在しないので考えなくて良くて、… などの内容です。そのおかげで、完全に分かれて作業してもAPIの機能に関する認識が一致し、つなぎこみに失敗することはありませんでした。 工夫2 重たい仕組みを必須要件から削除する 我々が普段見るWebサービスのほとんどは、だいたいログイン機能があり、何かしらデータを送信する機能があって、それを閲覧表示する機能があります。これらの機能のためにはデータを保存する仕組み、データベースが必ず必要になります。そしてログイン機能を実装するためには、ログイン画面やユーザー登録画面を実装する必要があるでしょう。 データベース、新しい画面、認証、ログイン処理、これらはサービスの実装の中でかなりのウェイトを占めてしまいます。私たちのように経験が浅いとなおさらです。これらを必須機能に要求してしまうと、いつまでたっても最初の機能するバージョンが完成しないということになりかねません。 今回私たちが取った戦略は、これらの重たい要素を極力排除することです。 私たちの画面にはログイン画面のような画面があります。しかし、これは厳密にはログイン画面ではありません。ユーザー登録がないからです。 入力された名前と秘密の言葉は、適当な文字列に加工され、これをシード値としてビンゴカードを生成します。生成されたビンゴカードを保存することすらしません。毎回生成し直します。このようにすると、利用者についてサーバー側で保存しておくべき情報は何もありません。 当初は、ビンゴカードのマス目をクリックして自分で開ける操作ができるようにするとか、ビンゴカードのマス目を自分で変更して自分好みのカードを作るなどの機能も想定されていました。これらはデータベースが必要になるという理由でコア機能としては見送りました。それくらい軽量化にはこだわったつもりです。 ここまで仕様を簡略化すると、フロントエンド側はこのログイン風画面とビンゴカードそのものの画面だけを作成すれば完成します。画面の遷移も「ボタンを押したらビンゴカードに移動する」の一言で済んでしまいます。残った時間をすべて、いちばん大切なビンゴカードの画面に費やすことができるようになります。 一方のバックエンド側も、データベースのテーブル設計・モデル設計をスキップし、接続周りの様々な面倒からも開放され、ビンゴカード生成ロジックに集中することができます。 ちなみに、最終的には一応データベースも利用しています。ある時点での試合結果の情報がないと、どのマスが空いているかを決定できないからです。一応ここでもデータベースを回避するために、デモ用に適当なAPIを生やしてインメモリでごまかすという逃げ道を考えてはいました。デモだけであればこれで十分で、小さく作る次の一手としてはこの歩幅でも良かったと思います。ただおかげさまで十分な時間的余裕があったので、順当にデータベースをセットアップすることができました。まあ案の定、色々と時間を溶かしてしまいましたね。でも焦りはありませんでした。常に見せられるものができている状況というのは本当に開発しやすいです。 工夫3: APIの仕様を何よりも一番最初に決め、モックを作る さて、いい感じに成果物の要件について思いを巡らせることができたら、次は実装です。スムーズな開発のため、APIのインターフェースとモックをなるべく早く決定しなくてはなりません。事前にある程度認識を固めてあるとはいえ、プロパティ名まで含めた具体的なデータ形式があったほうがフロントエンド側が気にすることが減ります。ここはスピードが重要です。 注意することは、後々の変更にも耐える、なるべく破壊的変更を起こさないインターフェースにすることです。そもそも最初から完璧なインターフェースが設計できればそれに越したことはないのかもしれませんが、短期の開発、アジャイル開発では、仕様を素早く確定してしまうことのほうがはるかに重要です。足りない情報はインクリメンタルに修正していけばよいからです。しかしだからといって、APIを修正するたびに既存のコードを書き換えなければいけなくなってしまっては大問題です。 例えば、私が最初に考えていたビンゴのマスのレスポンスの構造はこのようなものでした。 { "sport": "Archery", "event": "Mixed Team", "team": "JPN" } 競技、種目、チーム名、この3つでひとマスが表せるので、最初の機能としてはこれで十分です。しかし、もしかしたらそれぞれのプロパティに後々追加の情報を足したくなるかもしれません。そのようなとき、今まで文字列だったものがオブジェクトになってしまうと困ったことになります。 少し考えて、代わりに下のようなインターフェースで決定しました。 { "sport": { "name": "Archery" }, "event": { "name": "Mixed Team" }, "team": { "ioc": "JPN" } } 一見冗長なようですが、これで例えばスポーツ名の日本語名を足したくなっても name_ja のような項目を別に足すだけで済み、その時に既存のコードには影響を与えません。 実際、こうしておいてよかったです。開発中、チームの詳細情報を横に補足として表示するというアイデアが出て、最終的には次のようなレスポンスになったからです。 { "sport": { "name": "Archery" }, "event": { "name": "Mixed Team" }, "team": { "ioc": "JPN", "country_ja": "日本", "country_en": "Japan", "first_olympics": "1912", "remarks": "1956年冬・1960年夏 : GIA / 1960年冬 : JAP" } } アジャイルな開発では、次の機能に取り掛かるたびに必ずAPIの改修が発生します。その時に一度も破壊的変更を起こさないで済んだことも、私たちの開発がスムーズに進んだ理由だと思います。 工夫4: Rustで実装する あー待ってください。閉じないで。Rust大好きマンとして少しだけ語らせてください。 今回バックエンドにRustを選択したのにはいくつか理由があります。まず自分が好きだからというのが9割。そしてビンゴカードの生成処理のような重たい処理をリクエストごとに走らせる必要があったことが0.5割。バグを起こしづらいことが0.5割です。すなわち、上述の工夫を可能にし、スムーズな開発を裏で支えてくれたのがRustなわけです。 今回、データベースをなるべく排除した以上、ビンゴカードの生成処理を毎回走らせることが必要になってきます。いや、仮にデータベースに保存していたとしても、初回は必ずこの生成処理が走ってしまいます。そのビンゴカードに対してリーチやビンゴの判定も毎回行うことになります。そこをRustがネイティブバイナリの力を生かして最速で実行してくれました。本当に助かります。 また、Rustがバグを起こしづらいというのは、そこに非常にしっかりと型がついているからです。 たとえば、私が愛してやまないRustの機能の一つにenumがあります。Rustのenumは多くの他の言語のenumとは異なり、構造体的なものを一緒に持つことができます。tagged unionや代数データ型と呼ばれるものですね。今回のビンゴのセルもこのenumの力を多分に発揮しました。具体的には、セルの型は以下のように定義されています。 pub enum BingoCell { Free, Normal { sport: SportName, event: EventName, team: TeamIoc, opened_at: Option<i32>, }, } これの意味するところは、ビンゴのセルは中央の「Free」マスであるか通常のマスであるかの二通りがあるということです。これにより、Freeマスなのにスポーツやイベント名が設定されているとか、通常マスなのにそれらが設定されていないということはなくなります。 ここで嬉しいのは、コードの他の部分でビンゴのセルを扱うときは必ず条件分岐でどちらの値が入っているかを確認しなければならないことです。FreeかNormalかを確認することなく勝手にsportやeventにアクセスすることはコンパイル時エラーになります。 他にも細かい場所として、opened_atは、そのマスが何ターン目に開いたかを持ちます。もちろんまだ空いていない場合もありますから、これをOption<i32>型とすることで「空いていたらターン数、空いていなければNoneという特別な値」で表現できるようになります。そしてこれも、Noneでないかを確認せずに数字にアクセスすることはできません。プログラマーは、使う箇所で必ずNoneかもしれないことを意識させられることになります。 ちなみに、バグりにくいもう一つの理由として、テストが好きなところにかけるからというのもあります。Rustには組み込まれたテストシステムがあって、書いているファイルにそのままテストを書くことができます。今回もちょこっとだけですがテストを書いたりしました。普通ハッカソンでテストをかくのもなかなか難しいと思うのですが、強みが出ましたね。 リーチやビンゴの判定はビット演算を使ったちょっと複雑なロジックになっているので、以下のように、ちゃんとリーチやビンゴが判定できているかどうかをとりあえずチェックしています。全く網羅性はありませんが… // : // : // ここまで普通にBingoCard型の実装とかが書いてある // 唐突にこうやって追加すればその場でテストになってくれる #[cfg(test)] mod tests { use super::*; #[test] fn test_bingo_new() { let mut rng = rand::thread_rng(); let bingo = BingoCard::generate(&mut rng); println!("{:?}", bingo); } #[test] fn test_bingo_check() { let mut rng = rand::thread_rng(); let mut check = |order: &[(usize, usize)]| { let mut card = BingoCard::generate(&mut rng); assert!(!card.is_bingo()); let rest = &order[..order.len() - 2]; let reach_last = order[order.len() - 2]; let bingo_last = order[order.len() - 1]; for &(i, j) in rest { card.open(i, j, 0); assert!(!card.is_reach()); assert!(!card.is_bingo()); } card.open(reach_last.0, reach_last.1, 0); assert!(card.is_reach()); assert!(card.reach_last_cells().get(bingo_last.0, bingo_last.1)); assert!(!card.is_bingo()); card.open(bingo_last.0, bingo_last.1, 0); assert!(!card.is_reach()); assert!(card.is_bingo()); }; check(&[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4)]); check(&[(0, 3), (1, 3), (2, 3), (3, 3), (4, 3)]); check(&[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]); check(&[(0, 4), (1, 3), (2, 2), (3, 1), (4, 0)]); } } おわりに この記事では、今回のハッカソンでフロントエンドとバックエンドを完全に分離して作業を進めるために考えた工夫について書き残しました。全員が完全に成果物のイメージを持っていたことで、フロントとバックのすり合わせのための会話はほとんどなかったです。きれいに分割したことでお互いにコンフリクトを起こすことなく自分の責任範囲を実装できました。また、重たい仕組みを排除してできた時間で、フロントエンド側は一生懸命デザインに凝ってくれました。自分もそれに横から口出ししたりして、本当にクリエイティブな時間だったと思います。とてつもなく楽しく、貴重な時間でした。 ところで、振り返ってみると、これらの工夫はこの一年間のOJTを通じて培った知識でもあります。例えば、常に完成品を持っておいて小さな改善を続けるという開発は、ニフティで広く取り入れられているスクラム開発(アジャイル開発)の思想です。何としてもモックを先に作るぞという気概は、ニフティニュースの開発チームにお邪魔していたときに先輩方から学んだことです。サービスやAPIの設計も、色々なチームで設計に携わらせてもらった成果です。改めてこの一年間で多くのことを学んだなと思いました。 さて、もう1ヶ月もしないうちに2年目になるらしいです。これからもまだまだ新人として、たくさんのことを吸収していきたいと思います。一方、自分も先輩になるという側面もあります。来年度の新人に少しでもなにか良い影響を与えられるよう、精進していきます! ニフティでは、 さまざまなプロダクトへ挑戦する エンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトより お気軽にご連絡ください! ニフティ株式会社採用情報 カジュアル面談も随時受付中! ニフティに興味をお持ちの方は キャリア登録をぜひお願いいたします! キャリア登録 connpassでニフティグループに 参加いただくと イベントの お知らせが届きます! connpassで ニフティグループに参加する
アバター
 こんにちは。ニフティ株式会社、新卒2年目の小林です。  弊社では新人のスキルアップを目的として、エンジニア定例と呼称される勉強会が毎年行われています。その集大成として開催された3日間の開発合宿、通称「エンジニア定例合宿」に参加しました。  詳細は「 4年ぶりのリアルハッカソン合宿@ノジマ大磯スクウェアに行ってきました! 」 をご覧ください。  私たち新卒2年目は、前年、未曾有の災禍によりエンジニア定例合宿が開催出来なかったため、新卒1年目の方々と一緒に参加する形となりました  この記事では、「ニフティ社内全ブカツまとめサイト」というテーマに取り組んだ過程と結果について共有します。 メンバーについて 小林 普段の業務:@nifty光などの回線サービスの開発・運用 今回の担当:機能の実装やレイアウト、DB操作(CRUD)周り なにか一言:経験の浅い技術に着手出来て面白かった。ご飯が美味しかった。 柴田 普段の業務:「マイ ニフティ」(iOS, Android, バックエンド)の開発・運用 今回の担当:環境構築やTerraformを用いたIaC化 なにか一言:大磯おいしそ〜〜 テーマについて テーマ 「ニフティ社内全ブカツまとめサイト」 背景  ニフティ社内には「ブカツ」と呼ばれる制度があります。こちらは一般的に言うと部活動のようなもので、ニフティでは社内間コミュニケーションアップを目的として費用補助を頂きながら活動をすることが出来ます( 社内交流制度 )。  例えばフットサル部やボルダリング部などのアウトドア系のブカツから、ボードゲーム部やeスポーツ部などのインドア系のブカツが設立されています。  私たちもブカツに参加しているのですが、他のブカツ含めて「いつ行われているか分からない」や「気になってはいるが、ブカツに参加する際の手順が分からない」などの懸念が見受けられました。  そのため、円滑にブカツの管理が出来るように「ニフティ社内全ブカツまとめサイト」を作成することに決定しました。 成果物について WEBサイト  期間内では左端のようなまとめサイトを作成することが出来ました。  事前に作成しておいた記事一覧が最新5件で表示されるようになっており、題名やアイキャッチ画像、開催日時、いいね数、概要を記事ごとにこの画面では見ることが出来ます。他にもブカツ一覧や申込フォームがあります。  また、「記事の投稿」ボタンを押下すると、ブカツの選択を経て参加メンバーや活動記録(記事)を登録することが出来たり、左端のページより記事をクリックすると簡素にはなりますが活動内容の詳細なページが表示されます。 インフラ構成  インフラストラクチャについては画像の通りとなり、AWSのAmazon ECS(Fargate)やAmazon RDSを用いてWEBサイトの構築を完了させました。  また、Terraformを用いてIaC化を図ることで、運用負荷の削減やリソース全体の管理をより効率化することが出来ました。 3日間の過ごし方 1日目 簡単なハイレベルアーキテクチャをホワイトボードに5分程度で作成 要求定義 ブカツ一覧が見たい 説明が欲しい 活動報告が見たい クラウド上で運用したい … 役割分担 フロントエンド(Next.js × TailwindCSS) バックエンド (Next.js × Prisma) インフラストラクチャ (AWS × Terraform) Next.js のチュートリアルの実施 Devcontainerを含めたコンテナ上環境構築 2日目 DB設計 記事マスタとブカツマスタを作成 実装 ローカル環境にてDB接続を実現し、DB操作も実装 READ:記事一覧の取得 CREATE:記事の投稿 UPDATE:いいね機能 DELETE:実装せず 最新5件の記事を表示と、ブカツ紹介や活動報告ページへの遷移 TailwindCSSを用いたレイアウト修正 インフラ構築 Terraformを用いてAWSリソースを作成 WEBサイトへアクセスが出来ることを確認 Amazon RDSへの疎通を確認 遊び心で記事にいいね機能を追加 記事がいいねされた際は、Incoming Webhookを用いてSlack上に通知されるように 3日目 発表用資料作成 時間を鑑みて追加機能の実装は困難と判断 工夫したところ 現在のDBマスタからブカツ一覧を取得するように  DB設計を経て作成したブカツマスタを用いて、ブカツ一覧を一元管理できるようにしました。その結果、ハードコーディングを回避することが出来ました。 Terraformを用いたIaC化  「インフラ構築」にもある通り、AWSリソースの構築はTerraformにより実現しています。当初は「ローカル実行でもいいから実際に操作できたら嬉しい」という会話をしていましたが、2年勤務した中で学んだTerraformの経験を活かすため、挑戦することにしました。  まず、「一旦1から作成してみるか 」で積極的に行動できたことが素晴らしく、そしてエラー解消に数時間苦悩しつつも乗り越えたことで、とても良い経験が出来たと思います。 いいね機能とSlackへの通知機能の実装 荒ぶるSlack通知  2日目が終了する数十分前までは、Slackへの通知機能を実装しようという考えはありませんでした。  活動のモチベーションをあげることを目的としていいね機能を作成した後、「みんなが触るタイミングで通知機能あったら面白くない?笑」から始まり、Slackの機能であるIncoming Webhookを用いて実現しました。とても簡単に実装ができ、数分程度で完成させることが出来ました。 学んだこと 時間配分の難しさ  後悔していることの1つに、「もっと機能を実現できたのではないか」と考えています。  短期間でサービスとして完成させる上では、ある程度の「見た目」は必要だと思っており、「1機能が完成するとTailwindCSSを用いてレイアウトを作成し、またある1機能が完成すると…」の繰り返しで実装していきました。  この時点で想定以上の時間がレイアウトの作成に掛かったのは事実であるため、3日目にはレイアウトを考慮せずに機能の実装に時間を掛ければ良かったのかもしれないと思ってしまいました。  しかし、今回のエンジニア合宿については、皆さんに触って頂いた際に評判がとても良かったため、見た目にもこだわって良かったと嬉しさを感じています。この経験を通して、実際の業務については納品先が求めていることを明確化し、時間配分を見極めたいと思います。 ORMを用いたDB操作とサーバサイドとの連携  今までは、DB操作についてハンズオンや既存のコードを拡張することでのみ触れてきましたが、実際に0からサービスを作る過程でORMを用いてサーバサイドから操作が出来るように新規作成することは今まで行わなかったため、面白い体験になりました。  公式のドキュメントを参照しながら実装し、実現出来た時はとても嬉しかったです。 0からAWSリソースを作成する経験ができた  業務でAWSやTerraformを触ることはありますが、既存に構築されている環境への追加や修正に限っていました。今回ハッカソン形式で開催されたことで、よく使われるAmazon ECS, Amazon RDSの構成を0からAWS環境を構築する経験が出来たため、今後の業務にも活かしていきたいと思います。 まとめ  本記事を読んでいただきありがとうございました。  メンバーとして2人体制で行ってはいましたが、実用的に活かせるサービスを作れたと自負しています。もう少し時間があれば実際に運用が出来るサービスとして確立出来るかもしれません。  今回のエンジニア合宿では他の業務を大きく意識せず、特定のプロダクトの開発にのみ着手することが出来たこともあり、ある1つのサービスをインフラも併せて完成まで導けました。その経験はとても大きいものだと思っています。その反面、色々な業務を並行して遂行していく際のスケジュール管理についても同時に考慮することができたため、工数としての尺度として今回の体験と比較が出来ることを期待しています。 ニフティでは、 さまざまなプロダクトへ挑戦する エンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトより お気軽にご連絡ください! ニフティ株式会社採用情報 カジュアル面談も随時受付中! ニフティに興味をお持ちの方は キャリア登録をぜひお願いいたします! キャリア登録 connpassでニフティグループに 参加いただくと イベントの お知らせが届きます! connpassで ニフティグループに参加する
アバター
0. はじめに 1. ブース 1-1. リアルニフくじブース 1-2. コードレビューブース 1-3. @nifty光 10ギガ体験ブース 1-4. フォトブース 1-5. アンカンファレンスブース 1-6. Ask the Speakersブース 1-7. キャリア相談ブース 2. オンライン配信の裏側 3. まとめ 0. はじめに こんにちは! ニフティでは、2023年11月18日(土)にテックカンファレンス「NIFTY Tech Day 2023」を初のハイブリッド開催で実施しました。 今回は、セッション以外で当日会場で実施されていたブースの様子や、オンライン配信の裏側をお届けします! NIFTY Tech Day 2023 セッション編のレポートは こちら アーカイブ動画の再生リストは こちら 発表資料は こちら 1. ブース 開催日に会場へご来場された方は既にご存知だと思いますが、開催当日は 7 ブースと大変多く、盛況でした! 今回は各ブースの様子をご紹介します 1-1. リアルニフくじブース ニフティでは、 ニフくじ というキャンペーンを実施しております。 ニフくじとは、@niftyトップページ(PC/スマホ)、会員向けアプリ「マイ ニフティ」で引けるくじで、ニフティポイントがゲットできるキャンペーンです。 そんなニフくじを NIFTY Tech Day 限定でリアルで引けるようにしちゃいました! 今回の景品はモバイルバッテリーやTech Day Tシャツ・Tech Day 靴下など盛り沢山でした。 どの景品も今回限りの限定品のため、とても貴重ですね。 リアルニフくじの景品の写真!左から靴下・モバイルバッテリー・Tシャツとなります。 私の推しはモバイルバッテリーです 1-2. コードレビューブース エンジニアの業務にはコードレビューが付き物! よくない実装を来場者の方にレビューしていただくコードレビューブースです。 今回レビューをしていただいたコードと解答は以下の記事から確認できます! NIFTY Tech Day 2023 【出題編】コードレビュー問題 〜このReactコードを改善せよ〜 NIFTY Tech Day 2023 【解答編】コードレビュー問題 〜このReactコードを改善せよ〜 コードを見ていただいてと思った場所には付箋でレビュー内容を書いていただきました。 コードレビューブースでレビューをする皆さん。 わいわいとしており盛況でした! コードレビューブースで掲載されていたコードはこちら。 付箋同士でも議論されていますね! 1-3. @nifty光 10ギガ体験ブース 3つ目のブースは弊社商品である @nifty光 10ギガを実際に体験していただけるブースです! こちらでは、1ギガ回線と10ギガ回線の比較が可能となっております。 私も会場事前準備の時に体験してみましたが、10ギガの速さには圧倒されました…! 10ギガ体験コーナーの実際の様子です! 右奥にあるモニターに映っているセッションを視聴しながら10ギガを体験できます。 1-4. フォトブース NIFTY Tech Day 2023 参加の記念に特製パネルと一緒に撮影ができるブースです! こちらのブースでは参加者はもちろんのこと、登壇者が記念に撮影をしておりました 開場の前にフォトブースの様子を撮影 こうして写真で見るとパネルの大きさを感じますね。 フォトブースの隣にあるサイネージでTech Day 2023 実行委員であるお二人のツーショット! サイネージもTech Day 2023 仕様となっておりました。 1-5. アンカンファレンスブース 当日の午前には、参加者自身でテーマを提案していただき議論していくアンカンファレンスブースが開かれていました! アンカンファレンスのテーマとして、以下内容がテーマとなっていました。 Goのエラーハンドリングについて Rustの言語仕様について Vim VS VSCode …その他いろいろ 「その他いろいろ」ではどのような内容が議論されていたのでしょうか…? 1-6. Ask the Speakersブース 当日はセッション内容の質問の場として、slidoをご用意しておりました。会場では直接会話ができるAsk the Speakerブースもございました! Ask the Speakersブースではスクラムのトークなど様々繰り広げられてました。 こういった直接的な交流ができるのも会場開催の良いところです! 1-7. キャリア相談ブース エンジニアお悩み相談室と称して、将来のキャリアだったり、悩んでいる内容をニフティのベテランエンジニアに何でも聞けちゃうブースです。 昼食のお弁当を食べながら会話をされているようでした! 2. オンライン配信の裏側 今回はハイブリッド開催! ということで、YouTubeにて配信をしていたのですが、今回は配信の様子もチラッとご紹介! こちらは2レーンに変更した後の1レーン配信を管轄している様子。もう1つのセッションでも同様の設備となっております。 前日の準備ではカメラ位置の微調整だったり各種機器の動作確認・リハーサルなど多岐に渡り対応されていました! 初のハイブリッド開催にも関わらず、予定通りに進行できたのも配信チームのおかげです。頭が上がりません。 別の視点からも 裏方の仕事、かっこいいですね! 3. まとめ そんなこんなで、NIFTY Tech Day 2023 のレポートは以上となります! これからも、技術イベントを開催していきますのでぜひご参加ください〜。 connpassに登録くださいますと、イベント開催通知をメールで受け取れますのでぜひ以下のURLよりご登録ください! ニフティ株式会社のconnpassはこちら: https://nifty.connpass.com/ ここまでお読みいただきありがとうございました! ニフティでは、 さまざまなプロダクトへ挑戦する エンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトより お気軽にご連絡ください! ニフティ株式会社採用情報 カジュアル面談も随時受付中! ニフティに興味をお持ちの方は キャリア登録をぜひお願いいたします! キャリア登録 connpassでニフティグループに 参加いただくと イベントの お知らせが届きます! connpassで ニフティグループに参加する
アバター
イベント概要 NIFTY Tech Talkは、ニフティ株式会社の社員が主催するトークイベントです。 本イベントでは、ニフティグループの社員が業務を通じて学んだことを発信しています! TechTalk#17は「超入門 ここから始める開発環境」です。 開発を行うにあたり、まずは構築する開発環境。 どのような環境を整えればいいのかわからない、構築はできたけどちょっと使いにくかななどなど新人エンジニアにありがちな疑問や質問にお応えできればと思います。 今回はTech Talk初のオンライン、オフラインのハイブリッド開催となります。 Youtube配信だけでなくニフティ本社にお越しいただき参加することも出来ます。 概要 日程:3月14日(木)19:00〜20:00 参加方法 connpass にて登録をお願いいたします。 オフライン参加 ニフティ本社にて開催となります。 当日18:30開場いたしますので、エレベーターにて18階へお越しください。 受付時に名刺を1枚、もしくは身分確認が出来るもののご提示をお願いいたします。 懇親会等はございません。 オンライン参加 YouTube Liveにて配信いたします。 ※YouTube LiveのURLは決定後、参加者への情報欄に記載いたします。 こんな方におすすめ 新人エンジニア プログラミングに興味あるが、なにから手を付けていいかよくわからない方 今の開発環境をもう少し便利にするために参考にしたい方 タイムテーブル 時間 コンテンツ 18:30 開場 19:00 – 19:10 オープニング+会社紹介 19:10 – 19:25 LT1: dotfilesをつくるよ 19:25 – 19:40 LT2: フロントエンドを始める、その前に どうしていっぱいツールがあるの (仮) 19:40 – 19:55 LT3: ローカル環境を守れ、DevContainerのススメ(Python) 19:55 – 20:00 まとめ+クロージング 20:30 閉場 テーマ 超入門 ここから始める開発環境 登壇者プロフィール たけろいど(登壇者) ニフティ株式会社 会員システムグループ第二開発チーム こんにちは。たけろいどです。SvelteKitというフロントエンドフレームワークが大好きです。 最近はユニコーンオーバーロードというゲームをやっています 山田 良介(登壇者) ニフティ株式会社 会員システムグループ 第一開発チーム 三浦 拓実(登壇者) ニフティ株式会社 会員システムグループ第二開発チーム お客様向けセキュリティサービスのシステム開発担当です。 先月のTechTalkでは1on1について話しましたが、今回は開発者として話します ニフティグループでは一緒に働く仲間を募集中です 新卒採用、キャリア採用を実施しています。ぜひ リクルートサイト をご覧ください。 ニフティエンジニアが業務で学んだことやイベント情報を エンジニアブログ にて発信しています! ニフティエンジニアのTwitterアカウントを作りました NIFTY Tech Talkのことや、ニフティのエンジニアの活動を発信していきます。 Tweets by NIFTYDevelopers アンチハラスメントポリシー 私たちは下記のような事柄に関わらずすべての参加者にとって安全で歓迎されるような場を作ることに努めます。 社会的あるいは法的な性、性自認、性表現(外見の性)、性指向 年齢、障がい、容姿、体格 人種、民族、宗教(無宗教を含む) 技術の選択 そして下記のようなハラスメント行為をいかなる形であっても決して許容しません。 不適切な画像、動画、録音の再生(性的な画像など) 発表や他のイベントに対する妨害行為 これらに限らない性的嫌がらせ 登壇者、主催スタッフもこのポリシーの対象となります。 ハラスメント行為をやめるように指示された場合、直ちに従うことが求められます。ルールを守らない参加者は、主催者の判断により、退場処分や今後のイベントに聴講者、登壇者、スタッフとして関わることを禁止します。 もしハラスメントを受けていると感じたり、他の誰かがハラスメントされていることに気がついた場合、または他に何かお困りのことがあれば、すぐにご連絡ください。 ※本文章はKotlinFest Code of Conductとして公開された文章( https://github.com/KotlinFest/KotlinFest2018/blob/master/CODE-OF-CONDUCT.md )を元に派生しています。 ※本文章はCreative Commons Zero ライセンス( https://creativecommons.org/publicdomain/zero/1.0/ ) で公開されています。
アバター
はじめに こんにちは。ニフティ株式会社の並木です。 今回は「X API」を利用するための手順と、「AWS Lambda」から「X API」を呼び出す方法についてご紹介いたします。 背景 以前「 Zapierを使ってRSSフィードの更新をトリガーにしたTwitterへの自動投稿機能を作ってみた 」で紹介した方法で、RSSフィードの更新をトリガーにしたX(旧Twitter)への自動投稿機能を作成したのですが、上記記事の「④Twitterに文章を投稿したい」で紹介した機能が2023年9月に使用できなくなってしまいました。(詳細: https://help.zapier.com/hc/en-us/articles/18657531069965 ) 別の方法で自動投稿機能を復活できないかという話になり、前から使用していた「Zapier」を流用しつつ、新たに「Amazon API Gateway」「AWS Lambda」「X API」を使用して、自動投稿を実現することにしました。 構成図は以下の通りです。 構成図の【1】【2】については、「 Zapierを使ってRSSフィードの更新をトリガーにしたTwitterへの自動投稿機能を作ってみた 」の処理をそのまま流用します。 【3】【4】【6】については別途記事を執筆予定です。 「【5】LambdaからX APIを呼び出して投稿」が今回の説明範囲になります。 「X API」とは 外部のアプリケーションから、Xの機能やデータを利用するためのAPIです。 Freeプラン(無料プラン)では毎月1500件の投稿をすることができます。 「X API」を利用できるようにする X Developer Platform にアクセスし、Freeプランの説明の下にある「Get started」ボタンを押下します。 先の画面へ進んでいくと、「X API」の使用用途を250文字以上で入力する画面が出てきます。(使用用途は英語で入力する必要があるので注意してください) 使用用途や規約同意の入力が完了すると、「Developer Portal」のページが表示されます。 「Projects & Apps」に、自動生成されたProjectとAppが表示されますので、App(下の画像の左メニューの赤枠部分)を押下します。 「Settings」が選択された状態で、そのまま下にスクロールしていくと「Set up」ボタンがあります。 こちらを押下すると「User authentication settings」画面に遷移します。 今回は「X API」を使った投稿(Write)がしたいので、「App permissions」で「Read and write」を選択します。 上記画面で「Save」を押下後、「Keys and tokens」を選択し、「API Key and Secret」と「Access Token and Secret」をそれぞれ生成します。(以下画像ではボタン名が「Regenerate」となっていますが、初めて生成する場合はボタン名が「Generate」となっています) 生成した「API Key and Secret」と「Access Token and Secret」は後で使用するためメモしておきます。 「AWS Lambda」から「X API」を呼び出す 「AWS Lambda」から「X API」を呼び出せるようにします。 こちらのAWSの公式記事 の「4-2. AWS Lambda 関数のひな形を作成する」を参考にしながら以下を実施します。 ランタイム:Pythonの最新バージョンを選択 「AWS CloudShell」を使用してPythonモジュール「requests_oauthlib」をインストール インストールしてきた「requests_oauthlib」をzipファイルにまとめ、Lambda関数にソースコードとしてアップロード 上記を実施した上で、Lambdaにコードを書いていきます。 import json import os from requests_oauthlib import OAuth1Session import boto3 import ast def lambda_handler(event, context): ################################# # Secrets Managerからキーを取得 ################################# secret_name = "シークレットの名前" region_name = "リージョン名" # Create a Secrets Manager client session = boto3.session.Session() client = session.client( service_name='secretsmanager', region_name=region_name ) get_secret_value_response = client.get_secret_value( SecretId=secret_name ) secret_data = get_secret_value_response['SecretString'] secret = ast.literal_eval(secret_data) consumer_key = secret['API_KEY'] client_secret = secret['API_KEY_SECRET'] access_token = secret['ACCESS_TOKEN'] access_token_secret = secret['ACCESS_TOKEN_SECRET'] ################################# # Xにポストする ################################# oauth = OAuth1Session(consumer_key, client_secret, access_token, access_token_secret) text = event['text'] payload = {'text': text} response = oauth.post( "https://api.twitter.com/2/tweets", json=payload, ) if response.status_code == 201: result = 'OK' else: result = 'NG' return { "statusCode": 200, "headers": { "Content-Type": "application/json" }, "body": { "result": result, "api_response": response.text } } Pythonモジュール「requests_oauthlib」の「OAuth1Session」を使用することで、認証周りの実装を簡単に行うことができます。 当初は、Zapierから直接「X API」を呼び出すことを検討していたのですが、ZapierにPythonの外部ライブラリを入れることができず、認証周りの実装が困難であることから、Lambdaで「OAuth1Session」を使用して実装することにしました。 OAuthセッションを作るのに、最初に生成した「API Key and Secret」と「Access Token and Secret」を使用します。 ハードコーディングを避けるため「AWS Secrets Manager」を使って管理・呼び出しをしています。 「AWS Secrets Manager」の使い方については、以前投稿した「 LambdaでSecrets Managerを使ってみた 」を参照してください。 X投稿が成功した場合は「OK」、失敗した場合は「NG」を返すようにしています。(SlackにX投稿結果を通知するのに使用します) おわりに LambdaでPythonモジュール「requests_oauthlib」を使用することで、簡単に「X API」を呼び出すことができました。 当初、Zapierだけで何とか実装できないかと試行錯誤し、認証周りの調査に時間をかけてしまったので、Lambdaで実装するという手段に早めに切り替えれば良かったと感じました。 実現したいことにあわせて、様々なサービスを組み合わせて柔軟に対応することの大切さを学びました。 参考記事 https://aws.amazon.com/jp/builders-flash/202201/aws-drill-twitter-bot-1/?awsf.filter-name=*all ニフティでは、 さまざまなプロダクトへ挑戦する エンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトより お気軽にご連絡ください! ニフティ株式会社採用情報 カジュアル面談も随時受付中! ニフティに興味をお持ちの方は キャリア登録をぜひお願いいたします! キャリア登録 connpassでニフティグループに 参加いただくと イベントの お知らせが届きます! connpassで ニフティグループに参加する
アバター
はじめに ニフティでは新人エンジニアの研修の一環として「エンジニア定例」と言う内製の研修が行われます。先日そのエンジニア定例の1つのエンジニア定例合宿というハッカソン合宿を行いました。本記事ではこのハッカソン合宿での制作物をご紹介します。 チームメンバー紹介 チーム名:欲望の沼 村山 普段の業務:OJT3期、メールシステム運用業務 高田 食を愛しているが、舌と体が肥えてしまっているのが悩み kiqkiq 外食とみかん 白岩 リサイクルショップで変なものを買ってきて修理する人。 制作物 概要 私たちのチームでは「スポーツイベントを盛り上げられるようなサービス」としてスポーツギャンブルサービスを開発しました。これは、サッカーやバスケットボールのような2チームごとに競うスポーツに対して、どちらのチームが勝つかを予想しポイントを賭けるスポーツベッティング形式のサービスで、スポーツ観戦とギャンブルを同時に楽しめるようなWebアプリケーションです。 主体となる機能はオッズの計算と払戻です。自他の賭けたポイントによってオッズを計算し、ユーザーの賭けたポイントと勝敗に応じてポイントが払い戻されます。 使い方 まずはログインして最初に遷移するTOP画面です。この画面では試合一覧が表示される他、各試合の投票画面へのリンクがあります。ユーザーはこの画面で試合一覧から試合を選び、投票画面に遷移することができます。 次に投票画面について説明します。投票画面では、両チームのオッズが表示され、どちらのチームに何ポイントかけるかをプルダウンから選択し、「投票する」ボタンからポイントを賭けることができます。また、オッズの計算は全体の賭けポイントによって算出され、ユーザーは一度賭けた試合にオッズの変動を見て追加でポイントをかけることができます。 試合が終了すると、的中したユーザーにはオッズを元に算出されたポイントが払い戻され、払い戻しポイントが画面に表示されます。 次はランキング画面についてです。ランキング画面では、保有ポイントのランキングを確認できます。ランキングの項目は2種類実装しており、上位から表示したランキングとログイン中のユーザーの周辺を表示するランキングです。 ヘッダー部分は、TOP画面、ランキング画面へのリンクがある他、ログイン・ログアウトボタンとに加え、ログイン中のユーザー名と保有ポイントが表示されます。 使用技術 主要なフレームワークはチーム4人のうち2人が経験のあるFastAPIを選び、データベースは一般的なDBとしてMySQLを選びました。マークアップの部分はテンプレートエンジンのjinjaを用いて実装し、これらのシステムをdockerを用いて、アプリケーション用のコンテナとDB用のコンテナとして構成しました。最後にこの構成全体をAmazon EC2で構築しました。 構成図 工夫したこと 工夫したことは大きく3つあります。まず1つ目は臨機応変にモブプロで進めたことです。開発初期の環境構築時や開発におけるのエラーやトラブルの解決をモブプロで進めることで、共通理解の元に作業を進めることができ、エラーやトラブルを素早く解決できたと思います。 2つ目はChatGPTをうまく使い効率よく進めたことです。オッズの計算などのアルゴリズムは考えて実装するようなものでないものはChatGPTを用いて大まかな実装方法などを検索しました。 3つ目は各々の得意不得意を生かした役割分担で開発したことです。主な役割はデザイン担当、開発担当、インフラ担当の3つで、チームメンバーのそれぞれが得意な分野を担当するように役割分担しました。また、上記で述べた通り、エラー時には適宜モブプロを入れ、必要に応じてメンバー全体で考えながら、各々の得意な分野で実装を行いました。 学んだこと・成長したこと CSS経験がない中でUIなどを作ることができた 私たちは4人ともフロントエンド側の経験が少なく、特にCSSについては最初はデザインができてもそれを実装する方法が全然わからないという状態でした。それでもなんとかフレームワークやAIを活用してある程度形にすることができ、終わる頃にはCSSについて少しだけわかるようになりました。 問題発生時に臨機応変に対応できるようになった 実質2日程度の非常に短い開発期間で動くものを完成させていく中では当然さまざまな問題が発生し、その場での対応を常に求められました。今回の経験を通して臨機応変に動く力が身についたと思います。 デプロイ方法を模索した 合宿2日目の22時頃、ローカル環境である程度動くものが完成し、AWSへのデプロイを行う段階になりました。一般的なデプロイ方法としては、GitHubのリポジトリをCodeCommitへミラーリングする方法や、CodePipelineを使用したCI/CD環境の構築が挙げられますが、実現するにはあまりにも時間が足りません。 そこで、とにかく早く、シンプルにデプロイするにはどうすればよいかを考え、以下の方法にたどり着きました。 Amazon Linux 2023のEC2インスタンス、セキュリティグループ、NATゲートウェイを作成 インスタンス内にDockerをインストール リポジトリをtarに圧縮 S3に圧縮したリポジトリを置く EC2インスタンスからS3にリポジトリを取りに行く インスタンス内でtarを解凍 コンテナを起動 絶対に賢くない方法ですが、どんな方法であれデプロイできれば勝ちです。 これで無事AWSへのデプロイが完了しました。 バグの解決策を考えた 今回ソース管理にはGitHubを利用しました。しかし、merge、push、merge、revert…なんてことをやっているうちに「ブランチ間にあるはずの差分が認識されずPRが作れない」という事態が発生しました。 当初は頑張って原因調査などもしていましたが、他のチームの助けも借りて事態の解決を優先し強制resetなどを行ってどうにか事なきを得ました。期間の短いハッカソンならではの経験だったと思います。 DBにinsertしたテストデータを画面で表示すると文字化けしてしまう、という問題が発生しました。機能に関係なく困る不具合だったためモブで対応し、SQLやDBMSについて知見を深めることができました。 フロント・バックで分担していたが、機能ごとに開発するように修正した 開発初日は、各ページの入出力を決めた上でフロントエンドとバックエンドでブランチを分けて進めていく体制でした。しかし短期の開発ではどうしてもブランチの管理が煩雑になり進めづらかったため、2日目からは機能ベースでの分担に切り替えました。結果としてこちらの方が進めやすかったため、早めの決断が下せたことはよかったと感じています。 最後に 短期間での開発で、当初は動くものが完成するかどうか不安でしたが、なんとか形にすることができました。 AWSへのデプロイは必須ではないと指示されていましたが、チーム内で話し合った結果、せっかくなのでやってみようという流れになり、デプロイまでたどり着くことができました。 また、ページ全体を少し胡散臭いデザインにしたことで、発表の際の反応がよかったです。ブログ上では伏せていますが、実際には大量の広告やコラージュ画像を貼り付けていました。 ニフティでは、 さまざまなプロダクトへ挑戦する エンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトより お気軽にご連絡ください! ニフティ株式会社採用情報 カジュアル面談も随時受付中! ニフティに興味をお持ちの方は キャリア登録をぜひお願いいたします! キャリア登録 connpassでニフティグループに 参加いただくと イベントの お知らせが届きます! connpassで ニフティグループに参加する
アバター
はじめに 初めまして!新卒一年目のpopopopman、稲継、statiolakeです。 弊社では新人の育成のため、毎年エンジニア定例という勉強会が行われています。先日、その集大成として3日間にわたる開発合宿、通称「エンジニア定例合宿」に参加してきました。 詳細につきましては こちら をご覧ください。 本記事では私達チーム†skyscraper†の作ったスポーツイベントでビンゴを行うサービスについて紹介していきます。 メンバー紹介 popopopman 担当 :フロントエンド 普段の業務 :インフラ管理とセキュリティの運用 一言 :いい仕事は、いい遊びからよ。 稲継 担当 :フロントエンド 普段の業務 :バックボーンネットワーク運用 一言 :がんばるます statiolake 担当 :バックエンド、DB設計、インフラ 普段の業務 :Webサービス開発 一言 :NeovimでRustを書く、これが最強。 プロダクト紹介 概要 今年は第39回夏季オリンピック競技大会、パリ2024が開催されます。この楽しいイベントをさらに盛り上げるべく。オリンピックのメダル獲得をした国と競技に応じてビンゴを行うサービスを作成しました。機能を紹介していきます。 遊び方 今年開催されるパリオリンピックの試合結果を元にビンゴゲームを行います。 はじめに、トップページで”名前”と”秘密の言葉”を入力し、ビンゴカードに移動ボタンを押します。 すると、入力された”名前”と”秘密の言葉”を元にビンゴカードが生成されます。 このビンゴカードの1マス1マスには、競技と国がセットになって描かれています。オリンピック期間中、ある競技である国がメダルを獲得した場合、そのマスを開けることができます。普通のビンゴカードだと数字が書かれていて、呼ばれた番号のマスを開くことができますよね。このビンゴでは、例えば、仮に100m走で日本がメダルを獲得したときに、そのマスを開けることができるという寸法です。 ビンゴ画面(初期状態) 大会はまだ始まっていないため、今回は結果を仮で設定しました。すると、以下のように表示が変わります。青がビンゴで黄色がリーチ、灰色がどちらでもない開いているマス、黄色い線で囲まれているマスが、そのマスが空くとビンゴになるマスです。 ビンゴ画面(ゲームが進行した状態) また、マスをクリックすると画面右側に競技名、種目名、チーム名、パネルが開くことで得られる点数が表示されます。 ビンゴ画面(マスの情報を表示) システム構成図 システム構成図 フロントエンドはSvelteというJavaScriptフレームワークとTailwind CSSというCSSフレームワークを使用しました。これにより、少ないコードで高いユーザーエクスペリエンスを実現しました。また、バックエンドにはRustとそのWebアプリケーションフレームワークであるaxumを、データベースとしてPostgreSQLを使用しました。これにより、バックエンドの高速な処理を実現しています。 これらをコンテナ化してEC2上で動作させることでユーザーがこのサービスにアクセスできるようにしました。(実際にリリースはされていません。) 開発で工夫したところ 開発期間が短いながら、なるべく完成度の高いものを作り上げるため、様々な工夫をしました。ここでは、そのうちのいくつかをご紹介します。 フロントエンドとバックエンドを効率よく完全に分業する 開発期間の短縮と作業効率の向上を実現するために、バックエンドとフロントエンド間のデータ通信をAPIを介して行うことにより、開発を完全に分業しました。これにより、各自の担当範囲に集中することができ、プロジェクト全体の進行速度と生産性が向上しました。 フロントエンド側のUXにかなりの比重を置き、粗の少ないユーザー体験を作る フロントエンドの開発では、ユーザー体験(UX)に特に重点を置きました。アニメーションや直感的でシンプルなインターフェースの設計、ローディング時間の短縮、など、ユーザーがストレスなく、そして楽しく操作できるような環境を作り上げることに注力することで、長時間使用したくなるようなサービスを目指しました。 ビンゴ画面の動作 「最低限の機能」を十分小さく定義し、動作する状態をキープしながら拡張を続ける 開発の初期に「最低限の機能」を定義し、まずはその範囲内で動作するシステムを作りました。これ対し段階的に機能を追加していくことで、短い開発期間で間に合わないという不安のない状態を保ちつつ完成度を高めていく作業に注力することができました。 合宿を通じた学び 短期間でのチーム開発 今回の合宿では、各自が持つ技術や知識をチームの中でどう活かせるかについて深く考える機会を得ることができました。それぞれの強みを生かし、役割を効果的に分担することで、プロジェクトの進行が大きくスムーズになったのを感じることができました。また、短期間ならではの迅速な意思決定と効率的なタスク管理の技術を磨くことができ、自分の最高速の開発スピードを知ることが出来たので貴重な経験になったと思います。 新しい技術に触れる 私たちのチームの裏のテーマとして「触れたことのない新しい技術に触れる」というものがありました。誰も触れたことのないフレームワークだったり、言語を積極的に用いたことでチームメンバーとの相談や議論が盛り上がったと思います。ただ技術を学ぶだけでなく、新しい技術に触れることの面白さや、そしてそれをチームで共有する楽しさを経験することができました。 終わりに 合宿を通して、私達は限られたリソース、期間と持ちうる技術の中で最大限の成果を出すための戦略を体験しました。チームで協力し、強みに応じた役割の分担や「最小限の機能」からの機能の拡張といった工夫によってより良い成果物を生み出すことができたと思います。一つのシステムをゼロから作り上げ、かつ効率や完成度を求め達成するという貴重な経験ができました。 しかし、今回の成果物に完全に満足しているわけではなく、終わってから振り返ると、改善の余地や技術力の不足を感じています。 この経験を個人での学習やより大規模な業務でのチーム開発に活かしていきたいです。 引用 本記事に掲載されているシステムで使用されているピクトグラムは、Wikimedia Commonsによってパブリックドメインとして提供されたものです。 https://commons.wikimedia.org/wiki/User:Parutakupiu#Summer_sports ニフティでは、 さまざまなプロダクトへ挑戦する エンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトより お気軽にご連絡ください! ニフティ株式会社採用情報 カジュアル面談も随時受付中! ニフティに興味をお持ちの方は キャリア登録をぜひお願いいたします! キャリア登録 connpassでニフティグループに 参加いただくと イベントの お知らせが届きます! connpassで ニフティグループに参加する
アバター
はじめに こんにちは。新卒1年目の宮永です。もうすぐ新卒バリアが使えなくなるので怯えています。 先日、1年目・2年目を対象としたハッカソン合宿に参加しました(合宿概要は こちら )。 テーマがいくつかあり、今回私たちは「健康を増進するサービス」として飲酒量管理のwebアプリを作ったので紹介します。 メンバー 江口 普段の業務:社内システムの開発・運用 今回はDBやflaskなどのバックエンドを主に担当 三度の飯よりDBが好き。初日は不安でご飯の味がしなかった。 西根 普段の業務:ニフティポイントクラブの開発 今回はflaskとフロントエンドを主に担当 CSSを完全に理解している。得意なことは賑やかしです!!!!! 宮永 普段の業務:SREを社内に広める活動 今回はコンテナ周りやDB等のバックエンドを主に担当 パケットの話で盛り上がりたいタイプ。最近はダイヤルアップにはまっている。 成果物 今回は飲酒量管理のwebアプリを作成しました。 概要 飲酒量を入力して、純アルコール量と血中アルコール濃度、分解に必要な時間を表示 酔い度により肝臓の色が変化し、視覚的にどれくらい肝臓に負担がかかっているかを表示 ログイン機能と履歴機能を付け、飲酒習慣を可視化 デモ ページにアクセスすると最初にログイン画面に遷移します。 ログインすると、今までに登録した飲酒の履歴一覧が見れます。 飲酒量登録画面では、飲んだお酒の量と体重を入力します。 入力すると、アルコールが抜けるのに必要な時間や酔い度などが表示されます。酔い度によって肝臓が黒くなっていくのがポイントです。 ネタ枠で、好きな割合でハイボールを作るページも作りました。 TailwindCSSを使ったおかげもあり、短時間でいい感じの見た目にできたのではないかと思います。 システム構成 今回はDocker Composeを用いたコンテナで構成しました。メンバーの使用PCにWindowsとMacの両方があり、開発時に環境差分で苦しみたくなかったからです。 また、時間があればAWSデプロイしたかったのですが、その際もデプロイしやすいだろうという判断でコンテナ構成にしました。(結局デプロイまでは間に合いませんでした…) バックエンドはFlask、DBはMySQLを使用しました。入社時の技術研修で使っており、ネット上にも情報が多かったので採用しました。 フロントエンドにはTailwindCSSを使用しました。メンバー全員触ったことのない技術でしたが、面白そうなので思い切って採用しました。興味だけでシステム構成を決められるのは合宿の良い所ですね。 工夫した点 開発期間が短い制約がある中でも、工夫して上手にできた点がありました。 作業の優先順位をすばやく決める事ができた やりたい事、やらないといけない事が沢山ある中、手を動かす前に話し合って優先順位を上手に決めることができました。ある程度進んでいく中でも、無理そうであれば早めにあきらめる事もできました。 開発初期で環境を上手に作ることができた 最低限作らないといけない部分の優先度を上げたため、開発期間前半でバックエンド構成やDB初期データ自動投入の仕組みを完成させることができました。開発後半は「とりあえずシステムが動いている」という安心感を持った状態でアプリケーションの機能開発に集中して取り組むことができました。 CSSフレームワーク使って短時間でいい感じにできた 最初からCSSフレームワークを使ったため、「この画面と同じような感じで!」というざっくり指定でも別のメンバーに作業を引き継ぎやすかったです。導入は多少大変でも、トータルでかかる時間を短縮することができました。 作業が軌道に乗ってからは2時間毎に進捗確認→新規タスクの洗い出しと優先度決め→タスク割り振りをしたので作業を進めやすかった 後から思えば、スプリントがとても短いスクラムのように回すことができました。ハッカソンではハプニングがつきものですが、その中でも変化に強い動き方ができたのではないかと思います。 またコミュニケーションがとれていたため、メンバーの忙しさやスキル面をお互いに理解しやすく、結果として作業割り振りが上手にできました。重複が無いようなタスクの分割ができるようにも注意できたため、「マージしたら壊れて動かなくなった!」という事故が起こらなかったです。 苦労した点 もちろん苦労した部分も多かったです。 DB周り DB設計を23時に行ったため、頭が働いておらず不完全なものになっていました。翌日に結局DB構成を変えることになり、DBが関わる実装部分をすべて修正することになってしまいました。(江口君本当にごめんなさい…) コンテナNW周り Docker ComposeでアプリケーションコンテナとDBコンテナの2つを作る際にbridgeネットワークの設定を忘れており、ホスト側からは接続できるのにコンテナ同士は接続できない状態にしてしまいました。ホストから見るlocalhostとコンテナから見るlocalhostが違うことを理解するまでにかなり時間を費やしてしまいました。 flaskの導入が大変 メンバー全員が研修以来使っておらず、覚えていなさすぎて最初これ動くものできる?大丈夫?という気持ちになりました。普段の業務ではフレームワークの導入を触ることは無いため導入部分が一番大変であることを痛感しました。 フロント周り フロントを主に担当した西根さんはCSSに慣れており、はじめはCSSを想像してTailwindのクラス名調べて…という謎作業をしていました。フレームワークは慣れるまでも大変でした。 また、svg画像の扱いが不慣れで、画像にグラデーションを付ける作業(肝臓の色を悪くする部分)に苦労しました。 学んだこと 設計をちゃんとすることは大事 DBのカラムを別テーブルに移動させなければいけなくなったり、新規アカウント登録機能がないことに2日目の途中で気づいたりなど、本来序盤でビシッと決めておくべき部分が決まり切っていないせいで後半苦労した面が多かったです。とりあえずコードが書きたくなっても、決めるべきことはしっかり決めないと自分が痛い目に遭うという事を痛感しました。 コンテナ周りの知識 今回は一番最初に「全部コンテナで構成するぞ!」と決めましたが、メンバー全員Docker Composeでの構成経験はありませんでした。苦しみながらもコンテナやコンテナを接続するネットワーク回りの知識が付いたかなと思います。 エンハンスと新しく作ることで要求されるレベルの違い 普段の業務はどうしてもエンハンスが多くなりがちですが、新しく何かを作るとなると設計を考える力やチームビルディングの力など、様々な力が要求されることが実体験として理解できました。 大変な一方で、全体が理解できていることの安心感や、自分たちで作り上げた達成感も体感することができました。 まとめ 今回の合宿ではメンバーそれぞれ得意な部分を主に担当しつつ、普段触らない技術についても助け合いながら担当し、短い期間で成果物を作り上げることに成功しました。技術面はもちろん、なんとかすることができたという自信を得る事ができました。 制約がある中でなんとかすることができた経験を自信につなげ、これからの業務に生かしたいです。 ニフティでは、 さまざまなプロダクトへ挑戦する エンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトより お気軽にご連絡ください! ニフティ株式会社採用情報 カジュアル面談も随時受付中! ニフティに興味をお持ちの方は キャリア登録をぜひお願いいたします! キャリア登録 connpassでニフティグループに 参加いただくと イベントの お知らせが届きます! connpassで ニフティグループに参加する
アバター
前回の記事では、ニフティのISPオペレーションチームで働く社員に、業務内容やチーム環境についてインタビューを行いました。 今回はインタビューの後編をお届けします。前編はこちらの記事をご覧ください。 【インタビュー】ニフティのISPオペレーションチームチームの過去から未来について【ISP前編】 過去行った業務内容について H.Fさん、K.Hさんはニフティに長く勤めていますが、過去にはどういった業務を行ってきましたか K.Hさん 勤続年数が30年を超えたので、様々なことを経験しました。 入社当初はパソコン通信アプリの開発をしていました。お客さんの回線からきた通信に応答を返すプログラムを作っていました。当時はコンピュータを何十台も繋いで通信するような例が無い中でそれを実現するネットワークベースの通信ソフトの開発・運用をやっていましたね。 その後もNIFTY Managerという新規ソフトの立ち上げにも携わりました。いままでは1つのファイルしかリアルタイム通信できませんでしたが、バックグラウンドで複数のファイル送受信を可能にしたりなど、やりがいのあるものでした。他にも、当時の弊社のサービスはリアルタイムのチャット機能がなかったので、Javaアプレットを用いてチャットを行うようなツールを作ったりもしました。 技術の黎明に携わらせてもらうことが多かったように思います。誰もやったことがないことをスケジュール管理しながら取り組んだ経験が今の業務にも生かせているなと感じていますね。 H.Fさん 私が一番印象に残っているのは社内インターネットのデータセンターの立ち上げですね。 社内から外部インターネットの接続方法の検証なども行っていましたが、仮想化基盤の作成が一番大きい仕事でした。一つのマシン上に複数のサーバーを立てられるように、ローカル仮想マシンソフトウェアをデータセンターのマシンに導入しました。どうすれば動くかといった技術的課題について、当時のネットワークチームとも協力して解決に導きました。 一方で苦労した点としては、社内で動いていた沢山のサーバーを全てデータセンターに移行させるので、考慮すべきことや調整すべきことが複数あったことです。 社内の多種多様なマシンを移行するので、適切なスペックを計算したり、コストの見積もりをしたり、ネットワークの回線速度やキャパシティの観点を把握するのが大変でした。加えて、サーバーは複数部署で使われていたので、移行にあたり各所での調整が必要だったりスケジュールの調整などで頭を悩ませました。 これらを乗り越えて培った技術のお陰で、いまの回線状況の把握やスピードテストといった業務に繋がっています。 ニフティの「ISPオペレーションチーム」ができるまで ISPチームはどのような経緯で出来上がったのでしょうか? H.Fさん 実は、自分やK.Hさんの入社当初のニフティにはまだ「ISPのチーム」といったものはありませんでした。 M.Kさん そうだったんですか。 H.Fさん 以前のネットワーク運用はグループ会社が担当していたので、今とは異なる状況でしたね。ニフティの会社構造が変わるにつれてISPオペレーションチームが出来上がりました。そのため、社内にノウハウがない中で何をすればいいのか、お客様に快適に使用していただくためにはどうしたらよいのだろうかを日々考えながら一歩一歩手探りで進めてきて今のチームがあります。 K.Hさん ニフティが今のニフティであるのは、いままでサービスが続けられているのは、サービスの利用者は勿論、社員達が培っていた技術や経験のお陰と思っております。 現在のチームの課題とは 現在のチームの課題はどういったものがありますか、それに対してどうやって取り組んでいますか M.Kさん 先ほどのお話にもありましたが、ISPチームではDNSサーバーと認証サーバーの管理を行っています。しかし、アーキテクチャや設計思想が昔から引き継がれてきた状態のままになっております。 そのため、運用コストや利用料などの多くの面で最適化の余地が見られており、より柔軟で効率的な運用を目指すためにクラウド基盤への移行を検討しています。 具体的な移行計画を立てるために、現在は既存サーバーの詳細な仕様調査を進めています。 今後の展望 今後の展望を聞かせてください。 K.Hさん お客様サービスの品質を最重要視しつつ、新たに出てくる技術を用いてお客様に魅力あるISPサービスを引き続き提供していきたいと考えています。 M.Kさん ログの取得作業や分析データの前処理の自動化といった効率化を進めていますが、まだまだ手作業だったりモダンな技術に載せ替えられていない部分があります。その他データ処理の自動化だけでなく、運用をより手軽にしていくために、サーバー上で行っているバッチの実行を順次サーバーレスにしていくなど、引き続き改善を行っていきたいです。 H.Fさん チームとして成果を出すためには、皆が成長することが必須です。ISPチームはそのような土壌を作ってきましたので、皆で考え、あるべき姿を描き、それに向けて一丸となってチャレンジしていきたいと考えています。 今回はニフティのISPオペレーションチームのインタビューの様子をお届けしました。ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! このインタビューに関する求人情報/ブログ記事 ISPオペレーションチームの求人情報 ニフティでは、 さまざまなプロダクトへ挑戦する エンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトより お気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering connpassでニフティグループに 参加いただくと イベントの お知らせが届きます! connpassで ニフティグループに参加する .is-style-rounded + .has-text-color{ font-size:95%; }
アバター
自己紹介 K.Hさん ■入社年度・社歴 1992年入社 ■担当サービス   ・PPPoE用(@nifty光、NifMo)  接続認証サービス ・NTT系バックボーン運用 ・ダイヤルアップ運用 ■趣味やマイブーム、特技など ・自宅サーバ構築 ・飛行機や人などの写真撮影 ・北極ラーメン H.Fさん ■入社年度・社歴 1995年入社 ■担当サービス ・サービス用DNS ・NTT系バックボーン運用 ■趣味やマイブーム、特技など ・自宅サーバ構築 ・3Dプリンター工作 M.Kさん ■入社年度・社歴 2021年入社 ■担当サービス ・サービス用DNS ・NTT系バックボーン運用 ■趣味やマイブーム、特技など ・映画鑑賞・ゲーム ・SFやアクションなどを見る 最近見た映画は「キングスマン」 ISPとは? ニフティは「ISP(インターネットサービスプロバイダー)の老舗」と呼んでいただくことがあります。聞き馴染みの無い方に向けてISPとはどういったものなのか聞かせてください。 H.Fさん ISPはInternet Service Providerの略称で、インターネット接続サービスを提供する事業者のことをいいます。平たく言えば、プロバイダと契約したお客様がインターネットを使えるようにする役割を担っている人達ですね。 今やガス水道などのライフラインと同じように、無いと困るインフラの一つになってきています。 ISPに関する業務としては、一般的にはどういったものがありますか。 H.Fさん 業務は多岐にわたりますが、まずは、お客様が使用しているインターネットのネットワーク管理があげられます。また、お客様がきちんとサービスを利用できているか確認するために、インターネットの速度をモニタリングしたり、お客様の会員情報を管理することなどがあります。 これらを実現するために様々なサーバーを利用しますので、サーバーの運用や構築なども必要になります。 業務内容や取り組みについて 現在みなさんはどういったサービス、分野を扱っていますか。 H.Fさん お客様に提供しているインターネットのネットワーク管理分野に携わっております。インターネット利用者は年々増加し、それに伴うデータ量も増えてきています。かつてはテキスト中心だったインターネットが、今では動画やゲームなどのデータ容量の大きいものに変わってきました。そういったネットワークの使用量を観測し、将来のトラフィックを予測することで通信品質を確保しています。 お客様に提供しているインターネットの回線状況を確認するために、社内にお客様と同様の回線を複数用意して、回線スピードのチェックを定期的に行います。また、PC上で仮想マシンを構築し、複数の回線を適宜切り替えて利用できるようなシステムを整えています。これらにより、サービス品質を継続的に保証し、お客様により良いインターネット体験を提供する取り組みをしています。 これらの業務に加えて、DNSサーバの管理運用なども行っています。 K.Hさん 私はお客様がユーザー名とパスワードを入力することでインターネット接続を可能にするPPPoE認証の管理を中心に行っております。認証を行うだけでなく、インターネット接続サービスの使用開始及び終了についても管理しています。 対象は全てのお客様であり、PPPoE認証のリクエスト数が極めて多いです。大規模なデータを効率的かつ高速に処理することが求められています。そのため、処理にはC言語を用いています。ライブラリを使わず、システムコールをそのまま呼び出してオーバーヘッドを無くすことで、高速に動作させるようにしています。 M.Kさん 私もH.Fさんと同じく、DNSサーバーの管理を行っています。 具体的には、ドメイン名とIPアドレスの対応情報を管理するレコード情報の登録と変更作業を行っています。レコードは数万行に渡って存在するので、ニフティのISPとしての歴史の積み重ねを感じます。 また、バックボーンネットワークの管理に関しては、トラフィック需要を予測して対策を立てるプロセスの自動化に注力しています。現在はトラフィックログデータの取得や、分析の前処理などを自動化して効率化を図っています。 働き方やチーム環境について ISPオペレーションチームは様々な年齢層の方がご活躍している印象なのですが、チーム間のコミュニケーションはどのように取っていますか。また、どんなことを心がけていますか。 K.Hさん うちのチームはたまたま知見があったメンバーが集まり、そのあとに入社してくれた新人が加わった状態なので年齢層が高くなっていますね。 M.Kさん ベテランの先輩社員たちが多くの知見を持っていて、相談してもすぐに適格なアドバイスが返ってくるので、チャレンジしやすい環境だと思います。 H.Fさん M.Kさんは色々な物事に積極的に取り組んでくれていますね。仕事を進める上で気にかけないといけない部分や、大切な部分を理解しながら着手してくれていて助かっております。 M.Kさん ありがとうございます。 まだまだ覚えることがあるので引き続き頑張っていきます。 K.Hさん 毎朝、皆で議論する場をもっています。加えて、Slackを活用して悩んでいることや新しいアイデアを常に意見交換しています。メンバー皆が気軽に発言できる雰囲気づくりを心掛けています。 また、精神的に孤立しないよう、オープンチャンネル、DMを活用して交流を絶やさないようにしていますね。 後編に続きます! 今回はニフティのISPチームのインタビューの様子をお届けしました。続きは後編の記事をご覧ください。 【インタビュー】ニフティのISPオペレーションチームチームの過去から未来について【ISP後編】 このインタビューに関する求人情報 /ブログ記事 ISPオペレーションチームの求人情報 ニフティでは、 さまざまなプロダクトへ挑戦する エンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトより お気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering connpassでニフティグループに 参加いただくと イベントの お知らせが届きます! connpassで ニフティグループに参加する .is-style-rounded + .has-text-color{ font-size:95%; }
アバター
エンジニア定例 運営の南川です。 ニフティでは毎年、エンジニア定例という新卒1年目エンジニア向けの開発研修を行っています。 今年度の講義資料の一部を公開しているので、研修内容について気になる方は以下の記事をご確認ください。 ニフティ株式会社 エンジニア新人研修の内容を公開します | 2023年度版 – NIFTY engineering その研修の一環でハッカソン合宿を行っており、今回は4年ぶりのリアルでの合宿となっています! ちなみに私の代はリモートでの開催でした。その時の様子は以下の記事をご確認ください。 リモートでのハッカソン合宿を行いました! – NIFTY engineering ハッカソン合宿概要 目的 座学で学んだ技術を 実践 することで知識を定着させる。 2泊3日というまとまった時間で 集中したアウトプット を出す経験をする。 既存システムのエンハンスではなく、 0からシステムを作る力 を身につける。 個人開発と チーム開発 の違いを学ぶ。 スケジュール 1日目 2/5(月) 12:30 集合・チェックイン 13:00-18:00 開発 (14:00-14:30 オンライン配信) 18:00-19:00 夕食 19:00- 自由 (開発・入浴など) 2日目 2/6(火) 07:00-08:00 朝食 08:00-09:00 自由 (開発・散歩など) 09:00-12:00 開発 12:00-13:00 昼食 13:00-18:00 開発 (14:00-14:30 オンライン配信) 18:00-19:00 夕食 19:00- 自由 (開発・入浴など) 3日目 2/7(水) 07:00-08:00 朝食 08:00-09:00 自由 (開発・散歩など) 09:00-12:00 開発 12:00-13:00 昼食 13:00-14:00 成果報告会 14:00-15:00 終了連絡・撤収作業 15:00 解散 参加者 受講者 新卒1年目エンジニア 10名 3人チーム2組, 4人チーム1組 新卒2年目エンジニア 2名 2人チーム1組 新卒2年目エンジニアが少なく昨年度はハッカソン合宿ができなかったため、今回は1, 2年目合同で実施しています。 運営・開発サポート エンジニア6名 監督 シニアエンジニア1名 場所 ノジマ大磯スクウェア 〒255-0003 神奈川県中郡大磯町大磯1010 https://maps.app.goo.gl/qDRevCT8tqmRSnE88 JR東海道線 大磯駅から徒歩2,3分 レポート 1日目 2024/2/5(月) 今回の研修施設であるノジマ大磯スクウェアに現地集合しました。 集合時点で雪が降っていましたが、まだ交通網に影響が出る前で、誰も遅刻せずに来れました。 研修室にはWi-Fiやディスプレイ、ホワイトボード、延長コードなどが用意されており、開発する環境が整っています。 チームごとに分かれて、事前に行ったアイデアソンで考えてきたアイデアをもとに開発していきます! ドラッグストアやコンビニが近くにあるおかげで、2Lペットボトルやエナジードリンクなどの買い出しも気軽にでき、立地が良い感じです。(雪が降ってたのでしんどかったですが…) 14時からは社内向けのオンライン配信を行い、合宿や施設について、チームと作るものを紹介しました。 1日目の夕食ですが、配食の業者さんが雪の影響による交通渋滞に巻き込まれ遅れていたので、先に入浴を済ませ、20:30に待ちに待った夕食が来ました! こんな雪の中でも食事を作っていただき、ありがとうございました。 夕食を食べ終わった後も研修室に戻り開発です。 2日目に余力を残すため、22時上がりの参加者もチラホラ… ちなみに、宿泊室は個室でシングルベッド、机と椅子、洗面台、クローゼットがありました。 2日目 2024/2/6(火) 2日目は朝から丸一日の開発です! 朝食から1時間程度自由時間があり、海岸へ散歩しに行く方もいました。 昨日に引き続き、14:00から配信を行い、各チームの進捗報告を行いました。 段々と形になってきていますね。 開発も終盤戦ということもあり、この日は全員24時近くまで作業していました。 3日目 2024/2/7(水) 3日目は午前中が作業時間で午後は成果報告会になっており、発表準備やデザインなどの微調整がメインです。 成果報告会では作ったサービスとデモ、工夫点、開発での良かった点と悪かった点、成長したことや学んだことを発表します。 持ち運び式のプロジェクターとスクリーンが用意されており、スライドを投影しながらでの発表となります。 まずは、チーム「チームD」の飲酒量を管理するサービスです。 次は、チーム「欲望の沼」のスポーツの勝敗を賭けるサービスです。 そして、チーム「†Skyscraper†」のオリンピックビンゴです。 最後は、チーム「とり」の社内ブカツのまとめサイトです。 トリだけに最後です。 成果報告会も社内配信を行い、たくさんの方に見ていただきました。 おわりに 今年は4年ぶりのリアルでのハッカソン合宿となり、合宿史上初の試みとなるオンライン配信も実施しました。 触ったことがない技術を導入してみたり、 社内の ChatGPT の Slack BOT や GitHub Copilot などの AI を活用したり、AWS環境にデプロイして実際に触れるようにしたり、皆さんチャレンジや工夫をされていました。 最後に、開発環境を提供してくださったノジマ大磯スクウェアさん、ありがとうございました! 後ほど、各チームの記事を公開していきますので、お楽しみに! ニフティでは、 さまざまなプロダクトへ挑戦する エンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトより お気軽にご連絡ください! ニフティ株式会社採用情報 カジュアル面談も随時受付中! ニフティに興味をお持ちの方は キャリア登録をぜひお願いいたします! キャリア登録 connpassでニフティグループに 参加いただくと イベントの お知らせが届きます! connpassで ニフティグループに参加する
アバター
はじめに こんにちは、最近はCDKを触る機会がやや多く、Terraformとどっちを使うのが良いのかやや悩み気味な宮本です。 今回の記事はAWS Amplifyのビルド通知についてです。 Amplifyのビルド通知 ※以下の内容は全て2024/02/26現在の情報を元にしています 簡単にサイトを立ち上げることのできる Amplify ですが、ビルドする際の通知が貧弱という問題があります。 デフォルトで用意されているのは Eメールによる通知 のみ Eメールで送ることのできる通知内容が物足りない Eメール通知もCDKやTerraformのようなIaCで管理する方法が公式で説明されていない 通知内容が物足りないという点ですが、実際に送られてくるのは以下のようなメールです。 Build notification from the AWS Amplify Console for app: https://<ブランチ名>.<app id>.amplifyapp.com/. Your build status is <ビルドステータス>. Go to https://console.aws.amazon.com/amplify/home?region=<リージョン>#<app id>/<ブランチ名>/<ビルド番号> to view details on your build. Amplifyのビルド結果メール通知の例 メールに含まれている内容はapp idとブランチのみで、ぱっと見でどの環境かまではわかりません。複数のAmplifyによるアプリケーションを管理している場合は、もはや何がなんだかわかりません。URLがついているのでアクセスすればわかりますが、同じアプリの別ブランチの差であれば瞬時に見抜くのは難しいです。他にも、ビルドに失敗した場合であればコンソールのエラー内容も欲しいかもしれません。 Amplifyのビルド通知をSlackに送る ※重ねて注意。以下の内容は公式ドキュメントになく、仕様が変更される可能性は十分にあるのでご注意ください。 先に結論 Amplifyのコンソールから設定できるEメールによるビルド通知はEventBridge+SNSで実装されている コンソールで通知を作成した場合は必要なリソースが自動で作成される EventBridgeを用意すれば、そのまま直でLambda経由でSlackに通知することができる IaCで通知リソースを管理することもできる アプリ名などAmplifyの作成するイベントに含まれないデータは、Lambda内で別途データを取得する必要がある Amplifyのビルド通知 デフォルトだとAmplifyのビルド通知はコンソールからのみ作成できます。その際にAmplify自体に通知機能があるわけではなく、別のAWSサービスを利用してビルド通知を実現しているようです。なので、Amplify自体のTerraformやCDKに通知周りの設定がないんですね。 ビルド通知を設定した際に自動で作成されるリソースは次のようなものです。 Amazon EventBridge ルール: amplify-<app_id>-<branch名>-branch-notification ブランチ指定しない場合: amplify-<app_id>-AMPLIBRANCHSENTINEL-branch-notification Amazon SNS トピック: amplify-<app_id>_<branch名> ブランチ指定しない場合: amplify-<app_id>_AMPLIBRANCHSENTINEL EventBridgeの ドキュメント にも記載はないのですが、どうもAmplifyのビルド時にEventBridgeで引っ掛けることのできるイベントが配信されているようです。作成されるEventBridgeのルールを見ると、以下のようなイベントパターンを指定しています。ブランチを指定しない場合は、detailのbranchNameの項目自体がありません。 { "detail": { "appId": ["<app_id>"], "branchName": ["<ブランチ名>"], "jobStatus": ["SUCCEED", "FAILED", "STARTED"] }, "detail-type": ["Amplify Deployment Status Change"], "source": ["aws.amplify"] } この条件で引っ掛けたイベントを元に入力トランスフォーマーを使ってメール文面を作成し、SNS経由で送っています。 なお、引っ掛けているイベントの全体像は以下のようになっています。残念ながら、Amplifyのアプリ名までは入っていません。そのため、アプリ名を入れたい場合はLambdaを挟んでそこで別途データを取得する必要があります。 { "version": "0", "id": "<イベントid>", "detail-type": "Amplify Deployment Status Change", "source": "aws.amplify", "account": "<AWSアカウントid>", "time": "2024-01-01T00:00:00Z", "region": "ap-northeast-1", "resources": [ "<Amplifyのarn>" ], "detail": { "appId": "<app id>", "branchName": "<ブランチ名>", "jobId": "<ビルド id>", "jobStatus": "<ステータス>" } } Amplifyのビルド通知をSlackに送るために必要なリソースのCDK さて、Amplifyのビルド通知の仕組みがEventBridgeが元になっていると分かればこっちのものです。以下はCDKの場合ですが、このようなEventBridgeのリソースを作成することでイベントをLambdaに送ることができます。ビルド開始時の通知が不要な場合はパスパターンから STARTED を省くなど、工夫のしがいがあります。(なおlambdaのコード周り含めたリソース定義をここで書くと長くなるので省略します。) from aws_cdk import ( aws_iam as iam, aws_lambda as _lambda, aws_events as events, aws_events_targets as targets, Stack, ) from constructs import Construct class BuildNotificationStack(Stack): """指定したLambdaにAmplifyのビルド通知を送るEventBridge""" def __init__(self, scope: Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) app_id_list = ["hogehoge"] # 通知したいAmplifyのidリスト notification_brunch_list = ["master"] # ビルド通知したいブランチのリスト function = _lambda.Function(self, "NotificationLambda", ...) # 通知用のLambdaを作成(細かいコードは省略) # 以下の権限はLambdaから追加でAmplifyのデータを取得する場合に必要 function.add_to_role_policy( iam.PolicyStatement( actions=[ "amplify:GetApp", ], resources=["*"], ) ) # EventBridgeからLambdaを起動するために必要な権限 function.add_permission( "Eventbridge", principal=iam.ServicePrincipal("events.amazonaws.com") ) # appIdに複数のidを指定することで、一つのEventBridgeで複数のAmplifyのビルド通知を受け取ることも可能 notification_rule = events.Rule( self, "NotificationEventRule", event_pattern={ "detail": { "appId": app_id_list, "branchName": notification_brunch_list, "jobStatus": ["SUCCEED", "FAILED", "STARTED"] }, "detail_type": ["Amplify Deployment Status Change"], "source": ["aws.amplify"] }, ) build_notification_target = targets.LambdaFunction(function) notification_rule.add_target(build_notification_target) Slackに通知を送るLambda EventBridgeから叩かれた際、Lambdaはハンドラーの第一引数に入るeventとしてAmplifyから発行されたイベントがそのまま辞書形式で入ってきます。前述の通りAmplifyのアプリ名まではイベントに入っていないため、必要な場合はLambdaでアプリの情報を取得しなければいけません。 以下は、SlackのWebhook経由でビルド通知を送るLambdaの一例です。この例のメッセージ周りはだいぶ簡素なので、ビルドステータスによって必要な情報を増やしたり(e.g. 失敗した時のみコンソールへのURLを追加する)、通知文自体も見やすいようにカスタマイズしていくとわかりやすくなると思います。 import os import json import boto3 import requests from aws_lambda_powertools import Logger logger = Logger() # Lambdaの環境変数SLACK_WEBHOOK_URLにあらかじめSlackのWebhookを登録しておく SLACK_WEBHOOK = os.environ["SLACK_WEBHOOK_URL"] status_message = { "STARTED": "ビルドを開始します", "SUCCEED": "ビルドに成功しました", "FAILED": "ビルドに失敗しました", } @logger.inject_lambda_context def lambda_handler(event, context): try: logger.info("AmplifyのApp名取得") amplify_client = boto3.client("amplify", region_name="ap-northeast-1") # eventに入っていないAmplifyのアプリ名をboto3を使って取得する # lambdaのroleに「amplify:GetApp」の権限が必要 response = amplify_client.get_app(appId=event["detail"]["appId"]) app_name = response["app"]["name"] logger.info("Slack通知") data = json.dumps({"text": f"{app_name}の{event['detail']['branchName']}の{status_message[event['detail']['jobStatus']]}"}) response = requests.post( SLACK_WEBHOOK, data, headers={"Content-Type": "application/json"}, timeout=3 ) return None except Exception as e: logger.exception(e) return None 通知のサンプル おわりに 今回はAmplifyのビルド通知をSlackに流す方法について紹介しました。いくつか似たような方法を紹介していた記事はあったのですが、基本的にAWSのリソースは全てIaC管理しておきたい病にかかっているので、CDKで管理できるようにしました。リソース的にはEventBridgeとLambdaおよびそれに必要なIAM Roleを用意しているだけなので、Terraformでも問題ありません。 また、今回はLambdaを使いましたが、もともと出力されるイベントに含まれる内容自体で十分であれば、 EventBridgeから直にchatbotに送る こともできるようです。Lambdaを挟むとどうしてもランタイムのEOLによる継続的なメンテが必要になったりするので、不要であれば省きたいです。しかし、利用できるデータがどうしても限られてしまう点は現時点では解消できないため、細かくカスタマイズするのであればLambdaはまだ必要そうです。 他にも失敗したい場合はエラーログなども出せるとありがたいのですが、そもそもAmplifyのビルド時のログはCloudWatchにすら吐き出されないため現状打つ手が無さそうです。 参考 AWS Amplify(アプリケーションの構築とデプロイ)| AWS AWS Amplifyホスティングへようこそ – AWS Amplify ホスティング Amazon EventBridge とは – Amazon EventBridge Amplify Hostingのビルド結果をAWS ChatbotでSlackに通知 ニフティでは、 さまざまなプロダクトへ挑戦する エンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトより お気軽にご連絡ください! ニフティ株式会社採用情報 カジュアル面談も随時受付中! ニフティに興味をお持ちの方は キャリア登録をぜひお願いいたします! キャリア登録 connpassでニフティグループに 参加いただくと イベントの お知らせが届きます! connpassで ニフティグループに参加する
アバター
はじめに こんにちは。宮永です。 半年ほど前に電気通信主任技術者を取得した のですが、これを持っていると工事担任者の受験で科目免除が使えます。特に使う予定はないのですが覚える知識が似ているので、勢いで取得してみました。今回はその体験談です。 工事担任者とは アナログ伝送路設備又はデジタル伝送路設備に端末設備等を接続するための工事や監督に必要な免許です。平たく言えば、 電話線や光ファイバー周りの工事をするのに必要な免許 です。 第一級・第二級アナログ通信、第一級・第二級デジタル通信、総合通信の5つに免許が分かれており、総合通信はすべての範囲の工事が可能です。今回は総合通信を取得しました。 試験科目と免除科目 試験科目は 電気通信技術の基礎(基礎) 端末設備の接続のための技術及び理論(技術) 端末設備の接続に関する法規(法規) の3科目です。各科目60点以上で合格です。 電気通信主任技術者を持っていると3科目のうち基礎と法規が免除になります 勉強方法 基本的には過去問周回です。試験では過去問と同じor非常に似た問題が多く出題されるので、「見たことがある問題を可能な限り多く作り、絶対に落とさない」という戦法で挑みました。6割合格なので、数問出る初見問題は落としても合格できます。 電気通信主任技術者試験と出題方法がほぼ同じ(同じ団体が試験を主催)なので、電気通信主任技術者を持っている人であれば勉強法で苦戦することは無いかなと思います。 また、技術の試験範囲は電気通信主任技術者の出題範囲と一部被っているため、すべてを1から学習する必要が無いです。 総勉強時間は約14時間でした。土日+αの勉強時間で挑みました。 試験 試験申し込みの段階で科目免除の申請をする際は、申し込み時に手元に電気通信主任技術者証を用意する必要があります。 電気通信主任技術者試験に合格して最初の工事担任者試験に申し込もうとすると、申請にかかる時間と試験日程の関係上、 手元に電気通信主任技術者証がまだ届きません 。本来であれば資格者証が届くのを待ってから申請するべきなのでしょうが、記憶がフレッシュなうちに受験したかったので、今回は 免除申請を出さずに工事担任者試験を受験する(3科目受験) 技術のみ合格する(基礎と法規はノー勉なので不合格) 技術の科目合格と電気通信主任技術者の科目免除を併用して 全科目免除申請 をする 全科目免除申請はほぼ確定で合格するので、晴れて資格者証を手に入れる という手順で資格者証を手に入れました。全科目免除申請を追加でする分お金は余分にかかりますが、スピード重視です。 試験申し込み まずは免除申請を出さずに普通に工事担任者試験を申し込みます。主催団体が同じなので、工事担任者試験の申し込みも電気通信主任技術者試験とほぼ同じです。 試験料は科目免除・全科目受験問わず8700円です。 受験 日曜日の朝に頑張って起きます。年に2回しかない試験なので、寝坊すると次のチャンスは半年後になってしまいます。 試験会場では試験種別ごとに建物が分かれており、総合通信の受験者は150人ほどだったと思います。ほとんどが40~50代の男性に見えました。おそらく自分が会場内で一番若かったです。試験会場の雰囲気、試験の進み方は電気通信主任技術者試験とほぼ同じでした。 11月の寒い雨の日に試験でしたが、会場は暖房ガンガンでものすごく暑かったです。隣の人は半袖Tシャツになってました。調整しやすい服装で行くべきだったと後悔しています。 試験時間は3科目分で160分ですが、私は1科目だけ合格すればよかったので時間はものすごく余りました。指示に従って途中退出可能です。 合否発表(1回目) 試験からしばらくたつとwebで結果を見る事ができます。 結果は技術のみ合格で基礎・法規は不合格、つまり試験は不合格です。が、私の目的は技術科目の合格が欲しかったので実質合格です。不合格通知ですが喜びます。 全科目免除申請 技術科目の合格と電気通信主任技術者の科目免除を組み合わせて、全科目免除申請を行います。全科目免除申請は通常の試験とは異なり、通年で受け付けています。申請方法は通常の工事担任者試験や電気通信主任技術者とほぼ同じですので、困るところはありません。 申請手数料は5600円です。 合否発表(2回目) 全科目免除申請も一応試験という扱いのようで、1か月ほどで合否通知が届きます。虚偽申告をしなければ合格になるはずです。 これでついに工事担任者試験に合格したことになります! 資格者証申請 まだ安心できません。試験に合格した人は申請して「工事担任者資格者証」の交付を受けなければいけません。管轄の総合通信局へ申請書を提出します。 顔写真、収入印紙などを用意します。この資格者証は、電気通信主任技術者資格者証と同様に 有効期限がない ので、残念な写真は使わない方が良いです。一生残念な写真の資格者証と共に過ごすことになります。 申請から約1か月で資格者証が届きました。これで堂々と有資格者と名乗ることができます。 まとめ 工事担任者の試験内容は電気通信主任技術者試験と被っている部分が多いので、記憶が残っているうちに取得して正解でした。同じような方法で取得する方はかなり少数派だと思いますが、参考になれば幸いです。 リンク 電気通信国家試験センターHP  https://www.dekyo.or.jp/shiken/charge/ ニフティでは、 さまざまなプロダクトへ挑戦する エンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトより お気軽にご連絡ください! ニフティ株式会社採用情報 カジュアル面談も随時受付中! ニフティに興味をお持ちの方は キャリア登録をぜひお願いいたします! キャリア登録 connpassでニフティグループに 参加いただくと イベントの お知らせが届きます! connpassで ニフティグループに参加する
アバター
皆さん、お疲れ様です。ニフティ基幹システムグループの山田(山田一族)です。 突然ですが、皆さんも昔は英語を話せるようになりたいと思っていませんでしたか?私も昔はそう思っていた時期がありました。 英語を話せるようになりたいと思って、かれこれ8年ぐらいは通勤時の電車内で BBC放送 のpodcastを聞いています。ですが一向に英語を話せるようにはなりません。やはり聞くだけではだめで、能動的に英語フレーズを作り出す「会話」という動作をしていかないとダメなのでしょう。 では、その会話をしたいのですが、典型的な日本人ですから英語を話すのが恥ずかしいです。英会話スクールは費用も掛かるし、相手に何を思われてるか分かったものではありません(被害妄想)。そういえば最近AIの英会話アプリがあったような・・・でも音声を録音されてたらどうしよう(完全な被害妄想) じゃあ自分で作ればいいじゃないか!技術力もアップするし一石二鳥だ! この辺りの複雑な事情を踏まえて今回は、gradioとLLMを用いて英会話のアプリを作ってみたいともいます。結論から言うと。。。まだカイゼンの余地ありです。でもそこはニフティの素晴らしい社員の皆さんの協力しあう力でカイゼンしていきたいとおもいます。 今回使う機能などは以下の通りです。 Google Colaboratory (誰が実行しても同じになるよう環境を共通化します) gradio (数行のコードできれいなUIを作成してくれます) TinyLlama (今回の私の話相手です。Metaの Llama2 の小規模言語モデルといったところでしょうか。GPUメモリがかつかつなのでこちらを使います。) whisper (音声からテキストに起こしてくれます。安心と信頼の?openai製です) Google Coraboratoryの使い方についてちょっと勉強が必要ですが、エンジニアの方も、エンジニアでない方も実践できるようにしたつもりです。是非皆さんチャレンジしてみてください。では早速実装していきましょう! 1.まずは必要なパッケージを入れていきます。 !pip install -qqq accelerate gradio import gradio as gr import numpy as np ※記事作成時点ではlidaやllmx関連のエラーが表示されますが使えますので構わず進んでください 2.次に話相手をしてくれるTinyLlamaと、文字を起こしてくれるwhisperをインストールします。 GoogleCoraboratoryのフォームを使いmodelを選択できるようにするとオシャレですが今回はスキップします。 import torch from transformers import pipeline pipe = pipeline( "text-generation", model="TinyLlama/TinyLlama-1.1B-Chat-v0.6", torch_dtype=torch.bfloat16, device_map="auto", ) transcriber = pipeline( "automatic-speech-recognition", model="openai/whisper-base.en", device_map="auto" ) 3.ここで、AIさんの返信だけを抜き出すfunctionを用意します。 ROLE_SYSTEM = "<|system|>" # 今回は使わない ROLE_USER = "<|user|>" # 今回は使わない ROLE_ASSISTANT = "<|assistant|>" def extract_role_phrase(text): text_array = text.split("\n") start = 0 for i, x in enumerate(reversed(text_array)): if ROLE_ASSISTANT in x: start = i break return "\n".join(text_array[-1 * start :]) このAIとチャットすると以下のようなテキストを返してきます。このテキストから最後の<|assistant|>以降を抜き出したいだけです。もっといいやり方があるのかもしれませんがあきらめました(考えるのをやめた)。誰か教えてください! <|system|> You are a friendly chatbot who always responds in the style of a pirate <|user|> How many helicopters can a human eat in one sitting? <|assistant|> I am not capable of human interaction or information. However, based on the passage, it is stated that humans can eat up to 1,000 helicopters in one sitting. 4.AIの役割を決めましょう。私は英語の練習をしてみたかったので以下のように設定しました。contentのところをそれぞれ変更してみてください。 messages = [{"role": "system", "content": "you are my english teacher in japan"}] 5.最後に、おしゃれなUIを設定していきましょう。ここが今回のメインのコードになります。 このコードだけできれいなUIが表示されてくれますので、時代は変わったなあと・・・ with gr.Blocks() as demo: def transcribe(audio, chat_history): sr, y = audio y = y.astype(np.float32) y /= np.max(np.abs(y)) text = transcriber({"sampling_rate": sr, "raw": y})["text"] messages.append({"role": "user", "content": text}) chat_history.append([text, None]) return chat_history def generate(): prompt = pipe.tokenizer.apply_chat_template( messages, tokenize=False, add_generation_prompt=True ) outputs = pipe( prompt, max_new_tokens=256, do_sample=True, temperature=0.7, top_k=50, top_p=0.95, )[0]["generated_text"] result = extract_role_phrase(outputs) return result def post(chat_history): text = generate() messages.append({"role": "assistant", "content": text}) chat_history.append([None, text]) return None, chat_history chatbot = gr.Chatbot() audio = gr.Audio(sources=["microphone"]) audio.stop_recording(transcribe, [audio, chatbot], [chatbot]).then( post, [chatbot], [audio, chatbot] ) demo.launch(height=800) 使い方を軽く説明をすると、stopボタン(あとで出てきます)を押すと、transcribeファンクションにて、音声から文字を起こしてchatのボードに文字をセットします。その後(まさにthen)、postファンクションにて、AIさんにその言葉を投げかけて回答を再びchatのボードにセットさせます。 このコードを張り付けて実行することで、以下のような画像が表示されます。 ブラウザの設定によってはこの時、マイクの使用の許可を求めてきます。必要に応じて許可するようお願いします。 マイクの許可をしましたら、左下にあるRecordボタンを押してみてください。いきなり録音が始まります。(ボタンが以下のようにRecordからStopに変わります。) 何か一言しゃべってStopボタンを押してみてください。自動的に音声のテキスト化とAIとの会話が始まります。 では試していきましょう ランタイムのタイプをGPUにしたうえで、「すべてのセルを実行」を実施してください。 まっさらなchatbotのボードとrecordボタンが表示されますので、recordボタンを押して、お話を始めてください。終わったらstopボタンを押し、文字が起こされて、相手から返事が来たらまたrecordボタンを押して会話する。これの繰り返しになります。 今回は以下のように会話をしました。 「私はタローです。何か英語の質問をください」(本名はタローではありませんよ) 「日本の7月は何度なの?」 「70℃ぐらいかな、これって暑い?」(本当は17℃といったのですが・・・でも摂氏じゃなく華氏になった。日本の7月は17℃じゃない) 「うん。暑いね」 「Dooda japa」(日本は好きですか?って言ったつもりです。何話せばいいのかわからなり・・・) 「はい、そうです。 7 月の日本は高温多湿で知られ、気温は華氏 80 度、湿度は 100% に達します。」 最後は会話が崩壊してしまいましたが、慣れれば何とかなるのではないかという希望を持ちました。 最後に いかがでしょうか。 私の発音も含めてまだまだ完全体ではありませんが、これで相手を気にせずに英会話の練習ができます! うすうす感づいているかと思いますが、英会話に限定する必要はありません。messages 部分を書き換えることによっていろいろな応用を効かせることができます(本当に効いてたのか不安はありますが)。みなさんもぜひお試しください! 今回のコードでは、 stopボタンを押さないと会話ができない→無音が一定時間続いたら自動的に会話できるようにしたい chatの回答が文字のまま→しゃべらせたい などなどカイゼンの余地が多くあります。 そのあたりは次回以降やっていきたいと思います。 それでは皆さん、英語を話せるように頑張りましょう。自動翻訳機で済む時代が来るのかな? ニフティでは、 さまざまなプロダクトへ挑戦する エンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトより お気軽にご連絡ください! ニフティ株式会社採用情報 カジュアル面談も随時受付中! ニフティに興味をお持ちの方は キャリア登録をぜひお願いいたします! キャリア登録 connpassでニフティグループに 参加いただくと イベントの お知らせが届きます! connpassで ニフティグループに参加する
アバター
はじめましてニフティ株式会社インフラシステムグループインフラチームの松居と申します。以前、 福田から紹介をしていたインフラチーム 内でご紹介していた ②ネットワークを担当するチーム について今回はご紹介させていただきます。 私はニフティには中途で入社し、それ以来ネットワーク一筋、16年ほど携わっております。ネットワークと一口に言うとかなり広い範囲となりますが、私たちが担当している範囲はお客様向けではなく、下記のような主に社員やシステム間での通信を行う箇所となります。 担当範囲 ①拠点間 事務所(新宿本社) データセンタ クラウドへのプライベート接続 ②拠点内 いわゆるLANと呼ばれる範囲となり、主に社員が日常的に業務で利用する無線LAN等が対象となります。 ③データセンタ内 クラウドとの接続やオンプレミス環境の基盤となるネットワークを対象にしております。 業務内容 上記担当範囲においてメンバー全員で下記の業務を執り行っております。 新規案件や機器寿命による入替に伴う設計・構築 運用・保守 セキュリティのため通信制御している箇所のフィルタ開放 VPNにまつわる設定  機器故障等による障害対応、等々 日々の運用を効率化するための自動化 その他、ネットワークが関係しそうなトラブルや相談受付 業務で扱う機器やツール ネットワーク機器 Cisco Juniper BIG-IP FortiGate ツール(SaaS含む) NetBox(機器やIPアドレス等の論理情報も合わせて管理) Ansible Zabbix Grafana GitHub Slackワークフロー AWS Lambda 上記のように列挙いたしましたが、ネットワークに関わる範囲はなんでも担当するというチームになっております。スキル蓄積のため内製で対応を行うことを基本としております。運用・保守においては依頼件数が多く繰り返し発生する業務についてはAnsible等を利用して積極的に自動化による効率化を図っております。 現在は物理機器に頼る部分も多くなっておりますが、今後の事を見据えてコンポーネント単位での仮想化の導入や機器のクラウド管理を目指しております。   ニフティでは、 さまざまなプロダクトへ挑戦する エンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトより お気軽にご連絡ください! ニフティ株式会社採用情報 カジュアル面談も随時受付中! ニフティに興味をお持ちの方は キャリア登録をぜひお願いいたします! キャリア登録 connpassでニフティグループに 参加いただくと イベントの お知らせが届きます! connpassで ニフティグループに参加する
アバター
SREチームの島です。最近Terraformを書いてるのですがまだまだ理解不足なところもあり日々試行錯誤しています。 今日は開発環境をTerraformで作成した話をします。 背景 複数人でGCP上で動くアプリを開発したい 各自がローカルで変更したソースを動作確認できる環境を作りたい やりたいこと 各自がローカルで変更したソースを動かせる環境をGCP上に作りたい 全部ローカルに作れたら良かったが作るのが大変なので手っ取り早く動く環境を作りたかった 各自が自由に自分用の環境を作成、削除できるようにしたい。また環境の作成、削除をしても他の環境には影響を与えないようにしたい。 前提 ブランチ戦略 developブランチを親ブランチとしてそこから派生して子ブランチ(feature/X)を作成し、featureブランチで個人開発するようなイメージです。 以下、developブランチが動く環境をdevelop環境、featureブランチが動く環境をfeature環境、まとめて開発環境と呼びます。 クラウド構成概略 niftyというGCPプロジェクトの中にdevelop環境とfeature環境(N個)を作ります。feature環境は自由に作成、削除することを想定していますので数は増減します。 詳細は省きますがPub/SubでBigQueryに溜め込んだデータをCloudRunでグラフ化するようなアプリ「serviceA(仮名)」を想定しています。 各環境用のリソースの他に全環境共用のワークロードID、develop環境用、feature環境用のサービスアカウントの作成が必要です。これらは環境ごとに増減するものではないので一度作成すればいいものになります。 ポイント 「環境ごとに作るもの」はリソース名被りがないように作る必要がある 「共通設定」はTerraformでどのように定義すればいいのか 作ったもの Terraformのディレクトリ構造は以下のようにしました。 . ├── serviceA │ ├── envs │ │ ├── develop │   │ │ ├── main.tf │   │ │ └── variables.tf │ │ └── feature │   │ ├── main.tf │   │ └── variables.tf │      └── modules                // 環境ごとに作るリソース │      ├── bigquery.tf │      ├── dashboard.tf │   ├── iam.tf │      ├── locals.tf │      ├── outputs.tf │      ├── parsers.tf │      ├── provider.tf │      ├── services.tf │      └── variables.tf └── project-common // 共通設定 ├── projects/nifty │ ├── main.tf │ ├── output.tf │ └── variables.tf └── modules     ├── oidc-github-pool-provider // ワークロードID     │   ├── main.tf     │   ├── output.tf     │   ├── provider.tf     │   └── variables.tf     └── oidc-github-sa  // develop、feature環境のサービスアカウント    ├── main.tf    ├── output.tf    ├── provider.tf    └── variables.tf 解説 環境ごとに作るリソースの定義 develop環境はserviceA/envs/develop、feature環境はserviceA/envs/feature配下でterraform applyすると、serviceA/modulesで定義した「環境ごとに作るリソース」を作成します。 このとき、変数でブランチ名をモジュールに渡して、各リソース名にブランチ名を付けることでリソース名が被らないようにしました。 serviceA/envs/feature/main.tf module "serviceA" { source = "../../modules/serviceA" project_id = var.project_id (中略) branch_name = var.branch_name // ブランチ名を変数で渡す } serviceA/modules/dashboard.tf resource "google_cloud_run_service" "dashboard" { name = "dashboard-${var.branch_name}" // リソース名にブランチ名をつける location = var.region project = var.project_id (略) ステートファイルの管理 ステートファイルの管理についてはGCSで管理する設定にしました。 develop環境のステートファイルは下記のようにprefixを固定で設定しました。 serviceA/envs/develop/main.tf terraform { backend "gcs" { bucket = "tf-state-project-nifty" prefix = "service-a-develop" // prefixを固定で設定 } } feature環境については環境ごとにステート管理する必要があるので、固定で設定せずterraform initをする際に terraform init - backend - config = "prefix=service-a-${TF_VAR_branch_name}" といった感じでブランチ名を付けた値をprefixに設定するようにしました。 serviceA/envs/feature/main.tf terraform { backend "gcs" { bucket = "tf-state-project-nifty" // prefixはここには設定しない } } これで環境ごとにステートファイル管理ができます。 共通設定の定義 次に、共通設定は/project-common配下に定義しました。 project-common/projects/nifty/main.tf // develop環境用のサービスアカウント module "oidc-sa-develop" { source = "../../modules/oidc-github-sa" project_id = var.project_id env_name = "develop" } // feature環境用のサービスアカウント module "oidc-sa-feature" { source = "../../modules/oidc-github-sa" project_id = var.project_id env_name = "feature" } // ワークロードID module "oidc-github-pool-provider" { source = "../../modules/oidc-github-pool-provider" project_id = var.project_id } /modules/oidc-github-saをenv_nameの値を変えて2回実行しています。ここで「develop環境用のサービスアカウント」と「feature環境用のサービスアカウント」が作られます。 /modules/oidc-github-pool-providerは「ワークロードID」を定義しています。 さきほどの図に当てはめると以下のようなイメージです。 まとめると develop環境構築時(一度だけ実行):「serviceA/envs/develop」、「/project-common/projects/nifty」配下でterraform applyしてdevelop環境と共通設定を作成 feature環境構築時(環境数分実行):「serviceA/envs/feature」配下でterraform applyしてfeature環境を作る。共通設定は上記で作成済みなのでfeature環境を増やそうが消そうが影響を受けない といった状態を作ることができました。 これがベストな状態かは定かではないですが、ひとまず開発環境の動作確認ができる状態を作ることができました。 共通設定と環境ごとのモジュールの定義の分け方など実際に実装してみて良い学びになりました。 ニフティでは、 さまざまなプロダクトへ挑戦する エンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトより お気軽にご連絡ください! ニフティ株式会社採用情報 カジュアル面談も随時受付中! ニフティに興味をお持ちの方は キャリア登録をぜひお願いいたします! キャリア登録 connpassでニフティグループに 参加いただくと イベントの お知らせが届きます! connpassで ニフティグループに参加する
アバター