TECH PLAY

ニフティ株式会社

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

487

ニフティ株式会社でシニアエンジニアしています芦川です。 ニフティは他社と比べてトラブルが多いんじゃないか?とか、そういう話ではありません。 これまで「 基幹システムグループ サービスインフラチームの紹介です 」「 目指せ、自己管理型チーム! 役割分担の垣根を取っ払い、心理的安全性を高めるチームマネジメント手法の紹介 」とチーム全体の話を書いてきましたが、今回はエンジニアの学習と成長について私の経験談を通して思っていることを書きます。(長文です。すいません!) この記事を書いたきっかけ 社内では、これからどんなことを学習すればよいのか、どんなときに学習すれば良いのか、学習するモチベーションは何なのか、というような話がよく出ます。私自身はこれまで18年のエンジニア人生を送ってきました。今回のブログでは、どんなとき、どんな感じに私が学習してきたかということと、それらは成長のフレームワーク(コンフォートゾーン、ラーニングゾーン、パニックゾーン)にどんなふうに適合しているのかについて整理してみたいと思い、この記事を書くことにしました。 これからのエンジニア人生が長い人、これからエンジニアを目指す人が読んで、少しでも参考になればいいなと思います。 コンフォートゾーンとは、「居心地のいい場所」。居心地のいい場所に居続けると人間は成長しません。ラーニングゾーンに身を置いた方が人間は成長する、と言われています。 そもそもなぜ学習の必要があるのか? 日々、エンジニアは学習が必要であると言えます。メインのスクリプト言語の変遷でいうと、私が18年前に入社したときに学習したPerlはもう社内では廃れ、その後も、PHP、Rubyと続いてきましたが、今はPythonがメインになっています。しかし、このPythonもより便利で強力なものが出てくれば、いつの日か廃れることは間違いありません。こうした技術的な変遷がある限り学習の必要があります。 そうしたなか、気持ちはいつもポジティブ。学習した分、当然、開発効率があがり、明るい未来があることも経験を通して知っているためです。使いこなせるようになると単純に楽しいし。 余談ですが、「アンラーニング」という言葉がありますよね。これは、特に技術の移り変わりの激しいエンジニアには必要なことかもしれません。 「アンラーニング」(unlearning)とは、いったん学んだ知識や既存の価値観を批判的思考によって意識的に棄て去り、新たに学び直すこと。 引用: アンラーニング 私はいつ学習してきたのか? 私自身は、これまで業務の中で必要に迫られて学習をしてきました。次の業務で使う言語やフレームワーク、クラウドサービスなどについては、主として業務時間内に学習することが多かったです。稀に切羽詰まり、例えば、翌週の火曜日のプランニング(スクラムイベント)で必要なDjango REST Frameworkを知るために、土曜日をまる1日かけて本を完読するような学習をすることもありました。またAWS CDKの初期学習時は、AWS Documentationをスマホでずっと読んだりすることもありました。(スマホで読んだほうがなぜか私は公式ドキュメントが読みやすい。) また思い返してみると、数多くの障害対応、トラブル対応を経験することで、都度、未知の事象を調べ解決していくプロセスが自分の成長に繋がってきたということがあります。前述の学習はある程度のゆとりがある中での学習になりますが、トラブル時は調べないといけない期限が迫っている状態であり、かつ、何を差し置いてもその調査時間をとることになるため、いわば強制的なラーニングゾーンになれる時間です。また、あとから振り返ると、通常での学習では気づけないようなことや観点が経験として学べる、ということが大きかったと思います。ただし、この状況はきつい状況であり、ずっと居続けていてはいけない状態です。幸いにも社風もあるのかこれまで1人でこの状況に居続けることはなく、誰かに相談できたり一緒に解決したり、ということができてきました。結果的に限りなくパニックゾーンに近いラーニングゾーンだったのでしょう。もし解決できないときは、本当にパニックゾーンであり、肉体的、精神的に支障をきたしてしまうのだと思います。 余談ですが、解決できない技術的なトラブルはないと思っています。なぜなら、技術は人の手によって生み出されたもの。なので人の手によって解決できると思っています。ので技術的な課題に対してパニックゾーンに陥る必要はありません。 一方で、業務として必要に迫られてないものや、ちょっと興味がある程度で書籍のみで勉強したことは実は続きませんでした。。。しかし、プライベートで何かアプリケーションやサービスを作ろうと思ったときはその気持ちを優先し、いろいろと作ってきました。このようなときは「学習したい」という気持ちではなく、「作りたい」が先行している状態です。実現したいものが先にある状態。作ることを繰り返していくと、あとから「あー、これを学習したのか」となり、同時に自分に満足なアウトプットが出せるのでハッピーです。こちらは、コンフォートゾーンに近いラーニングゾーンなのかな、と思います。ずっと居たいゾーンですね。 また、どの学習においても、いろいろ自分に取り入れたものを、知ったことを整理し、他者に伝えることで、改めて調べたり、理解が進んだりすることはよくあります。 (まさに、このブログ執筆などもそうです。) 成長のフレームワーク(コンフォートゾーン、ラーニングゾーン、パニックゾーン)に経験をあてはめる 人が成長するのは、3つのゾーンの中で、ラーニングゾーンと言われていますが、さらにラーニングゾーンの中にもレベルがあると言われています。 高ラーニングゾーン パニックゾーンに近いが、ストレス負荷が高めで高成長が期待できる 中ラーニングゾーン その真ん中 低ラーニングゾーン コンフォートゾーンに近いが、ストレス負荷、成長率共に低いが伸びている ここで思ったのは、経験に照らし合わせると、各ラーニングゾーンに達するには、自分から行ける場合もあるし、業務上必要になり、ある意味、強制的に行かされる場合もあるのではないか、ということです。 言い換えれば、実は強制的に、必要に迫られて何かをするほうがが大きく学習できる、つまり身についていく、ということも言えるのではないでしょうか。 さらに言うと、その個人が人から言われなくても、「それが業務上必要である、という認知がどれだけできるか」が、個人の成長スピードにかかっている、とも考えられます。 ここは今回振り返ってみてはじめて気づいた点でした。(エンジニアに限らずとも、どんな職種でもおそらくそうなのでしょうね。) また社内での勉強会や輪読への参加など、学習スケジュールが決められているものに関しても、周囲からの強制力という意味では、真ん中あたりに位置しているのではないかと思います。 つまり、私の経験したことをあてはめると以下のような図ができそうです。外側に行くほど、高成長が期待でき、かつ、(個人の認知の違いはありますが)周囲からの強制力があります。 若くてこれからの人へ トラブルを起こそう、ということではありません。急成長するには、 今ある業務を見渡し必要な学習はすでにやれ、と誰かに迫られていると思ったほうが早く成長できるようになる 、ということだと思います。また、学習スケジュールが決められているものに参加をし 自分にあえて強制をかけていく 、ということも意識するとよいと思います。 で、トラブルが起きてしまったら、 すすんでトラブル対応に関わり普段経験できないことを経験しましょう。 ほかのプロジェクトであってもポストモーテムを読み、自身の経験値として取り入れていくことが大事だと思います。 そして、 モチベーションがあるとき、何かを作りたいと思うときは、贅沢に思う存分プライベートの時間を使い、満足いくまで手を動かし作りましょう! (これが一番楽しい。楽しい、と思う気持ちを大切にしてください。) そして、それらは、すべて他者に何かしらの形で共有し、自身の理解度を高めていきましょう。 以上が、私の経験談を通して、これからの方へ伝えたいことでした!もっと書きたいことがありましたが、長くなりすぎそうだったので、やめておきます!参考になれば幸いです! We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
アバター
イベントの概要 NIFTY Tech Talkは、ニフティ株式会社の社員が主催するトークイベントです。 本イベントでは、ニフティグループの社員が業務を通じて学んだことを発信しています! 第11回目のテーマは「 新人エンジニアに贈る最強の開発環境 」です。 ニフティのエンジニアが、働き始めた新人エンジニアに開発環境を紹介する回となります。 【5/30(火) 12:00~】NIFTY Tech Talk 新人エンジニアに贈る最強の開発環境 を開催します! 【LT】Python開発環境 ( 個人的Python開発環境構築 ) Pythonでの開発における便利ツールについて語っていただきました。 チーム開発における品質・生産性向上に効果があります。 Poetry – パッケージ管理ツール Ruff – Linter Black – Formatter Mypy – 静的型チェッカー Pytest – 単体テストツール 資料 【LT】ターミナル・シェルを最強にする話をすると思います 黒い画面の話。 開発環境で使うターミナルやシェルのカスタマイズ、ツール導入について語っていただきました。 iTerm2 設定、カラーなど zsh 高速化 モダンコマンド exa bat navi grex dotfilesのススメ 資料 【LT】StrongestNewsによる最強の自作WEBアプリ開発環境 WEBアプリケーションの開発・環境構築、学習方法・知識の定着プラクティスについて話ていただきました。 StrongestNews(ニュースサイト)はWEBアプリケーションを理解する上で適切で、その後の発展学習にもつながります。 主な技術 React Nginx FastAPI MySQL Docker Terraform Github (Actions) AWS 資料 まとめ 新人向けの最強開発環境ということで、チーム開発を効率化するためのツール活用、エンジニアにとってなくてはならないターミナル、CLIについてカスタマイズ、WEBアプリケーション作成を通じて学習を広げるプラクティスと新人エンジニアには参考になったのではないでしょうか。詳細な資料については以下のリンクから御覧ください。 アーカイブ(YouTube) 発表資料(Speaker Deck) We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 カジュアル面談も常時受け付けています。 カジュアル面談 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
アバター
はじめに こんにちは、ニフティのいかりがわです。 ニフティでは毎年、新卒エンジニア向けのOJTとしてエンジニア定例という勉強会を開催しています。 私は機械学習の講師を務めていて、講義の中で Amazon SageMaker を使ったハンズオン実習を行うことにしました。そのために、いろいろな勉強をして準備を進めていました。 その中で、 Amazon SageMaker JumpStart が学習済みのモデルをボタンポチポチで簡単にデプロイできて楽しいなぁと思ったので紹介させていただきます! Amazon SageMaker JumpStartとは まず、Amazon SageMakerを簡単に説明すると以下のようになります。 Amazon SageMaker JumpStartは、Amazonが提供する機械学習のツール 事前準備されたリソースを活用して、目的に合わせた機械学習の実行を容易にしてくれる 機械学習モデルを簡単に作成できるため、モデル開発の経験がない初心者でも簡単に使うことができる Amazon SageMaker JumpStartはAmazon SageMakerの一つの機能である、 Amazon SageMaker Studio から利用することができます。 また、GUIでの操作で簡単に実施することができ、数回のクリックだけで機械学習ソリューションの展開や学習済みモデルのデプロイ、ファインチューニング等を簡単に実行することができます! やりたいこと 今回の記事では以下のことを行います。 SageMaker JumpStartを使うことで、学習済み機械学習モデルを作成、デプロイする! さらに、 Lambda と API Gateway を使って機械学習APIを作成する! SageMaker JumpStartで学習済み機械学習モデルをデプロイする SageMaker Studioを立ち上げるために必要なドメインやユーザープロファイルはすでに設定済みとします。 作成方法は 公式チュートリアル よりご参照ください。 SageMaker Studioの起動 ユーザー名の右側にある、「起動」から「Studio」を選択すると、SageMaker Studioが起動します。 JumpStartを使用して学習済みモデルをデプロイ 1. ホーム画面から、JumpStartを選択します。 2. 使用したい機械学習モデルを選択します。(今回はStable Diffusion 2.1 base) 3. こんな感じの画面に遷移します。 4. 「Deploy」を選択し、デプロイ! 5. モデルとエンドポイントが作成されるまで5~10分ほど待機… しばらく待つと、Endpoint StatusがIn Serviceとなりモデルとエンドポイントが作成されました!(Endpoint nameは後で使います。) API Gateway + Lambdaで機械学習APIを作る Lambdaの作成 1. Lambdaのコンソール画面に移動し、「関数の作成」を選択します。 2. 作成画面では以下のように設定し、それ以外はそのままで「関数の作成」をクリック 。 関数名: 任意 ランタイム: Python 3.10 3. 関数が作成されたら、以下のソースコードをコピペ。 コード内の<エンドポイント名>は、先ほどSageMaker Studioで作成したEndpoint nameを入れてください。 import json import base64 import boto3 # 入力されたテキストデータから機械学習エンドポイントに対して、リクエストを送信し、結果を返す def query_endpoint(text): client = boto3.client('runtime.sagemaker') endpoint_name = '<エンドポイント名>' encoded_text = text.encode("utf-8") response = client.invoke_endpoint(EndpointName=endpoint_name, ContentType='application/x-text', Body=encoded_text, Accept='application/json;jpeg') return response # 機械学習エンドポイントからの出力結果のJSONを解析し、画像を返す def parse_response(query_response): response_dict = json.loads(query_response['Body'].read()) return response_dict['generated_image'] # ここが実行される def lambda_handler(event, context): body = json.loads(event['body']) text = body['text'] response = query_endpoint(text) img = parse_response(response) return { 'statusCode': 200, 'headers': { 'Content-Type': "'image/jpeg'", }, 'body': img, 'isBase64Encoded': True } 4. タイムアウトを5分に設定。 「設定」→「一般設定」→「編集」より設定 できます。 5. IAMロールの変更。 「設定」→ 「アクセス権限」→「実行ロール名」のロール名をクリックすると設定できます 「許可を追加」から「ポリシーをアタッチ」をクリック。 6. 検索フォームから「SageMakerFullAccess」と検索して出てきたポリシーを選択、「許可を追加」で追加し、ポリシーが追加されていることを確認します。 API Gatewayの作成 1. Lambda関数のページから、「トリガーを追加」をクリックし、「ソースを選択」から「API Gateway」を選択します。 2. 以下のように設定し、「追加」をクリック。 インテント: 新規APIを作成 APIタイプ: REST API セキュリティ: APIキー 3. Lambdaの「関数の概要」にAPI Gatewayが追加されていることを確認します。 4. 「設定」→「トリガー」より、API Gatewayが追加されていることを確認し、「APIエンドポイント」と「APIキー」をメモしておきます ローカルで実行! ここまできたらドキドキの実行タイムです! curlコマンドなどでAPIを叩いてみてください! <Stable Diffusionに読ませたい文字>には好きな文字を記述してください 。 curl -X POST <APIエンドポイント> \ -d "{\\"text\\": \\"<Stable Diffusionに読ませたい文字>\\"}" \ --header 'x-api-key:<APIキー>' | base64 -d > ~/Downloads/image.jpeg おわりに 今回は、Amazon SageMaker JumpStartを使用して学習済みの機械学習モデルを作成、デプロイし、LambdaとAPI Gatewayを使って機械学習APIを作成する方法を紹介しました。 Amazon SageMaker JumpStartを使えば機械学習についてあまり詳しくない初心者でも簡単に機械学習のAPIを作成することができます! また、自分で持っている画像を使ってファインチューニングしたモデルを作成することもできますので、機械学習に詳しい方でも色々使えると思いますのでぜひ活用してみてください! 最後に、作成したAPIに「1 pomeranian on the sofa」と入力した結果を貼っておきます! かわいいですね! We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
アバター
こんにちは! Notion勉強中の小浦です。 他の人が作ったスペースを覗いてみると、見たことない機能を駆使していたりして気になりませんか?私は気になります。 ということで、月に一度開催しているNIFTY Tech TalkでNotionについて話しました! イベントの概要 YouTube Liveにて、ニフティのNotion活用事例について3名が話しました。 詳細についてはこちらの記事をご参照ください。 【4/27(木) 12:00~】NIFTY Tech Talk「【エンジニア必見】Notionで仕事のスピードを加速するテクニックとは?」を開催します! 【LT】世界一利便性が高くてかっこいいプロダクトwikiを目指す Notion愛好家の松阪さんが「世界一利便性が高くてかっこいいプロダクトwikiを目指す」にあたり、重ねてきた工夫について話しました。 実は私のチームのwikiは松阪さんにベースを作ってもらったんです(ニフティの新入社員がいろんなチームを経験できる制度「ジョブローテーション」中に、私のチームに来てくれた時にお願いしました) 進化の過程を3段階に分け、それぞれ工夫したことと改善点を教えてくれました。 DBで何でも作ってしまい、v1で満足している方、多いのでは…(私です) 要素を縦長に並べると間延びしてしまうので、様々なブロックを使ってギュッとまとめたそうです。 特にコールアウトの使い方は目から鱗で、すぐに真似したいと思いました。 【LT】Zapierを使った Google FormsとNotion DBの連携 続いて N1!オートメーションスペシャリストの南川さん 。 Zapierを使って、ノーコードでGoogle Forms → Notionに連携するワザを教えてくれました。 社内で作業依頼をしたり受けたりすることもあるのですが、そんなとき依頼者が直接DBを編集すると予期せぬ編集をされてしまったりするんですよね。 連携の手順を、準備から動作確認までかなり詳しく説明いただきました! 手順通り操作すれば、誰でもできちゃうわけです。しかもノーコードで! Speaker Deckの資料にはもっと詳しい手順が載っていますのでぜひご覧ください。 Zapier初めての方にもおすすめです。 【LT】NotionのWiki機能を使ったページ管理を考えてみる 最後にNotionの運用担当者でもある石川さんのLTです。 最後に N1!プロダクティビティエンジニアの石川さん 。 話題のWiki機能についてのおすすめポイントです。 ページをデータベースアイテムのように扱える 最近追加・編集されたページ一覧が作れる デフォルトでページ配下を検索してくれるボタン Wiki機能を使って、ページツリーとDBのサブアイテムの階層が合っているスペースを作りたい石川さん。 発表資料を作成された時点ではWikiのデータベースプロパティはAPIから変更ができず、代替案で実現したとのことでした。最初はAPIからプロパティの取得もできなかったようですが、現在は可能になっています。今後は変更も可能になっていくのではないでしょうか。日々更新されるNotionに期待しましょう。 まとめ 今回のNIFTY Tech Talkでは、ニフティのエンジニアがNotionの活用事例を紹介しました。すぐに実践できる内容で、私も非常に勉強になりました。ご覧いただいた方が参考にできるものがあれば幸いです。 今後も NIFTY Tech Talk は継続して実施していきますので、ぜひご参加ください。 石川さんがニフティへNotionを導入された時の話はこちらで見られます。 導入を検討されている方、ニフティの社内システムの導入について興味がある方がいらっしゃいましたらぜひご覧ください。 Notion企業活用ウェビナーで「Notion全社導入に伴う移行とデータ整理のノウハウ」というタイトルで登壇しました YouTubeのアーカイブと、発表資料はこちらからご覧になれます。 アーカイブ(YouTube) 発表資料(Speaker Deck) We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
アバター
はじめに 基幹システムグループ 湊谷です。 突然ですが、皆さんGithub Actionsって使っていますか? GitHub Actions は、ビルド、テスト、デプロイのパイプラインを自動化できる継続的インテグレーションと継続的デリバリー (CI/CD) のプラットフォームです。 リポジトリに対するすべての pull request をビルドしてテストしたり、マージされた pull request を運用環境にデプロイしたりするワークフローを作成できます。 https://docs.github.com/ja/actions/learn-github-actions/understanding-github-actions 私の所属しているチームではCI/CDツールとして使ったり、プルリクエスト作成時に自動でテストを走らせたり、Issueを作成したら特定のプロジェクトに紐づけたり、と多くの面で活用しています。 「プルリクエストを作成した時にESLintを実行し、引っかかったらプルリクエストを承認できないようにする」というワークフローを作成していたのですが、一つ気になる点がありました。Github Actionsの仕様として、Warningが出た場合も失敗扱いにはならず、StatusはSuccessとなります。そのため、プルリクエストも承認できてしまいます。 eslintコマンドには –max-warnings というオプションが用意されており、これに0を指定して実行すると「出て良いWarningの数は0=一つもWarningを許容しない」となり、ESLintの実行結果もFailureとなります。 しかし、その様なオプションが無い場合や、Warning以外にも特定の文字列が出力されている時にそれを検知する方法はあるのか?と疑問に思ったため、Github Actionsの中でやる方法を探してみました。 特定の文字列を含む時にエラーになるようにする コードの完成形を見てみます。 name: pr-test on: pull_request: branches: [main] jobs: build: runs-on: ubuntu-latest strategy: matrix: node-version: [16.x] steps: - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - name: npm ci run: npm ci - name: npm run build run: npm run build --if-present - name: npm test run: npm test - name: npm run lint id: lint run: | result=$(npm run lint | tr '\n' ' ') echo "result=$result" >> $GITHUB_OUTPUT echo "$result" | tr ' ' '\n' - name: check lint if: contains(steps.lint.outputs.result, 'Warning') run: | echo 'lintでWarningが出ています。修正をお願いします' exit 1 色々なことをやっていますが、今回関わってくるのは以下の部分です。 - name: npm run lint id: lint run: | result=$(npm run lint | tr '\n' ' ') echo "result=$result" >> $GITHUB_OUTPUT echo "$result" | tr ' ' '\n' - name: check lint if: contains(steps.lint.outputs.result, 'Warning') run: | echo 'lintでWarningが出ています。修正をお願いします' exit 1 まず、 name: npm run lint のジョブではESlintを実行しています。 ESLintを実行した結果をresultに入れます。改行があると最初の一行しか取得できなかったため、改行を無くしています。 result=$(npm run lint | tr '\n' ' ') ESLintの結果を後続のジョブで使うため、 $GITHUB_OUTPUT で値をセットします。 echo "result=$result" >> $GITHUB_OUTPUT そして、ESLintを実行結果も確認したいため、出力します。改行が無いと読みづらいため元に戻しています。 echo "$result" | tr ' ' '\n' 次に、 name: check lint のジョブではESLintの実行結果をチェックしています。 今回は、ESLintの結果にWarningの文字列があったらエラーを返すようにし、ワークフローを失敗としましょう。 contains( search, item )を使います。searchの中にitemがあればtrueを返し、そうでない場合はfalseを返します。 if: contains(steps.lint.outputs.result, 'Warning') 「id:lintで指定したstepsの中のoutputsの中にセットしたresultの値の中にWarningが入っている場合」という条件を設定し、trueであればrun以降書かれた内容を実行します。 今回は「lintでWarningが出ています。修正をお願いします」という文章を出力し、exit 1を実行してジョブを終了させています。 実際に、ESLintを実行した際にWarningが出るようなファイルをわざと用意すると、以下のようになります。 ESLintを実行したところでは失敗とはなりませんが、その後のWarningが含まれているかどうかチェックするところで失敗となり、修正しないとプルリクエストを承認できない状態にできました! 最後に 今回は「特定の要素が含まれているかどうか」をチェックするcontainsを使ってみました。 これを使うと「ブランチ名に特定の文字列が含まれている場合」だけジョブを実行したい、といったこともできそうです。もっとGithub Actionsを活用していきたいです! We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
アバター
ニフティ株式会社でニフティニュース開発チームでスクラムマスターをやっている中村です。 この記事ではスクラムマスターが身につけるべき新たなスキルとして「動機づけ面接」を紹介します。 (途中のスライドは週次で行っているチーム会の内容からの引用です) スクラムマスターの難しさ 普段は開発チームにおいてスクラムマスターをやっているのですが、スクラムマスターが身につけるべき技術は多岐にわたります。 基本的なコミュニケーションもそうですが、ファシリテーション、コーチング、メンタリング、チームビルディングスキルなどなど、スクラムという枠組みはありながらチームをより良い方向に導くことに最大の責務を持っています。 そして、自分は認定スクラムマスターの資格も保持しているのですが、資格の講習中にこんなことを言われました。 「 スクラムマスターは何も指示しません。 指示をすることはスクラムマスターの責務にはありません。なぜならメンバーが自分で考えて決断できるようにするための役割だからです。」 指示をしないでチームを変える これを聞いた時に自分はこう思いました。 「メンバーが自分で考えて決断できるようにする、という役割は理解できる。でも指示をしないでチームを導けるんだろうか?そもそも人やチームを変えるためには指示に近いことが必要なのでは?」 そんなことを考えていました。 なんとなくはわかるんです。でも、できるとは信じられない。そんな状態でした。 心理療法の世界 話は少し変わりますが、人間の行動を変容させる科学的な技術として心理療法が存在します。 心理療法は1930年代まで「指示的」なカウンセリング手法が主流だったそうです。 相手の言葉の裏を読み取り、そこにカウンセラーが解釈した結果から説得やアドバイスを行う手法です。 しかし、1940年にC.ロジャースという人が「非指示的」な手法を提案します。 これは今日では「来談者中心療法」と呼ばれている心理療法において主流の手法です。 来談者中心療法とスクラム 「来談者中心療法」ではクライアントに対して何か指示することはありません。 人間はみんな「こうなりたい」という願望と現実とのギャップに苦しんでいます。(と考えます) そのギャップが大きくなると問題行動などにつながる、と考えます。 問題と解決策はクライアント自身が知っていて、カウンセラー自身が何かを教える必要はない、というのが「来談者中心療法」の考え方です。 そして、自分はこの説明を読んでいて直感的にこう思いました。 「スクラムマスターがやることってこれでは?」と 動機づけ面接という新時代のスクラムマスターに捧げる武器 「動機づけ面接」はこの来談者中心療法の流れを汲む「非指示型カウンセリング」です。 (行動変容を促すフェーズもあるため、準指示と言われることもあります) 指示をしない方法でありながら、飲酒・ダイエット・喫煙などのあらゆる行動変容の促進に科学的に効果があるとされています。 したがって、スクラムマスターのような「チームをより上手く動かす必要がある」「しかし指示はするのではない」というある種矛盾した立場の人間にとっては、これは必須スキルとも考えられます。 「相手と自分の解釈に違いはないのだろうか?」 「動機づけ面接」は体系化された手法であり、内容が多岐に渡るため、大事な1つの技術としてここでは「聞き返し」のみを取り上げます。 考え方として、私たちは相手が話したことを意識的・無意識的に関わらず、「こういう考えで話しているんだろう」とまとめて意味づけを行おうとします。 そしてこの推測は正しかったり間違ったりもします。 (ある研究によると人の気持ちを推測するテストの正答率は44%らしく、むしろ半分以上は間違っている可能性があります) ここで間違った推測のまま捉え続けてしまうことで、最終的に行き違いやミスコミュニケーションが生まれることになります。 これを乗り越えるために「動機づけ面接」では「聞き返し」によって、相手の意図を確認します。 「あなたが言っていることはこういう意味だと思うが、これで合っていますか?」 というこの意識だけでも、コミュニケーションは円滑になるのではないでしょうか? 「説得」や「指示」をしても人は動かない 自チームのチーム会ではさらに深い考えや手法について解説したのですが、それについてはまた別の記事に記載したいと思います。 自分がこういった方法を調べていて思うことは、結局「説得」や「指示」では人は変わらないし動かないということです。 自分も熱が入ったりすると自分の正当性を主張したくなってしまうのですが、それでは人の抵抗を大きくするだけで、結果的に人に影響をもたらすことは難しくなってしまいます。 そうではなく、相手の思考や価値観・感情も含めて正確に言葉にして理解をしながら、本当の意味で相手を理解するということが重要になるのだなと思います。 自分はスクラムマスターとして「チームを上手く動かすため」「人を理解するため」にこういった勉強を繰り返す傾向にあるのですが、勉強をすればするほど本当に難しいことをしているなと思います。 おわりに 本記事では、スクラムマスターの新しい武器として「動機づけ面接」を紹介しました。 いろんな手法を学び、実験を繰り返して、真のスクラムマスターを目指しましょう。 We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
アバター
はじめに こんにちは。新卒4年目の南です。 ニフティでは新卒採用活動の一環として、毎年インターンシップを開催しています。 私は2021年・2022年のチーム開発インターンシップにメンター社員として参加し、今年もメンター社員として参加します。 本記事では、今年も開催を予定している「チーム開発3daysコース」について紹介します。 少しでもニフティのインターンシップに興味を持っていただけた方は、是非 登録フォーム からマイページ登録をしていただき、書類提出をお願いいたします! インターンシップについて チーム開発3daysコース概要・応募要項 期間 半日(オリエンテーション)+3日間(プログラム本番) 開催日程(予定) ① オリエンテーション:2023年8月1日(火) 9:00~12:00 プログラム本番 :2023年8月2日(水)~8月4日(金) ② オリエンテーション:2023年8月22日(火) 9:00~12:00 プログラム本番 :2023年8月23日(水)~8月25日(金) ※参加希望日程については①②どちらかを選択いただく形となります。 実施形式 対面実施(新宿本社) ※オリエンテーションにつきましては、オンラインでの実施となります。 応募期間 書類提出〆切につきましては マイページ からご確認をお願いいたします。 参加条件 四年制大学、大学院、専門学校、高専の方(学年不問、文理不問) インターンシップの選考 書類選考あり 大まかなタイムスケジュール 1日目午前 スクラム講義 1日目午後~3日目 サービスサイトの改善課題(スクラム開発) 3日目午後 課題に対する発表/講評 ※いずれの日程も同内容となります。 ※開催日時や応募期間については変更の可能性がありますので、詳細は マイページ をご確認ください。 本インターンシップのおすすめポイント より実務に近いチーム開発を体験できる! 3日間で「スクラム開発」を体験してもらいます。 ニフティでは、スクラム導入の動きが会社全体で高まっており、スクラム開発を行っているチームが10以上存在します。そんなニフティで日々スクラム開発を行っている社員が、講師やメンターとして参加し皆さんのサポートに入ります。 また、スクラム開発での役割は全て学生の皆さんに担当いただきながら3日間の開発を行っていただきます。スクラムについて学びながら、チーム開発を体験できます。 【スクラムとは】 仕事のフレームワークの一つで、アジャイル開発で使われることが多いです。 決まった期間で必ずアウトプットを出す 決まった期間で振り返る などの特徴があります。チームを組んで役割やタスクを分散しつつ、コミュニケーションを取りながら行うので、チーム内のコミュニケーションがより大切になる開発手法です。 詳しくは、インターンシップ1日目に認定スクラムマスター(CSM)の資格を持つ社員から説明させていただきます。 サービスサイトの課題発見と解決に向けた実装に挑戦できる! インターンシップのために用意した架空のサービスサイトの改善を行ってもらいます。 実際にサービスを利用したり設計書などの資料を見ながら、解決すべき課題と改善方法をチームで探り改善に繋げていく流れになります。 仕事をする上で「新しいものを一から作り出す」ということはもちろんありますが、お客様目線を徹底して既存サービスをよりよいものにしていくということが日々の業務に繋がってきます。 別の人が作ったものを改修するということは学校ではなかなかない経験だと思いますので、最初は苦戦するかもしれません。しかし、言語やフレームワークがどのように記述されているのかを知って、スキル向上に繋げることができるいい機会だと思います。 またその中で、どの課題を優先で改善していくのか、改修規模はどのくらいなのか、など様々なことを考慮した上で優先順位をチームで決めて対応してもらいます。 開発スキルはもちろん、仕事をする上で必須となるスキル(タスクの優先順決定など)の向上に繋がるかもしれません。 会社の雰囲気を知ることができる! 今年は、数年ぶりにオフラインで開発インターンシップを開催します。 オンラインとは違い、直接会社の雰囲気を知っていただくことができます。 また、社員とも直接会話・交流が可能ですし、他の参加学生とも交流が可能です。3日目の最後には懇親会も予定しておりますので、この機会に現場社員と就活についてや社内の雰囲気について話して就活の参考にしていただければと思います。 1チーム1人以上の社員がサポートにつく! 各日程どちらもメンター社員6名+講義社員が参加予定です。 そのため、1チーム1人以上の社員がサポートにつく形が実現できます。チーム開発ということで、まずはチーム内で相談いただき解決に向けて動いていただきますが、スクラムに関する質問やチーム内での解決に時間がかかっている場合などは気軽に社員に相談できる環境となっております。 昨年のインターンシップ参加者の感想 インターンシップに参加した学生のみなさんからの感想をいくつかご紹介します。 スクラム開発という経験はなかなかできず、エンジニアを志望する上で必ず体験しておきたかったので、今回参加できてとても嬉しく、楽しく開発を行うことができた。 会社の雰囲気や実際の業務を肌で感じられて充実感のあるインターンシップでした。また、自分の足りていない部分や勉強しなければいけないことが明確になったので、今後の勉強にも役立てていきたいと思います。 文系大学でスクラム開発を行うことは全くないので、その経験自体が貴重な上で更にエンジニアとして働いた時の立ち位置というものをワークを通して理解することができた。 コードが書ければいいというものではなく、リーダーシップや積極性、明るさなども開発の大切な要素だと感じました。 本格的なスクラム開発のやり方やタスクをどのような優先度で行うか、どのようにタスクをこなしていくかという点について、貴社のインターンシップに参加していなったら知らないものばかりでした。 メンター社員の方からエンジニア業務の本音を多く頂くことができたので、実際に働く将来像を見ることができました。 スクラムの流れは授業等で知っていましたが、実際にそれを使って開発できたのが自分にとって1番大きかったです。 人の書いたプログラムから開発するのが初めての経験で大学で勉強したものとのギャップに最初つまずきましたが、日を追うごとにコードの理解度が上がっていき開発スピードが上がっていきました。 チーム開発ももちろんですが、実際の社員の方々の雰囲気を知ることができたことも大きな成果だと感じています。 スクラム開発における成果や実装における成果など様々な感想をいただきました。 また、社員との交流で得られるものに関する感想も多くいただきました。 おわりに ニフティのインターンシップの中でも、自社サービスを提供している会社に興味のある方、システムエンジニアに興味のある方におすすめのコースです。 エンジニアの業務内容について理解を深めていただくことや、チーム開発の楽しさ・難しさを味わっていただけるかと思います。また、このワークを通じてお客様目線を徹底するニフティの風土も感じていただけます! 「スクラム開発、聞いたことはあるけどあまり知らない」「スクラム開発が何かは知ってるけど実践したことがない」という方、多くいらっしゃると思います。是非この機会に、ニフティのチーム開発インターンシップに参加してスクラム開発(チーム開発)を体験してみませんか? 少しでもニフティのインターンシップに興味を持っていただけた方は、是非 登録フォーム からマイページ登録をしていただき、書類提出をお願いいたします! たくさんのご応募お待ちしております。 また、下記の通りニフティではチーム開発3daysコース以外のインターンシップも行っております。 こちら のご応募もお待ちしております。 サイバー攻撃対応コース 企画提案・販売促進体験1dayコース サービス企画・プロモ・マーケ2daysコース We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
アバター
はじめに こんにちは。ニフティ株式会社入会システムチームの高畑です。 最近マスタデータ管理のために、Adminer Editorというアプリケーションを試してみましたので紹介します。 背景 システム設定やマスタデータをDB上のテーブルで管理している際に、操作ミスによっては影響が大きいためSQLを直接操作したくありません。そのため、社内運用ツールを作成することもありますが、シンプルなデータであれば汎用的なツールで十分な場合もあると思います。 汎用的なツールとしてAdminer Editorというアプリケーションを検証しました。本記事では実際に使う上で必要な機能として以下を挙げてカスタマイズ例と動作確認をしています。 データ操作以外のテーブル作成、変更操作をしたくない 不要なテーブルは見えないようにしたい 不要な列は見えないようにしたい 誰がデータを操作したか記録を残したい アクセス制限をしたい Adminer Editorとは Adminer Editor とはPHP製のDBデータ編集ツールです。SQLを操作せずに画面上の操作だけでテーブル上のデータ修正ができます。類似のツールにAdminerがありますが、Adminerと比較するとテーブル作成や削除といったDDLが制限されているためDB管理者というよりはDB利用者のためのツールになります。 また、MySQL、PostgreSQL、OracleDB、Microsoft SQL Server等さまざまなRDBMSに対応しています。 ツール本体は単一のPHPファイルとなっており導入しやすく、クラスを継承してインスタンスメソッドをオーバーライドすることでPHP触ることができれば簡単にカスタマイズできます。 今回は、導入の手軽さと利用できるRDBMSの豊富さから検証してみました。 デモ ソースコードと実行環境はDockerを用意しています。MySQLが提供している world database というサンプルデータをMySQLにインポートして操作していますので、実際に触ってみたいという方はREADMEを参考に構築してみてください。 https://github.com/octop162/adminer-editor-customized Adminer Editorの設定とカスタマイズ方法 導入に必要なのはAdminer Editor本体と設定ファイルの2つだけです。設定ファイルにはDBのホスト名、ユーザー名、パスワード等の基本設定の他、データ挿入、変更、削除等の操作をした際に呼ばれるメソッドのオーバーライドをします。 ここでは設定ファイルをworld.php、本体をeditor.phpとしています。world.phpにアクセスするとAdminer Editorが利用できます。さらにadminer.cssを設置することでCSSを読み込み反映してくれます。 設定方法は以下ページを参考にしています。 https://www.adminer.org/en/extension/ . ├── adminer.css ├── editor.php └── world.php それぞれの機能実現方法 前述したカスタム方法により機能追加しています。 不要なテーブルを非表示にしたい tableNameをオーバーライドすることでどのテーブルを表示させるか制御できます。非表示にしたいテーブル名なら空文字を返します。 ここではテーブル名が country   を非表示にしています。 function tableName($tableStatus) { // countryテーブルを非表示 $ignored_list = ['country']; if (in_array($tableStatus["Name"], $ignored_list, true)) { return ''; } return parent::tableName($tableStatus); } 不要なテーブルの列を非表示にしたい 同様に非表示にしたい列名は空文字を返すと非表示にできます。ここでは、 ID 列を非表示にしています。 function fieldName($field, $order = 0) { // ID列を非表示 $ignored_list = ['ID']; if (in_array($field["field"], $ignored_list, true)) { return ''; } return parent::fieldName($field, $order = 0); } 操作記録を残す 必要なファイルが増えてしまいますが、利便性を考えてPHPのログライブラリであるMonologを導入します。追加情報としてIPアドレス、X-Forwarded-For、ログインユーザーを出力することで誰が操作したかわかるようにしています。 class AdminerSoftware extends Adminer { private $logger; function __construct() { $this->logger = $this->getLogger('php://stdout', Level::Debug); } function getLogger($filename, $level = Level::Debug) { $logger = new Logger('adminer'); $handler = new StreamHandler($filename, $level); $handler->setFormatter(new JsonFormatter()); $logger->pushHandler($handler); $logger->pushProcessor(function ($record) { $record['extra']['remote_user'] = $_SERVER['REMOTE_USER']; $record['extra']['remote_ip'] = $_SERVER['REMOTE_ADDR']; $record['extra']['xff'] = $_SERVER['X-Forwarded-For']; return $record; }); return $logger; } ... SELECT、INSERT、 UPDATE、DELETEはそれぞれ selectQuery 、 messageQuery メソッドがAdminer Editor本体から呼ばれるため、用意したロガーオブジェクトでログ出力します。 function selectQuery($query, $time, $failed = false) { $output_query = str_replace("\\n", " ", $query); $this->logger->debug($output_query); } function messageQuery($query, $time, $failed = false) { $output_query = str_replace("\\n", " ", $query); $this->logger->info($output_query); } Monolog導入後は以下のようなファイル構成になりました。 . |-- composer.json |-- composer.lock |-- public | |-- adminer.css | |-- editor.php | `-- world.php `-- vendor |-- autoload.php |-- composer |-- monolog `-- psr アカウント認証する ログイン認証は login メソッドが担当しています。ユーザ名、パスワードを入力すると引数として渡されますので、簡易的に認証したいのであれば、それらを比較するだけで認証できます。 実際にはIPアドレス制限やリバースプロキシ導入する、パスワードをハッシュ化しておく等対策が必要に思います。 以下はIPアドレスをもとにしてアクセス制限をかける例と、簡易的な認証の例です。 <?php $permit_ip = ["x.x.x.x", "y.y.y.y"]; if (!in_array($_SERVER['REMOTE_ADDR'], $permit_ip, true)) { } ... class AdminerSoftware extends Adminer { ... function login($login, $password) { return $login === 'xxxx' && $password === 'yyyy'; } 実際に触ってみる 上記の設定後、ローカル環境で動作確認を実施します。 ①ログイン画面   ②テーブル一覧(countryが非表示になっています)。 ③データ一覧で神奈川県で検索してみます(ID列が非表示になっています)。   ④神奈川県に人口2000人の町TestCityを追加してみます。追加時もID列は表示されていません。 ⑤無事TestCityが追加されました。 ⑥編集リンクを押すと修正、削除ができます。 ⑦ログからそれぞれの操作を確認できました。 adminer-editor-customized-adminer-1 | {"message":"INSERT INTO `city` (`Name`, `CountryCode`, `District`, `Population`) VALUES ('TestCity', 'JPN', 'Kanagawa', '2000');","context":{},"level":200,"level_name":"INFO","channel":"adminer","datetime":"2023-06-16T01:46:58.380121+00:00","extra":{"remote_user":null,"remote_ip":"xxxx","xff":null}} adminer-editor-customized-adminer-1 | {"message":"UPDATE `city` SET `Name` = 'TestCity', `CountryCode` = 'JPN', `District` = 'Kanagawa', `Population` = '3000' WHERE `ID` = '4081';","context":{},"level":200,"level_name":"INFO","channel":"adminer","datetime":"2023-06-16T01:48:36.217265+00:00","extra":{"remote_user":null,"remote_ip":"xxxx","xff":null}} adminer-editor-customized-adminer-1 | {"message":"DELETE FROM `city` WHERE `ID` = '4081';","context":{},"level":200,"level_name":"INFO","channel":"adminer","datetime":"2023-06-16T01:50:09.335932+00:00","extra":{"remote_user":null,"remote_ip":"xxxx","xff":null}} おわりに 本記事では、Adminer Editorをカスタマイズすることで運用上必要な機能を追加できることを検証しました。参考になれば幸いです。 We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
アバター
イベント概要 NIFTY Tech Talkは、ニフティ株式会社の社員が主催するトークイベントです。 本イベントでは、ニフティグループの社員が業務を通じて学んだことを発信しています! 第12回目のテーマは「スクラム開発の真髄を探る!認定スクラムマスター研修参加者が語る成功のカギ」です。 研修から試験、そしてその先へ。 研修や試験、資格取得後どうだったか、第一歩を踏み出す方へニフティの認定スクラムマスターが語る回となります。 概要 日程:6月27日(火)12:00〜12:45 配信方法:YouTube Live 視聴環境:インターネット接続が可能なPC/スマートフォン 参加方法 connpass にて登録をお願いいたします。 ※YouTube Liveにて配信いたします。 ※YouTube LiveのURLは決定後、参加者への情報欄に記載いたします。 こんな方におすすめ 認定スクラムマスターに興味ある方 認定スクラムマスター研修を受けてみようか考えている方 タイムテーブル 時間 コンテンツ 12:00 – 12:05 オープニング 12:05 – 12:10 認定スクラムマスターってなんですか? 12:10 – 12:20 LT1: 認定スクラムマスター研修と認定試験について 12:20 – 12:30 LT2: スクラムに向かない情シスチームのスクラムマスターがCSMを取得して2年の間に思ったこと 12:30 – 12:40 LT3: 認定スクラムマスターになった後 A-CSMって取るべき? 12:40 – 12:45 クロージング テーマ スクラム開発の真髄を探る!認定スクラムマスター研修参加者が語る成功のカギ 登壇者プロフィール 青木 大海(登壇者) ニフティ株式会社 会員システムグループ 第2開発チーム 新卒入社7年目で、ニフティポイントクラブの開発・運用を担当しています。 2023年3月に認定スクラムマスターを取得しました。 小浦 由佳(登壇者) ニフティの情シス担当者です。 主にプラットフォーム、アプリケーションの社内システムを見ているチームのスクラムマスターで、2021年に認定スクラムマスターを取得しました。 NIFTY Tech Talk、NIFTY Tech Dayを始め、社内外のイベントを企画したりもしているニフティのにぎやかしです。 西野 香織(登壇者) ニフティ株式会社 会員システムグループ 第2開発チーム ニフティのスペシャリストを任命するN1!制度にて、スクラムエヴァンジェリストを担当しています。 2019年?スクラムマスターとして、ニフティへのスクラム導入を開始。 8チーム、エンジニア約30名以上に対しスクラム導入を支援しています。 アドバンスド認定スクラムマスター(A-CSM)資格所持。 ニフティグループでは一緒に働く仲間を募集中です 新卒採用、キャリア採用を実施しています。ぜひ リクルートサイト をご覧ください。 ニフティエンジニアが業務で学んだことやイベント情報を エンジニアブログ にて発信しています! ニフティエンジニアのTwitterアカウントを作りました NIFTY Tech Talkのことや、ニフティのエンジニアの活動を発信していきます。 Tweets by NIFTYDevelopers 「NIFTY Tech Day 2022」を開催しました 技術イベント「NIFTY Tech Day 2022」のアーカイブはこちら  NIFTY Tech Day 2022 アンチハラスメントポリシー 私たちは下記のような事柄に関わらずすべての参加者にとって安全で歓迎されるような場を作ることに努めます。 社会的あるいは法的な性、性自認、性表現(外見の性)、性指向 年齢、障がい、容姿、体格 人種、民族、宗教(無宗教を含む) 技術の選択 そして下記のようなハラスメント行為をいかなる形であっても決して許容しません。 不適切な画像、動画、録音の再生(性的な画像など) 発表や他のイベントに対する妨害行為 これらに限らない性的嫌がらせ 登壇者、主催スタッフもこのポリシーの対象となります。 ハラスメント行為をやめるように指示された場合、直ちに従うことが求められます。ルールを守らない参加者は、主催者の判断により、退場処分や今後のイベントに聴講者、登壇者、スタッフとして関わることを禁止します。 もしハラスメントを受けていると感じたり、他の誰かがハラスメントされていることに気がついた場合、または他に何かお困りのことがあれば、すぐにご連絡ください。 ※本文章は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/ ) で公開されています。スクラム開発の真髄を探る!認定スクラムマスター研修参加者が語る成功のカギ第12回目のテーマは「スクラム開発の真髄を探る!認定スクラムマスター研修参加者が語る成功のカギ」です。
アバター
はじめまして。SREチームの島です。 今年の3月にニフティに入社した駆け出しSREです。 前職では10年ほどアプリ開発に携わっており、この度SREデビューしました。 そんな私がニフティに入って最初に行った「Four Keysの設定」について、試行錯誤した経験を交えながら綴りたいと思います。 この記事の内容 触れること Four Keysの概念 実体験に基づいたFour Keysの設定例 触れないこと Four Keysの詳細な説明 GitHubやCI/CDに関する用語の説明 前提のおはなし ※Four Keysを理解している方は読み飛ばしてOKです Four Keysとは ズバリFour Keysとは DevOps Research and Assessment(DORA)チームが実施した 6 年間の研究から、ソフトウェア開発チームのパフォーマンスを示す 4 つの指標が確立されました。 https://cloud.google.com/blog/ja/products/gcp/using-the-four-keys-to-measure-your-devops-performance DORAチームとは企業のDevOpsの導入状況やパフォーマンスを調査しているGoogle社内の組織のようです。 つまり要約すると Google社内の組織が決めた「開発チームのパフォーマンス」を測る4つの指標 のことです。 以下がその指標となります。 指標名 定義 デプロイの頻度 組織による正常な本番環境へのリリースの頻度 変更のリードタイム commit から本番環境稼働までの所要時間 変更障害率 デプロイが原因で本番環境で障害が発生する割合(%) サービス復元時間 組織が本番環境での障害から回復するのにかかる時間 チームのパフォーマンスとは? では、「開発チームのパフォーマンス」とは具体的に何なのでしょうか? Four Keysの世界では「ソフトウェアデリバリーのパフォーマンス」のことを指します。 分かりやすく言うと、 「開発したソフトウェアをいかに速く、安定して顧客に提供できるか」 です。 それを計測し、評価することがFour Keysの目的となります。 Four Keysのメリット/デメリット メリット チームのパフォーマンスを可視化できる 部外者からもパフォーマンスを評価しやすい チームメンバー自身もパフォーマンスを把握しやすい CI/CDの改善が反映される指標である CI/CDをより良くしようという働きかけになる デメリット(注意点) Four Keysが高い=パフォーマンスが高い ではない あくまで指標の1つ 例えば意味のないデプロイを繰り返せばFour Keysは高まるが、本来そうすべきではない。数値に捉われすぎないこと 自動化することが前提 Four Keysを計測するために労力を割くのは本末転倒 つまり、 チームのパフォーマンスが視覚的に分かるようになり、改善意識の向上、パフォーマンス改善につながる ということがメリットとして挙げられます。 実際に設計してみる ここからは実際にFour Keysを設計するために行なったことを述べていきます。 今回は@niftyトップページ開発チームのFour Keysを設計しました。 1.開発フローを知る まずは現状どのようにCI/CDが行われているのか、現状のフローを知る必要があります。 開発チームのメンバーにヒアリングを行い、情報収集をしました。 要点はこちらになります。 ソース管理はGitHubで行なっている 障害管理はGitHub上では行なっていない リリースが原因で障害が発生した場合は必ず切り戻しを行なっている 以上のことから、今回はGitHubから必要な情報を取得してFour Keysを作成しようと思います。 イメージはこんな感じです。 Four Keysに必要なデータ取得の流れ ※ Googleスプレッドシート icon by Icons8 まずは試作ということでスプレッドシートを使ってデータの集計、グラフ化をすることにしました。 2.定義を決める Four Keysの定義はGoogleで提唱されていますが、それを組織の定義に落とし込みます。 定義のポイントとしては 何を計測・改善したいか を意識することです。 例えばFour Keysの1つである「変更のリードタイム」について、以下の2通りの定義で指標の意味合いが変わります。 <変更のリードタイムの定義例> 定義 計測できるもの 開発に着手してからリリースされるまで 実装や単体テストを含めた 開発速度 PRを作成してからリリースされるまで 単体開発以降の リリース準備の速度 チームにとって最適な定義を決めましょう! @niftyトップページ開発チームでは以下のように定義しました。 <Four Keysの定義> 指標 @niftyトップページ開発チームでの定義 デプロイの頻度 1日あたりの平均デプロイ回数(切り戻しを除く) 変更のリードタイム ① 変更をメインブランチにマージしてから、本番環境へのデプロイが完了するまでの所要時間 ② 変更のPRを作成してから、本番環境へのデプロイが完了するまでの所要時間 変更障害率 デプロイ回数に対する、切り戻しによるデプロイの割合 サービス復元時間 障害発生源の変更が本番環境へデプロイされてから、その切り戻しがデプロイ完了するまでの所要時間 「変更のリードタイム」、「サービス復元時間」を開発フローに乗せて説明すると、下記のようなイメージです。 変更のリードタイムのイメージ サービス復元時間のイメージ 今回は開発速度ではなくリリースまでの所要時間を計測するため、PR以降の時間を計測することにしました。 変更のリードタイムは、試作として2パターン計測し、どちらを採用するか決める方針としました。 3.ロジックを決める 上記で決めた定義から、具体的に使うデータ、計算式を決めます。 今回は下記のように決めました。 <Four Keysの算出ロジック> 指標 ロジック デプロイの頻度 デプロイ回数(切り戻しを除く)/日数 変更のリードタイム ①(デプロイ完了日時 – メインブランチへのマージ完了日時)の合計/デプロイ回数 ②(デプロイ完了日時 – PR作成日時)の合計/デプロイ回数 変更障害率 (切り戻しのデプロイ回数/切り戻しを除くデプロイ回数) * 100 サービス復元時間 (切り戻しのデプロイ完了日時 – 障害発生源のデプロイ完了日時)の合計/切り戻しのデプロイ回数 4.データを取得する ロジックまで決まったら、いよいよ実際にデータを取得します。 今回はGitHub REST APIを使ってコミット履歴、PR履歴、デプロイ履歴を取得し、集計しました。 最終的にこのような集計結果となりました。(実際の計測値とは変えています) GitHubデータの集計結果 5.グラフ化する 上記の集計結果をスプレッドシートのグラフ機能を使ってグラフ化しました。 Four Keysをグラフ化した結果 上記の結果から 変更障害率は低く安定しており、サービス復元時間も短いため、 障害発生時の切り戻しを安定して素早く行えている デプロイの頻度も安定している。(障害の発生した月は増加傾向にある) 変更のリードタイムの マージ以降の所要時間は短く安定しているが、PR作成以降の所要時間は増加傾向 にある。つまりPR作成〜マージ間のタスクを改善できると良い といった分析ができます。 実際、このチームではマージ以降の処理(デプロイ)は自動化されているため、マージ以降の所要時間が短いという結果は実態と合っていると言えます。 また変更のリードタイムは マージ以降の所要時間(青色の線) を採用することにしました。 理由としては下記の2点となります。 PR作成後に企画担当とリリース日の調整を行うので、 PR作成以降の所要時間(赤色の線)は開発以外の要因に左右されやすい 。 そのためこちらは不採用 マージ以降の所要時間は今は安定しているが、 今後何かの要因で所要時間が増えた際に検知、分析できると良い。 そのためこちらを採用し、定期的に計測する。 以上でFour Keysの作成ができました。 まとめ 苦労したこと 定義、ロジックを決める作業が一番苦労しました。 定義は明確に決まっているわけではなく、チームにとって最適な定義を決める必要があります。 上では省略していますが、定義を決めるフェーズでは 何度もチームメンバーとレビューや議論を重ねて 定義を決定しました。 明確な正解がない中で、最適解を求める作業は大変でしたが、 納得できる定義が決まった時はとても達成感がありました。 今後の展望 データ収集、集計の自動化 継続的にFour Keysを計測するために、自動化できるところは自動化していく予定です。 また、今はスプレッドシートで集計からグラフ化まで行なっていますが、自動化するにあたって最適なツール選定なども行う予定です。 他チームへ展開するために、全社共通定義の 決定 今回は@niftyトップページ開発チーム独自の定義を決めましたが、ニフティ社内での共通定義を決めていく予定です。 共通定義が決まればニフティとしての指標が明確になり、チームごとの比較もできるようになるので、Four Keysをより有効活用できます。 最後に 今回はFour Keysを作成し、@niftyトップページ開発チームのパフォーマンスを計測しました。 パフォーマンスが可視化されたことで開発フローを見直すきっかけになれば幸いです。 まだまだ試作段階ですが、今後さらに便利なものにして有効活用していきたいと思います。 最後まで読んでいただき、ありがとうございました! 参考記事 エリート DevOps チームであることを Four Keys プロジェクトで確認する We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
アバター
こんにちは、最近はスプレッドシートの値をgetValuesした時の型が自由すぎることが悩みの宮本です。便利といえば便利なんですが、自由奔放すぎてTypeScriptだとちょっと手を焼いています。 はじめに みなさん clasp はご存知でしょうか?claspは、Google Apps Script(以下GAS)のプロジェクトをコマンドラインでデプロイできるようにできるツールです。GASをローカルで開発し、コード自体もgit管理したりと、これ一つでGASの使い勝手が一気に上がることでしょう。 さて、このclaspを使うとローカルからのデプロイの他に、デフォルトでもTypeScriptに対応しているという便利機能がついてきます。型がないと生きていけなくなってしまった私としては飛び上がって喜びたいのですが、残念なことに 対応しているバージョンが3.8.2 と若干古いです。他にもexport/importが素直に使えなかったりと、やや痒いところに手が届きません。どちらかというと、こっちの方が辛い……。 そこで私は gas-webpack-plugin を使ってローカル内でwebpackを使いコードをビルドし、ビルドしたコードをclaspでデプロイという方法を使ってます。さらにclaspで管理するプロジェクト設定の入っている .clasp.json を環境ごとに用意すれば、GASでも本番・開発環境を分けてデプロイすることができてしまいます。これで完璧。 と、言いたいところですが、これにもちょっと不便なところがあります。ちょっと多いんですよね……実行しないといけないコマンドが。 古いビルド済みファイルが残っていると嫌なので削除 webpackでビルド デプロイしたい環境に合わせて .clasp.json を切り替え claspでデプロイ いや、改めて見るとそんなに多くない気もしてきました。でも、これをちょっと変更して動作確認して……となってくると毎回打つのが結構面倒です。特にスプレッドシートと連携したGASだと、ちょっとした動作確認でもローカルだと難しくデプロイしないと正常に動くかわかりません。 ということで、環境を分けて一発でデプロイできるようにコマンドを整えましたというご紹介です。本題に入るまでが長かった。 一発で環境を分けてGASをデプロイできるようにする さて、ごちゃごちゃしたコマンドをまとめるとなると、シェルスクリプトでも用意する必要がありそうですが、ちょっと面倒です。ということで、今回はpackage.jsonのscriptsのpre/post scriptsを使って一発でデプロイできるようにしてみます。 pre/post scripts よくpackage.jsonのscriptsフィールドに "build": "next build" のようなものは登録すると思います。pre/post scriptは、たとえばscriptsフィールドにpreで始まるコマンド登録されていたらpreに続くコマンドの実行前に、postで始まるコマンドが登録されていたらpostに続くコマンドの実行後に自動で実行されるスクリプトです。 buildを当てはめるとこうなります。 prebuild: buildコマンドの前に自動で実行 postbuild: buildコマンドの後に自動で実行 実はいままで使ったことがなかったのですが、今回はこれで良さそうです。 デプロイコマンド では、コマンドで環境を分けつつ一発でclaspをデプロイするpackage.jsonのscriptsとdevDependenciesの抜粋です。 前提 環境ごとの .clasp.jsonは用意済み 開発環境: .clasp.json.dev 本番環境: .clasp.json.prod webpackのビルド設定は完了済み ビルドすると ./dist ディレクトリにビルド済みファイルが入る "scripts": { "prebuild": "rimraf ./dist", "build": "webpack", "predeploy": "yarn build", "deploy": "clasp push", "postdeploy": "rimraf .clasp.json", "predeploy:dev": "node -e \"require('fs').copyFileSync('./.clasp.json.dev', './.clasp.json')\"", "predeploy:prod": "node -e \"require('fs').copyFileSync('./.clasp.json.prod', './.clasp.json')\"", "deploy:dev": "yarn deploy", "deploy:prod": "yarn deploy" }, "devDependencies": { ... "rimraf": "^4.4.1", ... }, // 利用ライブラリの追加 yarn add -D rimraf // 開発環境へのデプロイ yarn deploy:dev // 本番環境へのデプロイ yarn deploy:prod やっていることの説明 まず、buildコマンドでwebpackを呼び出し、ビルドするようになっています。そしてprebuildとして、 rimraf ライブラリを使い以前のビルド済みファイルを削除しています。これで、buildコマンド実行時に以前のファイルを確実に削除してファイルをビルドすることができるようになっています。 そして、deployコマンドではpredeployとして、buildコマンドを実行するようにしています。これで、デプロイ時に事前にファイルを自動でビルドすることができます。ビルド後にclasp pushでGASのプロジェクトにデプロイします。その後、postdeployで.clasp.jsonを削除しています。 そして環境ごとの出力先変更ですが、それぞれdeploy:devとdeploy:prodの2種類のコマンドを用意しています。どちらもyarn deployを呼び出していますが、事前のpreコマンドで対応する.clasp.json.{dev|prod}をnodeのコマンドライン実行で.clasp.jsonにコピーしています。ここだけnodeのコマンドライン実行をしている理由としては、ファイルを別名コピーする丁度良いライブラリが見当たらなかったためです。 おわりに claspでコマンドラインからデプロイできるようになったけど、コマンド4つも打つの面倒くさい!という低レベルな悩みから、コマンド一つで環境を分けてGASのプロジェクトをデプロイできるようにしてみました。実際にやってみると、そこまで手間はかからない割にストレスフリーになって結構気に入っています。ただ、scripts内で別名で同じコマンドを呼び出していたり、もう少し綺麗にできないかなとも思ったり……。とはいえ現状はこれで十分かなと感じているので、ほどほどに妥協も入ってます。 claspというよりはpackage.jsonのscriptsでできること意外とある!!という感じの記事になっていますが、お役に立てれば幸いです。 参考 google/clasp: Command Line Apps Script Projects fossamagna/gas-webpack-plugin: Webpack plugin for Google Apps Script scripts | npm Docs rimraf – npm We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
アバター
はじめに ニフティ株式会社 会員システムグループの深田です。 ニフティではブカツ制度という社内交流の活動支援制度があり、最近会社でも健康志向が高まってきているので、筋トレ部なるものを発足しようかと考えています。 早速ですが、みなさんは Python でマルチスレッド(以下、並行処理)を実装されていますか? Python で並行処理を実装する方法はいくつか挙げられますが、ここでは concurrent.futures モジュールの ThreadPoolExecutor について紹介していきたいと思います。 ThreadPoolExecutorとは ThreadPoolExecutor は Python の concurrent.futures モジュールに含まれるスレッドプールを実装するクラスであり、並行処理を効率化するために使用されます。スレッドプールは、複数のスレッドを作成し、再利用することで、タスクの実行を効率化することができます。 ProcessPoolExecutorとの違い concurrent.futures モジュールには Executor のサブクラスとして ThreadPoolExecutor の他に、もう一つ ProcessPoolExecutor というクラスが存在ます。 ProcessPoolExecutor はプロセスを利用して並列処理(マルチプロセス)を行うため、複数のプロセスを実行します。主にCPU負荷の高いタスクに適しています。 一方、ThreadPoolExecutor はスレッドを利用して並行処理(マルチスレッド)を行うため、同一のプロセス内で複数のスレッドを実行します。メモリ使用量も比較的少ないため、I/OバウンドのタスクやCPU負荷の低いタスクなど、主にI/O待ちの時間が長いタスクに適しています。 Pythonでの並列処理・並行処理 Pythonで並列処理や並行処理を実装したい場合、主に以下が挙げられます。 threadingモジュール multiprocessingモジュール concurrent.futuresモジュール asyncioモジュール サードパーティのライブラリ 今回は「3. concurrent.futuresモジュール」のクラスである ThreadPoolExecutor について解説しますが、特徴の1つとして「1. threadingモジュール」をベースにしているという点にあります。concurrent.futures モジュールは threading モジュールを抽象化して提供し、スレッドやプロセスの選択を自動的に行っています。 したがって、concurrent.futures モジュールを使用することで、パフォーマンスやリソース利用の効率化を図った並列処理・並行処理を実現することができます。 しかし、場合によっては直接 threading モジュールを使用することもあるので、どちらを選ぶかは具体的な要件次第になります。 ThreadPoolExecutorの基本的な使い方 ThreadPoolExecutor を使用するには、まず concurrent.futures モジュールをインポートします。次に、ThreadPoolExecutor クラスのインスタンスを作成し、引数にスレッド数を指定します。スレッド数は、同時に実行されるスレッドの最大数を表します。 from concurrent.futures import ThreadPoolExecutor # スレッド数を指定してThreadPoolExecutorのインスタンスを作成 with ThreadPoolExecutor(max_workers=5) as executor: # タスクを実行する関数をsubmitメソッドでスレッドプールに登録 future = executor.submit(my_function, arg1, arg2, ...) submit   メソッドには、実行したいタスクを関数として渡し、必要に応じて引数を指定することができます。 submit   メソッドが実行されると、 my_function   メソッド内の実行を待たずに次の行に進み、非同期に処理が進行します。 コールバック関数を使用した結果の取得 submit   メソッドは、concurrent.futures.Future オブジェクトを返します。このオブジェクトを使用して、タスクの実行結果を取得したり、タスクの完了を待ったりすることができます。 from concurrent.futures import ThreadPoolExecutor # スレッド数を指定してThreadPoolExecutorのインスタンスを作成 with ThreadPoolExecutor(max_workers=5) as executor: # タスクを実行する関数をsubmitメソッドでスレッドプールに登録 future = executor.submit(my_function, arg1, arg2, ...) # コールバック関数を使用して結果を取得 future.add_done_callback(my_callback_function) def my_callback_function(future): result = future.result() # タスクの実行結果を取得 add_done_callback   メソッドを使用して、コールバック関数を登録することができます。コールバック関数は、タスクの実行が完了した際に自動的に呼び出され、タスクの結果を受け取ることができます。 例外のハンドリング ThreadPoolExecutor を使用して並行処理を行う際には、例外のハンドリングに注意が必要です。タスクの実行中に例外が発生した場合には、その例外を処理する必要があります。ThreadPoolExecutor では、各タスクの実行結果を保持する Future オブジェクトに例外が発生した場合には、その例外を含んだ状態で完了します。これを受け取るためには、 add_done_callback   メソッドで登録したコールバック関数の中で、Future オブジェクトの result   メソッドを呼び出すことで、例外を取得することができます。 from concurrent.futures import ThreadPoolExecutor # スレッド数を指定してThreadPoolExecutorのインスタンスを作成 with ThreadPoolExecutor(max_workers=5) as executor: # タスクを実行する関数をsubmitメソッドでスレッドプールに登録 future = executor.submit(my_function, arg1, arg2, ...) # コールバック関数を使用して結果を取得 future.add_done_callback(my_callback_function) # コールバック関数の中で例外をハンドリング def my_callback_function(future): try: result = future.result() # タスクの実行結果を取得 # タスクの結果を処理 except Exception as e: # 例外をハンドリング print(f"例外が発生しました: {e}") 実践的な使い方 先ほど紹介した add_done_callback   メソッドで完了した並行タスクを検知することができますが、 as_completed   メソッドでも並行タスクの完了を検知することができます。 as_completed   は、複数のタスクが同時に実行されている場合に、完了したタスクのイテレータを返します。つまり、各タスクが完了したときに取得できるため、コールバック関数を設定する必要がありません。 以下はHTTPリクエストを伴う大量の短時間タスクのバッチ処理を想定したサンプルコードです。 import urllib.request from concurrent.futures import ThreadPoolExecutor, as_completed # タスクを実行する関数(例として、指定したミリ秒数応答が返ってこないHTTPリクエスト) def long_task(milli_second: int) -> tuple[str, int]: with urllib.request.urlopen(f"https://httpstat.us/200?sleep={milli_second}") as response: body = response.read().decode() return body, milli_second # ThreadPoolExecutorを作成 executor = ThreadPoolExecutor() # タスクをリストに格納 tasks = [6000, 2000, 7000, 13000] # タスクを並行して実行 futures = [] for task in tasks: future = executor.submit(long_task, milli_second=task) futures.append(future) # 結果をas_completedメソッドで反復処理 for future in as_completed(futures): # タスクの完了を検出したら結果を取得 result = future.result() print(f"Task completed: {result}") # 出力例: # Task completed: ('200 OK', 2000) # Task completed: ('200 OK', 6000) # Task completed: ('200 OK', 7000) # Task completed: ('200 OK', 13000) add_done_callback   は、個々のタスクごとに結果を処理するために使用され、 as_completed   は、複数のタスクを並行で実行し、それぞれのタスクが完了したときに結果を取得するために使用されます。 要件によって使い分けましょう。 スレッドプールの最適なスレッド数の設定 ThreadPoolExecutor の引数である max_workers   には、スレッドプール内のスレッド数を指定します。この値の設定には注意が必要であり、適切な値を選ぶことが性能の向上に繋がります。スレッド数を多くしすぎると、スレッドの切り替えや同期によるオーバーヘッドが増え、逆にパフォーマンスが低下する可能性があります。一方、スレッド数を少なくしすぎると、スレッドプールが効果的に利用されず、処理能力が十分に引き出されない可能性があります。 最適なスレッド数は、実行するタスクの性質や環境によって異なります。I/Oバウンドなタスクの場合には、より多くのスレッド数を許容することができます。ただし、前述したようにスレッド数を無制限に増やすと、オーバーヘッドが発生する場合があります。リソースの制約やタスクの性質に応じて、適切なスレッド数を見極める必要があります。実際のシナリオでのベンチマークなどを通じて最適なスレッド数を見つけることが重要です。 まとめ ThreadPoolExecutor は、Python の concurrent.futures モジュールを使用して、スレッドプールを作成するための便利なクラスです。スレッドプールを使用することで、複数のタスクを並行して実行し、処理を効率化することができます。 ニフティではメールアカウントの作成をはじめとした、メールに関わる多種多様な設定変更をこの技術を用いて日々大量に処理しています。 ぜひ、必要な場面で活用していきましょう! 参考記事 https://docs.python.org/ja/3/library/concurrent.futures.html#module-concurrent.futures We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
アバター
はじめに 基幹システムグループの大里です。 新年度になってもう2か月になりました。新年度になってから部署替えやチーム編成の変更も生じるかと思います。 私の所属するチームは去年の6月に他のサービスを担当していた2人とチームが合併して3人チームになりました。このチーム編成の変更の際にまず立ち向かわないとならない問題として、自分が担当しているシステムを他のメンバーに理解してもらわなければならない問題が生じました。その際にシステムのコードを理解してもらう方法としてモブプロを選び実施しましたが、その時に工夫したことや所感などを記載します。 チームで実施したモブプロのルール モブプロの基本ルール チーム内でナビゲーターとドライバーで役割を分担する ナビゲーター:ドライバーに対しどのコードを見て、どのようなコードを入力するかを指示する ドライバー:ナビゲーターの指示を聞いてタイピングや画面切り替えを実施する それに加えてコーディング中に疑問があったら質問・回答を行う チームの独特なルール モブプロを実施する前に修正箇所の処理の流れをチーム全員で検討・共有する システムを理解している人は基本的にナビゲーターとして固定する 使用したツール Visual Studio Code チーム共有で使っているエディター Visual Studio Live Share リアルタイムで共同開発できるVisual Studio Codeの拡張機能、ドライバーの修正内容の共有に使用 Meet ビデオ会議ツール、音声を共有するためやVisual Studio Live Shareの画面共有に慣れるまでの画面共有に使用 draw.io 作図ツール、コード処理の共有や検討に使用 工夫したこと オンボーディング資料の準備 システムを理解してもらうためのモブプロの前にチームメンバーにはオンボーディング資料を読んでもらって、以下のような知識を共通認識として持ってもらうようにしました。 担当システムでどういうサービスを実現しているのか 担当システムにはどういったバッチやAPIがあるのか モブプロを始める前にコード内容は分からない状態であっても、担当システムの概要を理解してもらうようにしました。 設計書の記述もモブで実施する 設計書の記述もモブで実施することで、コードが分からない状態でも修正するコードのフローを議論できる状態にしました。修正するコードのフローを議論する際に、全体的なフローを設計書ベースで理解してもらえるように工夫しました。事前に設計を共有することによってコード記述をするモブプロをした時に、チームメンバーはコードの全体像を早く理解できるようにしました。 ナビゲーターはコードの記述するときの思考を言語化する ナビゲーターとしてコードを記述する際に考えることを一から言語化して伝えることで、実際に修正するコードだけではなくその周辺のコードや基本的な処理を漏れなく見せることを意識しました。チームの背景としてチームメンバーはシステムで使用しているフレームワークを触ったことがありませんでした。モブプロを通してチームメンバーが一人でコードを読めるようになるため、チームメンバーにとって初めて触れるフレームワークの処理の流れを説明する必要がありました。モブプロ中はコード修正をするときに最初に実施するであろう修正するコードを探すところから思考を言語化することに努めました。 良かったこと チーム全員で設計の検討ができた 設計書の記述からモブプロをすることによって、チーム全員で修正箇所のフローを検討できました。今回のチーム編成の変更では、幸運にも別のシステムの開発担当者と同じチームになりました。そのため、モブプロによって設計の議論を設計書ベースで考えることができるようになることで、コードを見たことがない開発者の知見を設計に生かすことができました。 副次的な効果として、設計に関してはチーム全員で責任が持てるようになったことが良かったです。このチーム編成の変更で担当システムの有識者が自分だけのような状態になり、自分の責任を重く感じてました。しかし、設計つまりコード修正の基本指針はチーム全員で合意が取れたことで、自分の気が軽くなりました。 実装力の強化 設計書さえあれば簡単な機能追加は各々1人で実装できるようになりました。これの要因の一つとして、モブプロ前にオンボーディング資料や設計書をチームメンバー全員が読み通すことで、モブプロ中は設計書をどのようにコードに落とし込むかの説明に集中できたためだと考えています。フレームワークの細かい仕様の理解ができていなくても設計書からコードへの落とし込み方を理解すれば、どのようにコードを記述すればよいかのヒントを各々で探すことが可能になりました。 反省点 疲労する これにつきます。 システムに慣れないドライバーの負担が大きい 今回のチームでは3人構成であったため、1人がナビゲーターとして固定されてしまい、他の2人がドライバーとなりました。さらに、ナビゲーターは見慣れたコードの修正を口頭で説明するだけで、ドライバーであるチームメンバーにとっては内部を見たことがないシステムの説明を聞きながら読み続けることになります。ナビゲーターとドライバーで負担が異なることになるため、意識して休憩を取らないと集中するのが難しいと分かりました。 モブプロの時間が長くなってしまう この工夫は設計のタイミングからモブプロを実施するため、時間が長くなってしまいます。上に述べたようにこの方法はシステムに慣れていないメンバーの負担が大きいことが分かったため、設計とコード修正で日を分けるなどの工夫が必要だと感じています。 終わりに システム理解を最優先の目的としてモブプロを実施したため、本来のモブプロの方法とは少し外れたルールで実施することになりました。次は開発速度を上げることやチームメンバーがコードに慣れるために、モブプロの本来の方法で実施できるように修正が必要だと考えています。 We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
アバター
基幹システムグループ N1! オートメーションスペシャリストの南川です。 今回は、自動ワークフロー作成サービスである Zapier を使った Google フォーム (Google Forms) と Notion データベースの連携について紹介します。 こちらの記事は、 NIFTY Tech Talk #10「 Notion で仕事のスピードを加速するテクニックとは?」 にて発表した内容がベースとなっており、その時の スライド も公開しているので、興味のある方は確認してみてください! 背景 Notion にはデータベースというアイテム(ページ)を管理する機能があり、その機能を使ってタスク管理をしているとします。データベースのプロパティにはタスクのタイトル、「Todo」「In progress」「Done」といったステータス、担当者、依頼者があります。 また、データベースには様々なビューがあり、ボードビューを使うと、タスクの進捗状況が分かりやすくなります。 そして、担当しているシステムに関する依頼は Google フォームで受け付けており、 Google フォームの申請内容をもとに手動で Notion のデータベースにアイテムを追加しています。しかし、手動でのデータベースへの追加は面倒だと思います。 「ならば、 Google フォームではなく、 Notion のデータベースに依頼者が直接追加すればいいのでは?」という話も出てくるかと思いますが、以下の理由から Google フォームを依頼の申請フォームとして使いたいです。 データベースのロック機能があるとはいえ、依頼者が誤ってアイテムを消してしまう可能性がある。 Google フォームだと、必ず記入してほしい必須項目の指定や、各項目の説明の記述などができて自由度が高い。 このような背景から、 Google フォームに送信された依頼の内容をもとに、 Notion のデータベースにアイテムを自動的に追加したい というわけです。ここで登場するのが Zapier というサービスです。 Zapier とは Zapier は複数のサービスやアプリを連携する自動ワークフローを、ノーコードで作れるサービスです。 対応しているサービス・アプリは5000個以上で、Gmail や Google スプレッドシート、 Google ドライブ、 Google フォームといった Google 製品はもちろんのこと、 Notion や Slack 、 GitHub などにも対応しています。対応サービスの一覧は https://zapier.com/apps から確認できます。 これらの対応しているアプリを互いに連携させ、以下のようなワークフローを作ることができます。 検索にマッチしたメールを受信したら、 Slack にメッセージを送信する。 Notion のデータベースに新しいアイテムが追加されたら、 Google スプレッドシートに行を追加する。 Zapier の用語 ここで Zapier に出てくる用語の一部を簡単に説明します。 今回紹介しない用語や詳しい説明については、以下のURLをご確認ください。 https://help.zapier.com/hc/en-us/articles/8496181725453 Zap Zap とは、アプリやサービスを連携させる自動化されたワークフローです。 Zap は Trigger と1つ以上の Action で構成されます。この Zap を On にすると、 Trigger のイベントが発生するたびに、 Action が実行されます。 Zap の例としては、先ほどの Zapier で作れるワークフローの例で挙げた「検索にマッチしたメールを受信したら、 Slack にメッセージを送信する。」や「 Notion のデータベースに新しいアイテムが追加されたら、 Google スプレッドシートに行を追加する。」が挙げられます。 Trigger Trigger とは、 Zap を開始するためのイベントです。 Trigger は、先ほどのワークフロー (Zap) の例における、「検索にマッチするメールを受信したら」や「 Notion の DB に新しいアイテムが追加されたら」に該当します。 Action Action とは、 Trigger が発動した後に Zap が実行するイベントです。 Action は、先ほどのワークフロー (Zap) の例における、「 Slack にメッセージを送信する」や「 Google スプレッドシートに新しい行を追加する」に該当します。 やりたいことを Zapier に落とし込む ここで、今回やりたいことについて振り返ってみます。今回は「 Google フォームに送信された依頼の内容をもとに、 Notion のデータベースにアイテムを自動的に追加する 」ということをやりたいです。これを Zapier に落とし込んでみると次のようになります。 以下の Zap を作成する。 Trigger : 「 Google フォームから回答が送信されたら」 Action : 「 Notion のデータベースにアイテムを追加する」 実際に作ってみる (1) 事前準備 Zap を作る前に、 Zap で連携する Google フォーム、 Notion のデータベースを作ります。 まず、「依頼デモ」という名前の Google フォームから送信された依頼を管理するための Notion のデータベースを作成します。このデータベースは、タイトル、ステータス、依頼者のプロパティを持っており、ステータスにはこの依頼の進捗状況として「Todo」「In progress」「Done」が値として入ります。先ほどのデータベースには担当者のプロパティを用意していましたが、今回は簡単にするためにプロパティをこの3つのみにします。 次に依頼を送信するための Google フォームを作成します。質問の内容は「依頼者の名前」「依頼の件名」「依頼の内容」となっています。 そして、 Zap を作るにあたり、 Google フォームで送信したダミーの回答が必要になってくるので、作成した Google フォームで以下のように適当な回答を記入して送信します。今回作る Zap では、左の Google フォームの回答を送信すると、右の Notion のデータベースのアイテムを自動作成することを目標とします。依頼者の名前がアイテムの依頼者プロパティ、依頼の件名がアイテムのタイトル、依頼の内容がアイテムの本文に対応しています。 (2) Zapier へのアクセス 事前準備が終わったので、本題の Zap 作成に移ります。 まず、 Zapier にログインし、左上の「Create Zap」ボタンを押します。この前に Zapier のアカウント作成などがあるかと思いますが、今回は省略します。 (3) Zap の名前を変更 「Create Zap」ボタンを押すと、 Zap の編集画面に遷移します。この画面の左上から、必要に応じてZapの名前を変更します。今回は「Google Form x Notion Demo」という名前にしました。 (4) Triggerの作成 次に、 Zap を開始するためのイベントである Trigger の作成をします。今回は「 Google フォームから回答が送信されたら」という Trigger を作成したいので、検索フィールドに「Google Forms」と入力し、「Google Forms」を選択します。 すると、 Event を選択するドロップダウンメニューが出てくるので、「New Form Response」を指定し、「Continue」ボタンを押します。 次に、 Google Forms account には、この Zap で Google フォームを操作するアカウントを指定します。今回は、黒塗りになっていますが私のアカウントを指定しています。 そして、 Form には、手順(1)で作成した Google フォームを指定し、「Continue」ボタンを押します。 あとは、作成した Trigger のテストをするため、「Test trigger」ボタンを押します。 すると、事前準備で回答した内容が表示されることが確認できるかと思います。確認できたら、「Continue」ボタンを押します。 (5) Action の作成 次に、 Trigger が発動した後に Zap が実行するイベントである Action の作成をします。今回は「Notion のデータベースにアイテムを追加する」という Action を作成したいので、検索フィールドに「Notion」と入力し、 Latest のほうの「Notion」を選択します。 すると、 Event を選択するドロップダウンメニューが出てくるので、「Create Database Item」を指定し、「Continue」ボタンを押します。 次に Notion を操作するアカウントの設定をします。 Notion account では、まず、「Connect a new account」ボタンを押します。 すると、 Notion へのアクセスをリクエストするウィンドウで出てくるので、「ページを選択する」ボタンを押します。 検索欄に手順(1)で作成したデータベース名を入力します。検索結果に候補として出てきたデータベースを選択し、「アクセスを許可する」ボタンを押します。 そして、作成したアカウントを選択し、「Continue」ボタンを押します。 次に、 Database には手順(1)で作成したデータベースを指定します。データベースを指定すると、そのデータベースの各プロパティの入力フィールドが出現します。 この入力フィールドには Trigger の情報(出力結果)を埋め込むことができます。タイトルでは、「Show all options」ボタンを押し、「1. 依頼の件名」を選択します。これにより、新しく追加するアイテムのタイトルは、先ほどの Google フォームの回答の依頼の件名の欄の値になります。 同じ要領で、依頼者のプロパティには「依頼者の名前」、 Content には「依頼の内容」を入力し、 Content Format には「Plain Text」を指定して、「Continue」ボタンを押します。 Content はデータベースのアイテムの本文で、以下の画像の赤枠の部分になります。 そして、作成した Action のテストをします。「Test action」ボタンを押すと、黒塗りが多いですが、 Action の実行結果が表示されます。 ここで、手順(1)で作成した Notion のデータベースを確認すると、先ほどの Google フォームの回答内容をもとに、アイテムが新しく作成されていることが確認できます。 (6) Zap の有効化・動作確認 Zap の編集画面に戻って、右上の「Publish」ボタンを押すと、 Zap が有効化され、トグルが On になります。 最後に Zap の動作確認をしてみます。 Zap を有効化した状態(トグルがOnになっている状態)で、 Google フォームから回答が送信されると、その内容をもとにして Notion のデータベースに新しくアイテムが作成されます。これで、 Google Form の回答内容を Notion DB に自動追加するワークフロー (Zap) の完成です。 まとめ 今回紹介したサービス Zapier を使うことで、 Notion や Google フォーム などの様々なサービスの連携をする自動ワークフローを、先ほどのデモのようにコードを一切書かずに作ることができます。 また、有料プランのみの話になりますが、 Zap は2つ以上の Action を持てるということで、 Action をさらに追加して、データベースにアイテムが追加されたことを Slack のチャンネルに通知することもできたりします。 他のサービスとの Notion の自動化の例については、公式サイトに色々載っているので興味のある方はご覧ください。 https://zapier.com/apps/notion/integrations We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
アバター
はじめに こんにちは!NIFTY Tech Talk運営の碇川(いかりがわ)です! 2023年4月19日(水)に開催した「落ちないシステムの作り方〜NIFTY Tech Talkとニフクラエンジニアミートアップのコラボレーション企画!〜」にて司会進行を務めさせていただきました。 今回のNIFTY Tech Talkは ニフクラエンジニアミートアップ とのコラボレーション企画で開催しました! 業務で扱っているシステムが安定して稼働するための工夫やノウハウを、クラウドサービス「ニフクラ」の提供者である富士通クラウドテクノロジーズ株式会社(以下、FJCT)と、多彩なクラウドサービスを扱って、様々なWebサービスを開発しているニフティ株式会社が「落ちないシステムの作り方」について語っていただきました! イベント概要 「NIFTY Tech Talk」は、ニフティ株式会社の社員が主催する、技術に関するトークイベントです。 このイベントでは、ニフティグループの社員が業務を通じて学んだ知見や経験をLT形式で発信しています。 今回のテーマは「落ちないシステムの作り方」として、業務で扱っているシステムが安定して稼働するための工夫やノウハウを、現場社員がLT形式で紹介していただきました! 今回の登壇内容は以下のようになっています。 落ちないシステムって何?可用性の基本と仮想環境のでの可用性の高め方 「高可用性と高い信頼性を持つシステム」を実現するためにアプリケーションエンジニアができる事って何だろう? 安定稼働するポータルサイトの作り方 月1億PVのニュースサイトを落とさない技術 また、今回のTech Talkのアーカイブ動画をYouTubeにアップロードしております。是非ご覧ください! 内容レポート 各セッションの内容について、紹介していきます! 落ちないシステムって何?可用性の基本と仮想環境のでの可用性の高め方 1つ目のLTは、FJCTの奥山さんです。 ハードウェア的な側面での落ちないシステムの基本的な考え方について語っていただきました。 まずは落ちないシステムを高可用性なシステムと定義し、高可用性なシステムを作るためにはどうしたら良いかわかりやすく説明していただきました。 また、仮想環境における可用性向上の具体的な手法として、VMwareHAについて紹介していただきました。 VMware HAは、仮想化環境において仮想マシンの可用性を高めるための機能です。 仮想マシンが障害を起こした場合に自動的に他のホスト上に仮想マシンを移動させることで、システムの停止を最小限に抑えることができるそうです! 最後に、クラウド環境における可用性の考え方についても触れられていました。 クラウド利用においては、高い可用性を確保するだけでなく、物理機器の故障やメンテナンスに対する注意やSLAの理解、責任の明確化が重要です。 これらのポイントを留意し、リスクを最小限に抑えながらクラウド環境を活用することが重要であると、説明していただきました。 ニフクラでの高可用性を保つための取り組みについても紹介していただきました! 「高可用性と高い信頼性を持つシステム」を実現するためにアプリケーションエンジニアができる事って何だろう? 続いては、同じくFJCTの北條さんです。 FJCTのアプリケーションエンジニアとして、様々な観点で高可用性と高信頼性を実現するためにどうすれば良いか、FJCTでの取り組みとともに話していただきました。 具体的にいくつかピックアップして紹介していきたいと思います! まず、モジュール性と疎結合についてです。 紹介されている通り、疎結合な設計を行うことは、システムの強化に不可欠です。 この設計手法により、システム全体が密結合でなくなり、モジュール間の依存性が低くなるため、変更や修正が容易になり、保守性や拡張性も向上します。 また、FJCTの一部プロジェクトではDDDやクリーンアーキテクチャの考え方を取り入れていることも紹介されました。 続いて、スケーラビリティです。 スケーラビリティは現代のアプリケーション設計において欠かせない要素であると説明していただきました! またFJCTでは、コンテナ環境を前提としたアプリケーション開発を行なっており、容易に水平スケーリングできるような環境が整っているプロジェクトもあるそうです。 一部抜粋して紹介させていただきましたが、それ以外でも様々な観点で、アプリケーションエンジニアとしての高可用性・高信頼性の実現について、FJCTでの取り組みを通じで解説していただきました! 安定稼働するポータルサイトの作り方 続いて、ニフティ株式会社の会員システムグループ第1開発チームでニフティのトップページを開発・運用を担当されている、渡邊さんに登壇していただきました! ユーザーが日常的に利用しており、安定稼働が必須なニフティのトップページを落とさないようにするためにどのような工夫をしているか語っていただきました。 安定稼働するための工夫として最初に挙げていたものは、APIの管理にはTerraform、アプリケーションのデプロイにはServerless Framewortkを採用しているということです。 こういった、IaCツールを使うことでコードでの変更の追跡や、バージョン管理が容易になります。 構文チェックなどの機能がデフォルトで搭載されていることがTerraformの魅力ですね! また、Lambdaを使ったサーバレス構成で動作しているため、サーバー内での作業が不要となり、アプリケーションの開発に専念することが可能になっています! 続いて、ソースコードの管理やデプロイ周りの工夫点です。 pre-commitを用いた構文チェックの自動化や、GitHub Actionsを用いた単体テストやデプロイの自動化など、CI/CDが実現されています。 こうすることで、リリース時のオペミスを防ぐことができ、安全なリリースを行うことができるようになっています! こちらのLTは資料を公開しておりますので、こちらも是非ご覧ください! 月1億PVのニュースサイトを落とさない技術 最後に、ニフティ株式会社の会員システムグループ第2開発チームで、@niftyニュースの開発・運用を担当されている中村さんに登壇していただきました! まず、ニュースサイトの特性について簡単に紹介していただきました。 SEO対策のための頻繁な更新あり、Googleから不定期な大規模な更新があると、そこに合わせた改修が必要となります。 また、瞬間的にPVが跳ね上がることもあり有名人のニュースなどが流れるとアクセスがスパイクしてしまいます。定常的なPV数も一般的なサービスと比較すると大規模となっています。 このような特性の中で、どんな時でも安定したレスポンスを返したい!ということが、目的となっています! 今回は以下のような3つの観点でニュースサイトを落とさないための工夫について話していただきました。 まずは、リリースの自動化です。 ニフティニュースは先ほど紹介したニフティのトップページ同様、リリースフローを自動化しています。 ニフティニュースでは、サーバレス構成ではなく、ECSを使ったコンテナ環境で動作させる構成のため、CodePipelineによるリリースの自動化を行なっています。 また、CodePipelineの機能の一つである、Blue/Greenデプロイによって寸断なく自動でデプロイされます。 続いてはコンテナとクラウド技術についてです。 ニフティニュースでは、ECSを使用しており、オートスケーリングが容易となっています。 この機能により、突発的にPV数が跳ね上がったとしても、開発者が手をいれる必要なくシステムが自動でスケーリングし、安定してサービスを提供することができます! また、一部の機能ではニフティトップページ同様、サーバレスアーキテクチャを採用しております。 そのため、運用の手間をかけることなく高い耐障害性を実現することができます。 最後にCDNの活用についてです。 CDNは、世界中に配置された多数のサーバーからコンテンツを配信し、ユーザーに高速で安定したアクセスを提供することができます。 AWSではAmazon CloudFrontというCDNがあり、ニフティニュースではこちらを利用しています! こういったCDNを活用することにより、キャッシュを利用してコンテンツを近くのサーバーに保存し、ユーザーへ高速で安定した配信が可能となります。 これにより、遅延を軽減し、コンテンツの読み込み時間を短縮することができます。 中村さんの発表は、月1億PVのニュースサイトを落とさないための技術でした! リリースの自動化やコンテナとクラウド技術の活用、CDNの活用など、多角的なアプローチが紹介されていました! これらの取り組みにより、ニフティニュースは高い安定性とパフォーマンスを維持しながら、ユーザーに最適なニュース体験を提供しています。 こちらのLTは資料を公開しておりますので、こちらも是非ご覧ください! まとめ 本記事では、落ちないシステムの作り方の各発表内容を紹介しました! 安定稼働のためには自動化、スケーラビリティ、監視、セキュリティなど多岐にわたる要素が重要であることがわかりました! また、クラウド技術や最新のツールの活用が安定稼働に大きく貢献していることがわかりました! 今回のイベントは、NIFTY Tech Talkとニフクラエンジニアミートアップのコラボ企画で開催させていただきました。 インフラからアプリケーションまでの様々な観点で、システムの安定稼働について考えることができました。 いつもとは異なる開催形式で一味違ったNIFTY Tech Talkでしたが、楽しんでいただけたでしょうか? 今後もコラボイベントをやっていきたいと思います! 次回のTech Talkもお楽しみに! We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
アバター
はじめに 初めまして。 ニフティ株式会社 会員システムグループの川上拓哉です。 今回は、私の所属しているチームでの運用業務を、Webサービス「Zapier」とSlackを用いてChatOps化をしてみた、という記事です。 Zapierとは Zapier とは様々なクラウドサービス、アプリ間をノーコードで連携することができるSaaS です。 クラウドサービスのイベントやスケジュール(Trigger)をもとに、特定の操作(Action)を実行させることができ、煩雑な操作の自動化に一役買うようなサービスとなっています。 設定、編集もGUIで直感的に操作できるため、導入と実装がとても簡単です。 Slackから実行したい操作 今回ChatOps化したい操作・作業は、毎朝実施している作業です。 クラウド上の自社サーバーにあるバッチを、サーバーに入って手動で実行しています。 毎回毎回サーバーに直接入らなければならず、サクッとSlackから実行できると便利そうですね。 Slackから直接サーバーの操作はできませんが、Zapier経由でSlackをトリガーにしたさまざまな操作が可能なので、いくつか組み合わせることで今回のChatOpsの一部を実装できそうです。 構成図 ChatOpsのシステム全体では以下のような構成にしていきます。 運用者がSlackワークフローを実行しSlackに特定のメッセージを投稿すると、Zapier が起動して AWS S3 のバケットにリクエストファイルが置かれます。(今回はこちらの処理について説明します。) サーバー側で定期実行されるシェルスクリプトが、リクエストファイルを検知し、バッチを自動実行してくれます。 今回使う機能 今回は、「指定のSlackチャンネルにメッセージが投稿」されたら「AWS S3の特定バケットにテキストファイル(リクエストファイル)を作成」する機能(Zap)を活用していきます。 ZapはTriggerとActionという要素でで構成されており、今回活用していくZapだと以下のようになります。 Trigger:指定のSlackチャンネルにメッセージが投稿される。 Action:AWS S3の特定バケットにリクエストファイルを作成する。 S3バケットにリクエストファイルを置くことができれば、サーバー上から検知できるので、この機能を活用していきましょう。 (S3の操作は、有料の Professional プラン以上でしか使えない機能となりますのでご承知おきください。) Zapier Tips 実際に編集していきましょう。 最終的には、実行結果をSlackに通知もしたいので、以下のような構成のZapにしました。 Trigger:Slackにメッセージが投稿される。 Action:Slackメッセージに特定のキーワードがあった場合に続行する。 Action:Slackメッセージの投稿時間をフォーマットして抽出する。 Action:AWS S3バケットに、名前に投稿日付を含めたリクエストファイルを作成する。 Action:実行結果をSlackに通知する。 ここからは、今回のZap実装に活用した、いくつかの便利な機能やActionを紹介したいと思います。 チャンネル一覧に出てこないSlackチャンネルを指定したい Slackのチャンネルをチャンネル名で検索してもでてこないことがあります。そんなときは「SlackチャンネルをIDで指定」しましょう。 SlackチャンネルID の確認方法は割愛いたしますが、ZapierのSlackチャンネル選択画面にて「Custom」を選択しIDを入力することで指定することが可能です。 特定のメッセージが投稿された時のみ処理をしたい チャンネルに投稿されたメッセージ全てで発火してほしくない。そんなときは「キーワードを指定して続行」させましょう。 Zapierの「Filter」の中の「Only continue if…」を使います。 画像のように設定することで、指定したSlackチャンネルに、「指定したい文言」が含まれたメッセージが投稿された時のみ後続の処理を行うことができます。 今回は、専用のチャンネルのSlackワークフローから、特定のキーワードを含んだメッセージを投稿するよう実装しました。 日時のフォーマットやタイムゾーンを変更したい 今回、ChatOps実行時の日時を取得してリクエストファイルの名前に含めることにしました。 Slackに投稿されたメッセージから時間が取得したいときは、「Format」の「Date / Time」を活用しましょう 実は、Slackメッセージから取得できる時間はUTCになっており、今回は日本時間(東京タイムゾーン)での実行開始時間が欲しいので少し工夫が必要でした。 Zapierの「Format」の「Date / Time」では、タイムゾーンを変更して出力できるだけでなく、出力フォーマットを指定できます。 出力形式についてはテンプレートもいくつか用意されています。 「YYYYMMDD」のように自由に指定もできます。 以下画像のように、フォーマットを指定した出力ができました。(タイムゾーンの修正もうまくいきました。) 後続の処理でも出力結果が利用できます。 無事ChatOps化できました! 今回作成したZapを使い、SlackからリクエストファイルをS3に作成することができました。加えてサーバーからシェルスクリプトでリクエストファイルを検知することでChatOpsを実装することができました。 ZapierにはSlack、S3の他にも連携サービスがたくさんあるので、みなさんもZapierを活用してみてください。 We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
アバター
イベント概要 NIFTY Tech Talkは、ニフティ株式会社の社員が主催するトークイベントです。 本イベントでは、ニフティグループの社員が業務を通じて学んだことを発信しています! 第11回目のテーマは「新人エンジニアに贈る最強の開発環境」です。 ニフティのエンジニアが、働き始めた新人エンジニアに開発環境を紹介する回となります。 概要 日程:5月30日(火)12:00〜13:00 配信方法:YouTube Live 視聴環境:インターネット接続が可能なPC/スマートフォン 参加方法 connpass にて登録をお願いいたします。 ※YouTube Liveにて配信いたします。 ※YouTube LiveのURLは決定後、参加者への情報欄に記載いたします。 こんな方におすすめ 新人エンジニアの方 Python開発環境に興味がある方 ターミナル・シェル開発環境に興味がある方 Webアプリ開発環境に興味がある方 ニフティが業務で使っているサービスに興味がある方 タイムテーブル コンテンツ 12:00 – 12:05 オープニング+会社紹介 12:05 – 12:20 LT1: Python開発環境 ( 個人的Python開発環境構築 ) 12:20 – 12:35 LT2: ターミナル・シェルを最強にする話をすると思います 12:35 – 12:50 LT3: StrongestNewsによる最強の自作WEBアプリ開発環境 12:50 – 13:00 まとめ+クロージング テーマ 新人エンジニアに贈る「最強の開発環境」 登壇者プロフィール 小倉 聡司(登壇者) ニフティ株式会社 基幹システムグループ 課金システムチーム 新卒入社3年目 書面発送システム他、入会系、課金請求系システム等の開発・運用を担当 上原 直希(登壇者) ニフティ株式会社 会員システムグループ 第2開発チーム 新卒入社3年目 ニフティニュースの開発・運用を担当、Rustオープン社内勉強会を主催 最強の開発環境を追い求めて、週末はdotfilesを育てている 中村 伊吹(登壇者 / ファシリテーター) ニフティ株式会社 会員システムグループ第2開発チーム 新卒入社5年目 ニフティニュースの開発リーダーを担当し、最近はモダンなフロントエンド開発を学習中。 男女混成チアリーディング元日本代表。 ニフティグループでは一緒に働く仲間を募集中です 新卒採用、キャリア採用を実施しています。ぜひ リクルートサイト をご覧ください。 ニフティエンジニアが業務で学んだことやイベント情報を エンジニアブログ にて発信しています! ニフティエンジニアのTwitterアカウントを作りました NIFTY Tech Talkのことや、ニフティのエンジニアの活動を発信していきます。 Tweets by NIFTYDevelopers 「NIFTY Tech Day 2022」を開催しました 技術イベント「NIFTY Tech Day 2022」のアーカイブはこちら  NIFTY Tech Day 2022 アンチハラスメントポリシー 私たちは下記のような事柄に関わらずすべての参加者にとって安全で歓迎されるような場を作ることに努めます。 社会的あるいは法的な性、性自認、性表現(外見の性)、性指向 年齢、障がい、容姿、体格 人種、民族、宗教(無宗教を含む) 技術の選択 そして下記のようなハラスメント行為をいかなる形であっても決して許容しません。 不適切な画像、動画、録音の再生(性的な画像など) 発表や他のイベントに対する妨害行為 これらに限らない性的嫌がらせ 登壇者、主催スタッフもこのポリシーの対象となります。 ハラスメント行為をやめるように指示された場合、直ちに従うことが求められます。ルールを守らない参加者は、主催者の判断により、退場処分や今後のイベントに聴講者、登壇者、スタッフとして関わることを禁止します。 もしハラスメントを受けていると感じたり、他の誰かがハラスメントされていることに気がついた場合、または他に何かお困りのことがあれば、すぐにご連絡ください。 ※本文章は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/ ) で公開されています。
アバター
はじめに こんにちは、ニフティ株式会社 基幹システムグループの小倉です。今回は、業務で扱うことの多いPython開発環境に対して、個人的に快適でモダンな開発環境を考えてみたので、共有しようと思います。 使用するツールについて Visual Studio Code 今回使用するエディタになります。 Docker コンテナ技術を提供するツールです。 Poetry PoetryはPythonパッケージマネージャの1つです。普段の開発ではpipenvを用いることが多いですが、Poetryでは依存解決を高速に行える点と他のパッケージの設定ファイルをまとめて管理できるメリットがあるため今回は使用してみました。 Ruff Ruffは、Rustで記述されたPython用Linterです。Rustを使用しているだけあって処理速度は既存のLinterライブラリの中で最速です。また、スター数も伸びていて、AWS SAMやFastAPI等の有名なオープンソースプロジェクトでも使用されています。 Black BlackはPEP8に準拠したFormatterライブラリです。autopep8やyapfなどの他のFormatterより制限が厳しく、個人で自由に設定できる項目が少ないです。このため、フォーマットに関して、チーム内でルールを決める時間を省けます。 Mypy MypyはPythonの静的型チェックを実行するライブラリです。mypyを用いることで、型ヒント不足や型の矛盾の検知が可能になり、コードの可読性向上や堅牢性向上に繋がります。 Pytest Pythonの単体テストでよく使われているライブラリです。 Poethepoet Poetryと相性の良いタスクランナーです。PoetryにはPipenvのScriptのようなタスクランナー機能がないので、Poethepoetを使って実現しています。 事前準備 Visual Studio Code(以下VSCode)、Dockerのインストール VSCode拡張機能のDev Containersのインストール 環境構築 開発環境としては、Dockerを用いたPythonコンテナ環境を構築し、VSCode拡張機能のDev ContainerのRemote先に今回のコンテナ環境を指定します。このように、Dev Containerを経由することで、コンテナ環境下でもローカル環境と同様にVSCodeの便利な拡張機能を使用した開発が可能になります。 作業ディレクトリ構成 作業ディレクトリは以下のようになっています。 . |____app | |____Dockerfile | |____pyproject.toml | |____tests | | |______init__.py | | |____test_main.py | |______init__.py | |____.gitignore | |____main.py |____.devcontainer | |____devcontainer.json |____compose.yaml Dockerfile まず、ベースとなるPythonコンテナ環境を作成するため、以下のようにDockerfileを記述します。 FROM python:3.11-slim WORKDIR /app RUN apt update -y && \ apt install -y curl ENV POETRY_HOME /etc/poetry RUN curl -sSL https://install.python-poetry.org | POETRY_HOME=$POETRY_HOME python3 - ENV PATH="$POETRY_HOME/bin:$PATH" ENV PYTHONPATH /app COPY ./app /app RUN poetry config virtualenvs.create false && \ poetry install compose.yaml compose.yamlに関しては以下のように記述しています。 services: app: container_name: "python-dev" build: context: . dockerfile: app/Dockerfile working_dir: /app volumes: - ./app:/app tty: true pyproject.toml pyproject.tomlではpoetryによる開発環境用と本番環境用のライブラリの記述以外にも、今回使用するRuff、Black、Mypy、Pytest、Poethepoetの設定もまとめて管理します。 [tool.poetry] name = "python-dev-demo" version = "0.1.0" description = "python dev-container env" authors = ["Your Name <you@example.com>"] readme = "README.md" [tool.poetry.dependencies] python = "^3.11" pydantic = "^1.10.4" [tool.poetry.group.dev.dependencies] mypy = "^0.991" ruff = "^0.0.237" black = "^22.12.0" pytest = "^7.2.1" pytest-cov = "^4.0.0" poethepoet = "^0.18.1" [tool.mypy] warn_return_any = true warn_unused_configs = true disallow_untyped_defs = true strict = true [tool.ruff] select = [ # pyflakes "F", # pycodestyle errors, warnings "E", "W", # isort # "I", # flake8-2020 "YTT", # flake8-bugbear "B", ] target-version = "py311" line-length = 120 [tool.black] line-length = 120 target-version = ["py311"] [tool.pytest.ini_options] testpaths = [ "tests", ] [tool.poe.tasks.pytest] shell = "pytest -v --cov=. --cov-branch" interpreter = "bash" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" Poetry 環境ごとにライブラリの依存関係を分離するためには tool.poetry.group.<group> を使用します。 Mypy strict = true にすることでmypyのオプションのエラーチェックフラグをすべて有効にし、厳重な型チェックが可能になります。ただし、いくつかのオプションはstrict モードでも無効になっています。無効になっているフラグに関しては、  mypy --help  の出力で確認することができます。 Ruff Ruffでは、現時点で500を超えるlint ルールをサポートしており、 select に追加したいルールに紐づくコード名を記述するで有効にすることができます。デフォルトでは Pyflakes(F) と pycodestyle (E)が有効になっています。 Black 基本的な設定としては、 line-length によって1行の文字数制限を変更できます。 Pytest testpaths でテストディレクトリの設定しています。 今回はついでにカバレッジを取得するPytest-covもInstallしています。 Poethepoet 基本的な使い方としては、今回のpyproject.tomlで定義しているように [tool.poe.tasks.<task_name>] で設定し、 poe <task_name> で実行できます。 今回の例では、 pytest -v --cov=. --cov-branch コマンドでpytestのテスト結果とカバレッジを毎回叩くのが面倒なので、 poe pytest で実行できるようにしています。 devcontainer.json devcontainerの設定にはdevcontainer.jsonを使用します。 今回の用途ではまず、compose.yamlの場所、compose.yamlで定義するservice名とワークディレクトリを指定しています。 devcontainer環境で使用したいVScode拡張機能を extensions 、その拡張機能の詳細設定を settings で定義します。 今回は拡張機能として、Python拡張機能とruffの拡張機能を入れています。 拡張機能の詳細設定としては、デフォルト設定の不要な機能無効化、それぞれのライブラリのインタープリタパスとpyproject.tomlで定義したライブラリの設定を拡張機能側に反映させています。 { "name": "Python-dev Template", "dockerComposeFile": ["../compose.yaml"], "service": "app", "workspaceFolder": "/app", "customizations": { "vscode": { "extensions": [ "ms-python.python", "charliermarsh.ruff" ], "settings": { "editor.formatOnSave": true, "[python]": { "editor.codeActionsOnSave": { "source.fixAll": true, } }, "python.defaultInterpreterPath": "/usr/local/bin/python", // "python.formatting.provider": "none", "python.formatting.provider": "black", "python.formatting.blackPath": "/usr/local/bin/black", "python.formatting.blackArgs": ["--config=${containerWorkspaceFolder}/pyproject.toml"], "python.linting.mypyPath": "/usr/local/bin/mypy", "python.linting.mypyArgs": ["--config=${containerWorkspaceFolder}/pyproject.toml"], "python.linting.mypyEnabled": true, "python.linting.enabled": true, "python.testing.pytestPath": "/usr/local/bin/pytest", "python.testing.pytest": ["--config=${containerWorkspaceFolder}/pyproject.toml"], "python.testing.unittestEnabled": false, "python.testing.pytestEnabled": true, "ruff.args": ["--config=${containerWorkspaceFolder}/pyproject.toml"], "ruff.path": ["/usr/local/bin/ruff"], "ruff.interpreter": ["/usr/local/bin/python"] } } } } 動作確認 以上の設定が完了したら、コマンドパレッド(command + option + P)を開き、 Reopen in Container を実行することで、以下の画像のようにdevcontainer環境に入れます。 Dev Container環境に入ると以下のような機能が利用できるようになっています。 それぞれのライブラリのルールに違反したコードに波線ハイライト e ditor.formatOnSave によってBlackによる保存の際に自動フォーマット Pythonコード内で保存した際にruffによる自動修正 Pytestの機能として、画面左側のフラスコマークをクリックすることでテスト対象のディレクトリ、ファイル名、テスト名が表示されデバッグやテストがGUIから実行可能 おわりに ここまで、Dev Containerを使ってPythonのDocker開発環境を構築しました。 今回は必要最低限の設定しかしていないので、このコードを参考に独自にカスタマイズしていただければ幸いです。 We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
アバター
イベント概要 NIFTY Tech Talkは、ニフティ株式会社の社員が主催するトークイベントです。 本イベントでは、ニフティグループの社員が業務を通じて学んだことを発信しています! 第10回目のテーマは「【エンジニア必見】Notionで仕事のスピードを加速するテクニックとは?」です。 ニフティのエンジニアがNotionを使ってどのように開発を進めているか、今すぐ真似できる事例、テクニックを交えつつLT形式で発表します。 概要 日程:4月27日(木)12:00〜13:00 配信方法:YouTube Live 視聴環境:インターネット接続が可能なPC/スマートフォン 参加方法 connpass にて登録をお願いいたします。 ※YouTube Liveにて配信いたします。 ※YouTube LiveのURLは決定後、参加者への情報欄に記載いたします。 こんな方におすすめ エンジニアのNotion活用事例、活用術について興味がある方 今すぐ役立つNotionのテクニックを知りたい方 Zapierを使ってNotionを自動連携して効率的に仕事を進めたい方 ニフティが業務で使っているサービスに興味がある方 タイムテーブル 時間 コンテンツ 12:00 – 12:05 オープニング+会社紹介 12:05 – 12:20 【LT/松阪】世界一利便性が高くてかっこいいプロダクトwikiを目指す 12:20 – 12:40 【LT/南川】Zapierを使った Google FormとNotion DBの連携 12:40 – 12:55 【LT/石川】NotionのWiki機能を使ったページ管理を考えてみる 12:55 – 13:00 まとめ+クロージング テーマ 【エンジニア必見】Notionで仕事のスピードを加速するテクニックとは? 登壇者プロフィール 石川 貴之(登壇者) AWS/GCPの組織管理、Notion/GitHub等のSaaS管理、自社Webサービス基盤の担当をしています。 松阪 僚子(登壇者) @nifty会員向けスマートフォンアプリ「マイ ニフティ」の開発・運用を担当しています。 快適な開発体験のため、ドキュメント整備に熱意を注いでいます! 南川 大樹(登壇者) 普段はシングルサインオンやユーザーサインアップなどの開発や運用を担当しています。Notionまわりの自動化を模索中。 小浦 由佳(ファシリテーター) ニフティの情シスをやっています。Notion力はまだまだなので、この機会に学びたいです! ニフティグループでは一緒に働く仲間を募集中です 新卒採用、キャリア採用を実施しています。ぜひ リクルートサイト をご覧ください。 ニフティエンジニアが業務で学んだことやイベント情報を エンジニアブログ にて発信しています! ニフティエンジニアのTwitterアカウントを作りました NIFTY Tech Talkのことや、ニフティのエンジニアの活動を発信していきます。 Tweets by NIFTYDevelopers 「NIFTY Tech Day 2022」を開催しました 技術イベント「NIFTY Tech Day 2022」のアーカイブはこちら  NIFTY Tech Day 2022 アンチハラスメントポリシー 私たちは下記のような事柄に関わらずすべての参加者にとって安全で歓迎されるような場を作ることに努めます。 社会的あるいは法的な性、性自認、性表現(外見の性)、性指向 年齢、障がい、容姿、体格 人種、民族、宗教(無宗教を含む) 技術の選択 そして下記のようなハラスメント行為をいかなる形であっても決して許容しません。 不適切な画像、動画、録音の再生(性的な画像など) 発表や他のイベントに対する妨害行為 これらに限らない性的嫌がらせ 登壇者、主催スタッフもこのポリシーの対象となります。 ハラスメント行為をやめるように指示された場合、直ちに従うことが求められます。ルールを守らない参加者は、主催者の判断により、退場処分や今後のイベントに聴講者、登壇者、スタッフとして関わることを禁止します。 もしハラスメントを受けていると感じたり、他の誰かがハラスメントされていることに気がついた場合、または他に何かお困りのことがあれば、すぐにご連絡ください。 ※本文章は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/ ) で公開されています。
アバター
「エンジニアを目指していながら、知らない事ばかりだった」 「炎上という言葉はニフティから生まれた?!」 「ブログブームの火付け役がニフティ?」 「多くの情報関連の法律が整備されるきっかけになっていた事を学びました」 これらは新入社員研修の中で、当社のCIO(最高情報責任者)の講義を聞いた後の新入社員の感想です。 これってIT業界を目指す就活生はほとんど聞いたことが無いのでは……? ……という事で、ネット業界のエンジニア界隈で「生ける伝説」が語る、特別説明会を急遽開催することにしました! 参加はこちらから(24新卒限定)。 https://job.axol.jp/jn/s/nifty_24/entry_5918530314/ マイページからご登録の上、ご予約をお願いいたします。 登壇者:取締役(兼)専務執行役員CIO 前島一就 本セミナーは4月25日限定でのWEB開催です。 創業時から日本のインターネット業界を大きく牽引してきた前島が、ニフティのこれまで、そして将来のIT業界を志す若者に期待することなどをお話します! ぜひご参加下さい! これから面接に参加される方や選考途中の方もぜひ当社への理解を深めるためにご参加ください! エンジニア職志望の方だけでは無く、ビジネス職(※)志望の方の参加も大歓迎です。 (※)カスタマーサポート、企画、営業、コーポレート) 日程(オンライン実施) 4月25日(火)10時~12時 内容 会社説明 役員からの話 質疑応答 若手社員からの業務紹介 選考のご案内 登壇役員の紹介 取締役(兼)執行役員(兼)CIO 前島 一就 パソコン通信「NIFTY-Serve」のサービス開発から運用まで携わる。 現在はCIO(最高情報責任者)としてニフティの技術部門を統括。 <登壇役員掲載記事> 社員インタビュー アマゾン ウェブ サービス (AWS)導入時のインタビュー記事 ニフティへの理解をさらに深める機会となります! ぜひご参加ください! 参加方法 https://job.axol.jp/jn/s/nifty_24/entry_5918530314/ マイナビ2024 マイページからご登録の上、ご予約をお願いいたします。
アバター