はじめに 突然ですが、この記事を読んでいるあなたには 「推し」 はいますか? 愛してやまない人やキャラクター、はたまたツールやプログラミング言語など、何かしら「推し」と呼べる存在がある人は多いのではないかと思います。 筆者にもいわゆる「推し」がいるのですが、ある日こんなことを思いました。 「推しの存在を業務中も感じていたい...!」 そこで今回は、筆者の切な願いを叶えるために、業務に欠かせない存在であるSlackのテーマカラーを、画像ベースで「推し」の概念を感じる色に変える方法を紹介したいと思います。 Slackのテーマカラー まずはSlackのテーマカラーについて仕様を確認します。 Slackでは、環境設定からテーマカラーを変更することが出来ます。 デフォルトで21種類のテーマを選択することが出来ます。 しかし、実はSlackでは自分でカスタムテーマを作成し、好きな色を設定することができます。 (参考: Slack のテーマを変更する | Slack ) それぞれの項目は以下の場所の色に対応しています。 補足 4. アイテムハイライト_ホバー時:サイドバーの項目をマウスオーバーした時に表示される色 6. アクティブアイコン:ユーザがオンラインの時にアイコンにつく印の色 これより、カスタムテーマを作るためには 9色 選ぶ必要があることがわかります。 方法の概要 カスタムテーマに必要な色数がわかったところで方法を紹介していきます。 以下の流れでSlackのテーマカラーを変えていきます。 画像からカラーテーマを抽出する 抽出したカラーをSlackのカラーテーマに割り当てる コントラストを確認しながら微調整する 画像からカラーテーマを抽出する まずは「推し」の画像を用意します。 今回は「いらすとや」さんからお借りしたこちらの画像を使用します。 ゆめかわ天使のイラスト | かわいいフリー素材集 いらすとや 「ゆめかわ天使ちゃん」です。かわいい。 推しの概念を感じる色、それはつまり推しを表現している色に違いありません。 推しの色を知るためには、画像上の色情報(カラーコード)を取得するカラーピッカーツールが便利です。 世の中には多くのカラーピッカーツールがありますが、今回は Adobe Color を使用していきたいと思います。 Adobe Color Adobe Colorを使う理由は以下の通りです。 無料で利用できる 画像に使われている色の数が多くても自動で数色に絞って抽出してくれる 操作が簡単&時短(休憩中にサクッと設定できる) コントラスト比を簡単に調べられる それではさっそくAdobe Colorを用いて色を選んでいきましょう! Adobe Colorで色を抽出する方法 Adobe Colorの 「テーマを抽出」 タブを選ぶとファイルをアップロードする画面になるので、説明の通りに画像を選択します。 すると画像の中でメインとなる5色を選択してくれます。 しかし、よく見るとイラストに使われていない黒(#0D0D0D)が選択されてしまいます。 これは元の画像の背景が透過されていることにより、透明部分が黒として認識されるため発生する事象となります。 このような場合や意図しない色が選択されてしまった場合は、ピッカーをずらして選択しなおすと良いです。 今回は目の色に使われている水色部分を選択しなおしました。 これで5色抽出することが出来ました。 一旦Slackに5色配置して、残りの4色を考えていきましょう。 抽出したカラーをSlackのカラーテーマに割り当てる カラーコードってなに? 各箇所の色はカラーコードで指定することが出来ます。 技術記事っぽくするために カラーコードについて軽く説明させていただきます。 カラーコードとはWebページ上の色指定で使われるコードで、シャープ(#)に続く16進数6桁で表されています。 コンピュータのディスプレイなどの光で色を表現するデバイスは、赤・緑・青の光の三原色を混ぜ合わせる(加法混色する)ことで色を表現します。 赤・緑・青は256段階の強さで光らせることができ、3色の強さの組み合わせで256×256×256=約1600万色を表現することが出来ます。 #の次に続く2桁が赤(R)、中央2桁が緑(G)、末尾が青(B)の強さを表します。 前述の通り、光の三原色がもとになっているので、#000000は黒になり#FFFFFFは白になります。 カラーコードの意味を知っておくと、コードからなんとなく色味がわかるようになります。 カラーコードにおける#の右隣の数値を1桁目にした時、1・3・5桁目がe~fであれば白寄りの色だな~とか、RとGの値が大きくてBが少ない時は黄色っぽい色だな~とかが掴めるようになります。 そんなことを思わなくても、世の中にはカラーコードを入れるとその色を表示してくれるサイトはたくさんあるので安心してください。 実はSlack上でカラーコードを入力しても色を表示してくれます。 さて、カラーコードの意味を踏まえたところで実際に配色していきましょう! 一旦配色してみる まずは画像から色の使われている面積を捉えます。 元にしたキャラの画像を見ると、髪と服のリボンに使われているピンク(#F29BBB)と、天使の輪や髪のリボンに使われている黄色(#F2DAAC)が広い面積に使われていることがわかります。 線の色に使われている薄い紫(#CAC4F2)や目の色に使われている紫(#B48FD9)や水色(#B9E5FF)はアクセントとして使われていることもわかります。 ここでもう一度カラーテーマと画面との対応を見ながら、面積通りに設定していきます。 今回はデフォルトテーマである「オーバージーン」をベースに、 サイドバー背景:ピンク(#F29BBB) トップナビゲーション:黄色(#F2DAAC) テキスト:薄い紫(#CAC4F2) アイテムハイライト_選択時:水色(#B9E5FF) アイテムハイライト_ホバー時:紫(#B48FD9) で配置してみました。(仮置きなのである程度お好みで色配置してもらっても大丈夫です) するとどうでしょう? 文字、読めない......。 いくら推しの色とはいえ、文字が読めず業務に支障をきたしたら本末転倒です。 これはコントラストを全く考えず配色してしまったため起きてしまった事故です。 次はコントラストを考えながら色を配置し、ついでに残りの4色も決めていきましょう。 コントラストを確認しながら微調整する コントラストとは、 「明暗の差」 のことです。 コントラストが高い、つまり明暗の差が大きいと色と色の境界がはっきりします。 なので文字をはっきり見せるには、背景色と文字のコントラストを高めることが必要になります。 コントラスト比は相対輝度を使って求めることが出来ます。 ざっくりと説明すると、黒の輝度を0・白の輝度を1とした時にコントラスト比を知りたい2色の相対的な輝度を求め、その比を計算することで求められます。 ※詳しく知りたい方は「相対輝度」や「Web Content Accessibility Guidelines (WCAG) 2.1」といった言葉で調べてみてください。 今回は計算する手間を省くため、Adobe Colorを利用してコントラスト比を求めてみます。 Adobe Colorのタブから 「アクセシビリティツール」 を選択します。 先ほどのテキストカラーと背景色を設定しコントラスト比を求めると 1.25:1となりました。 参考に、WCAG 2.1という基準では、「文字を見やすく表示するには 最低限コントラスト比が 4.5:1 必要 」という記載があります。 3分の1以下ですね!! ですが、これは誰にでも見やすいWebページを作るための基準なのでSlackで自分で使う分には絶対満たさなければいけない条件ではありません。 体感ですが、 2:1以上であればちゃんと読める と思います。 ※個人差もありますしディスプレイによっても変わります 色のついた四角をクリックするとカラーホイールを使って色を調整することができます。 明度を変えるだけではなく、色味(色相)を変えてもコントラスト比は変わるので色々いじって色を調整します。 個人的にコツは、 カラーホイールとカラーハーモニールール を使うことだと思います。 「これだけは絶対使う!」という色を1つ決めて、タブから 「カラーホイール」 を選び、その色をベースカラーに設定します。 そして、 カラーハーモニールール を変更した時に出てくる色を補助で使うと上手くまとまると思います。 また、カラーホイール上で距離が近い色はまとまりが生まれ、離れている色はアクセントになります。 ※この辺のテクニックは調べるとたくさん出てくると思います。 あとは、サイドバー背景の色は目が疲れないような色(白または黒に近い色が無難)をオススメします。 「テーマの抽出」に戻って、取得しなかった部分の色をピッカーで取得するのも良いと思います! 今回は、カラーハーモニールールの「類似色」を選択して得た色も使い、カスタムテーマを組みました。 完成!! というわけで完成しました! ポイントは 目の色に合わせてアイテム選択時のハイライトとテキストのカラーを合わせた アイテムハイライトのホバー時と選択時の色味を紫に合わせた サイドバー背景とテキストは、髪色のピンクと目の色の紫を調整して配色し、文字を読みやすくした トップナビゲーションに髪色に近いピンクと天使の輪やリボンの黄色を配色 メンションバッジのテキストカラーは白固定なので、メンションバッチの色はコントラスト比の高い色を選んだ という感じですかね! 正解はないので 自分がそこに「推し」の概念を感じられたら正解 です。 カラーテーマの共有 せっかくなので作ったテーマの共有をしてみます。 Slackにカラーコードをカンマ区切りで投稿するだけで、人に共有できるだけでなくそのままテーマを変更することが出来ます。 さらにカラーテーマ設定画面から、今使っているテーマのカラーコードセットをコピーすることも出来ます。便利! ぜひ、作ったテーマを共有してみてください! 今回作成したテーマと普段私が使っているテーマを共有します。 yumekawa-tenshi #FFDFEE,#FFF8D4,#B48FD9,#B1E2FF,#CAC4F2,#916DB5,#FFA1BA,#79CAF2,#FF9CB6,#FFEAAF Blossom Pink #FFE7E3,#89CFF0,#F77D8A,#FFFFFF,#FFC5AD,#F55358,#FFB12E,#DF3232,#EC686C,#FFFFFF オマケ 「とはいえ作るの大変...。」「もっとサクッと作れないの?」「推しなんていないから、キャラクターの画像以外からも良い感じに作れない?」という声もあるかと思うので、他の方法も少し共有させていただきます。 カラーテーマ配布サイトを使う Slack Themes : https://slackthemes.net/#/jellybeans 例えば上記のようなカラーテーマ配布サイトを見て、お気に入りのカラーテーマを見つけるという方法があります。 IDEを模した配色はこのようなサイトで配布されている場合が多いです! ぜひ探してみてください。 写真から色を抽出する Adobe Colorでは色数の多い写真からも色を5色抽出することができます。 お気に入りの風景写真やCDジャケット・衣装の写真などからも、同様の方法でカスタムカラーテーマ作成が出来ます。 Adobe Colorの「探索」機能を使う Adobe Colorには 色を言葉から検索する機能 があります。 ここから自分好みの色を探してから作れば楽にカラーテーマの作成ができると思います! 最後に ここまで読んでいただきありがとうございました! 今回はSlackのカラーテーマに絞って解説しましたが、色の選び方やAdobe Colorといったサービスの使い方は、資料作成に使ったり他のところでも応用できると思います。 働いている時間であっても、少しでも遊び心や楽しい気持ちを感じていただけたら幸いです。 投稿 Slackを「推し」色に染める ~オリジナルカラーテーマの作り方とコツ~ は マイナビエンジニアブログ に最初に表示されました。
はじめに この記事では、AWSの資格であるSAAを取得したもののそこまでAWSを触っていなかったAWS初心者が、業務にそこまで影響がない範囲内でAWSでなんか作ってみようと思い立ち、学習目的半分で試行錯誤した結果触ってみて初めて知った苦労などを記載しています。 AWSを日常的に触っている人にとっては知ってる内容かもしれませんが(もしくは触ったことなくても別に躓かないかもしれない)、AWS初心者でかつ日常的にコードも書かない、データベースの扱いにも全く慣れていない人間としては苦労したポイントがいくつかありました。 「そんなんも知らんのかプークスクス」と笑わずに大目に見てくれると嬉しいです!! 目指したもの Slackのフリープランでも90日前のメッセージを遡れるシステム きっかけ 2022年9月1日からのアップデートで、フリープランだとSlackで共有されたメッセージやファイルは90日経過後に閲覧できなくなりました。 社内のコミュニケーションにメイン使っているエンタープライズプランのものとは別に、アラート発報用のワークスペースをフリープランで契約しており、Slackでの契約プランは変更せずなんとか90日経過後でもメッセージが遡れるようにできないかという思いから作ってみました。 作ったシステムの概要 簡易構成図 大体の仕組み EventBridgeで毎月1回Lambda実行し、Slackに全メッセージを取りに行く Lambdaで取得したメッセージのファイル形式を変換し、S3に保管する Athenaで取得したい要件に合わせてクエリを投げる チャンネル名、日付、etc... 90日経過で消えるので月一じゃなくてもいいのですが、万が一コケた時に気付くのが遅れないよう月一実行にしました。 ※2022年8月のまだプラン内容が変わる前に、下準備として取り急ぎ全メッセージ取得しておきました。90日過ぎたら泣いても笑ってもプラン変更しないとメッセージ取得できませんのでご注意ください。 また、通常ログの保存や検索にはElasticSearchを使うのがベストプラクティスかと思いますが、今回は以下を理由にAthenaを採用しました。 クエリごとの課金となるので比較的コストを抑えられる システムの使用頻度的に、正直そこまでクエリ投げないであろう想定 サーバレスなのでインフラの面倒を見る必要がない クエリできるデータ形式が豊富である 正直に言うとAthenaを良い感じに使ってみたかった(本音) 個人的に苦労した実装に対しての感想 何度でも言いますが、大目に見てください... Athenaでクエリできるファイル形式がなんか思ってたのと違ったんだけど Athenaでクエリできるファイル形式としてcsv、parquet、jsonなどが公式で紹介されています。 AWSユーザーガイド : サポートされる SerDes とデータ形式 今回はSlackの検索結果がJSON形式で簡単に取得できるためJSON形式を選びましたが、 厳密には単なるJSONではない ことにすぐ気付けず、少し悩んでいた時間がありました。 公式ドキュメントには、サポートされるJSON形式について以下のように説明されています。 JSON (JavaScript Object Notation) JSON データでは、各行がデータレコードを表します。 各レコードは属性/値のペアと配列で構成され、それぞれがカンマで区切られます。 つまり、複数レコードの場合は、 [ {"key1": "value1", "key2":"value2"}, {"key1": "value1", "key2":"value2"}, {"key1": "value1", "key2":"value2"} ] ではなく、 {"key1": "value1", "key2":"value2"} {"key1": "value1", "key2":"value2"} {"key1": "value1", "key2":"value2"} としてファイル出力する必要があり、この形式は JSON Lines と言われている書式となります。 つまり、取得したJSON形式のファイルを更にJSON Lines形式へ変換する必要があります。 JSON Lines形式を扱う方法はpandasなどいくつかありますが、今回は jsonlines のライブラリを使って実装しました。 import jsonlines content = [ {"key1": "value1", "key2":"value2"}, {"key1": "value1", "key2":"value2"}, {"key1": "value1", "key2":"value2"} ] path = "/your/path/to/store/file.json" with jsonlines.open(path, mode="w") as writer: writer.write_all(contents) JSON形式と言われると、通常はファイル全体がJSONオブジェクトとして解釈可能である必要と思い込んでいました。 自分としては正しいJSON形式で出力しているにも関わらず、Athenaでクエリが失敗するため、何故…となり、地味に調査に時間がかかったポイントでした。 Athenaを使ったことがある方なら知っていることかもしれませんが、Athena初体験だったので印象に残っています。 S3にファイルをアップロードする際の暗号化の仕方ってマネージメントコンソール使わない時どうすればいいの? S3にファイルをアップロードする際、何らかの暗号化を施すことが多いかと思います。 マネージメントコンソール上で操作する際は画面上で選択すればよさそうですが、API上でどう指定すればいいのか知らなかったため苦労しました。 API上では、呼び出す際に指定する引数に以下のように ExtraArgs 内で指定するとSSE-S3により暗号化され、アップロードできます。 import boto3 bucket_name = "bucket name" object_name = "object name" s3 = boto3.resource("s3") s3.Object(bucket_name, object_name).upload( ExtraArgs={ "ServerSideEncryption": "AES256" } ) ちなみに、ここで AES256 を aws:kms に置き換えると、AWS KMSと連携して別のキーで暗号化できるため、ここは要件によって変えればよさそうだなと思っています。 Athenaのスキーマ作成の手間が思ってたより多くて諦めそうだった AthenaでJSONをクエリするためには、テーブルを作成する必要がありましたが、通常のSQLとスキーマの定義方法が異なります。 特に、 ネストしたJSONをテーブル上で定義する SQLとのデータ型の違い 暗号化・GZIP圧縮した元データの参照方法 は、テーブル作成において何度か詰まって確認したポイントです。 ただでさえデータベース苦手なので、何言ってんだこりゃあ…となりました。 以下は実際に作成したスキーマです。 CREATE DATABASE IF NOT EXISTS your_database LOCATION 's3://your-bucket/'; CREATE EXTERNAL TABLE IF NOT EXISTS `your_database`.`your_table` ( iid string, team string, channel struct< id: string, name: string>, type string, user string, username string, ts timestamp, text string, permalink string ) ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' WITH SERDEPROPERTIES ( 'ignore.malformed.json' = 'FALSE', 'dots.in.keys' = 'FALSE', 'case.insensitive' = 'TRUE', 'mapping' = 'TRUE' ) STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' LOCATION 's3://your-bucket/' TBLPROPERTIES ( 'has_encrypted_data' = 'true', 'classification' = 'json', 'write.compression' = 'GZIP', 'classification' = 'json' ); テーブル定義内の channel のカラムで、このキーはJSON上ではネストしたオブジェクトとして表現されていました。 このようなデータはAthenaでは struct(構造体) と表現されています。 AWSユーザーガイド : Amazon Athena のデータ型 今回は、 channel のオブジェクトの内一部が必要だったため、構造体として以下のように定義しました。 channel struct< id: string, name: string>, また、 timestamp にはJSON上では小数点付きのUNIXエポック時間が格納されていますが、このままでは不便なのでこのカラムには timestamp型 を設定しました。 これにより、日時でクエリしたい場合は、 SELECT * FROM "your_database"."your_table" WHERE ts > timestamp '2022-10-25 00:00:00' のように、日付文字列で直観的に検索が可能となります。 さらに、今回は参照するオブジェクトをSSE-S3による暗号化とGZIP圧縮しています。 そのため、テーブル定義の TBLPROPERTIES セクションにて以下のように指定しました。 TBLPROPERTIES ( 'has_encrypted_data' = 'true', 'classification' = 'json', 'write.compression' = 'GZIP', 'classification' = 'json' ); これで、元データが圧縮かつ暗号化されたデータでもクエリしてくれるようになります。 ちなみにですが、今回はAthena検索時のS3のパーティションは分けずに進めています。 ファイルは月毎に生成される想定なので、クエリを投げる際は全文検索のようになり、パーティション分けても分けなくてもこのシステムの構成上変わりはないです。 しかし、ファイル保存量が多かったり、クエリを投げる際の条件でもっと絞れるようでしたら、パーティションを分けた方が費用面でとてもよいです。 Amazon Athenaの料金 現在はこのシステムを作ったばかりなのでファイル量が多くなく、クエリ回数が少なく済んでいますが、今後のことを考えるとファイル保存方法の仕様を見直したいと思います。 EventBridge「cron式です(大嘘)」 EventBridgeで毎月実行のスケジュール登録する際、普通のcron表記と書き方が違ったのでおや…と思った部分になります。 今回はマネージメントコンソール上でやってたので時間がかかったとかよくわからなかったとかではないのですが、マネージメントコンソールを使わず設定してたら詰まったかもしれないなと思います。 AWSユーザーガイド : ルールのスケジュール式 例えば、毎月6日の7:00に実行する、というのを書こうと思うと 0 7 6 * * となると思いますが、AWSのドキュメントでは以下のように記載されています。 ? (疑問符) ワイルドカードは任意を意味します。 [日] フィールドに 7 と入力し、7 日が何曜日であってもかまわない場合、[曜日] フィールドに ? を入力できます。 さらに、最後尾には年も指定することになります。 今回は下記のようになります。 0 7 6 * ? * 実際の設定画面はこちら↓ マネージメントコンソールに従って設定していくとそこまで時間のかかる躓きポイントではないのですが、気になったのでいろいろ調べてみると下記の記事を見つけました。 記法に注意が必要そうな場面も出てきそう、ということで覚えておこうと思います。 参考 : クラスメソッド AWSでのCron表記でハマったので仕様を確認しておく なんやかんやあってできあがったもの こんな感じのものができました。 例えば、チャンネル名を指定して、指定のチャンネル内で交わされた全メッセージを見てみたいと思います。 見せられる部分が少なくて恐縮ですが…一応当初の想定通り、90日以上前のメッセージも取得できています。やったね! おわりに 今回はAWSの学習目的の元、Slackメッセージを取得しておいていつでもメッセージを見ることができるシステムを作りました。とりあえず動いてはいます。動いてるってすばらしいね。 ここまで書いておいてすごい今更なのですが、メッセージ数によっては有料プランに変更した方が結果的に安く済むかもし楽じゃない?、みたいな見方ももちろんあります!!ただ、今回のことを通じて1つ勉強になったので、良い機会だったなと思います。 まだまだ改修すべき点や設計を見直したい箇所、考慮漏れもありそうですが、とりあえず今動かしている部分で書ける分だけ今回記事にしてみました。 今後勉強すると共に、定期的に見直していきたいです。 今回の体験で、資格取得だけでは知り得ない世界を少し垣間見ることができてとてもよかったです。 お読みいただきありがとうございました。 投稿 普段AWS触ってない人間がLambdaとAthenaでなんか地味に苦労した話 は マイナビエンジニアブログ に最初に表示されました。
はじめに こんにちは。 プロセスデザイン部 コミュニケーションデザイン課です。 ITを通じコミュニケーションを最適化する ことをミッションとして、今年の4月に新しく発足した部署です。社内のコミュニケーションを活性化させることで「 横串の業務改革 」や「 サイロ解消 」を目指しています。 今回は組織の紹介も兼ねて、私たちがどのような活動を行っているのかを書いてみたいと思います。 どんなことをする部署? ITの企画部門 私たちは全社のITを管理する部門の中で、 今後の社内のIT環境を考えることを専門としている企画部門 です。 企業は常に変化し続けていかなければならず、 それに対応して社内のIT環境も変化し続けていく必要がある と考えています。 DX推進PJに参加 マイナビでは、IT部門だけでなく総務や経営企画といった管理部門と、事業部の有識者を集めて全社横断のDX推進PJを発足しています。 DX推進PJでは「横串の業務改革」「データ利活用」など様々なテーマを扱っています。私たちはその中の「 サイロ解消・情報共有 」に関する分科会に参加しています。 コミュニケーションの活性化を目指して サイロ化ってなに? 「サイロ化」という言葉を知っていますか? 組織ごとに業務プロセスやシステムなどが独自に存在し、全体で連携できていない状態のことを指します。 特に、企業で部署同士が縦割り状態になり、部署間の横の連携が取りづらい状態のことを「 組織のサイロ化 」と呼びます。 組織の縦割り状態は、各部署が各々の役割に専念できるというメリットがある一方で、互いが何をしているのかがわからないため、 企業全体でみたときには効率が悪く成長を阻害する 要因ともいわれています。 私たちの部署では、社内のコミュニケーションを活性化させることで、サイロ化を解消することを目指しています。 オープンコミュニケーションが大事 私たちの部署のミッションを達成したとき、マイナビはどのような状態になっているんだろう? 組織が発足したときにみんなで考え、以下のような状態を"目指すべき姿"としました。 組織を横断したコミュニケーションが活発化することで、 今まで共有されていなかったナレッジが共有されたり、新しいコラボレーションがうまれる など、様々な化学反応が起きる状態 そのためには、誰もが見られる場所でコミュニケーションをすること= オープンコミュニケーション が重要になると考えています。 まずは社内の課題を洗い出す 今年の4月に部署が発足してから、まずは社内のIT環境の実態を調べることから始めました。 サイロ化は本当に起きているのか?何か原因となっているツールがあるのか?など、今後のあり方を考えるために現状の課題を知ることを目的としました。 マイナビ社員約7,000人を対象にしたアンケート調査と、全国の様々な職種の社員15名にインタビューを実施しました。 社内調査をスクラムですすめてみた 社内の課題を洗い出すプロジェクトでは、運営をアジャイルの代表的な手法である「スクラム」をベースとして行うことにしました。 スクラムというとシステム開発で用いられるのが主流ですが、今回のような システム開発ではない案件にも適用できます 。 スクラムを用いることにした背景は大きく分けて2つあります。 一つ目は「 チームメンバーがほぼ全員初対面同士であったから 」です。 コミュニケーションデザイン課とEX推進課という二部署共同でおこないましたが、どちらも2022年4月に新設されたばかりでした。3月までの職種や業務内容もみんなバラバラでした。 それぞれ価値観にギャップがあり、プロジェクトに対する目線を合わせるのが難しい状況だったのです。 そのため、コミュニケーションをとる頻度が多くなるように工夫されているフレームワークを用いたいと思い、スクラムを取り入れることにしました。 二つ目は、「 全社的な規模でのアンケート実施を行った実績がなかったから 」です。 IT部門が主催する調査としては前例がないものであり、ノウハウや工数などが非常に不透明な状態で進める必要がありました。 そのため、プロジェクトレベルで見ても臨機応変に動くことのできるよう、工数を相対的に見積もりつつスプリント単位で動きを変えることのできるスクラムを取り入れることにしました。 スクラムの経験値があるメンバーは過半数以下でしたが、 初動で丁寧にスクラムについて説明を行った ことで上手く浸透し、プロジェクト自体もスムーズに進行することが出来ました。 皆さんも、 初対面のメンバーで新規案件を取り扱う場合には、スクラムで進めてみてはいかがでしょうか? これから取り組むこと 社内調査でわかったこと ITツールに関する社内調査によって、同じような役割のツールが社内でたくさん使われていることがわかりました。 特にチャットツールは、IT運用部門が管理している全社導入済みのツールが2種類あるほか、各現場が独自に導入しているツールも散見されました。 各現場によってメインで使っているツールが違う 状態です。 ツールが異なることにより、他事業部と連絡したいときに何のツールを使えばよいかわからなかったり、色んなツールから連絡がくるので通知を見落としたり、どこでやり取りしたか分からなくなるなど、 ちょっとした不便が起きている ことがわかりました。 ▼各コミュニケーションツールの利用率 C~Eは現場が独自で導入しているチャットツールですが、多いものだと約3割の社員が使っているという状況です。 インタビュー調査から、メールを含めると 常時3~4つのツールを使い分けている 社員がいる(!)こともわかりました。 社内の交通整理が必要 こういった状況を受けて、社内向けにチャットツールのガイドラインを作成しました。 マイナビで利用可能なツールを一覧化し、利用を推奨するツールや各ツールの特徴、現場で独自に導入する場合の申請方法などをまとめています。 社外からの要請などやむを得ない事情もあるので、利用するチャットツールをひとつに限定することは難しいと考え、まずは 社内のやり取りのスタンダードを決めて社内に発信 しました。 とはいえ、ツールの数の多さ自体にも問題があると考えており、今後は抜本的な見直しも図っていきます。 まだ結論は出ていませんが、今後 社内のチャットツールを統一し、全社共通のコミュニケーション基盤を構築していく 想定です。 ツールを統一するだけでよいの? 残念ながら、社内の チャットツールをひとつにしただけでは、コミュニケーションは活性化しない と考えています。 部署を横断したやり取りや新しいコラボレーションが発生する状態になるためには、 オープンコミュニケーションの文化をつくっていく 必要があります。オープンな場で気軽に発信できるような、心理的安全性が確保されている組織風土の醸成です。 文化や風土の醸成は、一朝一夕でできるものではありません。 コミュニケーション基盤を構築した後には、その環境をどのように使ってもらうかを考えながら、 オープンコミュニケーション文化を醸成できるよう、様々な仕掛けをおこなっていきます! 投稿 DX推進のために社内ITツールの利用状況を調査した は マイナビエンジニアブログ に最初に表示されました。
はじめに AIシステム部のS.Kと申します。 今回はAtCoderで水色まで到達した身として、さまざまな場面で役に立つ計算量についてまとめていこうと思います。 計算量という概念はアプリケーションに必要な計算リソースを見積もるのに便利な道具です。 従量課金制のクラウドサービスが主流 になっているこの世の中で、必要な 計算リソースを意識するのはとても重要 です。 また、AtCoderをしていると、嫌でも 計算時間 を気にする必要があります。基本的に1回の実行に対して 実行時間は2秒まで という制限があるからです。自分が書いたソースコードの実行時間が2秒程度で収まるのか、計算量を考えるとおおよその見積もりが立ちます。 アルゴリズムの性能を測る上で避けては通れないキーワード 「計算量」 について、可能な限り分かりやすく解説できればと思います。 計算量って何? そもそも計算量とはなんでしょうか? 計算量という概念は主に計算複雑性理論で使われる言葉です。 計算複雑性理論のWikipedia ではこんな記載がありました。 以下引用 アルゴリズムの計算量(けいさんりょう)とは、計算機がそのアルゴリズムの実行に要する計算資源の量をいい、アルゴリズムのスケーラビリティを示す。形式的には計算機をチューリング機械やランダムアクセス機械(random access machine)などの計算モデルとして定式化したうえで、アルゴリズムの使用する資源の量を入力データ長などに対する関数として表す。計算モデルの瑣末な詳細に影響を受けないよう、計算量はその漸近的な挙動のみに注目し、定数倍を無視するO記法で書き表すことが多い。 えーーっと……? よく分からないので コトバンクの「計算量とは」 のページを見てみましょう。 以下引用 世界大百科事典 第2版「計算量」の解説 けいさんりょう【計算量 computatinal complexity】 アルゴリズムの計算効率や問題の難しさを測るための尺度。主なものに,時間効率を測るための時間計算量,メモリー効率を測るための領域計算量などがある。他にも,計算回路の性能を議論するための計算量や,分散処理でのプロセス間の通信効率を測るための計算量など,用途に応じてさまざまな計算量が用いられている。 コンピューターで仕事を処理したり問題を解く場合,計算手順(アルゴリズム)の善し悪しで,プログラムの計算時間や使用する記憶容量が大幅に異なってくることが多い。 少し分かってきました。まとめてみると、計算量とはこういう概念です。 計算量の代表的なものとして、 時間計算量 と 領域計算量(空間計算量とも言う) がある。 計算手順の良し悪しで、必要な計算時間や記憶容量が異なる。 時間効率を測るのに時間計算量が用いられる。 メモリー効率を測るのに領域計算量が用いられる。 他にも用途に応じてさまざまな計算量が用いられている。 すなわち、以下の二つのことが言えます。 時間計算量が小さい→計算時間が短い 領域計算量が小さい→必要な記憶領域(メモリ量)が少ない なので基本的に 「計算量が小さければ小さいほど、いいアルゴリズムである」 と言っていいでしょう。 計算量の記述方法「ランダウの記号」とその意味 計算量を記述する方法として「ランダウの記号( 参考:Wikipedia )」が用いられます。\(O\)という記号を使った、このような記述方法です。 このアルゴリズムの時間計算量は、入力とするデータの個数を\(n\)とした時、\(O(n)\)である。 「\(O(n)\)」の部分は「オーダー \(n\)」と読みます。これの意味は 「このアルゴリズムの時間計算量は、入力とするデータの個数に(\(n\)に)比例する。」 という意味です。言い換えると、「データの個数(\(n)\)が倍になると、計算時間も倍になる」という意味になります。 このカッコの中身は、任意の\(n\)についての関数が入ります。 具体例を見てみましょう。 時間計算量が \(O(n^2)\) 時間計算量は\(n\)の2乗に比例する。つまり、\(n\)が2倍になると計算時間が4倍になる。 \(n\)が増加すると、 計算量が\(O(n)\)のアルゴリズムよりも計算時間が長くなりやすい 。 時間計算量が \(O(\log(n))\) 時間計算量は\(log n\)に比例する。つまり、\(n\)が2倍になると計算時間は\(log2\)増加する。 \(n\)が増加しても、計算時間は少しずつしか長くならない。 時間計算量が \(O(2^n)\) 時間計算量は\(2^n\)に比例する。つまり、\(n\)が2倍になると、計算時間が\(2^n\)倍になる。 \(n\)が少しでも増加すると、計算時間がとても長くなる。 時間計算量が \(O(c)\) (cは実定数とする。) 時間計算量は 常に一定 である。つまり、\(n\)が増加しても計算時間は変化しない。 つまり、この記述が表すのは 「データ量 \(n\) が増加(減少)した時、処理時間がどの程度増加(減少)するか」 なのです。計算量が空間計算量の場合は、 「データ量 \(n\) が増加(減少)した時、処理に必要する記憶領域がどの程度増加(減少)するか」 を表すことになります。 計算量が\(O(log n)\)であれば、データ量が増えるとしても、計算時間はそこまで長くならないので対して心配する必要はありません。しかし計算量が\(O(2^n)\)であれば、少しでもデータ量が増えると、計算時間がとても長くなってしまう、ということが分かりますね。 この様に計算量は何か基準となる変数(上記の場合は\(n)\)を決めて、それを使って記述します。\(n\)の取り方は他にも以下の例があるでしょう。 入力が文字列\(S\)の時、文字列\(S\)の長さ(文字数) 入力が整数\(N\)の時、\(N\)そのもの \(N = 2^n\)と表した時の\(n\)、(すなわち\(log N\))を基準とすることも多いです。 入力がグラフ構造を持つとき、その頂点の数。 色々書きましたが、ここでは、 「\(O(n)\) (オーダー \(n\) )ってそういう意味なのか!!」 というのが伝われば大丈夫です。そして 「\(n\)について増加しやすければしやすいほど、計算量が大きい」 ということに気を付けましょう。 詳しい数学的な定義が気になる方は、 ランダウの記号のWikipedia に十分な記述がありますので、目を通していただければと思います。 計算量の求め方 では、具体的な計算量の求め方を見てみましょう。今回は時間計算量に焦点を当ててみようと思います。 以下のPythonのソースコードを見てください。 cnt = 0for x in range(n): for y in range(n): for z in range(n): if x + y + z == w: cnt += 1print(cnt) このソースでは0以上\(n\)未満の整数3つの組み合わせで、その和が w になるものがいくつあるかを計算しています。 このソースの計算量は\(O(n^3)\)になります 。 この計算量になる理由は、 「【x+y+zがwと一致しているか】を確かめる演算を合計で\(n^3\)回するから」 です。forループの中の演算が何回行われるかを数えればいい訳ですね。 では次のコードを見てみましょう。 cnt = 0for x in range(n): for y in range(n): if 0 <= w - x - y < n: cnt += 1print(cnt) これは1つ前のコードと全く同じ結果を出力します。wと、2つの整数の和の差が0以上 \(n\) 未満であれば、整数3つの組み合わせで、その和がwになるものが存在するからです。 このソースの計算量は\(O(n^2)\)になります 。 「【w-x-yが0以上、\(n\)未満であるか】を確かめる演算を合計で\(n^2\)回するから」 が理由です。 計算量を求める場合はこのように、 「演算を行う回数を\(n\)を用いて記述した式」 を考えればよい訳です。これを考えることで、\(n\)が増加すると計算時間がどの程度長くなるのかが分かる、という訳ですね。 こうして計算量を考えることで、「処理の内容が同じだとしても、記述の仕方で処理速度がどの程度変化するか」を定量的に把握することができるのです。 ライブラリを利用する場合 現在のアプリケーション開発において、ライブラリの利用は不可欠なものです。そうなった時、 アプリケーション全体の計算量 を見積もるためには、 ライブラリで提供されている関数や、クラスのメソッドの計算量 を把握しておく必要があります。 これに関しては以下の対応が必要かと思います。 ドキュメントから仕様を確認する。 どのような処理を行っているのかドキュメントを確認し、その処理に必要な計算量を見積もる。 場合によっては計算量そのものの記載がある。 ドキュメントのみからでは正確な見積もりができない場合もある。 実際のソースコードを読み込む。 上記の手法で計算量を見積もる。 かなり正確な見積もりができるものの、ドキュメントを読むよりも時間がかかることが想定される。 どこまで正確な見積もりが必要になるかは、ケースバイケースだと思います。実際に実行した時の処理時間を計測した方が有効な場合もあるかと思います。 業務での計算量 例えば、Webアプリの計算量(時間計算量、空間計算量の両方)を小さくすると、以下のメリットがあるかと思います。 バックエンドでの計算量が小さい時 ユーザーの待ち時間が短くなる。 処理時間に対して従量課金がある時、利用料金が安く済む。 使用したメモリに対して従量課金がある時、利用料金が安く済む。 フロントエンドでの処理時間 ユーザーのPCにかかる負荷が軽減される。 UI/UX改善に繋がる。 フロント側の処理が重くても待ち時間の増加に繋がります。 以下のような場合は特に、より正確な計算量の確認が重要でしょう。 処理で取り扱うデータの量が膨大なとき。 計算リソースに制限があるとき。 「どの処理について」の計算量を考えるか 先ほどは時間計算量を比較演算の回数で見積もりました。しかし、どの処理の回数を基準として計算量を見積もるかは場合によって変わると思います。以下のような処理の回数はとても重要です。 外部との通信の回数と容量 回数や容量が多いことは、帯域の圧迫であったり、余計な費用増加に繋がります。 API等を利用する際は、APIの呼び出し回数に制限がある場合もあります。 DBにアクセスする処理の回数 回数が多いとDBの負荷が増加します。 クエリ回数に対して課金があるDBサービスもあるかと思います。 パスワードやトークン、秘密鍵といった機密情報が必要な処理の回数 特定のソースコードというよりかは、システム全体の設計で意識することかと思います。 計算量を定義する際に、 「他にも用途に応じてさまざまな計算量が用いられている。」 と述べたのはこれが理由です。「上記の処理の回数を少なくすることで、処理時間が短くなる」 という訳ではない こともあると思います。計算時間を短くすることを優先するべきなのか、はたまたDBの負荷を減らすべきなのか。 システムの仕様や要件と相談する必要があるかと思います。 計算量は常に考えるべきなのか ここまで計算量を小さくして、処理を効率化することばかり論じてきましたが、 計算量をあまり気にしなくていいケース もあります。 データの量や長さが固定、あるいは少ないとき システムの仕様上どうしてもその処理が必要なとき この様な場合は計算量が多少多くなっても問題ないかと思います。 なぜこのような場合をわざわざ論じたかと言うと、 計算量を小さくすることで以下の問題が生じる 可能性があるからです。 処理内容の無駄を極力省いた結果、他者がそのソースコードを読んだ時に、どんな処理が行われているのかが分からない。 特定の処理を効率よく行うことに特化するあまり、再利用性が損なわれてしまう。 効率がよいコードを書こうとするあまり、コーディングにかかる時間が長くなってしまう。 これらの問題から、 常に計算量を小さくするべき とは単純に断ずることができない部分があります。システムの要件や仕様、場合によっては納期も考慮した上で、どのような実装を行うべきなのか判断するべきです。 AtCoderにおける計算量 この章は競プロに取り組もうと思っている方向けです。 AtCoderにおいて意識するべき数字があります。それは \(O(10^8)\) という数字です。 AtCoderでは、実行時間が2秒に制限されています。これを超えないためには \(O(10^8)\) あたりが限度だということです。これを超えたアルゴリズムはTLE(実行時間制限オーバー)になる場合が多いです。 入力が長さNの配列として与えられる場合を考えてみましょう。 AtCoderにおいては、Nの最大値が制約として与えられています。そのため、それぞれの制約に対して、「これくらいの計算量ならTLEにならない」という目安を書いておきます。 \(N\)が最大で \(10^2\) \(O(N^3)\)のアルゴリズムを動かしても問題ないでしょう。 多くの場合、特に計算量を減らす工夫をする必要もないかと思います。 \(N\)が最大で \(10^3\)~\(10^4\) \(O(N^2)\)あたりが限度でしょう。 \(N\)が最大で \(10^5\)~\(10^6\) \(O(N \log N)\) あたりが限度でしょう。 一つ一つの処理が重い場合は\(O(N)\)にするべきかもしれません。 これはクイックソートの計算量にあたります。ソートができるのはこの辺りまでです。 2重ループによる全探索は難しいです。 \(N\)が最大で \(10^7\)~\(10^8\) \(O(N)\)が限度でしょう。 \(N\)が最大で \(10^9\) \(O(N)\)で軽い処理ならギリギリTLEにならないでしょう。 そもそも入力に\(O(N)\)時間がどうあがいてもかかります。処理が軽ければ間に合うはずです。 \(O(\log N)\)や定数時間(\(N\)に依存しない時間)で処理が終わるものが理想です。 表にまとめるとこんな感じです。慣れてくるとこの表がなんとなく頭に入ると思います。 \(N\)の最大値 計算量 備考 \(10^2\) \(O(N^3)\) 計算量を考慮する必要はほとんどない。 \(10^3\)~\(10^4\) \(O(N^2)\) \(10^5\)~\(10^6\) \(O(N \log N)\) クイックソートによってソートを行うことができる。 \(10^7\)~\(10^8\) \(O(N)\) \(10^9\) \(O(\log N)\) 若しくは\(O(c)\) 処理が軽いのであれば\(O(N)\)でもいける可能性あり。 AtCoderでは、 難易度が高いほど入力長の最大値が大きくなる場合が多いです 。そのため実装に工夫や知識が必要になってきます。なのでAtCoderで上位になるためには、計算量(主に時間計算量)が小さくて済むアルゴリズムについて学び、それを実装する技術が必要です。 すなわち、 優秀な色の持ち主はアルゴリズムに対する知識が深く、その応用方法を熟知している という訳です。 まとめ 私は競プロや研究のために計算量について学びましたが、気がつくと常に意識するようになっていました。まずはなんとなくでもこれを理解し、できるだけ計算量が小さくなる実装を心がけることは大事だと思います。 計算量が小さくなるような実装を行うには、様々なアルゴリズムの知識が必要になることがあります。その知識が足りていなかったとしても、「これから書くプログラムの計算量、これくらいかな…?」と分かるだけで、相談することや、実際に動作させたときに何が起こるか想像することができます。 まずは「この処理の計算量はこれくらいかな…?」と考えるところから始めてみてはいかがでしょうか。
はじめに 皆さんこんにちは!開発系の部署に配属された、2022入社新卒R.Mです! メイン業務はモバイルアプリ開発で、Flutterを使用しています! 学生時は生命科学系を専攻してましたが、3年生くらいからプログラミングに興味を持ち始めて、簡単なiOSアプリを開発してました。 研究はPythonを使って、創薬に関することを色々やってました。技術を学ぶことも楽しいですが、ビジネス関連の話を聞くのも楽しい人間です。 ちなみに、趣味の中で今一番熱いのがK-POPです🔥 背景 この記事を書こうと思った理由・背景なのですが、自分自身配属されてから、触ったことのない技術(Flutter・Dart)を、社内で教えてくれる人がいない中で開発ベンダーさんと協力しながら勉強し、約2ヶ月間過ごしてきました。 はじめは課長とベンダーさん、自分含めて4人で定例会議を行っていましたが、今では一人でベンダーさんと進捗共有などを行い、プロジェクトを進行しています。 新卒でこれらの経験は中々無く貴重であり、得られたものも多かったと思っているので、 プロジェクトを進めていく会議上でやったほうが良い! と思ったことを個人の主観でまとめてみました🎉 ⚠️やっておくと良いと書いてますが、絶対必要でしょ!っていう意見もあると思うのでそこはご了承ください。 具体的にそれをどうやるかまでは書いてません🙏 【1】情報を同期すること 情報を同期するとは: 会議に参加しているメンバー全員が、プロジェクトに関して知らない情報を共通認識として持つことを指しています! 私達のチームは開発タスクをここで共有しているのですが、この仕組みがあるだけで、 新しいタスクはあるか 既存のタスクの状況はどうなっているか 未対応・対応中・対応済み どのバージョンでこの機能(タスク)を実装するのか ※スマホアプリなので、バージョンごとにリリースする機能を事前に話して決めます このタスクにかける時間はどのくらいか このタスクは誰が担当するのか などを決めることができ、その場のメンバーに共有もできます。 これらができていれば、、、 ■タスクが終わっていれば順調と判断でき、終わっていなければその原因と課題、次への対策まで検討が可能! ■タスクの管理漏れがなくなる!🔥 →今日、誰が何をしているのかが分かり、PMも全体状況を把握しやすい! 【2】ロードマップを立てること スマホアプリ開発の場合では、 バージョンごとに、「いつ」そのバージョンを世にリリースするかを決定 タスクごとに、「いつ」そのタスクを「どの」バージョンに含めるかを決定 タスクにかかる時間を元に、1スプリントで完了させるタスクを決定 スプリント = 単位の無い一定の期間。私達は1スプリント = 1週間と定義しています〜 これらをロードマップを立てる、として実施しています。 これらができていれば、、、 ■いつまでに、何が終わるのかが見やすい! →臨機応変に、プロジェクト進行の調整を行うことができる! ■次スプリントのスケジュールも立てやすい! →仮に1週間程度で5個くらいのタスクを終わらせたとすると、次の1週間にタスクにかける時間の目安もすぐ分かる! 【3】パーキングロットを確保すること パーキングロットとは: 議論する際に、今すぐ話し合うべきではないと判断される話題などを一旦保留しておくために、机やホワイトボードの隅などに設けられるスペースのこと。 ▷▷▷会議が終わった後に、話したい議題について必要なメンバーだけ集まって話す流れのこととして定義しています! 私の場合によくパーキングロットで話す内容が、 モバイルアプリ開発における技術的な質問 使用するツール 細かい話 コミットメッセージの規則 タスク要件の再定義など など、たくさんありました!中でも技術的な質問が一番話していましたね😌 会議が終わった後に、個別でパーキングロットを開きます。話したい人は話して、聞く必要がある人は聞くイメージですね。 これができていれば、、、 ■議論の混乱や、無駄な議論を避けることができる! ■話を聞かなくても良いメンバーの時間を奪うことがない! 【4】変化があったものは記録を残すこと(その場で) イメージは、議事録という「誰に見せても分かるようなテキスト」ではなく、「話した内容が思い出せる粒度のメモ書き」みたいなものを想像してもらえると嬉しいです!! それを、会議の最中に書いてしまいます!会議後ではなくです! これができていれば、、、 ■メンバー間で共通認識が常に取れる! →専門的な話でも、言語化して記録されているので、どのような内容かはざっくり把握できる ■後から証拠として出せる! →相手の認識に齟齬がある場合に、メモを見せれば即解決! ■図や画像なども乗せることができて、イメージしやすい! →これも口頭で説明するより図で説明したほうが圧倒的にすぐ終わる ※記録がないと、後から再度聞くという二度手間になりますし、見返したい!と思った時に見れない、図が合ったほうが良い時に分からない、という最悪なことになります😇新卒研修の際にも可視化することの重要性を知りました。 【5】認識の齟齬がなくなるまで会議を終わらせないこと これは、曖昧な理解のままで会議を退出するなあああああ!!!!って意味ですね😇 チームでやることというより、 個人で 意識してやっておくと良いことになります。 分からない、と思ったまま退出するのが、自分にとってもチームにとっても危険です、、 ちょっとした疑問でも、その会議中で質問して解消するまで行うとGoodかなと、個人的には思ってます! これができていないと、、、💦 ■自分がこれから何をするのか分からない状況に陥ってしまう、、 →会議終了後にすぐ動ける状態になっていないのは、自分が一番困ってしまいます!席に座ったら何をしたらいいか想像できるくらいまで、理解の粒度を細かくしましょう〜! ■後から分からない点を聞くはめに、、 →自分のも、相手の時間も奪ってしまいメリットありません!(手戻りってやつですね)わかってはいるものの実行に移すのが難しいのですが😇 【※】開催頻度は毎朝☀️ これは、自分がプロジェクトを進めるにあたってスムーズに進められている要因の一つでもあ ったので書きました! 毎朝開催すると、、 ■プロジェクトの進行状況が1日置きで分かる! →何が進んで何が進んでいないかが明確! ■手元にきた重要な情報もすぐ共有できる! →共通認識がとりやすい! ■分からないことがあれば、直接聞ける! →テキストで聞くより圧倒的に早いから工数削減につながる 逆に毎朝開催しなかった時に一番困ったことは、自分目線、「分からないことを聞くこと」でした。 技術的な質問なんて、細かいところを文章で書き起こさないといけない場面がいくつもありました。 それを長文で返して、長文で返ってくる、それをまた長文で返す、みたいな繰り返しで ほぼ1日経ってるやんけえええ!! って思った日もあります。 毎朝であれば質問があれば聞く機会が既に設けられているので、心理的安全性もありますし、聞きたいことがない日はそれでOKなので非常に助かっています! 最後に。 以上です! (書いた内容がMECEにそってないかもしれませんが、追々意識します、!) 見返すと、意外と当たり前なことやな🥱って思った方も多いかもしれません! ただベンダーさん会議とは別で、社内の会議にいざ参戦!してみると、そんなこともなく、バラバラでした。 「会議」って一言で表せるけど、かなり奥深くて大変ですね😇 ベンダーさんもいつまでも契約が続くわけではないので、この当たり前は自分の中でも維持して、プロジェクトをスムーズに進めていきたいな!と思ってます! ※余談ですが、この間ちょうど社内の会議やコミュニケーションの最適化について議論する場に参戦したのですが、少し似たような話も上がってたので、少しは考え方が共通しているのではないかと思いましたっ 閲覧いただきありがとうございました〜!🥰
はじめに 本日12月15日は C++14 (ISO/IEC 14882:2014) と C++20 (ISO/IEC 14882:2020) のリリース日です。 C++14 は8年前の2014年12月15日、C++20 は2年前の2020年12月15日 にリリースされました。 C言語といえば、先日(2022/11/19)に「人間Cコンパイラコンテスト」に参加し、ランキング1位を獲得することができました。このエントリーでは人間Cコンパイラのはじめかたをまとめていきます。 人間Cコンパイラコンテストとは? 「人間Cコンパイラコンテスト」(HCCC)とは競技者自身がCコンパイラとなり C言語からアセンブリを生成し、その時間と正確さを競う競技です。日本ネットワークセキュリティ協会(JNSA) の SECCON実行委員会が実施する「SECCONCON」内で第一回大会が開催されました。 HCCC / 人間C言語コンパイラコンテスト 詳しくは、以下の 公式説明スライド を参照ください。 この大会ではチュートリアル問題も含めて全20問が出題されています。単純に数字を戻り値として返す問題から、四則演算、ローカル変数利用、文字列処理、ハローワールド、Fizzbuzzなど典型的なプログラムが多く出題されました。 人間C言語コンパイラコンテスト Problems チュートリアル チュートリアル問題 チュートリアル問題を解いていきましょう。実際に一問目として出題された 究極の疑問の答えを返すプログラム を題材とします。 //return_42.cint main(void) { return 42;} 開発環境の構築 これくらい単純なプログラムであればそのままポータルサイトに入力しても問題ありませんが、複雑なプログラムではローカル環境でのデバッグが必須です。ここでは公式が提供している検証環境を利用して開発環境を構築します。 ~$ git clone https://github.com/HumanCCompilerContest/HCCC_local_env~$ cd HCCC_local_env~/HCCC_local_env$ docker build -t hccc_local_env .~/HCCC_local_env$ docker run -it --rm hccc_local_env アセンブリコードの作成 開発環境では vim や emacs などコーディングエディタが利用できます。 ここでは、vim を利用して ファイル return_42.s を新規作成し、先のC言語のソースファイルをx86_64アークテクチャのアセンブリに変換してコーディングしていきます。 root@a741545b3735 ~$ vim hccc/return_42.s ▼return_42.s .globl mainmain: push %rbp mov %rsp, %rbp mov $42, %rax mov %rbp, %rsp pop %rbp ret アセンブルと実行 開発環境では アセンブリコードのアセンブル&実行するコマンド「asm2bin」 が用意されています。 作成したアセンブリコードファイルを引数にして実行します。 root@a741545b3735 ~$ asm2bin hccc/return_42.s 実行後、返り値として「42」が返っていることが確認できました。 root@a741545b3735 ~$ echo $?42 デバッグ 開発環境では PEDA 拡張された gdb が利用できます。 asm2bin 実行すると、実行オブジェクトファイルはカレントディレクトに「tmp」として保存されていますので、これをデバッグ実行します。 $ gdb tmp$ break main$ run 命令ポインタ前後の命令やレジスタ値、スタックフレームなどが可視化させれているため、効率的なデバッグが可能です。 人間コンパイルの知識リソース C言語からx86_64アセンブリにコンパイルするためには、C言語(C99)、CPU命令(x86_64)、ABI (System V Application Binary Interface)、アセンブラ疑似命令に知識が必要です。 以下、参考になるインターネットリソースを記載します。 (※競技中はレギュレーションで認められたもののみ閲覧可能です) 公式リソース 公式レポジトリ 公式チュートリアル C99 System V Application Binary Interface AMD64 Architecture Processor Supplement その他のリソース x86 Assembly Language Reference Manual : Assembler Directives AMD64 ABI の特徴 低レイヤを知りたい人のためのCコンパイラ作成入門
はじめに マイナビでは、一部のシステム職員に向けてDaaS環境を提供しており、サービスには「Azure Virtual Desktop」を採用しております。 Microsoft社が提供するAzure Virtual Desktopはなんと Windows 10 Enterprise Microdsoft 365 Business Premium以上 のライセンスがあれば、追加ライセンスは不要で利用が可能なDaaSとなっています。 加えて、Azure AD P1以上があれば条件付きアクセスによる詳細なアクセスコントロールもできます。 今回は、そのAzure Virtual Desktopを構築し利用できるまでの道のりと共に、メリットデメリットを含めて共有できればと思います。 Azure Virtual Desktopサービスとは? Microsoftが提供するクラウド型のDaaS(Desktop as a Service)は、実は2種類存在しています。 1. Windows 365 決められたプラン(スペック)の中から利用ができる、シンプルな構成のDaaS。 利用者数が少ない、利用要件が少ない…など「とりあえずDaaSが使いたい」環境向けサービス。 24H365Dで稼働しっぱなしのため、ランニングコストは安くない。 2. Azure Virtual Desktop 様々なカスタマイズ、利用方法を提供する上位のDaaS。 1台を複数人で利用できる「マルチセッション」や、細かなポリシーカスタマイズが可能。 利用状況に応じて自動シャットダウンも可能なため、費用をコントロール出来ます。 ある程度の数を展開する場合や、要件が明確な場合はこちらをオススメします。 Azure Virtual Desktopの構成を理解しよう Azure Virtual Desktop(以下、AVD)は、既存のVDIシステムと似ている部分が多々あります。 構築をしてみる前に、まずはどのような要素から成り立っているかを把握しましょう。 引用元: エンタープライズ向け Azure Virtual Desktop - 主要な論理コンポーネント間のリレーションシップ AVDは大きく、 コントロールプレーンと呼ばれる管理環境 ホストマシンやプロファイルの仮想デスクトップ実行環境 2つに分けられます。 コントロールプレーンはMicrosoft社の管理下にあるため、利用側での設定や運用は不要です。実際に、設定や運用管理が必要なのは仮想デスクトップを実行するための環境だけですね。オンプレでVDI環境を運用する場合、管理環境の維持だけでも大変なのでこれはありがたいですね。 また、ある程度の規模間の企業様であればExpressRouteを既にご利用の場合もあるかと思います。 オンプレ~Azure間を閉域でつなぐ場合はこちらも利用しましょう。 過去、AVDを利用するにはAD+AADのハイブリッド構成が必須でしたが、現在では、AADのみの環境もサポートされています。 ただし、一般的にはハイブリッド構成を利用している環境の方が多いと思いますので、今回は仮想マシンをオンプレADに参加させる方式で説明いたします。 構築をしてみよう ここまで概要を説明いたしましたが、ここからは実際にAVDを構築し仮想デスクトップを利用してみましょう。 まず、今回の前提条件としては下記構成で構築に臨みたいと思います。 ・ExpressRouteを利用し、オンプレとの相互通信が可能である・オンプレ上にActive Directoryが存在している・オンプレ上にAzure AD Connectが存在している(AD⇔AADが同期済みである) ①リソースグループを作る Azure上に作成される各コンポーネントを取りまとめるため「リソースグループ」を作成します。 リージョンは「東日本」か「西日本」のどちらかを選択しましょう。 ②仮想ネットワーク(VNET)を作る AVD環境で仮想マシンがドメインに参加できるように、オンプレADの名前解決が可能なサーバをDNSに指定しましょう。 ADサーバがDNSを兼ねている場合は、ADサーバを指定してあげると良いでしょう。 そのほか、仮想ネットワークではサブネットの設定も可能となっています。 ネットワークの環境や要件に応じて設定を行ってください。 ③マスターイメージの作成 FAT・VDIともに展開ではおなじみのマスターイメージを作成していきます。 このマスターイメージを元に、仮想マシンを展開していきます。 まずは、マスターイメージとなるAzureVMを作成しましょう。 AVD固有機能である「マルチセッション」を使う場合は、イメージを「Multi-session VM」から展開しましょう。 シングルセッションの場合は、Windows10であれば特に指定はありません。 展開後は、通常のWindowsマスタと同様にOSにカスタマイズを施していきます。 ※AzureVMのWindows 10は英語がデフォルトのため、日本語化が必要な場合はOSで設定変更がマストです。 マスターイメージである程度カスタマイズが完了したら、sysprepを行います。 AVDのsysprepでは、応答ファイルがサポートされていません。 弊社で検証した限り、応答ファイルを利用すると展開に失敗します。 そのため、プロファイルのコピーが応答ファイルで実施できません。 応答ファイルを使わないプロファイルコピー設定を事前に行うことで実現は可能です。 ※AVDのサポート対象外となる可能性が高いため、本記事では言及致しません。 sysprepまで完了したら、Azure上でイメージ化するために「キャプチャ」を行いましょう。 これでマスターイメージの完成です。 ③ホストグループの作成 ここまで来たら、あと一歩です。 AVD上の仮想マシンを束ねる「ホストグループ」を作成しましょう。 マルチセッションの仮想マシンの場合は「プール」を選択します。 「個人用」を選択した場合は、仮想マシンと利用者は1:1になります。 ホストプールを作るタイミングで、同時にAVDで利用する仮想マシンも作成することができます。 先ほど作ったマスターイメージから仮想マシンを展開するために「全てのイメージを表示」を選択しましょう。 「マイアイテム」を確認することで、キャプチャしたマスタイメージを選択できます。 あとはドメイン参加するための情報や仮想ネットワークの設定やらを入れてあげれば完成です。 初回作成の場合は、ワークスペースもここで一緒に作成すると展開が楽です。 無事展開が完了すると、ホストプールに仮想マシンが作成されます。 最後に、仮想マシンを利用できるユーザを設定してあげます。 シングルセッションの場合は前述の通り1:1ですが、マルチセッションでは複数人設定が可能です。 シングルセッションの場合↓ マルチセッションの場合↓ 接続してみよう ここまでの準備ができたら、いよいよ接続が可能になります。 AVDには2種類の接続方法があり、 ブラウザからのアクセス 専用RDPアプリからのアクセス が可能です。 ただし、ブラウザからのアクセスはレスポンスが悪いのでオススメしません。 今回は専用アプリから接続してみます。 専用アプリにAzureADアカウントでサインインをすると、割り当てを行った仮想マシンが表示されていますね。 選択してみるとこのように仮想マシンに接続ができます。簡単ですね!!!! ※オンプレADとAADのハイブリッド環境の場合、展開時に自動的にAD参加を行ってくれます。 そのため仮想マシン自体へのログインにはオンプレADアカウントを利用します。 運用編 ここまでで、なんとなく作り方や使い方のイメージが付いたかと思います。 ただし実際には、もう少し作りこみが必要です。 例えば、 このサービスは従量課金制です。 そのため、仮想マシンは使った分だけ課金され続けます。 ここで重要なのは「シャットダウン」だけでは課金され続けてしまいます。 停止 (割り当て解除) は、仮想マシンが稼働する物理ホスト サーバーから割り当てられているリソースの割り当てを解除する操作であり、起動は物理ホストサーバーからリソースを割り当てる操作です。 再デプロイと異なり、明示的に別の物理ホスト サーバーでデプロイを行うための手段ではありませんが、起動によって仮想マシンがデプロイされる物理ホストサーバーは前回と異なる場合がほとんどになります。 停止 (割り当て解除) では、仮想マシンとしての課金はかかりません。(※ ディスクの課金はかかります。) 引用元: Azure 仮想マシンにおける操作 (再起動、停止/起動、再デプロイ、再適用) について つまりは、仮想マシン側でシャットダウンをしたところで、 Azure側で割り当てを解除しなければ課金され続ける ということですね。 幸い、Azure Virtual Desktopには「スケジュールに応じて自動的に割り当てを解除する」仕組みがあります。 利用時間が決まっている環境であればこの実装だけで費用を抑えられます。 ただし、スケジュール外のメンテナンスで使っている場合などで、急に割り当てが解除されると困りますよね。 そういった場合は、仮想マシンへのセッション有無を定期的にAzure側で判断し自動で割り当てを解除する仕組みを導入する必要があります。 合わせて、 ARMテンプレートを利用しない場合ホスト名の規則に融通が利きません。 この二つの実装は、インターネット上に先駆者の情報がありますので、参考にしてみてください。 まとめ AD・AADのハイブリッド環境かつ物理リソースを持たないVDI という点は非常に魅力的です。 ただし、細かいカスタマイズが難しいのは否めません。このあたりは「Citrix with AVD」や「Horizon Cloud with AVD」を活用すると、オンプレVDIと同じ感覚で運用ができるかもしれません。 とはいえ、弊社環境では社員用のFAT PCと同様のカスタマイズが実現できていますし、本番運用環境は一人で構築しています。 元々Azureに知見がある、マスタ展開の経験がある、VDI構築に携わったことがあるなど、なんらかの条件があれば、抵抗なく構築運用が可能かと思われます。 PCの持ち出しができない環境がある場合、このDaaSの仕組みは非常に魅力的かと思います。既にM365の該当ライセンスをお持ちの方は、是非活用してみてはいかがでしょうか。
はじめに マイナビではマネージドなWordPress基盤「SMEW」が社内向けに提供されており、WordPressを使ったサイトの多くがSMEW上で稼働しています。 ご存知の通り、WordPressは多くの脆弱性が報告されます。脆弱性に迅速に対応できるよう、WPScanとElastic Stackを使って、SMEW上で稼働している各サイトのWordPress脆弱性を自動でスキャンするシステムを開発しました。本記事で簡単に紹介します。 ▼SMEWについての詳細はこちらをご覧ください ###card_post_id=1249### WPScanとは オープンソースのWordPressの脆弱性スキャンツールです。 WPScanを利用してみる WPScanは Kali Linux に標準で入っています。 wpscan --url "https://hogehoge/" --api-token "{token}" -format json オプション url サイトのURL api-token WPScanにユーザ登録した時に発行されるトークン format 出力結果のフォーマット 実行結果(一部抜粋) スキャン結果の「vulnerabilities」のフィールドに、脆弱性名、CVE、Fixのバージョン等の詳細情報が出力されます。 下記、スキャン結果から、All in One SEO Packというプラグインに脆弱性があることがわかります。 ▼スキャン結果 { "main_theme": null, "plugins": { "all-in-one-seo-pack": { "confidence": 30, "confirmed_by": {}, "directory_listing": null, "error_log_url": null, "found_by": "Comment (Passive Detection)", "interesting_entries": [], "last_updated": "2022-03-30T17:01:00.000Z", "latest_version": "4.1.9.4", "location": "https://hogehoge/webroot/plugins/all-in-one-seo-pack/", "outdated": true, "readme_url": null, "slug": "all-in-one-seo-pack", "version": { "confidence": 60, "confirmed_by": {}, "found_by": "Comment (Passive Detection)", "interesting_entries": [ "https://hogehoge/, Match: 'All in One SEO Pack 2.6.1 by'" ], "number": "2.6.1" }, "vulnerabilities": [ { "fixed_in": "3.6.2", "references": { "cve": [ "2020-35946" ], "url": [ "https://www.wordfence.com/blog/2020/07/2-million-users-affected-by-vulnerability-in-all-in-one-seo-pack/" ], "wpvulndb": [ "528fff6c-54fe-4812-9b08-8c4e47350c83" ], "youtube": [ "https://www.youtube.com/watch?v=2fqMM6HRV5s" ] }, "title": "All in One SEO Pack < 3.6.2 - Authenticated Stored Cross-Site Scripting" } ] } }, "requests_done": 186, "start_memory": 52584448, "start_time": 1648701772, "stop_time": 1648701796, "target_ip": "198.51.100.0", "target_url": "https://hogehoge/", "used_memory": 219262976, "used_memory_humanised": "209.105 MB" -略-} Elastic Stackとは Elasticsearch、Kibana、Beats、Logstashの総称。 ログをリアルタイムに検索、分析、可視化することができます。 Kibanaのアラート機能を利用して、特定の条件のログがあったら、SLACK等に通知できます。 自動化の取り組み 処理の流れ SMEW上で管理されたサイト一覧を取得し、DynamoDBに格納する。 スキャン対象キューに入れる ECSTaskを起動し、スキャンを実行する。 脆弱性があるログを検知したら、Slackに通知する。 構成図 通知結果(例) まとめ 今後もSMEWだけでなく、マイナビの全てのサイトのセキュリティを高めるための技術開発に取り組んでいきます。
はじめに こんにちは。AIシステム部のS.Tです。 AIモデルを作るための学習環境といえば、JupyterNotebookを思い浮かべる方も多いと思います。セルにコードを書き、順次実行して結果を確認しながらコーディングを進めることができるので、研究開発には持ってこいのツールとなっています。 ただ、AIに関する業務となると、AIモデルの学習のあと、そのAIモデルの予測結果を、自社のサービスや業務改善に活用するフローを運用するところまでがセットとなります。ビジネス的なニーズによって、定期バッチで実行したり、モデルの予測機能をサーバアプリとして提供する場合もあります。これを行う場合、JupyterNotebookでは少々やりにくいかな、と思います。 Vertex AI Training で、こういったニーズを解決するために、Google Cloud Platform(以降GCP)では、 Vertex AI というAIに特化したプロダクトが開発されております。そのサブプロダクトである Vertex AI Training を用いると、GCPのマネージドな環境で、学習やハイパーパラメータチューニングを行ったり、そのモデルの予測提供するための環境も比較的簡単に作れます。 Vertex AI Trainingでは、 AutoML という、コーディングをせずとも学習ができる方法と、 カスタムトレーニング という、自前でプログラムを用意して学習を実行する方法がサポートされております。今回は、Dockerコンテナを使った カスタムトレーニング の方法を行ってみます。 今回使用する学習タスク 今回は、サンプルですので、機械学習のHelloWorldとも言える、アイリスデータの分類に挑戦してみましょう。モデルは、サポートベクターマシンによる分類器を試してみます。 (あ、ちなみに著者はあまり機械学習モデルの詳しい仕組みについては詳しくないのであしからず。。) データ BigQueryの iris_data というデータセットに iris_table というテーブルを用意しました。列名はこんな感じです。 列名 型 説明 sepal_length___cm__ FLOAT がくの長さ sepal_width___cm__ FLOAT がくの幅 petal_length___cm__ FLOAT 花びらの長さ petal_width___cm__ FLOAT 花びらの幅 label (今回の予測対象) INT アヤメの種類(0, 1, 2) 学習コードを書く ディレクトリ配置 ディレクトリ配置は最終的に以下のようになります。 .├── custom_training│ ├── Dockerfile│ ├── Pipfile # 環境構築用│ ├── Pipfile.lock # 環境構築用│ └── src # 学習用ソースコード│ └── train.py└── docker-compose.yml 環境構築 まずは、 custom_training というディレクトリを作ります。その中に、 src というフォルダを作ります。 mkdir custom_training && cd $_mkdir src いま、 custom_training ディレクトリにいますので、ここで pipenv による環境構築。 pipenv install scikit-learn google-cloud-bigquery pandas click すると、こんな感じになります。 .└── custom_training ├── Pipfile ├── Pipfile.lock └── src では、srcのなかに train.py を作成して、学習コードを書きます。 (以降、GCPプロジェクト名は <YOUR_PROJECT_ID> で伏せています) from __future__ import annotationsimport osimport pickleimport refrom dataclasses import dataclassfrom typing import Unionimport clickfrom google.cloud import bigqueryfrom sklearn.svm import LinearSVCfrom sklearn.model_selection import train_test_split# Vertex AI Trainingの場合は、実際に学習が実行されるGCPプロジェクトIDが# CLOUD_ML_PROJECT_IDという環境変数に格納されるif os.getenv('CLOUD_ML_PROJECT_ID'): client = bigquery.Client(project=os.getenv('CLOUD_ML_PROJECT_ID'))else: client = bigquery.Client()@dataclassclass GCSPath(): bucket: str key: str @classmethod def get_fuse_directory_path_from_gcs_uri(cls, gcs_uri) -> str: """ GCSのURLを受け取って、その場所をCloud Storage FUSE経由で見るためのパスを返す。 """ gcspath = cls.get_gcspath_from_gcs_uri(gcs_uri) return f"/gcs/{gcspath.bucket}/{gcspath.key}" @classmethod def get_gcspath_from_gcs_uri(cls, gcs_uri) -> GCSPath: """ GCSのURL表記からバケット名とキー名を抽出して、GCSPathオブジェクトにして返す """ pattern = "gs://(?P<bucket>[^/]+)/(?P<key>.+)" m = re.match(pattern, gcs_uri) if m: bucket = m.group("bucket") key = m.group("key") return cls(bucket=bucket, key=key) else: raise ValueError(f"{pattern} is invalid GCS URI.")def get_gcsfuse_model_save_dir() -> Union[str, None]: """ GCS上にモデルを保存する用のディレクトリを取得。 Vertex AI Training上で実行していない場合はNoneを返す。 Returns: Union[str, None]: GCS上にモデルを保存する用のディレクトリ。 Vertex AI Training上で実行していない場合はNoneを返す。 Note: Vertex AI Trainingで実行するとき、 自動的に環境変数AIP_MODEL_DIRにモデルの保存先のGCSのURLが渡される。 """ model_save_dir = os.getenv("AIP_MODEL_DIR") if model_save_dir: return GCSPath.get_fuse_directory_path_from_gcs_uri(model_save_dir)def get_training_data(): """学習データをDataFrameで取得する""" df = client.query('SELECT * FROM `<YOUR_PROJECT_ID>.iris_data.iris_table`').to_dataframe() return dfx_col = [ "sepal_length__cm_", "sepal_width__cm_", "petal_length__cm_", "petal_width__cm_"]y_col = "label"@click.command()@click.option("--model-save-dir", type=str, help="学習モデルの保存先")def train(model_save_dir: Union[str, None] = None): """ 学習を実行し、モデルを保存する。 Args: model_save_dir (Union[str, None], optional): ローカル環境で実行するときは指定が必要である。 Vertex AI Trainingで実行するときは指定は不要。 """ # モデルを作成 model = LinearSVC() # 学習データを取得する train_data = get_training_data() X, y = train_data[x_col], train_data[y_col].tolist() X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) # いざ、学習! model.fit(X_train, y_train) # モデルの保存先を取得する。 # Vertex AI Trainingで学習している場合はGCS Fuseでアクセス可能なディレクトリが # ローカル実行の場合は、引数のmodel_save_dirが使用される。 model_save_dir = get_gcsfuse_model_save_dir() or model_save_dir if not model_save_dir: raise ValueError("モデルの保存先が設定されていません。") # モデルを保存する if not os.path.exists(model_save_dir): os.makedirs(model_save_dir) model_save_path = f"{model_save_dir}/model.p" with open(model_save_path, "wb") as fp: pickle.dump(model, fp)if __name__ == "__main__": train() ためしに動かしてみます。 # BigQueryのテーブルが存在するプロジェクトをデフォルトプロジェクトにするgcloud config set project <YOUR_PROJECT_ID># 学習を実行するpipenv run python src/train.py --model-save-dir $(pwd) 学習が実行されて model.p というファイルが生成されました。 Dockerイメージを作る 今回はカスタムコンテナを使ってVertex AI Trainingで学習しますので、Dockerイメージを作成します。 custom_training/ ディレクトリ内に Dockerfile を作ります。 FROM python:3.9.6COPY ./Pipfile.lock /app/COPY ./src /app/srcWORKDIR /appRUN pip install pipenvRUN pipenv sync# ENTRYPOINTで学習実行スクリプトが開始するようにする!ENTRYPOINT pipenv run python src/train.py docker-compose.yml を、 custom_training の親ディレクトリに作ります。 services: backend: image: vertex-custom-training/iris_data build: context: ./custom_training ビルド docker compose build リポジトリにプッシュ Vertex AI Trainingから見える位置(GCP環境上か、Docker Hub)に、Dockerイメージをプッシュしましょう。 今回はGCP内のプライベートなコンテナレジストリであるGoogle Container Registry(GCR)にプッシュします。 # GCRの認証ヘルパーを設定。gcr.ioに認証できるようになるgcloud auth configure-docker# あとはpushするdocker tag vertex-custom-training/iris_data:latest gcr.io/<YOUR_PROJECT_ID>/vertex-custom-training/iris_data:latestdocker push gcr.io/<YOUR_PROJECT_ID>/vertex-custom-training/iris_data:latest Vertex AI Trainingで実行する 手元環境用に、 google-cloud-aiplatform をインストールします。 pipenv install --dev google-cloud-aiplatform custom_training 内に、 submit-training-job.py を作成します。 from google.cloud import aiplatformdisplay_name = "verify-vertex-ai-training-iris"# さっき作ったDockerイメージのURLimage_uri = "gcr.io/<YOUR_PROJECT_ID>/vertex-custom-training/iris_data:latest"# ステージング(モデルを置いたりチェックポイントをおくところ)用のバケットを1つ作るstaging_bucket = "gs://<YOUR_BUCKET_NAME>/verify-vertex-ai-training-iris/staging"custom_job = aiplatform.CustomContainerTrainingJob( display_name=display_name, container_uri=image_uri, staging_bucket=staging_bucket)custom_job.run( machine_type="e2-standard-4") このスクリプトを実行すると、Vertex AI Training上で学習が実行できます。 pipenv run submit-training-job.py 学習が完了すると、 submit-training-job.py 内で変数 staging_bucket に設定したGCSの場所に、モデルが保存されていると思います。 感想とまとめ 今回は普通にモデル学習のみを行う部分を作ってみました。 アイリスデータのような小さなデータであれば、デスクトップ上でも実行できてしまいますが、実際もっと大きなデータを扱う場合は、もっと大きな計算リソースが必要になる場合もあります。 大きな計算リソースでNotebookを手動で実行することもできますが、Vertex AI Trainingのようなマネージド学習環境を使うと、学習が終わると使われた計算リソースが勝手に落ちるので、安心だしコスト効率もいいと思います。 また、すごーく長くなりそうなので今回は触れなかったのですが、分散処理やハイパーパラメータチューニングも、コスト効率よく実行できたり、予測サービスとして提供する場合のコンテナも簡単に作れるので、機会があればやってみたいと思います。 ※サムネ画像で利用しているロゴはVertex AI Trainingより引用
はじめに この記事は、自分が効率化をしていくうえでGASを用いたので、GASの使い方を載せたものです。 今回の内容としては、スプシの内容を整形してTeamsに通知するというものになります。 準備 まず、GASで整形した内容をTeamsに送るために準備が必要になります。 まずは、Teams上にチャネルを用意します。 用意したら、三点リーダーからコネクトを選択し、Incoming WebHooksをクリックします。 Incoming WebHooksのセットアップを作成すると、URLが発行されるので、大切にとっておきましょう。 これで準備は終わりです。 内容 まずは、Teamsに内容を送る関数notificationを作成します。 function notification(title,completetext){ var payload = { 'title' : title , //投稿の題名 'text' : completetext //投稿の本文 }; var options = { 'method' : 'post', 'contentType' : 'application/json', 'payload' : JSON.stringify(payload), // jsの値をJSON文字列に変換する }; var url = 'URL'; //さきほど大切にとっておいたURLを記入 UrlFetchApp.fetch(url, options); //送る } 上記のコードを簡単に説明すると、通知する内容をTeamsに適切に表示し、通知できるようにするコードです。 コード内にある、title,textについては次の関数で中身を入れます。 次に、スプシの内容を読みこみ、内容をTeams上で表示できるようにするgetmessage関数を作成します。 function getmessage(content){ console.log(JSON.stringify(content)); //メッセージを表示させる//スプシ関連 var ss = SpreadsheetApp.openById("フォルダID");//スプシのフォルダIDを入力 var sheet = ss.getSheetByName('通知内容'); //読み込むスプシ var range = sheet.getDataRange(); //全範囲を指定 var values = range.getValues();//データ取得 ①上記のコードのSpreadsheetApp.openByIdの後にスプシのフォルダIDをいれます。 ②getSheetByNameの後にはシート名をいれます。 では、内容の作成にいきます。 今回はスプシにある内容から明日の予定を抽出し、出力する内容にします。 //日付関連 var date = new Date(); //現在の日本の日付を取得 var onedate = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1); //1日後にする var twodate = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 2); //2日後にする//タイトル var title = '明日の予定'//本文 var row = sheet.getLastRow(); //最終行の取得 var text = ''; for (var i=1; i<row; i++){ var text1 = ''; if(values[i][0] >= onedate && values[i][0] < twodate){ text1 = text1 + '\n\n<br><u>**' + '・名前:'+ values[i][1] + '**</u>'; text1 = text1 + '\n\n・時間:' + values[i][3]; text1 = text1 + '\n\n・内容:' + '**'+values[i][2] + '**'; text = text + text1; } } if(text == ''){ text = '明日の予定はありません' } notification(title,text);} Teamsに通知がきました。 おわりに 今回は簡単な出力にしましたが、もっとたくさん活用できます。 また、私自身もまだまだ初心者なのでより便利に使いこなせるように精進してまいります。
はじめに 私の所属するサイバーセキュリティ課では、マイナビグループの事業発展をサイバーセキュリティで支えるべく、日々業務に励んでいます。 サイバーセキュリティに関することは何でもやる!という部署で、主に以下のような業務に取り組んでいます。 セキュリティモニタリング セキュリティエンジニアリング セキュリティポリシーや制度の立案・運用 システム企画、設計のレビュー システム実装、運用の支援 インシデントハンドリング サイバーセキュリティに関する情報収集と提供 セキュリティ教育、訓練 現在、私は脆弱性関連を担当しており、脆弱性診断の内製化に取り組んでいます。 本記事では、脆弱性診断の内製化(内製診断)にあたり準備したことをまとめました。 なぜ内製化? マイナビでは、規模の異なる多数のWebサイトを管理しています。 定期的な脆弱性診断を実施するにも、すべてを外部業者に依頼するには、時間もコストもかかりすぎてしまいます。 そこで、一部Webサイトでの脆弱性診断を内製化することで、タイムリーかつコストパフォーマンスよく実施できると考えました。 準備すること 診断方法やツールを選定する 診断すべき脆弱性項目を一覧化する 脆弱性の評価基準を決定する ユーザーからの申請方法を決定する 1. 診断方法やツールを選定する どのように診断を行なうのかを決めます。 ツールを用いた自動診断だけなのか、手動診断も行なうのか、ツールは何を使うのか・・などです。 診断ツールは、無償で利用できるものもあります。「OWASP ZAP」や「Burp Suite」が有名です。 OWASP ZAPを試してみる OWASP ZAPは、オープンソースの脆弱性診断ツールです。 ナレッジが多く、導入が簡単なため、まずはこちらを試してみることにしました。 ソフトウェアのインストール 以下のソフトウェアをインストールします。 OWASP ZAP Java Firefox(診断時に利用するブラウザ) 各種設定 OWASP ZAPのローカルプロキシ機能を設定します。 OWASP ZAPを起動し、歯車マークからローカルプロキシの設定を開きます。 デフォルトでは localhost:8080 となっていますが、必要に応じて変更します。 診断時に利用するブラウザを開き、OWASP ZAPのローカルプロキシの値を設定します。 Firefoxの場合は「FoxyProxy Standard」という拡張機能が便利です。 スキャン実行 ※第三者のWebサイトに、勝手に脆弱性診断を行うと攻撃とみなされます。診断を行なう際は、自身で管理しているWebサイトに限ってください。 プロキシを設定したブラウザ(Firefox)から診断対象にアクセスすると、OWASP ZAPの左ペインにWebサイトのURLが追加されます。 OWASP ZAPには、4つのモードがあります。 「攻撃モード」「標準モード」は、対象外のWebサイトへも診断を行なってしまう可能性があるため、「プロテクトモード」でのスキャン実行がおすすめです。「セーフモード」ではスキャンが行なえません。 「プロテクトモード」では、診断対象をコンテキストに含めることでスキャンが可能になります。 診断対象のURLを右クリックし、「攻撃」を選択するとスキャンが実行されます。 スキャンは、「スパイダー」と「動的スキャン」の2つがあります。 スパイダー 診断対象に存在するURLを洗い出し、レスポンスの内容などを検査します 動的スキャン リクエストパラメータを変えるなどして検査をします レポート生成 メニューバーの「レポート」から診断結果を生成することができます。 HTMLやPDFなど形式を選択できます。 2. 診断すべき脆弱性項目を一覧化する IPAや脆弱性診断士スキルマッププロジェクトなどで、一覧化された脆弱性項目が公開されています。 マイナビでは、 OWASP ASVSなどを参考に策定したセキュリティチェックシートが存在するため、これらを掛け合わせて診断すべき項目を一覧化しました。 実際に診断を行なう際は、対象サイトの仕様に応じて診断すべき項目を精査します。 3. 脆弱性の評価基準を決定する 発見された脆弱性が、どの程度影響のあるものなのかを評価するための基準を決めます。 高・中・低・情報レベルで分けることが多いかと思います。 マイナビでは単に脆弱性自体の危険性だけでなく、SSVCを用いて実際の影響度を考慮し判断することにしました。 SSVCは、判断ポイントがわかりやすく、ユーザーにも説明がしやすいという点で採用しました。 SSVCとは? 脆弱性を対応する基準として、多くの場合はCVSSのベーススコアや深刻度を用いますが、 これは「脆弱性自体の危険性」を表しており、対応の優先順位付けを行なうには情報が不十分です。 実際の影響度は、システムが置かれている環境や扱っている情報の重要度により変わってきます。 SSVCは、この問題を解決するために考案された脆弱性管理のフレームワークです。 以下の4つの情報をインプットとして、4段階の対応レベルを導出します。 情報 攻撃コードの公開有無と悪用レベル 攻撃者にとっての有用性 システムの露出レベル 攻撃された際の業務影響 対応レベル Immediate 全てのリソースを集中し必要に応じて組織の通常業務を停止して可能な限り迅速に対応する Out-of-Cycle 通常よりも迅速に行動し、計画外の機会に緩和策または修復策を実施する Scheduled 定期メンテナンス時に対応する Defer 現時点では対応しない 4. ユーザーからの申請方法を決定する 内製診断を実施したいユーザーからの受付窓口が必要です。 ヒアリングも兼ねて、以下のような項目を入力するフォームを用意しました。 部署名・氏名 サイト名・サイトURL サイトの仕様 プラットフォーム、OS、開発言語、構成など 診断実施希望日 リリース予定日 いつまでに診断を完了する必要があるか確認するためです 注意事項の確認 診断実施にあたり注意事項のページを別途用意しました まとめ 今回は、内製診断をスモールスタートするために準備したことをまとめてみました。 ここに記載したツールの利用方法や評価基準だけでなく、脆弱性に対する理解は必須です。 ユーザーに安心してWebサイトを利用してもらえるように、抜け漏れなくしっかりと診断を実施していきたいと思います。 サイバーセキュリティ課では、様々な施策に取り組んでいます。 脆弱性診断に限らず、さまざまなセキュリティ知識を身に着けるべく自身のスキルアップにも努めてまいります。💪 最後まで読んでいただきありがとうございました!
はじめに こんにちは、IT企画推進部のA.Hです。 IT企画推進部は、デジタルテクノロジー戦略本部内の教育や組織活性を主に担当する部署で、入社した新卒の研修の企画・運営などを担当しています。 例年、マイナビ社に入社したWeb/IT系の新卒は、入社後3か月程度の研修に入りますが、その研修期間中は、研修の最後に日報を提出して一日を締めくくります。 今年からは、新卒研修の日報を管理するシステムとしてRedmineを設定し、提供致しました。 その導入に至った背景、設計の考え方、実際の設定の 雰囲気 などを書いてみようと思います。 (この7つの矩形が何を表すのかはよく分からない。) 導入の背景 さて、一口に日報といっても、会社の業種や規模によって、日報の提出先や確認フローなどは様々かと思います。 そもそも日報管理にシステム?と思う方もいらっしゃるかも知れません。 例えば、チャットツールにチャネルを作り、今日学んだことを新卒が投稿して、それに先輩がコメントやスタンプをつける、という形式でも、十分に日報として成立します。 実際、去年まではチャットやスプレッドシートの活用によって日報活動を行っていました。 現在のマイナビ社はデジタルテクノロジー領域に大変に力を入れており、新卒採用を積極的に行った結果、2022年度は数十名程度のWeb/IT職の新卒が入社することとなりました。 ・・・そうなってくると、ファイルベースでの更新・閲覧は一覧性や可読性、更新検知において段々と窮屈になってきます。 日報は、新卒の学びの定着のための振り返りであると同時に、先輩からのコメントをもらうコミュニケーションの場でもあります。 また、少し考えてみれば、『あるテーマにそって投稿が行われ、関係者が閲覧してコメントを行う』という行動パターン自体は、エンジニアであれば管理ツール・プロジェクト管理ツールの中で、日々実践しているおなじみの行動です。 新卒はWeb/IT職で、先輩達も当然Web/IT職です。 だったらRedmineで良くね? と思い立ったのが、導入の経緯です。 じゃ、なんでRedmineなの?BacklogとかAsanaじゃだめなの? ITSを日報報告に使うなら、まだリテラシーが低い新卒が混乱しないために、通常よくある機能(例えば工数、開始日・終了日とか)を削るような方向になる。 ⇒ツールの自由度が求められる。 新卒は書く人、先輩は読む人。通常の開発のようにメンバーが同じ権限ではなく、ロールが全く異なりやる事も異なる。特に、新卒は出来ることを限定して迷わないようにしたい。⇒運用ルールが極力システムで表現できる。 多分、多少の改善はあれど来年も同じことをやる可能性が高い。構造だけコピーして使いまわしたい。 お金を掛けたくない。何故ならお金を掛けたくないから。 上記の要求に答えるプロダクトは、正直Redmineくらいしか思い当たりません。 多少の予算があれば機能的にはJiraは選択肢になると思いますが、「多くの先輩にみてもらう」という要件と、アカウント課金は相性が悪すぎます。 日報を掲示板の延伸的な感覚で使う分には、運用ルールの徹底がなされればどのようなBTS/ITSでも使えると思いますが、ただでさえ入社して色々な事を詰め込まれる新卒、日々の業務で忙しい会社の先輩達に、ルールを覚えてもらうことを期待するのは酷というものです。 エンドユーザーに提供する機能を削り、統制を提供するという観点においては、やはりRedmineに軍配があがります。この部分において、BacklogやAsanaは最適解ではないと思います。 などと色々と理由を書きましたが、勿論、 新卒の日報管理のためだけにド新規のシステムなんて入れてられない という話もあります。 幸い、別用途で管理者権限を持つRedmine環境を持っているため、日報管理という業務を理解して、それをRedmineの設定に落とし込めれば、ITSで実現できるな、と思えたわけです。 日報管理という業務 端的には、『新卒が日報を書き、先輩や、研修運営チームはそれを確認してコメントする』だけです。 文字に起こせば当たり前のことを書いていますが、少なくともユースケースに登場しそうなアクターが三種類も登場しています。 もう少し具体的に考えてみます。 新卒のやること 新卒は、Web/IT職採用とはいえ、完全なる初心者です。 基本的には何も知らないし、不都合なことをやりうる可能性があることを想定して考慮します。 まず、新卒は自分の書いたチケットは編集できても、他の新卒が書いたチケットは編集できてはいけません。 開発の課題管理であれば、他の人が書いた誤りを訂正出来るので良いですが、今回は新卒研修なので他の人が編集したり、誤って消したりしないようにする必要があります。 また、Redmineは一度削除したチケットを復元する機能は標準では存在しないため、そもそもチケット削除の権限を取り上げる必要があります。 BTS/ITSそのものにも慣れていません。日報記入に関係がない項目は極力画面から消します。 長い目で見ればトラッカーやステータスなどはしっかり教えたい所ですが、今回はそれすらも意識させないように消します。 私達の研修では、先輩役はローテするので新人は自身の先輩を知り得ません。 なので、「担当者」欄も、今はいりません。 一方で、例えばKPTなど必ず入力してほしい項目は記入されて欲しいです。 同期の新卒が書いた日報は、見せることも見せないようにすることも出来ます。 私達は、「良い日報は他の新卒にも真似をしてほしい」と考えているので、見せるようにします。 先輩のやること 先輩は、日報は書きませんので、新規チケットを作成したり、誰かのチケットを編集する必要はありません。 コメント(注記)が出来ればよいです。 運営研修チームのやること 運営管理者は、ふるまいはほとんど先輩と同じですが、万が一に備えてチケットを追加編集する権限は持っておきたいところです。 Redmineの設定への落とし込み 日報管理にまつわることは、何となく伝わりましたでしょうか。 ユースケースを考える時、私はユーザーの行動を起点に機序を想像するんですが、 Redmineのどのあたりの機能でそれを表現するかは、因数分解をするような感じで、あてはめていきます。 Redmineの機能の全体像 まず、Redmineの全体像を簡単にご紹介致します。 界隈では鉄板ですが、JAXAの方がまとめた下記の図をご確認下さい。 引用: https://www.jss.jaxa.jp/about_coda/ Redmineの仕組みは、上図の通り複層的です。 この辺りの仕組みは管理者権限を得てもシステム内で特に説明がないため、割と初見殺しな部分です。 それだけに色々な使い方が出来るのですが、とりあえず一つだけ、太字の部分を覚えて下さい。 上図の「論理的な定義」に含まれるものは、Redmineの環境単位で共通の設定です。 あるプロジェクトAとBで、トラッカーXを使っているとしたら、トラッカーXの修正はプロジェクトAとBに影響を与えます。 新しいRedmine環境なら、自由にトライアンドエラーをすればいいと思います。 既存のRedmine環境においては、必ず先輩の管理者権限の指示やシキタリに従ってください。 プロジェクト全ての設定を一律で変更出来るのは、メリットであると同時に、 下手に触ると、それはもう凄いことが起こります。 慣れないうちはサンドボックスを用意するか、使いまわさずに独自のものでやりましょう。 という訳で、日報を実現するためにRedmineのどこをいじるかを考えながら設定していきます。 ロールの考え方 文字通り、権限をつかさどる機能です。 Redmineのロールの仕組みは、70を超える細かい機能の利用有無をそれぞれチェックして、 ロールに好きな名前をつけることが出来ます。 例えば、新卒のロールを設定する画面はこんな感じです。 新卒は自分の書いたチケットは編集できても、他の新卒が書いたチケットは編集できてはいけません。 上記要件に関連する設定は、この辺りです。 「チケットの編集」なら、誰が書いたチケットでも編集可能ですが、「自分が追加したチケットの編集」は、自分が書いたチケットでなければ編集が出来ない権限です。 (ちなみに、両方適用すると強い方の前者が適用されます。) Redmineは一度削除したチケットを復元する機能は標準では存在しないため、 そもそもチケット削除の権限を取り上げる必要があります。 これもチケットトラッキング周りです。上の図のチケットの削除をオフにします。 Redmineにはゴミ箱による一時退避のような機能はありませんので、基本的にはオフを推奨します(二度目) 今回は新卒・先輩上司・運営と3つの役割が存在していますので、 この3つを設定していくことになります。 試しに、先輩上司のロール設定を見てみましょう。 今回の日報管理には下記の要件がありますので、 先輩は、日報は書きませんので、新規チケットを作成したり、 誰かのチケットを編集する必要はありません。 コメント(注記)が出来ればよいです。 チケットの追加にチェックが入っていません。 おまけ:他の新卒が書いたチケットを見せたくない場合。 日報とは別に、後続課程の新卒向けのインターンシップの報告書については、ネタバレ防止などの観点から他の新卒が書いた日報は見れないように変更しました。 この設定は「表示できるチケット」の項目を「作成者か担当者であるチケット」に設定することで実現します。 ただし、1つのロールでは1通りなため、別のロールとして定義して提供しました。 ロールで出来る事の雰囲気が伝われば幸いです。 トラッカーの考え方 トラッカーは『行動パターンの大分類』です。 今回は新卒からの日報以外の行動パターンはありませんので、トラッカーは「日報」だけがあれば大丈夫です。 トラッカーの設定画面はこんな感じです。 Redmineは、標準フィールドすら使わないことが選べます。 一般的な開発用途であれば、担当者や日付情報などは必須ですが、その日かけば期日もなにもなく、新卒が書いたものを先輩は寄ってたかって読むので担当者も不要。 BTS/ITSそのものにも慣れていません。日報記入に関係がない項目は極力画面から消します。 なので、標準フィールドでは説明だけが残ります。 一方、研修担当としては書いてほしい事は色々ありますので、 カスタムフィールドとして項目を定義します。 今回の研修においては、KPTと自由記入欄を分け、振り返ってほしいことをしっかり入力してもらうようにシステム側で制御をしています。 Redmineは、アカウント情報に事業部や例えば趣味などのカスタムフィールドを拡張することは出来ますが、チケット内に拡張したアカウント情報をLookupするような機能はありません。 なので、新卒は毎回配属事業部を入力しなければならないのでちょっと面倒です。 まぁ書いて覚えることもあるだろうということで。。。 配属事業部やチーム名は、後々一覧画面などで検索する時に必要なため、つけています。 カスタムフィールドの考え方 一方で、例えばKPTなど必ず入力してほしい項目は記入されて欲しいです。 チケットの入力項目のカスタマイズをしたいのであれば、カスタムフィールドです。 先述の通り、トラッカーが定まると、その行動パターンで必ずやってほしいことの土台が何となく見えてきます。 研修日報は、できたこと、できなかったことなど書いてほしいことが明示的です。 帳票項目については、カスタムフィールドを利用することで帳票っぽく仕上げていきます。 例として、Keepの項目のカスタムフィールドはこんな感じです。 一度カスタムフィールドを設定した後、形式を切り替えるは出来ませんが、 こんな感じの選択肢があります。 おまけ:特定の人にしか見せたくないフィールドを作りたい デフォルトでは表示の項目は「すべてのユーザー」が選択されていますが、特定のロールのみ表示するという制御が出来ます。 この部分です。 例えば、社外からの問い合わせに対して、社内でのやりとりを問い合わせしてきた人に見せたくない場合など、同じチケットでも閲覧ロールによって情報を出し分けしたい時などに活用します。 私達の日報管理システムでは特に出番はありませんでしたが、 新卒インターンシップの報告書トラッカーにおいては、メンター⇒管理職と情報を申し送りしたので、その時に活用しました。 ステータスの考え方 ステータスは、チケットの考えうる状態のことです。 例えば、お仕事は「未着手」⇒「対応中」⇒「完了」というフローなのであれば、ステータスはその3つを設定します。 日報にはどういう状態が考えられるでしょうか? まず、新卒の研修が終わった直後、これから日報(のチケット)を書く場合、『未着手』の状態です。 研修日報をすべてチケットとして予めセットするのであれば、 まだ誰も手をつけていない『未着手』という状態ですが、 『研修終了後、15分以内にチケット追加して書いて下さいねー』という場合、 未着手である時間はほとんど存在しないため、『記入済み』という状態から初めてもいいかも知れません。 日報が『記入済み』になったら、先輩上司や運営チームは一定期間の間でチケットを確認してコメントを書きます。 先輩上司と運営チームのどちらが先にコメントを書くか分からないので、一定期間が終了したら、チケットを終了の状態に変更すれば良さそうです。 ステータスの詳細画面はこんな感じで、 Redmineのステータスでは、「終了したチケット」としてステータスを設定すると、 チケットの検索一覧で完了したチケットとして扱われます。 チケット一覧は未完了のチケットのみ表示する設定になっていることが多いので、 もう対応する必要がないチケットを一覧から消し込むことで、先輩上司や運営チームはコメントが捗りそうです。 ステータスの一覧画面はこんな感じです。 この一覧では、このRedmine環境に登場する全てのステータスが表示されています。 日報という業務の流れにおいては、記入済みと完了だけで良いと決めたので、 どこかでこの業務の流れ、 ワークのフロー を指定してやる必要があります。 おまけ:進捗率の2つの考え方 Redmineは、チケット個別に進捗率を手動入力するモードと、ステータスにデフォルトの進捗率を持たせて手動管理しない、二つのモードがあります。 このモードは環境で単一設定のため、どちらかしか選べません。 管理 > 設定 >チケットトラッキングから選べます。 ワークフローの考え方 ワークフローとは、トラッカーとロール別に、カスタムフィールドやステータスの制御を行う設定画面です。 この機能により、新卒は余計な項目の表示を削る、操作できないようにする、完了ステータスに変更できないようにする、などの運用ルールをシステムの機能として設定することが出来ます。 日報トラッカー×新卒のステータス遷移はこんな感じです。 新しいチケットは「記入済み」のみで作成可能で、作成済みから勝手に完了できないようにしています。 一方で、運営ロールは完了しても良いし、誤って完了した場合は記入済みに戻せても良いので、こんな感じになります。 新卒ロールに戻って、フィールドに対する権限タブを見てみましょう。 制約をたくさん入れているのでこんな感じです。 プロジェクトの考え方 チケットは必ずプロジェクトに紐づきます。 プロジェクトでは、使用する機能モジュール、紐づけるユーザーとそのロール、トラッカーとカスタムフィールド、などを定義します。 親子構造にして親が子のチケットをすべてみる、といった事も可能ですが、今回は新卒用の1つのプロジェクトがあれば大丈夫そうです。 モジュールの設定 例えば、ロール側でニュースの機能に権限を振っていたとしても、プロジェクト側でニュースのモジュールをONにしていなければ、このプロジェクトではニュース機能は提供されません。 上図、チケットトラッキングは日報そのものが入ります。wikiはこのシステムの利用マニュアルを記載していて、ファイルはその記事内に添付するためのファイルのために利用しています。 メンバーの設定 メンバー欄は個人情報が満載なので割愛しますが、選んだユーザーがどのロールかを必ず設定します。ここで、誰がどのロールかをプロジェクトに設定していきます。 チケットトラッキングの設定 チケットトラッキングのタブでも、このプロジェクトで使うトラッカーやカスタムフィールドを明示的に指定します。 運用管理者の頭が良ければよいほど、業務フローの派生を単一のトラッカーの設定に落とし込んで提供できるんだと思います。(遠い目) これらを抜かりなく設定すると、利用者の皆様にもおなじみの、 こんな画面がやっと使えるようになります。 チケットの入力画面はこんな感じに仕上がりました。 終わりに 本記事、解説以上マニュアル未満なので雰囲気と謳っていますが、 設定をする時の考え方や雰囲気、伝わりましたでしょうか? 他にも細かい設定やらTipsはたくさんあるのですが、 Redmineの管理者権限がざっくりとやる流れの説明としては以上です。 「へぇ、こんな仕組みになっているんだ」 「あ、こういう事が出来るなら使ってみようかな」 と、思って頂ける方が一人でもいれば嬉しいです。 ・・・てか、めんどくさくね? ・・・まぁ、手間はかかりますよね・・・。 でも、エンタープライズな本格的なものって、大体そういうもんじゃね?という気もします。 Backlogがインスタントラーメンだとすると、Redmineはラーメン屋のラーメンです。 Backlogなら「運用ルールはこうだからね!」だけで終わるもんを、わざわざ運用設計して設定しているので、そりゃ手間暇がかかります。かつ、上手く作れないならカップ麺のほうが美味しいです。運用してれば変更管理もあります。それも手間っちゃ手間。 でも、運用ルールだけで運用できる範囲には限界があります。 限界を超えて声掛けしたりルールを周知したり教育したりミスをダブルチェックするより、 システム制御の方が楽になる、という損益分岐点のようなものが必ずあり、 規模と戦うのであればRedmineのような複雑さが頼もしく、結果的には楽が出来る、という事もあると思っています。 個人的には、カップラーメンより上手いラーメンが作れるなら、そりゃ作ってあげたいという気持ちもあります。根っこはエンジニアだもん。 一方で、やはり運用管理者に一程度の知識経験を求める所から、自由度が高く複雑で難しいのは事実です。 業務フローが頻繁に変わる時期や、個々人で全然違う業務フローの人たちが同じチームです、といった場合、運用者が伴走することのコストは増大します。 また、インフラの運用の側面でもメジャーアップデートへの対応やプラグインの互換性など、それを乗り切るだけのリソースが必要にはなります。 インフラ面においてはホスティングサービスへの移管で軽減されますが、代償としてSQLの直叩きとかメール受信結果をチケットに起票する系の機能は、恐らく使えません。 なにより、UXにおいてはRedmineの管理者権限の機能を理解している人の有無が大きいです。 手作りでも不味いなら仕方ないです。Backlogには勝てません。 お急ぎの新規プロジェクトでRedmineの運用管理経験者がいないのであれば、僕はBacklogを勧めます。 でも、大規模向けなのにオープンソースで無料です。 タダです。 今回は扱っていないですがプラグインによる拡張性もあり、 日本の開発陣の貢献によって2006年からの開発も現在に至るまで連綿と続いていて、 プロダクトとしての安定感も抜群。 AWSのLightsailでもWordPressみたいな感じでサクっと利用可能です。 謝辞 マイナビ社として、Redmineは数多く利用しているOSSの中の1つで、このプロダクトに支えられているプロジェクトが社内には沢山存在します。 改めて、過去から現在までの全ての開発者と開発コミュニティの方に感謝御礼を申し上げます。
はじめに サービスのインフラにAWSやGCPを用いる場合、ドキュメントなどで構成図の画像を見かけることはよくあるかと思います。 また、同じくドキュメントに貼り付けられたER図の画像ファイルを見かけることもあるでしょう。 今回は、これらをGithub上でいい感じに管理していきたいと思います。 ER図を描く ER図をコードで描く方法はいくつかあります。 React-diagramsやReact-flow-chartなんかは、もしかしたら触ったことがあるかもしれません。 ですが、個人的にはvscodeにDraw.ioの拡張を入れ、svgファイルを直接触るが良いと考えています。 ※hoge.drawioファイルをsvgにエクスポートしてhoge.drawio.svgとすると、svgファイルをdraw.ioの拡張で直接編集できます なぜsvgファイルが良いのか Githubは、コードだけではなくsvgの差分を直接見ることができるためです。 参考に、vscodeのDraw.io拡張で描いたER図のsvgファイルにPRを出し、Githubで比較した際の様子をスクリーンショットしました。 このように、Githubではsvgを画像として比較することができます。 また、上記の参考例では左右に並べる形で比較していますが、画像下にあるメニューを操作することで他の形式で比較することも可能です。 構成図を描く 構成図を書く際は、先に挙げたvscodeのDraw.io拡張か、 Diagrams というツールを用いると良いかと思います。 個人的には、特にDiagramsがお勧めです。 Diagramsの何が良いのか 構成図を描く上で一番の問題は、うまいことノードを配置するセンスだと思います。 Diagramsは、このセンスがなくともいい感じに構成図を作成することができます。 他の多くのツールが場所XにYという内容のノードを置き、別のノードZと繋げるという過程を経るのに対し、DiagramsはYというノードを作成してZというノードと繋げるだけで済みます。 どこに置くのか、という点を考えなくても良いので、私のように構成図を描くセンスを磨いてこなかった人間としては嬉しい限りです。 Diagramsの環境を作成する Diagramsの利用には、GoかPython環境が必要です。 社内ではPython利用者の方が多いため、今回はPythonで環境を構築しようかと思います。 パッケージマネージャには、Poetryを使用します。 前提条件として、Python3が導入されていることとします。以下のサンプルでは3.9を用いています。 poetry のインストール pip install poetry# macの場合はbrewでも可 パッケージのインストール poetry init# 以下の質問まで適当に入力Search for package to add (or leave blank to continue): diagramsEnter package # to add, or the complete package name if it is not listed: [0] diagrams [1] railroad-diagrams [2] ipfabric-diagrams [3] airflow-diagrams [4] infrastructure-diagrams [5] sphinxcontrib-diagrams [6] mkdocs-diagrams [7] sphinx-diagrams [8] neon-diagrams [9] diagrams-adapters > 0 # 以下も適当な値を入力またはEnter # Poetryの仮想環境をプロジェクト内に作成 poetry config --local virtualenvs.in-project true # パッケージのインストール poetry install 構成図の作成 参考として、公式ドキュメントのサンプルを作成します 適当な位置に以下の内容のファイルを作成 # sample.pyfrom diagrams import Diagramfrom diagrams.aws.compute import EC2from diagrams.aws.database import RDSfrom diagrams.aws.network import ELBwith Diagram("Web Service", show=False): ELB("lb") >> EC2("web") >> RDS("userdb") 仮想環境で処理を実行 poetry run python sample.py うまく作成できました。 コードにも、特に位置に関する記述をしていないことがわかるかと思います。 終わりに 今回紹介した以外にもこうした図を作成するツールは他にもあります。 例えばmermaid.jsなどであれば、githubや一部のドキュメント共有ツールなどで利用できたりします。 いずれにせよ、その場でだけあればいいといった状況でなければ、コード管理できる環境に寄せるべきである以上、何かしらGithub等で管理できるようにしておいた方が良いかと思います。 もしもしそういった環境に無いのであれば、ぜひ今後はこうした環境で管理できるようにしてみてください。
はじめに 先日、AWSが主催するAWSワークショップ『AWS JumpStart』に参加してきました。 2日間の 9:00 - 18:00 で行う事になりますので、業務の調整が必要にはなりそうですがとても学びが多いワークショップでした。 カリキュラム カリキュラム内容は以下の通りです。 アーキテクチャ検討 とあるテーマに沿ってアーキテクチャの検討・設計します チームで行います 私が参加したワークショップは4人一組で行いました 機能要件が決められており、それをどうアーキテクチャに落とし込んでいくかが肝になります 最後はチームごとに 成果発表会 の時間があります アーキテクティングのコツ AWS Solution Architect Associate(SAA)レベルの知識の座学を行います 事前に案内される動画の視聴を行っておくと理解がスムーズです 以下「事前学習」にリンクを貼ってます ハンズオン(アーキテクチャの構築) AWSからハンズオン用の環境を与えられ、実際にアーキテクチャを構築します マネジメントコンソールからポチポチと作っていきます 参加ツール Amazon Chime 本ワークショップに参加するためのビデオ通話ツールです。主催側から事前にURLが共有され、そちらから参加する形となります Slack サポーターや参加メンバーとコミュニケーションがとれるチャットツールです こちらも事前にチャンネル招待のメールが届きます 私は当時招待メールを見逃し、前日夜に慌てて登録しました(戒め) BlueScape アーキテクチャ作成時に利用するホワイトボードツールです クラウド上でチームメンバーとアイコンをポチポチしながらアーキテクチャを構築していきます 参加日 2022年 08/09(火) - 08/10(水) https://awsjumpstart220809.splashthat.com 本ワークショップの開催は2回目で、今後も何度か開催される予定のようです イベントスケジュール 以下のプログラムでワークショップを行いました。 事前学習 開催当日までに以下の動画を視聴しておくよう主催側から案内がありました。 AWS知識有/無問わず、一度視聴しておいたほうが良さそうです。 視聴中にすでに知ってる内容であると判断したら、2倍速にして視聴してもよさそうです(ある程度時間も要するので) 【はじめてのアーキテクティング (60分)】 https://www.youtube.com/watch?v=cD870G8uqhY 【AWS入門】 https://youtu.be/Kb7ZEBwqUAI?t=2006 プログラムの詳細 オープニング 主に以下の内容について説明がありました。 ワークショップの趣旨の説明 スケジュールについて 「アーキテクチャ検討」におけるチームごとにツールアクセス先のURLの共有 Amazon Chime BlueScape 上記「参加ツール」参照 アーキテクティングのコツ 上記の「事前学習」と内容が被るところもありますが、主催側から「アーキテクチャ検討」を行う上でのコツをスライドに沿って説明いただけます。 課題発表/チーム自己紹介 「アーキテクチャ検討」での課題が発表されます。 また、 基本的に このタイミングで初めてチームメンバーを知る事ができます。 アーキテクチャ検討 本ワークショップの一番の目玉です。 あるテーマに沿って、チームメンバーで話合いながらBlueScape上にアーキテクチャ(構成図)を作成していきます。 「課題発表」にて提示された要件定義が箇条書きで示されていて、それらを解決するサービスを模索し構成図におこしていきます。 また2日間のあいだに、20分×3回、サポーターの方に質問・相談できる時間が設けられています。 チームとして動いているため、かなり頭を使います。 適度に休憩を提案するタイムキーパーを作るのがおすすめです。 ハンズオン(ALB+ECS+RDS) ECS(AWSのコンテナサービス)を採用した簡易的なアーキテクチャを、マネジメントコンソール(GUI)上で作成します。 手順書(パワポ)と主催のデモを基に構築していきます。 ※最後には個別フォローもあり EC2ではなくECSを採用していたため、 コンテナについても同時に学びたい自分 にとっては学びの大きいハンズオンでした。 また セキュリティグループという壁に阻まれる可能性が高い ので、手順を意識して(リソース同士の通信状態を把握して)行うのが良いです。 成果発表会 発表時間は7~10分程度、残りの10分程度で他チームから質問を受けたり、主催からレビューを受けられます。 発表の仕方は自由ですが基本的にはBlueScapeで作成した構成図を画面共有しながら、チームメンバー内で1人選出し発表するのが基本的なケースでした。 アーキテクチャに正解はない(多様の構成がある) というスタンスなので、間違いを恐れずに肩の力を抜いて発表すれば間違いないです。大丈夫です。怖くない。 クロージング・懇親会 主催者から全体の総括があり、懇親会は自由参加となります。 懇親会では、サポーターの方が考えたアーキテクチャを公表・解説していただけました(アーキテクチャに正解はないというのはありつつも、見本となるアーキテクチャは気になりますよね) 我々のチーム成果物 2日間の汗と涙の結晶がこちらです! 特徴としては、ECS/Fargate構成としてコンテナそれぞれに機能を持たせ、AutoScalingで冗長化構成をとりました。 また機能要件について軽く触れると以下のような要件を考慮したアーキテクチャを構想する必要がありましたので、それぞれの要件に沿ったAWSサービスを構成図に組み込みました。 1秒当たりのリクエスト数 データの保存期間 ピーク利用時間帯 提供エリア など 感想 アーキテクチャ検討ではチームメンバー4人のうち1人は同社同部署メンバー、もうお二方は別会社でアプリ開発に携わっている方々でした。 我々は普段インフラ寄りの業務に携わっているため、アプリ/インフラの両面を考慮した議論ができました。 そのため、アプリ面での意見がとても新鮮に思えました(アプリ/インフラ側それぞれの意見で議論になった際の落としどころの決定が難しいと感じ、個人的な課題だなと感じました。 さらにハンズオンにてECSを学べた点も、これからコンテナを業務で触る自分にとっては勉強になりました。 全体を振り返ると、実践的という点でかなり勉強になりました。 書籍やセミナー等でAWS各サービスの名前と概要・用途は学んでいましたが、その知識を実務や今回の場で100%活かせるかといったらそうではないので、今回のワークショップへの参加で次のステップに進めたように感じました(ドリブルやパス・シュートを練習していた人間が、初めてコートに立たせてもらえたときの感覚に似ています) そのため、多少の知識はあれど、実務的な設計の経験がない(少ない)人にとっては、得るものが大きいワークショップであるかなと思いました。一方で知識に不安がある方は、 グループワークでの話し合いに参加していけるように という観点で、上記でお伝えした「事前学習」を行っておくことをおススメします。
はじめに 皆さん、こんにちは。ITディベロップメント1部のI.Kです。 何気なく普段使っている電話ですが、これってどんな仕組み何だろう?とふと思ったので、「電話ってそもそもどんな仕組み?」「エンジニアでも作れるの?」を調べてみました。 電話の種類(固定電話とIP電話)について 電話には「固定電話(さらにアナログ電話とひかり電話の2種類がある)」と「IP電話」の2種類があります。2種類の違いは何かと言うと、音声通話を行うネットワークの接続方法が異なります。 固定電話は、従来の固定電話回線)を用いて電話と電話を接続しますが、IP電話は主にインターネットを構成する時に用いられるIPネットワークを利用して音声通話を実現します。 IP電話の仕組みをもう少し詳しく説明すると、 SIP(Session Initiation Protocol)サーバーに、自分と通話相手の電話番号とIP情報を保持し、SIPサーバーにIPを指定してリクエストすることで電話の発信を可能にしています。 電話ってシステムエンジニアに作れるのか? 固定電話は流石に作れませんが、IP電話であれば何と作れてしまいます!! (もちろんそれなりの知識やスキルは必要ですが) ここでは2種類の例を使って、少し詳しく解説していきます。 方法①オープンソースソフト「Asterisk」等を使ったSIPサーバーから構築する 一つ目のやり方は「オープンソースソフト「Asterisk」等を使ったSIPサーバーから構築する」です。 過去の実装例で、とある自治体がIP電話500端末を外注すると2億円かかるところ、内製で構築を行い820万で完成させた事例がありました。2億→820万ってすごいですね・・。 ざっくり実装イメージは以下の通りです。 (参考サイト: http://st-asterisk.com/archives/22 ) Lunixサーバーの設定ファイルに下記のような記載をすることで、内線同士の発信が可能になります。 [default]exten => 201,1,Dial(SIP/201,30,r)exten => 201,2,Hangup()exten => 202,1,Dial(SIP/202,30,r)exten => 202,2,Hangup() exten => のあとに、内線番号,処理順番,処理コマンドを書きます Dial():発信する。 Answer():着信に応答する。 Playback():サウンドファイルを再生する。 Hangup():通話を切断する。 調べた感じ、難易度が高そう(内線の構築方法は簡単そうだが、外線の設定が大変そう)だと感じました。 通話料が掛からないことがメリットですが、サーバー代金はかかります。そうなると保守作業も大変そうだなという印象です。 方法②CPaaS(Communications Platform as a Service)を利用する 二つ目のやり方は「CPaaS(Communications Platform as a Service)を利用する」です。 CPaaSは通信機能をAPIで接続するクラウドサービスのことで、音声通話やSMS、映像会議、通話録音・音声認識を実行するAPIを従量課金で買う形になります。安く簡単に始められますが、通話時間が長いと費用は高くつく恐れもあります。 有名どころですと「AmazonConnet」です。 SFA連携、録音、通話モニタリング機能あり、音声分析、文字起こし機能のある電話基盤サービスとなります。 他にも「Twilio」「pluscomm」「Bandwidth」などがあります。 ざっくり実装イメージは以下の通りです。 ※Pythonの実装サンプル ▼Twilio ▼Bandwidth インポートを行って、call関数に引数を渡すと電話をかけられる形になります。 これであればWEBアプリを作る感覚に近いなと感じました。 おわりに 今回は「電話」について取り上げました。 普段何気なく使っているものですが、仕組みは案外知らないものなので、一つ勉強になって良かったです。 最後までお読みいただきありがとうございました。 引用 https://atmarkit.itmedia.co.jp/ait/articles/0711/16/news146_3.html https://www.twilio.com/ja/docs https://dev.bandwidth.com/
はじめに みなさんはWEBサイトをスクレイピングしたことありますか? 僕は入社前に内定者サイトをスクレイピングしたことがあります。 そこで、スクレイピングをやってみたい人のために、内定者サイトをスクレイピングしたときのことを記事に書きました。 ※入社した今、既に内定者サイトは閉鎖されており、スクショも撮っていなかったので画像などはないのですが、イラストでイメージしてもらえれば幸いです。 もともとスクレイピングに関する経験があったわけではなく手探りでやっていった結果なので、いろいろ間違いや不正確な記述があると思いますが、参考程度にご覧ください! スクレイピングとは スクレイピングという言葉を聞いたことがあるでしょうか? wikipedea によると ウェブサイトから情報を抽出するコンピュータソフトウェア技術のこと。 らしいです。 例えば、全国のカラオケチェーン店で一番平日昼のフリータイムが安い店舗を探したいとします。 500個近いすべての店舗のサイトを見れば、一番安い店を見つけることができるでしょう。 しかし、この作業には膨大な手間がかかり、見逃しなどもあるかもしれません。そういった作業を自動化できるのがスクレイピングです。 上記の例で言うと、まずカラオケ店の公式サイトから店舗一覧や各店舗のサイトへのリンクを取得して、それぞれの店舗のサイトにアクセスします。 次に、そのサイトのhtmlを解析することによってほしい情報(平日昼のフリータイム料金)を取得します。 これはあくまでイメージなので実際はこんな簡単にうまくはいかないと思いますが、こういったことがライブラリを使えば意外と簡単にできちゃいます。面倒な仕事はコンピューターにさせちゃいましょう!! 注意点 スクレイピングは、法律的にグレーなところがあります。実際、過去に逮捕者も出ているようです。 趣味の範囲でやっている限りは逮捕されることはあまりないと思われますが、サーバーの負荷にならないように適宜スリープを入れるなどして、迷惑にならないようにしましょう。 内定者サイトをスクレイピングした背景 以前の内定者サイトがどのようなものだったのかは知らないのですが、 私の時は、内定者の自己紹介ページ、チャット機能、採用部からのお知らせなどいろいろな機能があって、僕は入社後にマイナビで働く日を想像しながら日夜眺めていました。 ただ一つ、内定者サイトに不満がありました。 それは、自己紹介ページにおいて、職種での絞り込みが出来ないことです。 内定者サイトの一覧画面からは職種が分からず、総合職も含めた全同期の中からなかなかシステム職の同期を見つけることが難しかったです。 エリアでの絞り込みはできたので、システム職が働くことになる東京(関東だったかも?)を選択すればある程度絞り込むことはできたのですが、総合職の割合が多いため、システム職の同期を効率的に見ていくことができませんでした。 そこで、研修でPythonを使うということは聞いていたので、就職前の3月にPythonの復習も兼ねて内定者サイトをスクレイピングしてシステム職の同期を見つけてみようと考えました。 環境・言語・ライブラリ 今回は、以下のような環境でスクレイピングを行いました。 windows Python Selenium Beautiful Soup 実装の概要 実際のコードの処理の流れにそって、説明していきたいと思います。 次のような順番でプログラムは処理を行います。 ログイン それぞれの内定者の自己紹介ページに行く htmlを解析してシステム職か判断する 詳しくは、以下で説明します。 ログイン 内定者サイトは全世界に公開されているわけではなく、パスワードなどを入力してログインする必要があります。 ログインが必要ないサイトと比べていろいろめんどくさくなるのですが、今回はPythonのSeleniumというライブラリを使用することによって、比較的簡単に侵入(?)することができました。 Seleniumは UI テストを自動化する目的で開発されたWeb ブラウザの操作を自動化するためのツールです。パスワードのフォームを選択してそこにパスワードを記述する処理を書いてあげればログインすることが出来ます。 ちなみに、1日に10回くらいログインすると警戒されて、CAPTCHA(私はロボットではありません的なやつ)が追加されるので、そうなったらお手上げでした。 僕は当時、夜から作業を始めて、CAPTCHAが出てきたら寝る、という生活をしていました。 個々の内定者の自己紹介ページに行く ログイン状態を維持したまま、自己紹介ページの東京エリアのリンクを選択して移動します。 ページネーションが実装されており、1ページあたり20人しか表示されていないので、そのページの最後の人のページをみたら、次のページへのリンクを選択しなければなりません。 また、最後のページの最後の内定者に到達したらそこで処理を終了します。 こういった細々とした場合分けに結構手間をとられた気がします。 また、サーバーへ過剰な負荷を与えないよう、1人の自己紹介ページに行くたびに1秒スリープをさせました。そのせいもあってすべての内定者をチェックするのに数分くらいかかってた気がします。 システム職か判断する 個々の内定者の自己紹介ページのhtmlをBeautiful Soupによって解析します。htmlを解析し、職種の所の文字列だけを抜き出し、それがITエンジニアなら、名前と自己紹介ページのurlをリストに格納します。 内定者サイトの場合、ddというクラス名の表の3行目に職種名があったので、そこの値を抜き出しました。 なお、職種は内定者が記入するものではなくもともと設定されている項目なので、表記の仕方が人によって違うなどの問題はありませんでした。 実際にプログラムの実行結果を見て頂きたいのですが、内定者サイトは既に閉鎖されており試すことが出来ないので、ここでは「マイナビ」を例にして簡単なスクレイピングを行い、Beautiful Soupを利用したスクレイピングの威力をご覧頂こうと思います。 まず、requestsというライブラリを使用して、「マイナビ」の内容を取得します。 from bs4 import BeautifulSoupimport requestsurl = "https://job.mynavi.jp/2024/?utm_medium=e-cpc&utm_source=google-text&utm_campaign=2661271774_16693468728&gclid=CjwKCAjw1ICZBhAzEiwAFfvFhKXVJyim0w6ZeJF2VcnY3NUXfVxN-q_KMSNR0gC_ylFNhcS9TGrCaRoChUAQAvD_BwE"r = requests.get(url)soup = BeautifulSoup(r.text, "lxml") Beautiful Soupのprettifyというメソッドを利用すると、「マイナビ」の内容を見やすく整理してくれます。 <!DOCTYPE html><html lang="ja"> <head> <meta charset="utf-8"/> <title> マイナビ2024 - 学生向けインターンシップ・就職情報サイト </title> <meta content="学生向けインターンシップ・就職情報サイト。インターンシップ情報や就活スケジュールなどの就活準備コンテンツを提供しています。" name="description"/> <meta content="noarchive" name="robots"/> <meta content="telephone=no" name="format-detection"/> <meta content="summary" name="twitter:card"/> <meta content="@mynavi2024" name="twitter:site"/> <meta content="マイナビ2024 - 学生向けインターンシップ・就職情報サイト" property="og:title"/> ... ... あとは、取得したい箇所のCSSセレクタを指定することによって好きな情報をとってこれます。 print(soup.find_all('title'))# <title>マイナビ2024 - 学生向けインターンシップ・就職情報サイト</title>を取得 print(soup.find_all('p', class_='list-hdg'))# <p class="list-hdg"><b>広告</b></p>, <p class="list-hdg"><b>福祉サービス</b></p>, <p class="list-hdg"><b>福祉サービス</b></p> このように、わずか数行のコードでサイトから好きな情報をとってくることが出来ました。あとは取得した文字列で場合分けしても良いし、いろいろなサイトに回って情報を収集しても良いです。 夢が広がりますね! その後 実は、システム職の名前が分かったところで満足して、それぞれの内定者ページを見に行くことはしていませんでした。本末転倒です。 しかも入社してしばらくして22卒の内定者サイトは閉鎖してしまったので、もう何も残されていません。。 ただ、内定者サイトで予習なんてしなくても仲良くなれる良い同期に恵まれたのでオッケーということにしています👌 ぜひみなさんも、スクレイピングを使ってめんどくさい作業は全てコンピューターに任せましょう!
はじめに どうも、こんにちは。 突然ですが皆さん、 拡張現実 ってご存じですか? 名前の通り「現実を拡張する」もので、現実世界のものに、本来存在しない仮想の情報を表示します。 AR という呼び方のほうが耳にするかもしれません。 ※この説明ではピンとこない方向けに端的に言ってしまうと、ポケ○ンGOをイメージしてもらえればと思います。 今回はARを使って自分を召喚してみました。 ARの種類 この素敵なAR君ですが、大きく分けて3つの種類があります。 ロケーションベースAR、マーカー型AR、マーカーレス型AR です。 それぞれがどんなものか、以下で簡単に説明したいと思います。 ロケーションベースAR GPSなど、各種センサーによって位置情報を取得し、その場所に基づいて情報を画面上に表示する手法です。地図アプリなんかで活用されています。 マーカー型AR マーカーと呼ばれる図をカメラで読み取り、その位置に情報を表示する手法です。マーカに基づくので、細かい位置調整などが比較的容易ですが、現実世界にマーカーを用意する必要があります。 マーカーレス型AR 名前の通りマーカーは必要とせず、カメラ映像から得た情報(風景や建造物、看板、人など)を識別し、それぞれに合わせた情報表示する手法です。 マーカー型ARを使ってみよう さて、前置きはこれくらいにして実際にARで遊んでみましょう。 今回はマーカー型でやっていきたいと思います。 今回使用するもの 以下の2つのものを使用します。それぞれのダウンロードに関しては記載を省きます。 Unity いわずもがな、ユニティ・テクノロジー社が提供する、名の通ったゲーム開発プラットフォームです。手軽に3Dゲームの開発ができ、高いシェアを誇っています。ゲーム以外の分野でも活用することができるため、様々なものが作成されています。 Vuforia Vuforiaは、AR開発においてよく使用されているAR開発用ライブラリです。カメラからオブジェクトや空間を認識し、AR体験のできるアプリを開発できます。認識精度が高いことで知られており、平面のマーカー認識、立体のマーカー認識、カメラからマーカーが離れた際の追従認識など、様々な事が簡単に実装させてくれます。 すごい子です 。 VuforiaでARマーカーを作成しよう! さっそくですが、ARマーカーを作成します。 VuforiaにはもともといくつかのARマーカーが用意されていますが、自分で任意の画像をARマーカーにすることも可能です。せっかくなので今回はARマーカーも自作していきたいと思います。 まずは Vuforia Engine developer portal にアクセスします。 ARマーカーを作成!…のまえにライセンスをゲットする必要があります。 ページにアクセスしたらログインをして、Developタブを選択し、Lisence Managerを開きます。開いたら、「Get Basic」をクリックしてライセンスを作成。作成時にライセンスの名前を聞かれるので、任意で設定して作成! 作成ができたら、ここで一度作成したライセンスを開き、License Keyをコピーしておきましょう。 次にTarget Managerタブを選択し、「Add Database」をクリック。ここで作ったデータベースにARマーカーを作成していきます。 作成時にポップアップが表示されるので、任意の名前を入力し、TypeはとりあえずDeviceを選択します。 さあ、データベースを作成したらいよいよARマーカーの作成です!自分が作成したデータベースを開き、「Add Target」を選択します! 今回は平面の画像をARマーカーとしたいので、TypeはImageを選択します。 File欄では任意の画像を設定します。ここで設定した画像がそのままARマーカー委になるわけですね。 今回は自分を召喚することを最終目標としているので、拾ってきたフリーの魔法陣の画像を使用。魔法陣っていいよねやっぱり。 Widthはなんとなく1です。 Name欄は言わずもがな、ノリでお願いします。 これだけ入力してAddを押せば、もうARマーカーの完成です。自分のデータベースに新しく魔法陣が追加されていることが分かります。 ちなみにRating、星マークの欄ですが、これは「ARマーカーとしてどれだけ適しているか」みたいなことを指し示しています。おそらく。 作成したARマーカーを使用するためには、データベースをダウンロードする必要があります。「Download Database(All)」からダウンロードをします。今回はUnityで使用したいので、Unity Editorにチェックを入れます。 ここまでやればもうARマーカーの準備は完了、あとはUnity側でちょちょっと遊ぶだけですね。 召喚だってできる。そう、Unityならね… ここからはUnityでの作業に入ります。Unityで適当に3Dのプロジェクトを立てて、そこにVuforiaを入れていきます。ここはUnityのバージョンによって手順が異なるので省略します。ノリでいきましょう。(※筆者はVuforiaのWebページからダウンロードしてきて入れました) では、始めて行きましょう。 まずは先ほどダウンロードしたデータベースをプロジェクトにインポートします。Unityのプロジェクトを開いた状態で、ダウンロードしたファイルをダブルクリックするだけで可能です。ウインドウが表示されるので、全部チェックされた状態でImportしてしまいましょう。 つぎに、 ARCamera を追加していきます。Vuforiaが無事入っていればGameObjectにVuforia Engineの欄が追加されているはずなので、その中からARCameraを選択します。 このタイミングで、デフォルトで生成されるCameraは削除しておきます。 ここからはARCameraの設定をしていきたいので、ARCameraを選択し、Vuforia Behaviourの 「Open Vuforia Engine configuration」 を開きます。 するとLisence Keyを入力する欄があるので、前章でコピーしておいたキーを入力してください。 さあ、ここまででもうARマーカーを捉えるためのカメラの設定は済みました。次はARマーカーを設定していきます。 先ほどのARCameraと同じく、GameObjectから辿っていくと Image Target というものがあるので、こちらを作成してください。こいつがARマーカです。 作成したImage Targetを選択すると 「Image Target Behaviour」 という欄があるので、Typeを 「From Database」 に設定してください。 そうするとその下のDatabaseの欄とImage Targetの欄で自身が作成したデータベースとARマーカが選択できるようになるので、任意のものを選択してください。 やったぞ!!魔法陣だ!!!やった!やった!!!!! (魔法陣じゃなくて召喚陣では…?) さて、カメラができた、ARマーカーもできた、とくればあと足りないのでARマーカーを読み取ったうえで出てくるもの。ARで表示するもの。 そう、私です。 というわけでUnity内に、本日召喚する私を用意しました。 大学時代の私です。今回はこいつを召喚していきます。 というわけでUnity内に配置していきます。 ドーン! デカ過ぎんだろ… このままではデカ過ぎます。こんなにデカくてはテニスもできません。 ということでサイズを調整します。 今回の方法だと、Unity上のImageTargetと表示するもの(今回は筆者)のサイズ関係はそのままARで再現されます。つまり今のままだと、魔法陣(召喚陣)に対してとんでもなくデカすぎる筆者が表示されてしまうわけです。 ほどほどのサイズに調整しました。いい感じですね。 最後に自分の画像をImageTargetの子オブジェクトにしたら完了です。子オブジェクトにするというのがピンとこない方もいらっしゃるかもしれませんが、まああまり気にしなくても良いです。二つのオブジェクトを関連付けるくらいの気持ちで見ていてください。画像のオブジェクトをドラッグアンドドロップでImageTargetにもっていくだけでできます。 それでは…実行!!! でたああああああああああああああああああああああああああああああああああああああああ!! ついに自分を召喚することができました。手乗りサイズの可愛い(??)筆者です。ARマーカーによって位置や向きが決まるので、もちろんARマーカーを動かすと表示しているオブジェクトも動きます。 いやあ、満足です。 終わりに 無事、自分を召喚することができました。ARって面白いですね。 これ、今回は画像を使用していますが、もちろんUnity内の3Dオブジェクトや、インポートしてきた3Dモデルでも可能です。 動きのあるものでも可能なので、夢が広がりますね。 エフェクトを付けたりもできるわけです。 人はだれしも、いつかは自分を召喚したくなる時が来るかと思います。 そんな時にはぜひためしてみてはいかがでしょうか。 それでは、またお会いしましょう。
はじめに GitHubを開くのが面倒くさい。。なんで、わざわざブラウザ操作してPull Request作らんといかんのか。 後回しにすると忘れるので気がついた時にissueを書きたいけど、ブラウザを立ち上げると集中力が切れるのでエディタやターミナルからissueを書きたい。。 割とよくある悩みだとは思います。少なくとも私はそうです。 そんなわけで、それを解決するためのツール、 GitHub CLI を今回触ってみようかと思います。 GitHub CLIは、GitHub公式が提供しているCLIツールです。 ghコマンドを用いて、issueの立ち上げ、PRの作成及びレビューなどのGitHubで行う各種操作を実行できます。 インストール Macの場合は、Homebrewで持ってこれます。 Linuxであればaptやdnf, yum等でインストール可能です。 Linuxでのinstallについて、詳しくは こちら を参照 # UbuntuなどのDebian系type -p curl >/dev/null || sudo apt install curl -ycurl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \&& sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \&& sudo apt update \&& sudo apt install gh -y# CentOS後継やRHELなどのFedora系sudo dnf install 'dnf-command(config-manager)'sudo dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.reposudo dnf install gh# Amazon Linuxなどのdnfが使用できない一部環境のFedora系sudo yum-config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.reposudo yum install gh 使い方 --help オプションによる解説がかなり充実しているため、わからなければヘルプを見れば大体わかるかと思います。 主に使用すると思われるのは、以下のコマンドです。 PRが作成されたブランチを確認したい gh pr list で既存のPRを確認 gh pr checkout <number> で該当のブランチにPRのID指定でチェックアウト ローカルで確認したPRにapproveをつける gh pr review <number> -a コメントや変更依頼なども可能です PRの作成 push後に gh create --title "タイトル" -b "本文" 今いるディレクトリのリポジトリをブラウザで開く gh browse issueの作成 gh issue create -t "タイトル" -b "本文" -l bug issueの確認 gh issue list gh issue view <number> --web オプションでブラウザを開くこともできる 終わりに Push後にいちいちブラウザ開いてPRを作成するのは大変面倒だったため、このコマンドは嬉しいコマンドでした。 ブラウザを開かずとも VScodeの GitHub Pull Requests and Issues でも可能ではあったのですが、こういったことはコマンドでできた方が無駄にタブを増やさず済むのでコマンドで済ませた方が良いかと思います。 よければぜひ触って見てください。
きっかけ はじめまして、私はインフラエンジニア(42)です。 突然ですが、のっぴきならない事情にて以下のような要件の環境を至急手に入れる必要がありました。 EC2を42台準備 EC2にはSSH接続をする SSH接続する際のIPアドレスは変えたくない 時期によってインスタンスタイプを変更 EC2インスタンスのインスタンスタイプを変更するには、そのインスタンスを先に停止する必要があります。 EC2インスタンスを停止後に再起動しますとパブリックIPは変わってしまいます。 つまり上記の要件を満たすためには42個の固定IPが必要となります。 早速Elastic IPアドレスを なんとmaximumと怒られてしまいました… どうやらElastic IPはリージョンあたり5つまでと制限されているらしいのです。 パブリックインターネットアドレスは数に限りのあるリソースなので仕方がないのですが、そうも言ってられません。 今回は Service Quotas というAWSのサービスを利用して、Elastic IPの上限を緩和してみましたのでこの記事に残しておきます。 上限緩和のお願いをしていく サービス>Service Quotas>ダッシュボード Service Quotasのダッシュボードを開くと、その環境内での色々なサービスで上限があるとわかりますね。 AWSのサービス上で「EC2」と検索し、EC2サービスクォータ上で「IP」と検索すると お目当てのElastic IPまでたどり着くことが出来ました。 EC2-Classicというのは、単一のフラットネットワーク内で稼働するインスタンス環境のことで、VPCが提供される前に提供されていました。 ちなみに2022年8月15日に廃止になりました。 というわけで今回はこっちを選択します。 デフォルトのクォータ値は5のようです。 42まで爆上げしてみます。 保留中のリクエストに入りました。 上限緩和されてた 数日後、解決されていました。 具体的に何日ほどだったのか確認できておらず申し訳ないのですが本当に「数日程度」でした。 おまけ Service Quotasって一体何だったんだ AWS アカウントには、AWS のサービスごとにデフォルトのクォータがあり、基本的にはリージョンごとに存在しています。 ちなみに以前はクォータではなく「制限」と呼ばれていたそうです。 Service Quotas は、AWS のサービスクォータを 1 か所から管理できるようにする AWS のサービスです。 機能としては以下の2つです。 クォータ値を確認 クォータの引き上げをリクエスト Service Quotas でのリクエスト対象として、まだ利用可能になっていないサービスもあります。 その場合は AWS サポートセンターを使用してクォータの引き上げをリクエストすることができるとのことです。 課金体系としては、クォータの引き上げを行っただけでは請求は発生しません。 実際にAWSのサービスを使用したりリソースを作成した時点から請求が発生します。 今回はのっぴきならない理由で42個もEIPを取得することにはなりましたが、 クォータによって、ユーザーが必要以上にサービスを使用して請求額が膨大になってしまうことも防いでくれていると考えられます。
はじめに 今年もアドベントカレンダーの季節がやってきました。マイナビからも20人以上の社員が参加して、クリスマスまで毎日記事を投稿しますのでお楽しみに! Twitterでも発信中 マイナビの公式Techアカウントでも、毎日更新していきます。 こちらもぜひご覧ください! @mynavi_tech