電通総研のブログ - TECH PLAY

TECH PLAY

電通総研

電通総研 の技術ブログ

全867件

みなさん、こんにちは。コーポレート本部コーポレートHRユニット人事部の今村と申します。 私自身、人事部ではここ10年ほどは人材開発、組織開発にどっぷり関わってきたのですが、今年から「ピープルアナリティクス」というテーマに取り組んでいます。 「HRアナリティクス」とか「データドリブン人事」とか表現はいろいろありますが、要は 「人」に関する取り組みの判断においてこれまで重視されがちだった「勘と経験」だけではなく、「人」のデータを収集/可視化/分析して様々な意思決定の確度を向上させよう ということをねらいとしたものです。 マーケティング を始め、日常のビジネスプロセスではごくごく当たり前の取り組みが、昨今、ようやく人事の領域でも本格的に注目されてきました。 個人的にこの領域には以前から興味があり、少なからず業務の中で取り組んできたこともあったのですが、ここに来て改めて新たな領域へ本格的にチャレンジなので、まずは体系的に学ばねば、ということで、今年に入ってからから本格的にピープルアナリティクスの勉強を始め、先日、 Academy to Innovate HR(略称AIHR)が認定している「People Analytics Specialist」のcertificationを取得することが出来ました ので、その内容について紹介いたします。 AIHRという学習機関 この「Academy to Innovate HR」は2016年に設立されたオランダの学習機関で、HR(人事)プロフェッショナルとして必要なスキルをオンラインで学べる学習プラットフォームです。 ※AIと略しているので一瞬あのAIと勘違いしがちですがもちろん別物です。 https://www.aihr.com/ その名の通り、HR全般を学べる学習機関で、People AnalyticsやDigital HR、OD(組織開発)等11のcertificationに加え、Hiring & Recruitment Strategy、Employee Experience and Design Thinking等の学習コースがあり、中にはBlockchain and HRと言った、日本ではなかなかお目にかかれないコースもあります。 そもそも日本ではなかなか「ピープルアナリティクス」という領域にフォーカスして体系的に学べる場が見つからなかったのですが、私が社外活動として理事も務めている人材育成のグローバルな会員組織である「ATD(The Associaton for Talent Development)」日本 支部 ( https://www.atdj.jp/atd-imnj )の方から紹介され、ここに来て業務上の必要性にも迫られたことあり、覚悟を決め本格的に学び始めることにしました。日本ではまだ全くと言っていいほど馴染みがないので、ちょっとレア感もあるのが自分好みだったということもありチャレンジしてみましたが、予想以上に価値のある学びの多い内容でした。 もしかすると、日本人でこのcertification取得したのはまだほとんどいなさそうなので、そういう意味でも心地よい達成感があったりします。 AIHRの特徴 なお、このAIHRは、 ・すべて英語(但し、字幕付き) ・すべてオンライン ・費用は、こんな感じ。 いくつかコースのオプションがあり、個々人の学習スタイルに応じて選択できる点も学習しやすい点だと感じました。 People Analytics certificationのカリキュラム このPeople Analytics certificationで学べる内容は、以下のとおりです。 「Statistics in HR」のパートがいわゆる分析手法をやや深めに学ぶパートです。深めと言っても、数学に全く明るくない私にも無理なく理解できる内容で、実際にデータを自分でいじりながら学ぶこともできるので、実務で活用するイメージも湧きやすくできています。(そもそも統計で使われている専門用語って「英語だとこう言うんだー」という素朴な発見もありました) なお、このパートについては、日本語で統計を解説している一般のサイトも並行して使いながら学ぶと、より効率的に学べると思います。 認定取得に要した学習時間 ちなみに、今回certificationを取得するまでに要した時間ですが、 おおよそ毎日30分~1時間の勉強で、約3か月 かかりました。一つのLessonの動画がおおよそ15-20分程度(+ボーナスレッスンや推奨動画/記事等もあり)なので、比較的無理なく学習できるペースでした。(もちろん期間中は何度でも視聴可能です) この学習コースから学んだこと 前述したように、カリキュラムとしては、 1.HR Analytics Leader 2.Statistics in HR 3.HR Data Analyst 4.Capstone Project という4つのモジュールに分かれていて、People Analyticsの基礎的な考え方や、分析プロセス、 フレームワーク 、そして具体的な分析手法等を学びました。「People Analytics」という名前の印象から、「Analytics」の手法を掘り下げて学ぶイメージがあるかもしれませんが、 全体を通して、再三、強調されている(と私が感じている)点は、「ビジネス課題」へのアプローチの重要性とビジネス インパク トを重視する、 ということです。 こう書くととても当たり前の話なのですが、単に人事関連のデータを分析する、そして インサイト を出す、予測をする、ということはもちろんPeople Analyticsの大事な要素であり、プロセスではあるものの、そもそもの目的はビジネスゴール(組織目標)を達成することである、というメッセージが何度も出てきます。 さらに言えば、 ビジネスゴールを達成するためには、いくつかの課題があり、その課題と人のパフォーマンスの関連をしっかりと紐づけた上で、その課題が生まれた背景やコンテクストも正しく理解することが重要 ということです。要は「 チェンジマ ネジメント」のプロセスそのものだよ、ということもメッセージの一つでした。 また、 Agile で進める、small-winを積み重ねる 、という点もキーメッセージの一つだと感じました。 なお、「どこから手を付けていいかわからない」という人のために、実務上の推進プロセスの整理の方法として、 「The HR Value Chain」 という フレームワーク が紹介されていました。 とてもシンプルではありますが、今後、People Analyticsを進めていく上では実践的で活用しやすそうです。 https://www.aihr.com/blog/hr-value-chain-essential-tool-for-adding-value-to-hr/ 今後実践していきたいこと 今回のcertificationの取得によって、私自身もこれから「ピープルアナリティクス」の実践スキルを高めていく上での前準備ができたという段階なので、これからさらに実践していきながらこのスキルを磨いていき、少しでも早くビジネス成果につなげていきたいと考えてます。 とはいえ、この取り組み自体はスタートしたばかりなので、まずは一つ目のsmall-winに向けて社内外での仲間を少しずつ増やしていければと思っています。 <参考>こんなデジタル証明書がもらえます。 執筆: @masayuki 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
みなさん、こんにちは。コーポレート本部コーポレートHRユニット人事部の今村と申します。 私自身、人事部ではここ10年ほどは人材開発、組織開発にどっぷり関わってきたのですが、今年から「ピープルアナリティクス」というテーマに取り組んでいます。 「HRアナリティクス」とか「データドリブン人事」とか表現はいろいろありますが、要は 「人」に関する取り組みの判断においてこれまで重視されがちだった「勘と経験」だけではなく、「人」のデータを収集/可視化/分析して様々な意思決定の確度を向上させよう ということをねらいとしたものです。 マーケティング を始め、日常のビジネスプロセスではごくごく当たり前の取り組みが、昨今、ようやく人事の領域でも本格的に注目されてきました。 個人的にこの領域には以前から興味があり、少なからず業務の中で取り組んできたこともあったのですが、ここに来て改めて新たな領域へ本格的にチャレンジなので、まずは体系的に学ばねば、ということで、今年に入ってからから本格的にピープルアナリティクスの勉強を始め、先日、 Academy to Innovate HR(略称AIHR)が認定している「People Analytics Specialist」のcertificationを取得することが出来ました ので、その内容について紹介いたします。 AIHRという学習機関 この「Academy to Innovate HR」は2016年に設立されたオランダの学習機関で、HR(人事)プロフェッショナルとして必要なスキルをオンラインで学べる学習プラットフォームです。 ※AIと略しているので一瞬あのAIと勘違いしがちですがもちろん別物です。 https://www.aihr.com/ その名の通り、HR全般を学べる学習機関で、People AnalyticsやDigital HR、OD(組織開発)等11のcertificationに加え、Hiring & Recruitment Strategy、Employee Experience and Design Thinking等の学習コースがあり、中にはBlockchain and HRと言った、日本ではなかなかお目にかかれないコースもあります。 そもそも日本ではなかなか「ピープルアナリティクス」という領域にフォーカスして体系的に学べる場が見つからなかったのですが、私が社外活動として理事も務めている人材育成のグローバルな会員組織である「ATD(The Associaton for Talent Development)」日本 支部 ( https://www.atdj.jp/atd-imnj )の方から紹介され、ここに来て業務上の必要性にも迫られたことあり、覚悟を決め本格的に学び始めることにしました。日本ではまだ全くと言っていいほど馴染みがないので、ちょっとレア感もあるのが自分好みだったということもありチャレンジしてみましたが、予想以上に価値のある学びの多い内容でした。 もしかすると、日本人でこのcertification取得したのはまだほとんどいなさそうなので、そういう意味でも心地よい達成感があったりします。 AIHRの特徴 なお、このAIHRは、 ・すべて英語(但し、字幕付き) ・すべてオンライン ・費用は、こんな感じ。 いくつかコースのオプションがあり、個々人の学習スタイルに応じて選択できる点も学習しやすい点だと感じました。 People Analytics certificationのカリキュラム このPeople Analytics certificationで学べる内容は、以下のとおりです。 「Statistics in HR」のパートがいわゆる分析手法をやや深めに学ぶパートです。深めと言っても、数学に全く明るくない私にも無理なく理解できる内容で、実際にデータを自分でいじりながら学ぶこともできるので、実務で活用するイメージも湧きやすくできています。(そもそも統計で使われている専門用語って「英語だとこう言うんだー」という素朴な発見もありました) なお、このパートについては、日本語で統計を解説している一般のサイトも並行して使いながら学ぶと、より効率的に学べると思います。 認定取得に要した学習時間 ちなみに、今回certificationを取得するまでに要した時間ですが、 おおよそ毎日30分~1時間の勉強で、約3か月 かかりました。一つのLessonの動画がおおよそ15-20分程度(+ボーナスレッスンや推奨動画/記事等もあり)なので、比較的無理なく学習できるペースでした。(もちろん期間中は何度でも視聴可能です) この学習コースから学んだこと 前述したように、カリキュラムとしては、 1.HR Analytics Leader 2.Statistics in HR 3.HR Data Analyst 4.Capstone Project という4つのモジュールに分かれていて、People Analyticsの基礎的な考え方や、分析プロセス、 フレームワーク 、そして具体的な分析手法等を学びました。「People Analytics」という名前の印象から、「Analytics」の手法を掘り下げて学ぶイメージがあるかもしれませんが、 全体を通して、再三、強調されている(と私が感じている)点は、「ビジネス課題」へのアプローチの重要性とビジネス インパク トを重視する、 ということです。 こう書くととても当たり前の話なのですが、単に人事関連のデータを分析する、そして インサイト を出す、予測をする、ということはもちろんPeople Analyticsの大事な要素であり、プロセスではあるものの、そもそもの目的はビジネスゴール(組織目標)を達成することである、というメッセージが何度も出てきます。 さらに言えば、 ビジネスゴールを達成するためには、いくつかの課題があり、その課題と人のパフォーマンスの関連をしっかりと紐づけた上で、その課題が生まれた背景やコンテクストも正しく理解することが重要 ということです。要は「 チェンジマ ネジメント」のプロセスそのものだよ、ということもメッセージの一つでした。 また、 Agile で進める、small-winを積み重ねる 、という点もキーメッセージの一つだと感じました。 なお、「どこから手を付けていいかわからない」という人のために、実務上の推進プロセスの整理の方法として、 「The HR Value Chain」 という フレームワーク が紹介されていました。 とてもシンプルではありますが、今後、People Analyticsを進めていく上では実践的で活用しやすそうです。 https://www.aihr.com/blog/hr-value-chain-essential-tool-for-adding-value-to-hr/ 今後実践していきたいこと 今回のcertificationの取得によって、私自身もこれから「ピープルアナリティクス」の実践スキルを高めていく上での前準備ができたという段階なので、これからさらに実践していきながらこのスキルを磨いていき、少しでも早くビジネス成果につなげていきたいと考えてます。 とはいえ、この取り組み自体はスタートしたばかりなので、まずは一つ目のsmall-winに向けて社内外での仲間を少しずつ増やしていければと思っています。 <参考>こんなデジタル証明書がもらえます。 執筆: @masayuki 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
みなさん、こんにちは。ISID CIT事業部の石際です。 コンタクトセンターの クラウド 化が進んでいますが、 Salesforce Service Cloud(以下「Service Cloud」)のような顧客管理( CRM )アプリケーションと連携することでのカスタマーエクス ペリエ ンス(CX)の向上も重要視されています。 Service Cloudで CTI (Computer Telephony Integration)機能を具備したコンタクトセンターを構築する場合、 Salesforce が提供しているOpen CTI というライブラリを利用して各テレフォニーベンダーが作成した CTI とService Cloudを連携することで実現できます。 コールセンター構築と聞くと複雑で構築に時間が掛かる印象ですが、Twilioが提供している クラウド 型コンタクトセンターのTwilio Flex であればクイックスタートが可能です。 今回はService CloudにTwilio Flex を連携させることで、 CTI 機能を具備したコンタクトセンターを構築してみました。 1. Twilio Flexとは 2. Service CloudとTwilio Flexを連携してみる 2-1. セットアップ Twilio Flexの設定 1. 設定を有効にする 2. パラメータを設定する 3. コールセンター定義ファイルをダウンロードする Salesforceの設定 1. コールセンター定義ファイルをインポートする 2. 着信時のアクションを設定する 3. ソフトフォンを追加する 2-2. 連携すると何ができるか 着信時の動作を確認してみる 1. 着信がポップアップする 2. 着信を受けると顧客情報ページを表示する/新規登録ページを表示する 3. タスクにログを記録する 3. 簡単なコールフローを作ってみました 4. 感想 1. Twilio Flex とは Twilioは、電話やSMS・ビデオ・チャット・ SNS など世の中にある様々なコミュニケーションチャネルをWeb・モバイルアプリケーションとつなぐ クラウド コミュニケーション API サービスです。そのTwilioの各種サービスを組み合わせた プログラマブル な クラウド 型コンタクトセンタープラットフォームがTwilio Flex になります。マルチチャンネルに対応し、オペレータの画面のUIはもちろんIVR 1 やACD 2 などのフルカスタマイズが可能となっています。 2. Service CloudとTwilio Flex を連携してみる 今回は Integrate Twilio Flex with Salesforce を参考に設定を行いました。 Service Cloudに電話を連携する場合、一番メジャーなのは Amazon Connect CTI Adapterだと思います。 Amazon Connectは Salesforce のAppExchangeからパッケージのインストールが必要です。 一方で、Twilio Flex との連携ではパッケージのインストールが不要です。Twilio Flex の設定とTwilioで用意されているコールセンター定義ファイルを Salesforce にインポートし Salesforce の設定を行うだけで完了します。10分程度あれば完了してしまうという驚きの簡単さです。 では、さっそくセットアップをしてみましょう。 (事前にTwilioで電話番号を取得しておきます。電話番号の取得方法は Twilioコンソールから電話番号を購入する方法 を参考にしてください。) 2-1. セットアップ Twilio Flex の設定 まずは、Twilio Flex の設定を行います。 Flex 管理画面から [INTEGRATIONS] をクリックし CRM 連携設定の画面に遷移します。 CRM 連携設定の画面で [ Salesforce ] を選択し、 Salesforce 連携の設定を行っていきます。 1. 設定を有効にする [STATUS] のセクションでトグルを [Enabled] にして、連携の設定を有効化します。 (こちらは公式ドキュメントに書いていないのでご注意ください) 2. パラメータを設定する [CONFIGURATION] のセクションで下記の項目を設定します。 Workflow SID (任意):エージェントのルーティングルール(Workflow)を指定します。デフォルトの場合は空欄にしておきます。 Task Channel SID (任意):音声チャネルとは異なるチャネルを使用したい場合にチャネルを指定します。 Agent Caller ID (必須): Salesforce からClick to Dialで発信するために使用する発信者IDを指定します。(上記の画像ではこの項目が表示されていませんが、初回の設定でのみ項目が表示されます。設定後はTwilioコンソールの [ Flex ] > [Manage] > [Voice] 画面の [ Flex Dialpad] にて設定が可能です) Salesforce Base URL (必須): Salesforce ドメイン を登録します。(初回の設定後はTwilioコンソールの [ Flex Settings] 画面で設定を行います) SSO : Salesforce がIdPとしてSSOの設定が可能です。(今回は設定していませんが、利用する際は Configure Salesforce SSO With Twilio Flex などを参照して必要な設定を行ってください) LOG :ログを Salesforce に記録したい場合はチェックを付けます。 それぞれの項目は設定後変更が可能です。 3. コールセンター定義ファイルをダウンロードする 最後に [FILES] のセクションの [DOWNLOAD] からコールセンター定義ファイルをダウンロードします。 Salesforce の設定 次に Salesforce の [Setup] にて設定を行います。 1. コールセンター定義ファイルをインポートする [Call Centers] の設定画面から [import] ボタンをクリックし、Twilio Flex からダウンロードしたコールセンター定義ファイルをインポートします。 インポート後、 [Call Center Users] のセクションにある [Manage Call Center Users] ボタンをクリックし、ユーザーを追加します。 2. 着信時のアクションを設定する [Softphone Layouts] の設定画面から着信時の挙動を必要に応じて設定します。 3. ソフトフォンを追加する [App Manager] の設定画面からTwilio Flex を表示させたいアプリを選択します。今回は [Service Console] にTwilio Flex のソフトフォンを追加します。 [App Settings] から [Utility Items] を選択します。 [Utility Items] のリストに [ Open CTI Softphone] を追加し、下記の内容で項目を設定します。 はい、これで完了です!すべて GUI ベースでクイックに連携ができました。 Service Consoleを見てみると、Twilio Flex のソフトフォンが表示されるようになっています。 2-2. 連携すると何ができるか さて、Service CloudとTwilio Flex を連携することで何ができるでしょうか。 着信時の動作を確認してみる Twilio Flex はコールフローをStudioで設定できます。動作確認では着信があるとすぐにオペレーターにつなぐフローを使用します。 早速、Twilioで取得した電話番号に電話をしてみます。 1. 着信がポップアップする まず、着信があると Flex のソフトフォンをポップアップします。 2. 着信を受けると顧客情報ページを表示する/新規登録ページを表示する 着信している電話番号をクリックすると電話番号からオブジェクトを検索し、画面に表示します。 電話番号がヒットしない場合は、新規登録ページが表示されます。この時、電話番号がフィルされます。 3. タスクにログを記録する Twilio Flex の Salesforce Integrationの設定でログを有効にした場合は、タスクにログが記録されます。 このように、デフォルトの設定で必要最低限の機能が実装されています。 カスタマイズが必要な場合はTwilio Studioや Salesforce の開発が必要になってきます。 3. 簡単なコールフローを作ってみました Studioを使って少しコールセンターっぽいコールフローを作ってみました。 フローの流れは上記のようになります。 "sfdcSearchString": "{{widgets.getInput.Digits}}" をセットすることで、グローバル検索に値を渡すことができます。 オペレータが見ている Salesforce の画面では、 会員番号がある顧客は会員番号でグローバル検索される 会員番号がない顧客は電話番号で検索され、なければ新規登録画面が表示される という動きになります。 このように、Studioをカスタマイズすることでオペレータにとっては効率的な、顧客にとっては便利で親切なコンタクトセンターの構築が可能です。 4. 感想 想像以上に簡単にService Cloudとの連携ができました! Amazon Connect CTI Adapterを使った連携よりもシンプルな構成のためクイックにスタートできる点が良いところだと感じました。 また、Twilio Flex を利用するメリットとしては、 対応チャネルが豊富 API や開発用のライブラリなどが充実 コンタクトセンターの総合的な改善が可能 などが挙げられます。 機能の拡張性も優れているため、クイックにはじめた後、業務に応じて開発を柔軟に行っていくことも可能です。Service Cloudでコンタクトセンターを構築する際、 Amazon ConnectだけでなくTwilio Flex も検討してみてはいかがでしょうか? 最後までお読みいただきありがとうございました。 執筆: @ishigiwa.yumi 、レビュー: @higa ( Shodo で執筆されました ) IVR (Interactive Voice Response) 自動音声応答:コールセンターなど企業の電話窓口で、音声による自動応答を行うコンピューターシステム。発信者のダイヤル操作に合わせて、あらかじめ録音してある音声を発信者側に自動的に再生する。 音声認識 機能を備え、相手の発話に応じて再生内容を決める製品もある。 ↩ ACD (Automatic Call Distribution) 自動着信呼分配機能:着信したコールを自動的に管理、コン トロール する装置。次々に入る着信コールを、その時点で空いている、あるいは次の応答を最も長時間待っている適切なスキルを持ったテ レコミュニ ケーターから順次均等に配分できる機能を備える。 ↩
みなさん、こんにちは。ISID CIT事業部の石際です。 コンタクトセンターの クラウド 化が進んでいますが、 Salesforce Service Cloud(以下「Service Cloud」)のような顧客管理( CRM )アプリケーションと連携することでのカスタマーエクス ペリエ ンス(CX)の向上も重要視されています。 Service Cloudで CTI (Computer Telephony Integration)機能を具備したコンタクトセンターを構築する場合、 Salesforce が提供しているOpen CTI というライブラリを利用して各テレフォニーベンダーが作成した CTI とService Cloudを連携することで実現できます。 コールセンター構築と聞くと複雑で構築に時間が掛かる印象ですが、Twilioが提供している クラウド 型コンタクトセンターのTwilio Flex であればクイックスタートが可能です。 今回はService CloudにTwilio Flex を連携させることで、 CTI 機能を具備したコンタクトセンターを構築してみました。 1. Twilio Flexとは 2. Service CloudとTwilio Flexを連携してみる 2-1. セットアップ Twilio Flexの設定 1. 設定を有効にする 2. パラメータを設定する 3. コールセンター定義ファイルをダウンロードする Salesforceの設定 1. コールセンター定義ファイルをインポートする 2. 着信時のアクションを設定する 3. ソフトフォンを追加する 2-2. 連携すると何ができるか 着信時の動作を確認してみる 1. 着信がポップアップする 2. 着信を受けると顧客情報ページを表示する/新規登録ページを表示する 3. タスクにログを記録する 3. 簡単なコールフローを作ってみました 4. 感想 1. Twilio Flex とは Twilioは、電話やSMS・ビデオ・チャット・ SNS など世の中にある様々なコミュニケーションチャネルをWeb・モバイルアプリケーションとつなぐ クラウド コミュニケーション API サービスです。そのTwilioの各種サービスを組み合わせた プログラマブル な クラウド 型コンタクトセンタープラットフォームがTwilio Flex になります。マルチチャンネルに対応し、オペレータの画面のUIはもちろんIVR 1 やACD 2 などのフルカスタマイズが可能となっています。 2. Service CloudとTwilio Flex を連携してみる 今回は Integrate Twilio Flex with Salesforce を参考に設定を行いました。 Service Cloudに電話を連携する場合、一番メジャーなのは Amazon Connect CTI Adapterだと思います。 Amazon Connectは Salesforce のAppExchangeからパッケージのインストールが必要です。 一方で、Twilio Flex との連携ではパッケージのインストールが不要です。Twilio Flex の設定とTwilioで用意されているコールセンター定義ファイルを Salesforce にインポートし Salesforce の設定を行うだけで完了します。10分程度あれば完了してしまうという驚きの簡単さです。 では、さっそくセットアップをしてみましょう。 (事前にTwilioで電話番号を取得しておきます。電話番号の取得方法は Twilioコンソールから電話番号を購入する方法 を参考にしてください。) 2-1. セットアップ Twilio Flex の設定 まずは、Twilio Flex の設定を行います。 Flex 管理画面から [INTEGRATIONS] をクリックし CRM 連携設定の画面に遷移します。 CRM 連携設定の画面で [ Salesforce ] を選択し、 Salesforce 連携の設定を行っていきます。 1. 設定を有効にする [STATUS] のセクションでトグルを [Enabled] にして、連携の設定を有効化します。 (こちらは公式ドキュメントに書いていないのでご注意ください) 2. パラメータを設定する [CONFIGURATION] のセクションで下記の項目を設定します。 Workflow SID (任意):エージェントのルーティングルール(Workflow)を指定します。デフォルトの場合は空欄にしておきます。 Task Channel SID (任意):音声チャネルとは異なるチャネルを使用したい場合にチャネルを指定します。 Agent Caller ID (必須): Salesforce からClick to Dialで発信するために使用する発信者IDを指定します。(上記の画像ではこの項目が表示されていませんが、初回の設定でのみ項目が表示されます。設定後はTwilioコンソールの [ Flex ] > [Manage] > [Voice] 画面の [ Flex Dialpad] にて設定が可能です) Salesforce Base URL (必須): Salesforce ドメイン を登録します。(初回の設定後はTwilioコンソールの [ Flex Settings] 画面で設定を行います) SSO : Salesforce がIdPとしてSSOの設定が可能です。(今回は設定していませんが、利用する際は Configure Salesforce SSO With Twilio Flex などを参照して必要な設定を行ってください) LOG :ログを Salesforce に記録したい場合はチェックを付けます。 それぞれの項目は設定後変更が可能です。 3. コールセンター定義ファイルをダウンロードする 最後に [FILES] のセクションの [DOWNLOAD] からコールセンター定義ファイルをダウンロードします。 Salesforce の設定 次に Salesforce の [Setup] にて設定を行います。 1. コールセンター定義ファイルをインポートする [Call Centers] の設定画面から [import] ボタンをクリックし、Twilio Flex からダウンロードしたコールセンター定義ファイルをインポートします。 インポート後、 [Call Center Users] のセクションにある [Manage Call Center Users] ボタンをクリックし、ユーザーを追加します。 2. 着信時のアクションを設定する [Softphone Layouts] の設定画面から着信時の挙動を必要に応じて設定します。 3. ソフトフォンを追加する [App Manager] の設定画面からTwilio Flex を表示させたいアプリを選択します。今回は [Service Console] にTwilio Flex のソフトフォンを追加します。 [App Settings] から [Utility Items] を選択します。 [Utility Items] のリストに [ Open CTI Softphone] を追加し、下記の内容で項目を設定します。 はい、これで完了です!すべて GUI ベースでクイックに連携ができました。 Service Consoleを見てみると、Twilio Flex のソフトフォンが表示されるようになっています。 2-2. 連携すると何ができるか さて、Service CloudとTwilio Flex を連携することで何ができるでしょうか。 着信時の動作を確認してみる Twilio Flex はコールフローをStudioで設定できます。動作確認では着信があるとすぐにオペレーターにつなぐフローを使用します。 早速、Twilioで取得した電話番号に電話をしてみます。 1. 着信がポップアップする まず、着信があると Flex のソフトフォンをポップアップします。 2. 着信を受けると顧客情報ページを表示する/新規登録ページを表示する 着信している電話番号をクリックすると電話番号からオブジェクトを検索し、画面に表示します。 電話番号がヒットしない場合は、新規登録ページが表示されます。この時、電話番号がフィルされます。 3. タスクにログを記録する Twilio Flex の Salesforce Integrationの設定でログを有効にした場合は、タスクにログが記録されます。 このように、デフォルトの設定で必要最低限の機能が実装されています。 カスタマイズが必要な場合はTwilio Studioや Salesforce の開発が必要になってきます。 3. 簡単なコールフローを作ってみました Studioを使って少しコールセンターっぽいコールフローを作ってみました。 フローの流れは上記のようになります。 "sfdcSearchString": "{{widgets.getInput.Digits}}" をセットすることで、グローバル検索に値を渡すことができます。 オペレータが見ている Salesforce の画面では、 会員番号がある顧客は会員番号でグローバル検索される 会員番号がない顧客は電話番号で検索され、なければ新規登録画面が表示される という動きになります。 このように、Studioをカスタマイズすることでオペレータにとっては効率的な、顧客にとっては便利で親切なコンタクトセンターの構築が可能です。 4. 感想 想像以上に簡単にService Cloudとの連携ができました! Amazon Connect CTI Adapterを使った連携よりもシンプルな構成のためクイックにスタートできる点が良いところだと感じました。 また、Twilio Flex を利用するメリットとしては、 対応チャネルが豊富 API や開発用のライブラリなどが充実 コンタクトセンターの総合的な改善が可能 などが挙げられます。 機能の拡張性も優れているため、クイックにはじめた後、業務に応じて開発を柔軟に行っていくことも可能です。Service Cloudでコンタクトセンターを構築する際、 Amazon ConnectだけでなくTwilio Flex も検討してみてはいかがでしょうか? 最後までお読みいただきありがとうございました。 執筆: @ishigiwa.yumi 、レビュー: @higa ( Shodo で執筆されました ) IVR (Interactive Voice Response) 自動音声応答:コールセンターなど企業の電話窓口で、音声による自動応答を行うコンピューターシステム。発信者のダイヤル操作に合わせて、あらかじめ録音してある音声を発信者側に自動的に再生する。 音声認識 機能を備え、相手の発話に応じて再生内容を決める製品もある。 ↩ ACD (Automatic Call Distribution) 自動着信呼分配機能:着信したコールを自動的に管理、コン トロール する装置。次々に入る着信コールを、その時点で空いている、あるいは次の応答を最も長時間待っている適切なスキルを持ったテ レコミュニ ケーターから順次均等に配分できる機能を備える。 ↩
こんにちは。X(クロス) イノベーション 本部 ソフトウェアデザインセンターの耿です。 Amazon Aurora Serverlessは、コンピューティングとメモリのキャパシティ(Aurora 容量ユニット = ACU)をリク エス ト数に応じて自動で変化させることができるデータベースサービスです。事前のスケーリング計画が不要になるほか、実際のワークロードに合わせてキャパシティを増減させるため、費用の最適化に向いています。 Aurora Serverlessは v1 と v2 の2つのバージョンが一般利用可能ですが、v1 の方はしばらくアクセスがないと 0 ACU まで落として一時停止する機能があり、コンピューティングとメモリの料金が全くかからなくなります。本番環境であれば利用されることはあまりないと思いますが、リク エス ト数が限定的な開発環境ではこの機能をうまく利用することで、費用をさらに節約することができます。 しかし、 0 ACU で一時停止している状態のデータベースにアクセスしようとすると、キャパシティがないため初回接続が失敗してしまいます。本記事はシンプルにこの問題を解消し、費用を抑える方法を記載します。 Aurora Serverless の ACU 設定 Aurora Serverless のバージョンの違い 開発で遭遇した問題点 実現したいこと 実現方法 他の選択肢 CDKコード 実際の料金 Aurora Serverless の ACU 設定 Aurora Serverless は Aurora 容量ユニット (ACU) の最大値と最小値を指定することで、その間で負荷に応じてオートスケーリングします。v1に限って一時停止設定が可能で、リク エス トが全くない時に 0 ACU までスケールダウンできます。 Aurora Serverless v1の一時停止設定 Aurora Serverless のバージョンの違い 2022年5月時点において、Aurora Serverless v1にできてv2にできないことがあります。 v2は Data API を利用できない CloudFormationはまだv2をサポートしていない v2は 0 ACU(一時停止)にできず、最小ACUは 0.5 である ACUに関する補足として、2022年5月時点でv2のACU費用はv1の2倍に設定されています。すなわちv2を最小キャパシティ0.5 ACUで常時稼働した場合の費用は、v1を1 ACUで常時稼働した場合の費用と同等になります。v1は一時停止が可能なため、一時停止をした時間の分だけv2より費用を節約できます。 ※その他のAurora Serverless v2の特徴は、以下の動画で詳しく解説されています。 JAWS-UG横浜 #44 Aurora Serverless v2 開発で遭遇した問題点 Data API とCDKを利用したかったため、Aurora Serverless v1を利用して開発している環境があります。費用を抑えるために一時停止機能を有効にしていますが、0 ACUのときはコンピューティングとメモリの動作が完全に停止するため、 初回接続ではデータベースへの接続が失敗する という問題に遭遇しました。 Communications link failure The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.; SQLState: 08S01 しばらく(体感30秒〜1分程度)するとデータベースが起動し、問題なく接続できるようになるのですが、費用を抑えつつ初回接続でも失敗しないようにしたかったため、その仕組みを検討しました。 実現したいこと Aurora Serverlessに アクセスする可能性のある時間帯は一時停止をさせずに最低でも1 ACUで稼働させ、それ以外の時間帯は0 ACUへのスケールダウンを許容 すれば、余分な費用を削減し、初回接続でエラーになる問題も解消できます。今回はアクセスする可能性のある時間帯は余裕を持って 7:00 ~ 22:00 と広めに定義しています。 整理すると、実現したいことは次のようになります。 平日の7:00 ~ 22:00 は、Aurora Serverlessが 0 ACUにならないようしに、DBへの接続が常に成功するようにしたい それ以外の時間(平日深夜と土日)は 0 ACUにスケールダウンしても良い 実現方法 Aurora クラスタ が一時停止しない場合の最小 ACU を 1 とする Aurora クラスタ へ 2時間 アクセスがなかった場合、一時停止するよう(0 ACU になるよう)に設定する Aurora クラスタ へ参照系のクエリを発行するLambda関数を作成し、 平日の7:00 ~ 20:00 の間は1時間ごとに定期実行 する こうすることで、平日は20:00に最後のLambda関数が実行され、22:00まではAurora クラスタ が0 ACUにならないことが保証されます。夜間や土日はAurora クラスタ への接続がないと一時停止し、次の平日の朝7:00に最初のLambda関数が実行され、Aurora クラスタ が起動します。 他の選択肢 シビアに費用を抑える必要がない場合 、一時停止設定を無効にし、0 ACUにスケールダウンしないようにすれば、データベースへのアクセスがなくても停止しなくなり、本記事で述べるような ワークアラウンド は必要ありません。 あるいは 0 ACUにスケールダウンした後の初回接続が失敗しても、 起動を待ってからクエリを再実行することが許容できる場合 も、本記事の ワークアラウンド は必要ありません。 CDKコード 以下のCDKコードで環境を作成します。 import { Duration , Stack , StackProps } from "aws-cdk-lib" ; import * as ec2 from "aws-cdk-lib/aws-ec2" ; import * as events from "aws-cdk-lib/aws-events" ; import * as eventTargets from "aws-cdk-lib/aws-events-targets" ; import * as iam from "aws-cdk-lib/aws-iam" ; import * as lambda from "aws-cdk-lib/aws-lambda" ; import * as lambdaNodejs from "aws-cdk-lib/aws-lambda-nodejs" ; import * as rds from "aws-cdk-lib/aws-rds" ; import { Construct } from "constructs" ; export class MyStack extends Stack { constructor( scope: Construct , id: string , props?: StackProps ) { super( scope , id , props ); const privateSubnetName = "myPrivateSubnet" ; // VPCを作成 const vpc = new ec2.Vpc ( this , "MyVpc" , { cidr: "10.0.0.0/16" , enableDnsHostnames: true , enableDnsSupport: true , subnetConfiguration: [ { name: privateSubnetName , subnetType: ec2.SubnetType.PRIVATE_ISOLATED , cidrMask: 20 , } , ] , } ); // Aurora Serverless v1 クラスタを作成 const auroraCluseter = new rds.ServerlessCluster ( this , "MyAuroraCluster" , { engine: rds.DatabaseClusterEngine.AURORA_MYSQL , vpc: vpc , vpcSubnets: { subnetGroupName: privateSubnetName } , // 最小ACUを1、最大ACUを2、一時停止までに必要な非アクティブ時間を2時間に指定 scaling: { minCapacity: 1 , maxCapacity: 2 , autoPause: Duration.hours ( 2 ) } , // Data APIを有効化 enableDataApi: true , } ); // Lambda関数 const awakeAuroraFunction = new lambdaNodejs.NodejsFunction ( this , "MyFunction" , { // Lambda関数へのファイルパス entry: "functions/awake-aurora-serverless.ts" , runtime: lambda.Runtime.NODEJS_14_X , // Data APIを利用するため、AuroraクラスタARNとシークレットのARNを環境変数で渡す environment: { CLUSTER_ARN: auroraCluseter.clusterArn , SECRET_ARN: auroraCluseter.secret?.secretArn ?? "" , } , } ); // Lambda関数の実行ロールにData APIへのアクセスを許可するポリシーを追加 if ( auroraCluseter.secret?.secretArn ) { const auroraDataApiPolicy = new iam.ManagedPolicy ( this , "MyAuroraDataApiPolicy" , { statements: [ new iam.PolicyStatement ( { resources: [ ` ${ auroraCluseter.secret.secretArn } *` ] , actions: [ "secretsmanager:GetSecretValue" ] , effect: iam.Effect.ALLOW , } ), new iam.PolicyStatement ( { resources: [ auroraCluseter.clusterArn ] , actions: [ "rds-data:ExecuteStatement" ] , effect: iam.Effect.ALLOW , } ), ] , } ); awakeAuroraFunction.role?.addManagedPolicy ( auroraDataApiPolicy ); } // 日本時間 平日の 7:00 ~ 20:00 の間に1時間ごとにLambda関数を定期起動する // cron式は UTC で記載するため、「日曜 ~ 木曜の22:00 ~ 23:00」と「月曜 ~ 金曜の 0:00 ~ 11:00」の2つに分ける new events.Rule ( this , "MyEventRule1" , { schedule: events.Schedule.cron ( { minute: "0" , hour: "22-23" , weekDay: "SUN-THU" } ), targets: [ new eventTargets.LambdaFunction ( awakeAuroraFunction , { retryAttempts: 3 } ) ] , } ); new events.Rule ( this , "MyEventRule2" , { schedule: events.Schedule.cron ( { minute: "0" , hour: "0-11" , weekDay: "MON-FRI" } ), targets: [ new eventTargets.LambdaFunction ( awakeAuroraFunction , { retryAttempts: 3 } ) ] , } ); } } Lambda関数の部分では、 NodejsFunction コンストラクト を利用することで、TypeScript で記述した Lambda 関数の JavaScript への コンパイル からデプロイまでをCDKがやってくれます。 Aurora クラスタ へクエリを発行するLambda関数は、 functions/awake-aurora-serverless.ts に以下のように実装します。Data API を利用してクエリを発行します。 import * as RDS from "@aws-sdk/client-rds-data" ; import { Handler } from "aws-lambda" ; const client = new RDS.RDSDataClient ( { region: "ap-northeast-1" } ); export const handler: Handler = async () => { const input = { // Data APIを利用するための、AuroraクラスタのリソースARNとシークレットのARNを環境変数から取得する resourceArn: process .env.CLUSTER_ARN , secretArn: process .env.SECRET_ARN , // 発行するSQL文 sql: "SHOW databases;" , } ; const command = new RDS.ExecuteStatementCommand ( input ); await client.send ( command ); } ; 発行する SQL 文は更新系でなければ何でも良いですが、シンプルに SHOW databases; としています。 実際の料金 以上の構成でしばらく稼働した場合の料金を確認しました。 土日はAurora クラスタ が停止し、料金がかかっていないことがわかります。平日も24時間のうち15時間しか稼働していません。 今回の条件では一週間 24h * 7日 = 168h のうち、 15h * 5日 = 75h 稼働しているため、常時稼働に比べて 75h / 168h = 45% の費用に抑えることができています。 一方で平日の業務時間中は常に稼働状態のため、接続が失敗することがなくなり、今回の要件を満たすことができました。 執筆: @kou.kinyo2 、レビュー: @higa ( Shodo で執筆されました )
こんにちは。X(クロス) イノベーション 本部 ソフトウェアデザインセンターの耿です。 Amazon Aurora Serverlessは、コンピューティングとメモリのキャパシティ(Aurora 容量ユニット = ACU)をリク エス ト数に応じて自動で変化させることができるデータベースサービスです。事前のスケーリング計画が不要になるほか、実際のワークロードに合わせてキャパシティを増減させるため、費用の最適化に向いています。 Aurora Serverlessは v1 と v2 の2つのバージョンが一般利用可能ですが、v1 の方はしばらくアクセスがないと 0 ACU まで落として一時停止する機能があり、コンピューティングとメモリの料金が全くかからなくなります。本番環境であれば利用されることはあまりないと思いますが、リク エス ト数が限定的な開発環境ではこの機能をうまく利用することで、費用をさらに節約することができます。 しかし、 0 ACU で一時停止している状態のデータベースにアクセスしようとすると、キャパシティがないため初回接続が失敗してしまいます。本記事はシンプルにこの問題を解消し、費用を抑える方法を記載します。 Aurora Serverless の ACU 設定 Aurora Serverless のバージョンの違い 開発で遭遇した問題点 実現したいこと 実現方法 他の選択肢 CDKコード 実際の料金 Aurora Serverless の ACU 設定 Aurora Serverless は Aurora 容量ユニット (ACU) の最大値と最小値を指定することで、その間で負荷に応じてオートスケーリングします。v1に限って一時停止設定が可能で、リク エス トが全くない時に 0 ACU までスケールダウンできます。 Aurora Serverless v1の一時停止設定 Aurora Serverless のバージョンの違い 2022年5月時点において、Aurora Serverless v1にできてv2にできないことがあります。 v2は Data API を利用できない CloudFormationはまだv2をサポートしていない v2は 0 ACU(一時停止)にできず、最小ACUは 0.5 である ACUに関する補足として、2022年5月時点でv2のACU費用はv1の2倍に設定されています。すなわちv2を最小キャパシティ0.5 ACUで常時稼働した場合の費用は、v1を1 ACUで常時稼働した場合の費用と同等になります。v1は一時停止が可能なため、一時停止をした時間の分だけv2より費用を節約できます。 ※その他のAurora Serverless v2の特徴は、以下の動画で詳しく解説されています。 JAWS-UG横浜 #44 Aurora Serverless v2 開発で遭遇した問題点 Data API とCDKを利用したかったため、Aurora Serverless v1を利用して開発している環境があります。費用を抑えるために一時停止機能を有効にしていますが、0 ACUのときはコンピューティングとメモリの動作が完全に停止するため、 初回接続ではデータベースへの接続が失敗する という問題に遭遇しました。 Communications link failure The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.; SQLState: 08S01 しばらく(体感30秒〜1分程度)するとデータベースが起動し、問題なく接続できるようになるのですが、費用を抑えつつ初回接続でも失敗しないようにしたかったため、その仕組みを検討しました。 実現したいこと Aurora Serverlessに アクセスする可能性のある時間帯は一時停止をさせずに最低でも1 ACUで稼働させ、それ以外の時間帯は0 ACUへのスケールダウンを許容 すれば、余分な費用を削減し、初回接続でエラーになる問題も解消できます。今回はアクセスする可能性のある時間帯は余裕を持って 7:00 ~ 22:00 と広めに定義しています。 整理すると、実現したいことは次のようになります。 平日の7:00 ~ 22:00 は、Aurora Serverlessが 0 ACUにならないようしに、DBへの接続が常に成功するようにしたい それ以外の時間(平日深夜と土日)は 0 ACUにスケールダウンしても良い 実現方法 Aurora クラスタ が一時停止しない場合の最小 ACU を 1 とする Aurora クラスタ へ 2時間 アクセスがなかった場合、一時停止するよう(0 ACU になるよう)に設定する Aurora クラスタ へ参照系のクエリを発行するLambda関数を作成し、 平日の7:00 ~ 20:00 の間は1時間ごとに定期実行 する こうすることで、平日は20:00に最後のLambda関数が実行され、22:00まではAurora クラスタ が0 ACUにならないことが保証されます。夜間や土日はAurora クラスタ への接続がないと一時停止し、次の平日の朝7:00に最初のLambda関数が実行され、Aurora クラスタ が起動します。 他の選択肢 シビアに費用を抑える必要がない場合 、一時停止設定を無効にし、0 ACUにスケールダウンしないようにすれば、データベースへのアクセスがなくても停止しなくなり、本記事で述べるような ワークアラウンド は必要ありません。 あるいは 0 ACUにスケールダウンした後の初回接続が失敗しても、 起動を待ってからクエリを再実行することが許容できる場合 も、本記事の ワークアラウンド は必要ありません。 CDKコード 以下のCDKコードで環境を作成します。 import { Duration , Stack , StackProps } from "aws-cdk-lib" ; import * as ec2 from "aws-cdk-lib/aws-ec2" ; import * as events from "aws-cdk-lib/aws-events" ; import * as eventTargets from "aws-cdk-lib/aws-events-targets" ; import * as iam from "aws-cdk-lib/aws-iam" ; import * as lambda from "aws-cdk-lib/aws-lambda" ; import * as lambdaNodejs from "aws-cdk-lib/aws-lambda-nodejs" ; import * as rds from "aws-cdk-lib/aws-rds" ; import { Construct } from "constructs" ; export class MyStack extends Stack { constructor( scope: Construct , id: string , props?: StackProps ) { super( scope , id , props ); const privateSubnetName = "myPrivateSubnet" ; // VPCを作成 const vpc = new ec2.Vpc ( this , "MyVpc" , { cidr: "10.0.0.0/16" , enableDnsHostnames: true , enableDnsSupport: true , subnetConfiguration: [ { name: privateSubnetName , subnetType: ec2.SubnetType.PRIVATE_ISOLATED , cidrMask: 20 , } , ] , } ); // Aurora Serverless v1 クラスタを作成 const auroraCluseter = new rds.ServerlessCluster ( this , "MyAuroraCluster" , { engine: rds.DatabaseClusterEngine.AURORA_MYSQL , vpc: vpc , vpcSubnets: { subnetGroupName: privateSubnetName } , // 最小ACUを1、最大ACUを2、一時停止までに必要な非アクティブ時間を2時間に指定 scaling: { minCapacity: 1 , maxCapacity: 2 , autoPause: Duration.hours ( 2 ) } , // Data APIを有効化 enableDataApi: true , } ); // Lambda関数 const awakeAuroraFunction = new lambdaNodejs.NodejsFunction ( this , "MyFunction" , { // Lambda関数へのファイルパス entry: "functions/awake-aurora-serverless.ts" , runtime: lambda.Runtime.NODEJS_14_X , // Data APIを利用するため、AuroraクラスタARNとシークレットのARNを環境変数で渡す environment: { CLUSTER_ARN: auroraCluseter.clusterArn , SECRET_ARN: auroraCluseter.secret?.secretArn ?? "" , } , } ); // Lambda関数の実行ロールにData APIへのアクセスを許可するポリシーを追加 if ( auroraCluseter.secret?.secretArn ) { const auroraDataApiPolicy = new iam.ManagedPolicy ( this , "MyAuroraDataApiPolicy" , { statements: [ new iam.PolicyStatement ( { resources: [ ` ${ auroraCluseter.secret.secretArn } *` ] , actions: [ "secretsmanager:GetSecretValue" ] , effect: iam.Effect.ALLOW , } ), new iam.PolicyStatement ( { resources: [ auroraCluseter.clusterArn ] , actions: [ "rds-data:ExecuteStatement" ] , effect: iam.Effect.ALLOW , } ), ] , } ); awakeAuroraFunction.role?.addManagedPolicy ( auroraDataApiPolicy ); } // 日本時間 平日の 7:00 ~ 20:00 の間に1時間ごとにLambda関数を定期起動する // cron式は UTC で記載するため、「日曜 ~ 木曜の22:00 ~ 23:00」と「月曜 ~ 金曜の 0:00 ~ 11:00」の2つに分ける new events.Rule ( this , "MyEventRule1" , { schedule: events.Schedule.cron ( { minute: "0" , hour: "22-23" , weekDay: "SUN-THU" } ), targets: [ new eventTargets.LambdaFunction ( awakeAuroraFunction , { retryAttempts: 3 } ) ] , } ); new events.Rule ( this , "MyEventRule2" , { schedule: events.Schedule.cron ( { minute: "0" , hour: "0-11" , weekDay: "MON-FRI" } ), targets: [ new eventTargets.LambdaFunction ( awakeAuroraFunction , { retryAttempts: 3 } ) ] , } ); } } Lambda関数の部分では、 NodejsFunction コンストラクト を利用することで、TypeScript で記述した Lambda 関数の JavaScript への コンパイル からデプロイまでをCDKがやってくれます。 Aurora クラスタ へクエリを発行するLambda関数は、 functions/awake-aurora-serverless.ts に以下のように実装します。Data API を利用してクエリを発行します。 import * as RDS from "@aws-sdk/client-rds-data" ; import { Handler } from "aws-lambda" ; const client = new RDS.RDSDataClient ( { region: "ap-northeast-1" } ); export const handler: Handler = async () => { const input = { // Data APIを利用するための、AuroraクラスタのリソースARNとシークレットのARNを環境変数から取得する resourceArn: process .env.CLUSTER_ARN , secretArn: process .env.SECRET_ARN , // 発行するSQL文 sql: "SHOW databases;" , } ; const command = new RDS.ExecuteStatementCommand ( input ); await client.send ( command ); } ; 発行する SQL 文は更新系でなければ何でも良いですが、シンプルに SHOW databases; としています。 実際の料金 以上の構成でしばらく稼働した場合の料金を確認しました。 土日はAurora クラスタ が停止し、料金がかかっていないことがわかります。平日も24時間のうち15時間しか稼働していません。 今回の条件では一週間 24h * 7日 = 168h のうち、 15h * 5日 = 75h 稼働しているため、常時稼働に比べて 75h / 168h = 45% の費用に抑えることができています。 一方で平日の業務時間中は常に稼働状態のため、接続が失敗することがなくなり、今回の要件を満たすことができました。 執筆: @kou.kinyo2 、レビュー: @higa ( Shodo で執筆されました )
こんにちは、 電通国際情報サービス デジタル イノベーション 1部の加世です。 今回は「FluentBitを利用したログルーティング」を進める際に、「FluentBitについて理解する」ことを目的とした記事となっております。 具体的なFluentBitの使い所や設計を考える前段階として、本記事を参考にしていただければと思います。 Fluent Bitについて Fluent Bitの特徴 検証環境と処理フローについて Fluent Bit設計前の準備 データパイプラインの理解 データの構造化について まとめ Fluent Bitについて FluentBitは、データ(メトリクス、ログ、それ以外の生情報など)をInput情報として収集し、加工処理したうえで任意の転送先に転送します。 クラウド サービスプロバイダを利用するうえでは、既に「システム」から「サービス」に転送する仕組みを用意していることが多いため、ログルーティングについて考慮しなくても問題ないケースが多いです。 そのため、FluentBitの利用は「複数のシステム(サーバ/コンテナ)」から「様々なデータ」を「複数の宛先」に「加工」して「集約」する場合が有効であると考えています。 FluentdとFluent Bitの違いについて ■Fluentd&Fluent Bit https://docs.fluentbit.io/manual/about/fluentd-and-fluent-bit FluentBitは、Fluentd傘下で開発された軽量なログルータであり、Fluentdの アーキテクチャ を踏まえて構築されています。 Fluent Bitの特徴 FluentBitは、大きく6種類「Input」->「Parse」->「Filter」->「Buffer」->「Router」->「Output」のPluginで構成されています。 また、「Output」 プラグイン は、主要な クラウド サービスプロバイダ( AWS , Azure, GCP , Datadog...etc)に対応しています。 そのため、データ転送先は アーキテクチャ ・データ分析方法を踏まえて、 プラグイン の対応範囲はありますがさまざまなサービスを選択できます。 FluentBitは、次の点で優れていると考えています。 優れていると考えられる点 Input/Output プラグイン でさまざまなソースと出力先を選択できる。 生データをParseして構造化して出力できる。 同じデータを複数出力先に対して、同時にルーティングできる。 一般的に必要とされる機能を備えた プラグイン が提供されている。 Fluent Bit ■ GitHub : Fluent Bit https://github.com/fluent/fluent-bit ■Fluent Bit : Official Manual https://docs.fluentbit.io/manual ■Release Notes https://fluentbit.io/announcements/ FluentBitに関する情報は、こちらを参照してください。 検証環境と処理フローについて 検証環境は、「 AWS Fargate」で「テストアプリケーションコンテナ (Firelensログドライバ付き)」「FluentBitコンテナ」を稼働しています。 また、FluentBitは、ログルーティング先として複数の転送先「CloudWatch」「S3」を指定します。 ※FluentBitコンテナを使用できる環境であれば、FluentBitの基礎的な機能は検証できます。 ※検証環境のホストOS カーネル パラメータ設定によっては、挙動が変わる場合はあります。 ※FireLensログドライバは、Fargate標準出力(stdout/stderr)をFluentBitにログルーティングするためだけに使用します。 AWS FargateでFirelensログドライバを利用して、標準出力をFluentBitに送信する方式について Firelensログドライバは、仕様を細かく確認していませんが「td-agent」の仕組みでFluentBitのInput プラグイン 「Forward」を利用して標準出力を転送していると思われます。 そのため、タグは「<コンテナ名>-firelens」となるため、必要に応じて「 rewrite _tags」などでタグを変更することで、Output プラグイン でのタグ条件指定がしやすくなります。 処理フロー アプリケーション(stdout/stderr) -> Firelensログドライバ -> (forward:24224) -> サイドカー コンテナ(FluentBit) -> CloudWatch/S3 アプリケーション(ローカルファイル) -> (tail:Volume共有マウント) -> サイドカー コンテナ(FluentBit) -> CloudWatch/S3 AWS 専用のFluentBitコンテナ https://docs.fluentbit.io/manual/installation/getting-started-with-fluent-bit AWS に最適化されたFluentBitコンテナが提供されています。 マニュアルにしたがって、 サイドカー コンテナとして起動します。 aws -for-fluent-bit AWS Fargateの場合は、「Firelens」ログドライバと連携して「 aws -for-fluent-bit」が一部設定を自動生成します。 また、オプション設定をすることで追加のFluentBit設定ファイルを読み込むことも可能です。 GitHub https://github.com/aws/aws-for-fluent-bit https://github.com/aws/amazon-cloudwatch-logs-for-fluent-bit Release Notes https://github.com/aws/aws-for-fluent-bit/releases IAMロール設定について 「 aws -for-fluent-bit」コンテナは出力先となる「CloudWatch」「S3」などに対して操作権限が必要になります。 そのため、Fargateコンテナを前提とした場合は「ECSタスクロール」に設定しておく必要があります。 なお、 AWS 以外から「CloudWatch」「S3」に転送する場合は、FluentBit向けのIAMロールを用意して「cloudwatch」「S3」 プラグイン でIAMロールを指定して使用できます。 Fluent Bit設計前の準備 データパイプラインの理解 FluentBitを設計するうえで、データパイプライン「Input」->「Parse」->「Filter」->「Buffer」->「Router」->「Output」を理解する必要があります。 Input https://docs.fluentbit.io/manual/pipeline/inputs 「Forward( TCP リスナポート経由のメッセージ受信)」「tail(ローカルファイスシステム上のログファイルなどのtail)」などで「生データ」の入力を受け付けます。 他にもメトリクスデータを取得する プラグイン も多数用意されています。 Parse https://docs.fluentbit.io/manual/pipeline/parsers Input プラグイン で受け取ったデータを「Parser」で処理することにより、「データ構造化」や「 マルチライン 処理」を行います。 「Input」「Filter」 プラグイン で使用できます。 データ構造化 「生データ(log)」を「時間(time)」「レベル(level)」「メッセージ(message)」などのフィールドに分割します。 事前に用意されているParser https://docs.fluentbit.io/manual/pipeline/parsers/configuring-parser 「 Apache 」「Docker」などは構造化を目的として、すでにParserが用意されています。 マルチライン 処理 複数行データ(たとえば、 Java スタックトレース の「at」など)を1つのデータとして扱います。 ※なお、「\n」「\t」が エス ケープされずにファイル出力されますが、回避方法は執筆時点で未調査です。 処理前 { "hostname": "ip-172-24-136-132.ap-northeast-1.compute.internal", "level": "EROROR", "message": "org.apache.catalina.startup.Catalina.start Server startup in 135176 ms", "thread": "main", "time": "02-Mar-2022 15:33:32.000" } { "hostname": "ip-172-24-136-132.ap-northeast-1.compute.internal", "level": "EROROR", "message": "\tat com.myproject.module.MyProject.badMethod(MyProject.java:22)", "thread": "main", "time": "02-Mar-2022 15:33:32.000" } { "hostname": "ip-172-24-136-132.ap-northeast-1.compute.internal", "level": "EROROR", "message": "\tat com.myproject.module.MyProject.oneMoreMethod(MyProject.java:18)", "thread": "main", "time": "02-Mar-2022 15:33:32.000" } 処理後 { "hostname": "ip-172-24-136-132.ap-northeast-1.compute.internal", "level": "EROROR", "message": "org.apache.catalina.startup.Catalina.start Server startup in 135176 ms\n\tat com.myproject.module.MyProject.badMethod(MyProject.java:22)\n\tat com.myproject.module.MyProject.oneMoreMethod(MyProject.java:18)", "thread": "main", "time": "02-Mar-2022 15:33:32.000" } Filter https://docs.fluentbit.io/manual/pipeline/filters 入力された「生データ」を「Filter」で加工(追加・変更・整形・削除 etc)します。 「Parser」「Multiline(Parser)」「Record Modifier」「 Rewrite Tag」「 Lua 」「 Kubernetes 」などがあります。 ※「 AWS Metadata」はEC2向けであり、Fargate向けのものではありません。(Fargate自体は、 メタデータ を参照するURLは提供されています) Buffer https://docs.fluentbit.io/manual/concepts/buffering 生データを保管する領域として、「メモリ」または「 ファイルシステム (永続領域)」を選択できます。 「Service」「Input」「Output」 プラグイン などで定義します。 なお、「処理間隔(メモリリフレッシュ、データ出力などのタイミング)」「各種バッファサイズ(ファイル初期読み込みサイズなど)」はチューニング要素となります。 補足 通常は、「メモリ」のみを選択する方針で問題ありません。 生データの過去分までの情報(オフセットなど)を持っておきたい場合は、「 ファイルシステム 」を選択します。 Fargateなどを前提とした エフェメラ ルストレージを利用する場合は、コンテナ内のメトリクス・ログデータなどは更新時に初期化されるため「メモリ」を採用する点は問題ありません。 一方で、データ分析などで永続領域にあるデータを漏れなく・重複なく読み込む必要がある場合は、EFSと連携するなどの永続領域のデータを参照する構成が必要になります。 Router https://docs.fluentbit.io/manual/concepts/data-pipeline/router 出力対象となるデータは、Input時点でデータとひもづけられたTag(または、Filterで書き換えられたTag)をもとに「識別」できるようにします。 そのうえで、正しく条件を指定することで適切な出力先に出力します。 ルーティング条件は、Output プラグイン の「Match( ワイルドカード 指定のみ)」と「Match_ regex 」により一致条件を設定します。 Output https://docs.fluentbit.io/manual/pipeline/outputs 「 クラウド サービスプロバイダ向けのストレージサービス」「ローカルログファイル」「FluentBitコンテナの標準出力」などに対して「データ」を出力します。 データの構造化について Inputデータは、「データフィールド名の追加・加工」「データ値の追加・加工」が可能です。 Inputデータが JSON 形式であり、すでに構造化されているデータの場合は、そのまま「フィールド名(キー名)」「値」を利用することが多いと考えられます。 ※ただし、どのようなデータでも「Filter」 プラグイン により追加の加工処理は可能です。 フィールドの追加・加工 Inputデータは、「Filter」 プラグイン でデータフィールド名を追加・加工できます。 Firelensログドライバ経由でInputした標準出力・ 標準エラー出力 は、「container_id」「container_name」「log」「source」フィールドをInputします。 これは既に構造化されたInputデータですが、例えば「log」「source」に対して「キ名ー(フィールド名)」を統一する目的で「message」「file_path」に変換できます。 また、追加の加工処理としてコンテナ内の 環境変数 「$HOSTNAME」の情報をもとに、「hostname」フィールドを追加できます。 Inputデータ { "container_id": "3885a532543547978adf8d6e9bdf729b-2449111020", "container_name": "test-container", "log": "test message.", "source": "stdout" } { "container_id": "625a41f4c1a241f49e7308b9g62911cb-1475094415", "container_name": "test-container", "log": "java.io.IOException: listener timeout after waiting for [60000] ms", "source": "stderr" } 加工済みデータ { "container_id": "3885a532543547978adf8d6e9bdf729b-2449111020", "container_name": "test-container", "file_path": "stdout", "hostname": "ip-172-24-100-100.ap-northeast-1.compute.internal", "message": "test message.", } { "container_id": "625a41f4c1a241f49e7308b9g62911cb-1475094415", "container_name": "test-container", "file_path": "stderr" "hostname": "ip-172-24-100-100.ap-northeast-1.compute.internal", "message": "java.io.IOException: listener timeout after waiting for [60000] ms", } データ値の追加・加工 Inputデータは、「Filter」 プラグイン でデータ値を追加・加工できます。 Docker標準出力などであれば、すでに「Parser」 プラグイン として用意されているパーサ「docker」を利用できます。 事前に用意されているParserで構造化が難しい場合は、独自にParserを定義できます。 たとえば、以下に示す独自の「Parser」 プラグイン 定義は、 Tomcat の標準出力ログを加工します。 これは、Inputデータのログを Regex に指定した 正規表現 でパースして、「time」「level」「thread」「message」などのフィールド名に マッピング します。 「Parser」 プラグイン 定義 [PARSER] Name tomcat Format regex Regex /^(?<time>\d{1,2}-\D{3}-\d{4} \d{1,2}:\d{1,2}:\d{1,2}.\d{3}) (?<level>[^\s]+) \[(?<thread>[^\]]*)\] (?<message>.*)/ Time_Key time Time_Format %d-%b-%Y %H:%M:%S.%L Time_Offset +0900 Time_Keep On # Command | Decoder | Field | Optional Action | # ==============|==============|=========|===================| Decode_Field_As escaped message インプットデータ 04-Mar-2022 12:34:39.072 ERROR [main] org.apache.catalina.startup.Catalina.start Server startup in 123094 ms 加工済みデータ { "file_path": "/usr/local/tomcat/logs/catalina.test.log", "hostname": "ip-172-24-136-164.ap-northeast-1.compute.internal", "level": "EROROR", "message": "org.apache.catalina.startup.Catalina.start Server startup in 135176 ms\n\tat com.myproject.module.MyProject.badMethod(MyProject.java:22)\n\tat com.myproject.module.MyProject.oneMoreMethod(MyProject.java:18)\n\tat com.myproject.module.MyProject.anotherMethod(MyProject.java:14)\n\tat com.myproject.module.MyProject.someMethod(MyProject.java:10)\n\tat com.myproject.module.MyProject.main(MyProject.java:6)", "thread": "main", "time": "04-Mar-2022 12:42:28.000" } まとめ 本記事では、「FluentBitについて理解する」ことを目的として記事を作成しました。 次回の記事では、「FluentBitを実際に動かしたうえで確認した設計・設定ポイント」をお話できればと考えています。 執筆: @kase.teruyoshi 、レビュー: @sato.taichi ( Shodo で執筆されました )
こんにちは、 電通国際情報サービス デジタル イノベーション 1部の加世です。 今回は「FluentBitを利用したログルーティング」を進める際に、「FluentBitについて理解する」ことを目的とした記事となっております。 具体的なFluentBitの使い所や設計を考える前段階として、本記事を参考にしていただければと思います。 Fluent Bitについて Fluent Bitの特徴 検証環境と処理フローについて Fluent Bit設計前の準備 データパイプラインの理解 データの構造化について まとめ Fluent Bitについて FluentBitは、データ(メトリクス、ログ、それ以外の生情報など)をInput情報として収集し、加工処理したうえで任意の転送先に転送します。 クラウド サービスプロバイダを利用するうえでは、既に「システム」から「サービス」に転送する仕組みを用意していることが多いため、ログルーティングについて考慮しなくても問題ないケースが多いです。 そのため、FluentBitの利用は「複数のシステム(サーバ/コンテナ)」から「様々なデータ」を「複数の宛先」に「加工」して「集約」する場合が有効であると考えています。 FluentdとFluent Bitの違いについて ■Fluentd&Fluent Bit https://docs.fluentbit.io/manual/about/fluentd-and-fluent-bit FluentBitは、Fluentd傘下で開発された軽量なログルータであり、Fluentdの アーキテクチャ を踏まえて構築されています。 Fluent Bitの特徴 FluentBitは、大きく6種類「Input」->「Parse」->「Filter」->「Buffer」->「Router」->「Output」のPluginで構成されています。 また、「Output」 プラグイン は、主要な クラウド サービスプロバイダ( AWS , Azure, GCP , Datadog...etc)に対応しています。 そのため、データ転送先は アーキテクチャ ・データ分析方法を踏まえて、 プラグイン の対応範囲はありますがさまざまなサービスを選択できます。 FluentBitは、次の点で優れていると考えています。 優れていると考えられる点 Input/Output プラグイン でさまざまなソースと出力先を選択できる。 生データをParseして構造化して出力できる。 同じデータを複数出力先に対して、同時にルーティングできる。 一般的に必要とされる機能を備えた プラグイン が提供されている。 Fluent Bit ■ GitHub : Fluent Bit https://github.com/fluent/fluent-bit ■Fluent Bit : Official Manual https://docs.fluentbit.io/manual ■Release Notes https://fluentbit.io/announcements/ FluentBitに関する情報は、こちらを参照してください。 検証環境と処理フローについて 検証環境は、「 AWS Fargate」で「テストアプリケーションコンテナ (Firelensログドライバ付き)」「FluentBitコンテナ」を稼働しています。 また、FluentBitは、ログルーティング先として複数の転送先「CloudWatch」「S3」を指定します。 ※FluentBitコンテナを使用できる環境であれば、FluentBitの基礎的な機能は検証できます。 ※検証環境のホストOS カーネル パラメータ設定によっては、挙動が変わる場合はあります。 ※FireLensログドライバは、Fargate標準出力(stdout/stderr)をFluentBitにログルーティングするためだけに使用します。 AWS FargateでFirelensログドライバを利用して、標準出力をFluentBitに送信する方式について Firelensログドライバは、仕様を細かく確認していませんが「td-agent」の仕組みでFluentBitのInput プラグイン 「Forward」を利用して標準出力を転送していると思われます。 そのため、タグは「<コンテナ名>-firelens」となるため、必要に応じて「 rewrite _tags」などでタグを変更することで、Output プラグイン でのタグ条件指定がしやすくなります。 処理フロー アプリケーション(stdout/stderr) -> Firelensログドライバ -> (forward:24224) -> サイドカー コンテナ(FluentBit) -> CloudWatch/S3 アプリケーション(ローカルファイル) -> (tail:Volume共有マウント) -> サイドカー コンテナ(FluentBit) -> CloudWatch/S3 AWS 専用のFluentBitコンテナ https://docs.fluentbit.io/manual/installation/getting-started-with-fluent-bit AWS に最適化されたFluentBitコンテナが提供されています。 マニュアルにしたがって、 サイドカー コンテナとして起動します。 aws -for-fluent-bit AWS Fargateの場合は、「Firelens」ログドライバと連携して「 aws -for-fluent-bit」が一部設定を自動生成します。 また、オプション設定をすることで追加のFluentBit設定ファイルを読み込むことも可能です。 GitHub https://github.com/aws/aws-for-fluent-bit https://github.com/aws/amazon-cloudwatch-logs-for-fluent-bit Release Notes https://github.com/aws/aws-for-fluent-bit/releases IAMロール設定について 「 aws -for-fluent-bit」コンテナは出力先となる「CloudWatch」「S3」などに対して操作権限が必要になります。 そのため、Fargateコンテナを前提とした場合は「ECSタスクロール」に設定しておく必要があります。 なお、 AWS 以外から「CloudWatch」「S3」に転送する場合は、FluentBit向けのIAMロールを用意して「cloudwatch」「S3」 プラグイン でIAMロールを指定して使用できます。 Fluent Bit設計前の準備 データパイプラインの理解 FluentBitを設計するうえで、データパイプライン「Input」->「Parse」->「Filter」->「Buffer」->「Router」->「Output」を理解する必要があります。 Input https://docs.fluentbit.io/manual/pipeline/inputs 「Forward( TCP リスナポート経由のメッセージ受信)」「tail(ローカルファイスシステム上のログファイルなどのtail)」などで「生データ」の入力を受け付けます。 他にもメトリクスデータを取得する プラグイン も多数用意されています。 Parse https://docs.fluentbit.io/manual/pipeline/parsers Input プラグイン で受け取ったデータを「Parser」で処理することにより、「データ構造化」や「 マルチライン 処理」を行います。 「Input」「Filter」 プラグイン で使用できます。 データ構造化 「生データ(log)」を「時間(time)」「レベル(level)」「メッセージ(message)」などのフィールドに分割します。 事前に用意されているParser https://docs.fluentbit.io/manual/pipeline/parsers/configuring-parser 「 Apache 」「Docker」などは構造化を目的として、すでにParserが用意されています。 マルチライン 処理 複数行データ(たとえば、 Java スタックトレース の「at」など)を1つのデータとして扱います。 ※なお、「\n」「\t」が エス ケープされずにファイル出力されますが、回避方法は執筆時点で未調査です。 処理前 { "hostname": "ip-172-24-136-132.ap-northeast-1.compute.internal", "level": "EROROR", "message": "org.apache.catalina.startup.Catalina.start Server startup in 135176 ms", "thread": "main", "time": "02-Mar-2022 15:33:32.000" } { "hostname": "ip-172-24-136-132.ap-northeast-1.compute.internal", "level": "EROROR", "message": "\tat com.myproject.module.MyProject.badMethod(MyProject.java:22)", "thread": "main", "time": "02-Mar-2022 15:33:32.000" } { "hostname": "ip-172-24-136-132.ap-northeast-1.compute.internal", "level": "EROROR", "message": "\tat com.myproject.module.MyProject.oneMoreMethod(MyProject.java:18)", "thread": "main", "time": "02-Mar-2022 15:33:32.000" } 処理後 { "hostname": "ip-172-24-136-132.ap-northeast-1.compute.internal", "level": "EROROR", "message": "org.apache.catalina.startup.Catalina.start Server startup in 135176 ms\n\tat com.myproject.module.MyProject.badMethod(MyProject.java:22)\n\tat com.myproject.module.MyProject.oneMoreMethod(MyProject.java:18)", "thread": "main", "time": "02-Mar-2022 15:33:32.000" } Filter https://docs.fluentbit.io/manual/pipeline/filters 入力された「生データ」を「Filter」で加工(追加・変更・整形・削除 etc)します。 「Parser」「Multiline(Parser)」「Record Modifier」「 Rewrite Tag」「 Lua 」「 Kubernetes 」などがあります。 ※「 AWS Metadata」はEC2向けであり、Fargate向けのものではありません。(Fargate自体は、 メタデータ を参照するURLは提供されています) Buffer https://docs.fluentbit.io/manual/concepts/buffering 生データを保管する領域として、「メモリ」または「 ファイルシステム (永続領域)」を選択できます。 「Service」「Input」「Output」 プラグイン などで定義します。 なお、「処理間隔(メモリリフレッシュ、データ出力などのタイミング)」「各種バッファサイズ(ファイル初期読み込みサイズなど)」はチューニング要素となります。 補足 通常は、「メモリ」のみを選択する方針で問題ありません。 生データの過去分までの情報(オフセットなど)を持っておきたい場合は、「 ファイルシステム 」を選択します。 Fargateなどを前提とした エフェメラ ルストレージを利用する場合は、コンテナ内のメトリクス・ログデータなどは更新時に初期化されるため「メモリ」を採用する点は問題ありません。 一方で、データ分析などで永続領域にあるデータを漏れなく・重複なく読み込む必要がある場合は、EFSと連携するなどの永続領域のデータを参照する構成が必要になります。 Router https://docs.fluentbit.io/manual/concepts/data-pipeline/router 出力対象となるデータは、Input時点でデータとひもづけられたTag(または、Filterで書き換えられたTag)をもとに「識別」できるようにします。 そのうえで、正しく条件を指定することで適切な出力先に出力します。 ルーティング条件は、Output プラグイン の「Match( ワイルドカード 指定のみ)」と「Match_ regex 」により一致条件を設定します。 Output https://docs.fluentbit.io/manual/pipeline/outputs 「 クラウド サービスプロバイダ向けのストレージサービス」「ローカルログファイル」「FluentBitコンテナの標準出力」などに対して「データ」を出力します。 データの構造化について Inputデータは、「データフィールド名の追加・加工」「データ値の追加・加工」が可能です。 Inputデータが JSON 形式であり、すでに構造化されているデータの場合は、そのまま「フィールド名(キー名)」「値」を利用することが多いと考えられます。 ※ただし、どのようなデータでも「Filter」 プラグイン により追加の加工処理は可能です。 フィールドの追加・加工 Inputデータは、「Filter」 プラグイン でデータフィールド名を追加・加工できます。 Firelensログドライバ経由でInputした標準出力・ 標準エラー出力 は、「container_id」「container_name」「log」「source」フィールドをInputします。 これは既に構造化されたInputデータですが、例えば「log」「source」に対して「キ名ー(フィールド名)」を統一する目的で「message」「file_path」に変換できます。 また、追加の加工処理としてコンテナ内の 環境変数 「$HOSTNAME」の情報をもとに、「hostname」フィールドを追加できます。 Inputデータ { "container_id": "3885a532543547978adf8d6e9bdf729b-2449111020", "container_name": "test-container", "log": "test message.", "source": "stdout" } { "container_id": "625a41f4c1a241f49e7308b9g62911cb-1475094415", "container_name": "test-container", "log": "java.io.IOException: listener timeout after waiting for [60000] ms", "source": "stderr" } 加工済みデータ { "container_id": "3885a532543547978adf8d6e9bdf729b-2449111020", "container_name": "test-container", "file_path": "stdout", "hostname": "ip-172-24-100-100.ap-northeast-1.compute.internal", "message": "test message.", } { "container_id": "625a41f4c1a241f49e7308b9g62911cb-1475094415", "container_name": "test-container", "file_path": "stderr" "hostname": "ip-172-24-100-100.ap-northeast-1.compute.internal", "message": "java.io.IOException: listener timeout after waiting for [60000] ms", } データ値の追加・加工 Inputデータは、「Filter」 プラグイン でデータ値を追加・加工できます。 Docker標準出力などであれば、すでに「Parser」 プラグイン として用意されているパーサ「docker」を利用できます。 事前に用意されているParserで構造化が難しい場合は、独自にParserを定義できます。 たとえば、以下に示す独自の「Parser」 プラグイン 定義は、 Tomcat の標準出力ログを加工します。 これは、Inputデータのログを Regex に指定した 正規表現 でパースして、「time」「level」「thread」「message」などのフィールド名に マッピング します。 「Parser」 プラグイン 定義 [PARSER] Name tomcat Format regex Regex /^(?<time>\d{1,2}-\D{3}-\d{4} \d{1,2}:\d{1,2}:\d{1,2}.\d{3}) (?<level>[^\s]+) \[(?<thread>[^\]]*)\] (?<message>.*)/ Time_Key time Time_Format %d-%b-%Y %H:%M:%S.%L Time_Offset +0900 Time_Keep On # Command | Decoder | Field | Optional Action | # ==============|==============|=========|===================| Decode_Field_As escaped message インプットデータ 04-Mar-2022 12:34:39.072 ERROR [main] org.apache.catalina.startup.Catalina.start Server startup in 123094 ms 加工済みデータ { "file_path": "/usr/local/tomcat/logs/catalina.test.log", "hostname": "ip-172-24-136-164.ap-northeast-1.compute.internal", "level": "EROROR", "message": "org.apache.catalina.startup.Catalina.start Server startup in 135176 ms\n\tat com.myproject.module.MyProject.badMethod(MyProject.java:22)\n\tat com.myproject.module.MyProject.oneMoreMethod(MyProject.java:18)\n\tat com.myproject.module.MyProject.anotherMethod(MyProject.java:14)\n\tat com.myproject.module.MyProject.someMethod(MyProject.java:10)\n\tat com.myproject.module.MyProject.main(MyProject.java:6)", "thread": "main", "time": "04-Mar-2022 12:42:28.000" } まとめ 本記事では、「FluentBitについて理解する」ことを目的として記事を作成しました。 次回の記事では、「FluentBitを実際に動かしたうえで確認した設計・設定ポイント」をお話できればと考えています。 執筆: @kase.teruyoshi 、レビュー: @sato.taichi ( Shodo で執筆されました )
皆さんこんにちは!金融ソリューション事業部 市場系ソリューション1部の寺山です。 かなり温かく、というか暑くなってきましたね。私は、今の時期から冷房に頼ると本場の夏の暑さに耐えられないぞ!という戦略で冷房を使うのを我慢しています。 これまではインフラ/ クラウド 関連の記事を投稿してきた私ですが、今回は打って変わってローコード関連の内容となります。背景を踏まえてローコードツール:Power Appsを用いて実現した内容をご紹介したいと思います! 背景 Power Appsを作成 アプリの作成とコネクタの追加 初期化 カレンダーの描画 表示する年/月のセレクタ あとはカレンダーらしさが出る修飾 ローコードをはじめてちゃんと触ってみた感想 参考文献/記事 背景 私は、昨年度の弊社 アドベントカレンダー で記事を投稿した以降に、当テックブログの運営チームに参加しました。 テックブログの運営において、誰がいつ投稿する予定なのか?/投稿の途切れてしまう期間があるか?といった観点で、 執筆状況をカレンダー形式で可視化したいよね という意見が生まれました。 結論として、 Microsoft Plannerで執筆タスクを管理することにより上記の目的を達成しようとなりました。理由は以下のとおりです。 Plannerにはカレンダー機能がある。 機能がシンプルであり、厳密なタスク管理ルールを策定しないことにより執筆者・運営側の双方の負荷にならないよう、執筆管理を運用可能と考えた。 1. でカレンダー形式で可視化するという当初の目的は達成しました。加えて、弊社内でテックブログの活動や執筆ガイドを共有するための SharePoint ポータルサイト を構築していたため、そこにカレンダー形式として埋め込むことで、 活動状況を執筆メンバー以外にも共有したいよね! という考えに発展しました。 そこで、プレビュー版ではあるもののWebパーツが提供されているPower Appsを用いてカレンダーを作成し、 SharePoint に埋め込んでみようと思い立ったのが背景となります。 実際に埋め込んだ PowreAppsは以下のように表示されます! Power Appsを作成 前述のPower Appsアプリをどのように作成したのかを簡単にご紹介します。 作業はすべてPower AppsのWebコンソールにて行いました。 私はPower Appsについて無知な状態からスタートしたため、Power Appsの各機能や コンポーネント (Power Apps用語ではコン トロール )の説明は割愛し、全体的な流れの説明に比重を置かせていただきます。 アプリの作成とコネクタの追加 まずはアプリを作成します。Power Appsのサブメニューより、 作成 > 空のキャンバスアプリ > 作成 と選択し、アプリ名を設定して空のキャンバスアプリを作成します。 私は利用していませんが、PowreAppsではアプリのテンプレートも提供されています。 形式 ですが、 SharePoint の ポータルサイト は弊社の社員が業務中にPCから参照するケースの方が多いと考え、 タブレット を選択しました。 次はコネクタの追加です。Power Apps で表示/加工するデータは、Office365の他のアプリケーションや サードパーティ ツール( DBMS やDWHなど)を データソース として コネクタ で接続して取得します。 今回利用したコネクタは以下のとおりです。 Planner:カレンダーに表示するPlannerタスクや バケット の取得に利用 O365Group:タスクの担当者名の取得に利用 コネクタの追加は、サブメニューの データ > データの追加 より行います。データソースに対する認証情報に自身のOffice365アカウントを指定します。 初期化 キャンバスアプリのトップエンティティはスクリーンです。空のキャンバスアプリを作成すると執筆時点のデフォルトではスクリーンのみが作成された状態となります。 私の作成した Power Apps ではスクリーンの OnVisible プロパティに以下の関数を設定することで、Power Appsの描画時に初期化がされるようにしました。 // 共通して使用する変数の宣言 UpdateContext ( { planId : "<PlannerのPlanID>" , groupId : "<PlannerのGroupID>" , officeGroupId : "<PlannerのGroupID>" , weekDay :[ "Sun." , "Mon." , "Tue." , "Wed." , "Thu." , "Fri." , "Sat." ] } ); // カレンダーとして表示対象の月の1日と月末の日付を設定 UpdateContext ( { startOfMonth : Date (TextInputYear_1.Text,DropdownMonth_1.Selected.Value, 1 ), endOfMonth : Date (TextInputYear_1.Text,DropdownMonth_1.Selected.Value + 1 , 1 )- 1 } ); // カレンダーに表示する開始日と終了日を計算 UpdateContext ( { fromDate :startOfMonth-( Weekday (startOfMonth, 1 )- 1 ), toDate :endOfMonth+( 7 - Weekday (endOfMonth, 1 )) } ); // PlannerとOffice365Groupデータソースから、Plannerタスク一覧、Plannerのバケット一覧、Office365Groupのメンバー一覧を取得してテーブルに格納 UpdateContext ( { tasks :Planner. ListTasksV3 (planId,groupId).value, buckets :Planner. ListBucketsV3 (planId,groupId).value, members :O365Group. ListGroupMembers (officeGroupId).value } ); // カレンダーに表示する開始日から終了日までの全日付をテーブルに格納 UpdateContext ( { days : ForAll ( Sequence (toDate-fromDate+ 1 ), DateAdd (fromDate- 1 ,Value,Days)) } ) UpdateContext はスクリーンがスコープとなる変数を宣言/更新する関数です。 以下は各UpdateContextブロックに対する補足です。 1つ目のブロックで変数の値に設定している PlannerのPlanID と PlannerのGroupID はPlannerのURLから確認可能です。 2つ目のブロックでは、後述する TextInputYear_1 という テキスト入力 コン トロール の初期値と、 DropdownMonth_1 という ドロップダウン コン トロール の初期値から取得しています。 5つ目のブロックの ForAll は、第一引数のテーブルに対して第二引数の操作を繰り返す関数です。 Sequence 関数を使用してカレンダーに表示する開始日から終了日までのインデックスのテーブルを作成して、カレンダーの開始日からインデックスを相対距離として日付を計算することで、カレンダーの開始から終了日までに含まれる全日付のテーブルを作成しています。 Power Apps上での作業は以下のようになります。 カレンダーの描画 カレンダー風に描画するために、2つの ギャラリー コン トロール を作成しています。 ギャラリーとは、指定したデータに対し、他のコン トロール をテンプレートとして展開可能なコンテナ型のコン トロール です。 1つ目のギャラリーは、カレンダーの曜日を表示するための水平ギャラリーです。 前のセクションで初期化した weekday テーブルをギャラリーの Items プロパティに指定し、ギャラリー内には テキストラベル コン トロール を配置しています。 テキストラベルに表示する Text プロパティで以下の関数を指定することで、曜日の表す列のように描画しています。 ThisItem にはギャラリーの Items プロパティに指定したテーブルの要素が格納されます。 ThisItem.Value 2つ目はカレンダーの各日のボックスを表現する水平ギャラリーです。 Items プロパティには前のセクションで初期化した days テーブルを指定しています。 水平ギャラリーには、まず垂直コンテナを配置し、内部に配置する2つのコン トロール の位置関係と描画範囲を調整しています。 コンテナ内に配置する1つ目のコン トロール は テキストラベル で、以下の関数を設定することでカレンダーの「日付」を表示しています。 Text (ThisItem.Value, "dd" ) Plannerのタスクを表示する領域は垂直ギャラリーを使用しました。ギャラリーに表示するデータは、 Items プロパティに以下の関数を設定し、前のセクションで取得したPlannerタスク一覧から抽出しています。 Sort ( Filter (tasks, And (dueDateTime>=ThisItem.Value,dueDateTime<ThisItem.Value+ 1 )),title) これにより、「各日のボックスを表現する水平ギャラリー」の ThisItem に格納されている各日がPlannerの 期日 に一致するタスクのテーブルが、垂直ギャラリーのデータに設定されます。 垂直ギャラリーのテンプレートに以下のコン トロール を配置することでタスクを表示しています。 テキストラベル :Plannerタスクのタイトル ThisItem.title テキストラベル と楕円の図形:Plannerタスクの バケット 本件では、Planner タスクのステータスではなく、タスクが属する バケット をタスクのステータス情報として採用しました。 LookUp は、 Excel のVLOOKUPと同じイメージで、第一引数のテーブルから第二引数の条件でデータを抽出する関数です。 buckets には前のセクションで初期化したPlannerの バケット 一覧が格納されています。 LookUp (buckets,id=ThisItem.bucketId).name テキストラベル :Plannerタスクのオーナー members には前のセクションで初期化したOffice365Groupのグループメンバー一覧が格納されています。 LookUp (members,id= First (ThisItem._assignments).userId).displayName ポイントとしては、「カレンダーの各日のボックスを表現する水平ギャラリー」の WrapCount(折り返しの数) プロパティに 7 を指定している点です。 水平方向に7アイテムが表示される毎に折り返されるので、カレンダーのように描画されます。 また、描画範囲を調整するため、上記の2つの水平ギャラリーは コンテナ コン トロール に配置しています。 表示する年/月の セレクタ 前述までのセクションでカレンダーは表示されます。 初期化の年/月以外のカレンダーを表示可能なよう、 セレクタ を作成しました。 年は テキスト入力 コン トロール で利用者に入力してもらう仕様としました。入力された値は、 <コントロール名>.Text で参照できます。 初期値として、 Default プロパティに以下の関数を設定しています。「初期化」セクションで startOfMonth と endOfMonth 変数の入力の一方が、この値です。 Text ( Today (), "yyyy" ) 月は、 ドロップダウン コン トロール から選択する仕様です。プルダウンに表示するリストは、 Items プロパティに01~12のテーブルとして設定しました。選択された値は、 <コントロール名>.Selected.Value で参照可能です。 初期値として、 Default プロパティに以下の関数を設定しています。「初期化」セクションで startOfMonth と endOfMonth 変数の入力の他方が、この値です。 Text ( Today (), "mm" ) 上記2つのコン トロール の入力をカレンダーに反映する ボタン コン トロール を追加します。 OnSelect プロパティに以下の関数を設定することでカレンダーを更新します。内容は初期化セクションとほぼ同じです。 UpdateContext ( { startOfMonth : Date (TextInputYear_1.Text,DropdownMonth_1.Selected.Value, 1 ), endOfMonth : Date (TextInputYear_1.Text,DropdownMonth_1.Selected.Value + 1 , 1 )- 1 } ); UpdateContext ( { fromDate :startOfMonth-( Weekday (startOfMonth, 1 )- 1 ), toDate :endOfMonth+( 7 - Weekday (endOfMonth, 1 )) } ); UpdateContext ( { days : ForAll ( Sequence (toDate-fromDate+ 1 ), DateAdd (fromDate- 1 ,Value,Days)) } ) おまけで、利用者の入力を Default に戻すリセットボタンも配置しました。 あとはカレンダーらしさが出る修飾 見た目の修飾として以下を行っています。 当日のボックスの日付を強調 土日の背景をグレー表示 年/月 セレクタ で選択された月以外の日付をグレー表示 例えば、2022年04月が選択された場合、2022/04は4/1~4/30ですが、カレンダー上には3/27~3/31も表示されるため、これらの日付文字の色はグレーになるようにしています。 タスクのステータス(Plannerの バケット )毎に表示色を変更 公開済みステータス(Plannerの バケット )の場合はクラッカーの画像を表示 これらは、各コン トロール のプロパティに If 関数を使用して実現しています。すべての紹介は割愛しますが、代表として当日日付の強調をご紹介します。 当日日付は テキストラベル コン トロール で、 Color プロパティに以下の関数を設定することで、当日日付のテキストラベルの背景色を変更しています。 If ( Text ( Today (), "yyyy/mm/dd" )= Text (ThisItem.Value, "yyyy/mm/dd" ), RGBA ( 20 , 165 , 255 , 1 ), RGBA ( 255 , 255 , 255 , 1 )) ローコードをはじめてちゃんと触ってみた感想 ご参考までに利用したコン トロール の一覧は下図のとおりです。 私はこれまで、Power Appsに限らずローコードツール/プラットフォームというものはほとんど触ったことがありませんでした。 本件で確りと触ってみて、専門的な知識がなくても、それっぽいものを比較的簡単に作れるという便利さが印象的でした。 Microsoft 製品だけでも、Power Appsの他にPower Automateなども提供されています。また、弊社のようなベンダーだけでなくエンドユーザー様でも利用しやすい点から、業務効率化やDXの一環として活用できる強力なツールであると実感しました。 最後までご覧いただきありがとうございました。弊社にはローコード開発やお客様の業務効率化/DX推進のご支援も行っている組織もございます。この記事の内容が参考になるか、弊社に興味を持つ機会になれば幸いです。また次の記事でお会いしましょう! 参考文献/記事 キャンバス アプリでのコントロールの追加と設定 Microsoft Planner との統合 Power Apps で Planner の機能を強化してみる(後編) Power Apps プランナー(Planner)のタスクをギャラリー(Gallery)で一覧表示する! 執筆: 寺山 輝 (@terayama.akira) 、レビュー: @sato.taichi ( Shodo で執筆されました )
皆さんこんにちは!金融ソリューション事業部 市場系ソリューション1部の寺山です。 かなり温かく、というか暑くなってきましたね。私は、今の時期から冷房に頼ると本場の夏の暑さに耐えられないぞ!という戦略で冷房を使うのを我慢しています。 これまではインフラ/ クラウド 関連の記事を投稿してきた私ですが、今回は打って変わってローコード関連の内容となります。背景を踏まえてローコードツール:Power Appsを用いて実現した内容をご紹介したいと思います! 背景 Power Appsを作成 アプリの作成とコネクタの追加 初期化 カレンダーの描画 表示する年/月のセレクタ あとはカレンダーらしさが出る修飾 ローコードをはじめてちゃんと触ってみた感想 参考文献/記事 背景 私は、昨年度の弊社 アドベントカレンダー で記事を投稿した以降に、当テックブログの運営チームに参加しました。 テックブログの運営において、誰がいつ投稿する予定なのか?/投稿の途切れてしまう期間があるか?といった観点で、 執筆状況をカレンダー形式で可視化したいよね という意見が生まれました。 結論として、 Microsoft Plannerで執筆タスクを管理することにより上記の目的を達成しようとなりました。理由は以下のとおりです。 Plannerにはカレンダー機能がある。 機能がシンプルであり、厳密なタスク管理ルールを策定しないことにより執筆者・運営側の双方の負荷にならないよう、執筆管理を運用可能と考えた。 1. でカレンダー形式で可視化するという当初の目的は達成しました。加えて、弊社内でテックブログの活動や執筆ガイドを共有するための SharePoint ポータルサイト を構築していたため、そこにカレンダー形式として埋め込むことで、 活動状況を執筆メンバー以外にも共有したいよね! という考えに発展しました。 そこで、プレビュー版ではあるもののWebパーツが提供されているPower Appsを用いてカレンダーを作成し、 SharePoint に埋め込んでみようと思い立ったのが背景となります。 実際に埋め込んだ PowreAppsは以下のように表示されます! Power Appsを作成 前述のPower Appsアプリをどのように作成したのかを簡単にご紹介します。 作業はすべてPower AppsのWebコンソールにて行いました。 私はPower Appsについて無知な状態からスタートしたため、Power Appsの各機能や コンポーネント (Power Apps用語ではコン トロール )の説明は割愛し、全体的な流れの説明に比重を置かせていただきます。 アプリの作成とコネクタの追加 まずはアプリを作成します。Power Appsのサブメニューより、 作成 > 空のキャンバスアプリ > 作成 と選択し、アプリ名を設定して空のキャンバスアプリを作成します。 私は利用していませんが、PowreAppsではアプリのテンプレートも提供されています。 形式 ですが、 SharePoint の ポータルサイト は弊社の社員が業務中にPCから参照するケースの方が多いと考え、 タブレット を選択しました。 次はコネクタの追加です。Power Apps で表示/加工するデータは、Office365の他のアプリケーションや サードパーティ ツール( DBMS やDWHなど)を データソース として コネクタ で接続して取得します。 今回利用したコネクタは以下のとおりです。 Planner:カレンダーに表示するPlannerタスクや バケット の取得に利用 O365Group:タスクの担当者名の取得に利用 コネクタの追加は、サブメニューの データ > データの追加 より行います。データソースに対する認証情報に自身のOffice365アカウントを指定します。 初期化 キャンバスアプリのトップエンティティはスクリーンです。空のキャンバスアプリを作成すると執筆時点のデフォルトではスクリーンのみが作成された状態となります。 私の作成した Power Apps ではスクリーンの OnVisible プロパティに以下の関数を設定することで、Power Appsの描画時に初期化がされるようにしました。 // 共通して使用する変数の宣言 UpdateContext ( { planId : "<PlannerのPlanID>" , groupId : "<PlannerのGroupID>" , officeGroupId : "<PlannerのGroupID>" , weekDay :[ "Sun." , "Mon." , "Tue." , "Wed." , "Thu." , "Fri." , "Sat." ] } ); // カレンダーとして表示対象の月の1日と月末の日付を設定 UpdateContext ( { startOfMonth : Date (TextInputYear_1.Text,DropdownMonth_1.Selected.Value, 1 ), endOfMonth : Date (TextInputYear_1.Text,DropdownMonth_1.Selected.Value + 1 , 1 )- 1 } ); // カレンダーに表示する開始日と終了日を計算 UpdateContext ( { fromDate :startOfMonth-( Weekday (startOfMonth, 1 )- 1 ), toDate :endOfMonth+( 7 - Weekday (endOfMonth, 1 )) } ); // PlannerとOffice365Groupデータソースから、Plannerタスク一覧、Plannerのバケット一覧、Office365Groupのメンバー一覧を取得してテーブルに格納 UpdateContext ( { tasks :Planner. ListTasksV3 (planId,groupId).value, buckets :Planner. ListBucketsV3 (planId,groupId).value, members :O365Group. ListGroupMembers (officeGroupId).value } ); // カレンダーに表示する開始日から終了日までの全日付をテーブルに格納 UpdateContext ( { days : ForAll ( Sequence (toDate-fromDate+ 1 ), DateAdd (fromDate- 1 ,Value,Days)) } ) UpdateContext はスクリーンがスコープとなる変数を宣言/更新する関数です。 以下は各UpdateContextブロックに対する補足です。 1つ目のブロックで変数の値に設定している PlannerのPlanID と PlannerのGroupID はPlannerのURLから確認可能です。 2つ目のブロックでは、後述する TextInputYear_1 という テキスト入力 コン トロール の初期値と、 DropdownMonth_1 という ドロップダウン コン トロール の初期値から取得しています。 5つ目のブロックの ForAll は、第一引数のテーブルに対して第二引数の操作を繰り返す関数です。 Sequence 関数を使用してカレンダーに表示する開始日から終了日までのインデックスのテーブルを作成して、カレンダーの開始日からインデックスを相対距離として日付を計算することで、カレンダーの開始から終了日までに含まれる全日付のテーブルを作成しています。 Power Apps上での作業は以下のようになります。 カレンダーの描画 カレンダー風に描画するために、2つの ギャラリー コン トロール を作成しています。 ギャラリーとは、指定したデータに対し、他のコン トロール をテンプレートとして展開可能なコンテナ型のコン トロール です。 1つ目のギャラリーは、カレンダーの曜日を表示するための水平ギャラリーです。 前のセクションで初期化した weekday テーブルをギャラリーの Items プロパティに指定し、ギャラリー内には テキストラベル コン トロール を配置しています。 テキストラベルに表示する Text プロパティで以下の関数を指定することで、曜日の表す列のように描画しています。 ThisItem にはギャラリーの Items プロパティに指定したテーブルの要素が格納されます。 ThisItem.Value 2つ目はカレンダーの各日のボックスを表現する水平ギャラリーです。 Items プロパティには前のセクションで初期化した days テーブルを指定しています。 水平ギャラリーには、まず垂直コンテナを配置し、内部に配置する2つのコン トロール の位置関係と描画範囲を調整しています。 コンテナ内に配置する1つ目のコン トロール は テキストラベル で、以下の関数を設定することでカレンダーの「日付」を表示しています。 Text (ThisItem.Value, "dd" ) Plannerのタスクを表示する領域は垂直ギャラリーを使用しました。ギャラリーに表示するデータは、 Items プロパティに以下の関数を設定し、前のセクションで取得したPlannerタスク一覧から抽出しています。 Sort ( Filter (tasks, And (dueDateTime>=ThisItem.Value,dueDateTime<ThisItem.Value+ 1 )),title) これにより、「各日のボックスを表現する水平ギャラリー」の ThisItem に格納されている各日がPlannerの 期日 に一致するタスクのテーブルが、垂直ギャラリーのデータに設定されます。 垂直ギャラリーのテンプレートに以下のコン トロール を配置することでタスクを表示しています。 テキストラベル :Plannerタスクのタイトル ThisItem.title テキストラベル と楕円の図形:Plannerタスクの バケット 本件では、Planner タスクのステータスではなく、タスクが属する バケット をタスクのステータス情報として採用しました。 LookUp は、 Excel のVLOOKUPと同じイメージで、第一引数のテーブルから第二引数の条件でデータを抽出する関数です。 buckets には前のセクションで初期化したPlannerの バケット 一覧が格納されています。 LookUp (buckets,id=ThisItem.bucketId).name テキストラベル :Plannerタスクのオーナー members には前のセクションで初期化したOffice365Groupのグループメンバー一覧が格納されています。 LookUp (members,id= First (ThisItem._assignments).userId).displayName ポイントとしては、「カレンダーの各日のボックスを表現する水平ギャラリー」の WrapCount(折り返しの数) プロパティに 7 を指定している点です。 水平方向に7アイテムが表示される毎に折り返されるので、カレンダーのように描画されます。 また、描画範囲を調整するため、上記の2つの水平ギャラリーは コンテナ コン トロール に配置しています。 表示する年/月の セレクタ 前述までのセクションでカレンダーは表示されます。 初期化の年/月以外のカレンダーを表示可能なよう、 セレクタ を作成しました。 年は テキスト入力 コン トロール で利用者に入力してもらう仕様としました。入力された値は、 <コントロール名>.Text で参照できます。 初期値として、 Default プロパティに以下の関数を設定しています。「初期化」セクションで startOfMonth と endOfMonth 変数の入力の一方が、この値です。 Text ( Today (), "yyyy" ) 月は、 ドロップダウン コン トロール から選択する仕様です。プルダウンに表示するリストは、 Items プロパティに01~12のテーブルとして設定しました。選択された値は、 <コントロール名>.Selected.Value で参照可能です。 初期値として、 Default プロパティに以下の関数を設定しています。「初期化」セクションで startOfMonth と endOfMonth 変数の入力の他方が、この値です。 Text ( Today (), "mm" ) 上記2つのコン トロール の入力をカレンダーに反映する ボタン コン トロール を追加します。 OnSelect プロパティに以下の関数を設定することでカレンダーを更新します。内容は初期化セクションとほぼ同じです。 UpdateContext ( { startOfMonth : Date (TextInputYear_1.Text,DropdownMonth_1.Selected.Value, 1 ), endOfMonth : Date (TextInputYear_1.Text,DropdownMonth_1.Selected.Value + 1 , 1 )- 1 } ); UpdateContext ( { fromDate :startOfMonth-( Weekday (startOfMonth, 1 )- 1 ), toDate :endOfMonth+( 7 - Weekday (endOfMonth, 1 )) } ); UpdateContext ( { days : ForAll ( Sequence (toDate-fromDate+ 1 ), DateAdd (fromDate- 1 ,Value,Days)) } ) おまけで、利用者の入力を Default に戻すリセットボタンも配置しました。 あとはカレンダーらしさが出る修飾 見た目の修飾として以下を行っています。 当日のボックスの日付を強調 土日の背景をグレー表示 年/月 セレクタ で選択された月以外の日付をグレー表示 例えば、2022年04月が選択された場合、2022/04は4/1~4/30ですが、カレンダー上には3/27~3/31も表示されるため、これらの日付文字の色はグレーになるようにしています。 タスクのステータス(Plannerの バケット )毎に表示色を変更 公開済みステータス(Plannerの バケット )の場合はクラッカーの画像を表示 これらは、各コン トロール のプロパティに If 関数を使用して実現しています。すべての紹介は割愛しますが、代表として当日日付の強調をご紹介します。 当日日付は テキストラベル コン トロール で、 Color プロパティに以下の関数を設定することで、当日日付のテキストラベルの背景色を変更しています。 If ( Text ( Today (), "yyyy/mm/dd" )= Text (ThisItem.Value, "yyyy/mm/dd" ), RGBA ( 20 , 165 , 255 , 1 ), RGBA ( 255 , 255 , 255 , 1 )) ローコードをはじめてちゃんと触ってみた感想 ご参考までに利用したコン トロール の一覧は下図のとおりです。 私はこれまで、Power Appsに限らずローコードツール/プラットフォームというものはほとんど触ったことがありませんでした。 本件で確りと触ってみて、専門的な知識がなくても、それっぽいものを比較的簡単に作れるという便利さが印象的でした。 Microsoft 製品だけでも、Power Appsの他にPower Automateなども提供されています。また、弊社のようなベンダーだけでなくエンドユーザー様でも利用しやすい点から、業務効率化やDXの一環として活用できる強力なツールであると実感しました。 最後までご覧いただきありがとうございました。弊社にはローコード開発やお客様の業務効率化/DX推進のご支援も行っている組織もございます。この記事の内容が参考になるか、弊社に興味を持つ機会になれば幸いです。また次の記事でお会いしましょう! 参考文献/記事 キャンバス アプリでのコントロールの追加と設定 Microsoft Planner との統合 Power Apps で Planner の機能を強化してみる(後編) Power Apps プランナー(Planner)のタスクをギャラリー(Gallery)で一覧表示する! 執筆: 寺山 輝 (@terayama.akira) 、レビュー: @sato.taichi ( Shodo で執筆されました )
こんにちは。 電通国際情報サービス (ISID) グループ経営ソリューション事業部の高崎です。 私が担当しているプロダクトの開発・運用中に発生した各種インシデントについて、解決後に再発防止を目的とした振り返りを実施しています。振り返りの方法として、ポストモーテムを導入してみました。 導入して3ヵ月が経過し、導入してよかったと思うことや今後の課題などが見えてきたので、紹介したいと思います。 後述するポストモーテムの内容は下記の書籍を参考にしています。 SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム (O'Reilly Japan) ポストモーテムとは インシデントが発生したことによる影響、解決のために行ったアクション、発生した原因、再発防止策などを記録したドキュメントを指します。 ポストモーテムを作成する上で個人を非難してはいけません。ポストモーテムの目的は、誰がインシデントを引き起こしたのかを明らかにすることではなく、なぜインシデントが発生してしまったのかを組織としてはっきりとさせることです。 焦点は人ではなくプロセスと技術にあてられなければなりません。 また、完成したポストモーテムは記載されている教訓が役立つよう、可能な限り広い範囲に共有することが重要です。 ポストモーテムを導入したきっかけ 開発プロジェクトの体制は以下のようになっています。 PM配下に業務領域ごとの開発チーム、その開発チームを横断的に見ているTech Leadがいます。 ※私のポジションはTech Leadです これまでインシデントが発生した場合、原因となった機能を担当している各開発チームごとに振り返りを実施し、再発防止策を作成していました。そうすると同じチーム内では再発しないのですが、振り返りの内容や再発防止策が他チームに浸透しておらず、同様の原因によるインシデントが他チームで発生するという課題がありました。 上記を解決するための方法を検討していた中で、ポストモーテムを導入してみようと思ったことがきっかけです。 どのようにしてポストモーテムを作成しているか 以下のフォーマットに沿って、関係者が各項目について対面で会話しながら作成しています。 ファシリテーター はTech Leadが担当しています。 # インシデント名 ## インシデント発生日 ## 作成日 ## 作者 ## ステータス → インシデントの現在のステータス ## サマリ → インシデントの概要 ## インパクト → インシデントによってどんな影響があったか ## 検出 → インシデントを検出した方法 ## 対応 → インシデントを収束させるために実施したこと ## タイムライン → インシデント発生から復旧までのタイムラインを書く ## 教訓 ### うまくいったこと ### うまくいかなかったこと ## 根本原因 → インシデントが発生した根本原因 ## 発生要因 → 根本原因が発生した要因 ## 再発防止策 特に重要な根本原因・発生要因・再発防止策については、 マインドマップ を使って深掘りを行っています。 まず根本原因(Where)が何かを突き止めます。次に根本原因となった事象がなぜ発生したのか(Why)を突き止め、最後に再発させないために何をするべきか(How)を決定します。 上記手順を踏まないと、根本原因や発生要因を明らかにしないまま、再発防止策ありきで話が進んでしまい、効果的な対策を打てない可能性があるため、注意が必要です。 問題解決の手段は下記の書籍を参考にしました。 問題解決(英治出版) ポストモーテムが作成できたら、可能な限り広い範囲に共有したいため、各開発チームのメンバー全員が集まっているデイリー スクラム の中で内容の説明を行います。 導入してよかったこと ポストモーテムを導入した目的である、同じ原因によるインシデントが他チームで発生するということは今のところ発生していません。また、しっかりと時間をかけて振り返りを行うことで、効果的な再発防止策を作成することができていると感じています。 今後の課題 実際にポストモーテムを作成してみて難しいなと思ったことなのですが、インシデントが発生した原因を突き止めるために、結局は特定のメンバーに当時の様子を細かく ヒアリ ングする必要があります。 ヒアリ ングするメンバーに 心理的 負担をかけてしまうと、本音を包み隠さず話すことができなくなってしまいます。 いかにメンバーに 心理的 負担をかけずに振り返りを実施できるかは、 ファシリテーター である私にかかっているため、改善していきたいと思っています。 まとめ まだ導入して3ヵ月しか経っていないため、今後もポストモーテムを実施する上で課題が出てくるかと思いますが、プロダクトを改善するためにどうすればよいかを軸に、改善を進めていきたいと思います。 最後までお読みいただき、ありがとうございました。 執筆: @takasaki.keisuke 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
こんにちは。 電通国際情報サービス (ISID) グループ経営ソリューション事業部の高崎です。 私が担当しているプロダクトの開発・運用中に発生した各種インシデントについて、解決後に再発防止を目的とした振り返りを実施しています。振り返りの方法として、ポストモーテムを導入してみました。 導入して3ヵ月が経過し、導入してよかったと思うことや今後の課題などが見えてきたので、紹介したいと思います。 後述するポストモーテムの内容は下記の書籍を参考にしています。 SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム (O'Reilly Japan) ポストモーテムとは インシデントが発生したことによる影響、解決のために行ったアクション、発生した原因、再発防止策などを記録したドキュメントを指します。 ポストモーテムを作成する上で個人を非難してはいけません。ポストモーテムの目的は、誰がインシデントを引き起こしたのかを明らかにすることではなく、なぜインシデントが発生してしまったのかを組織としてはっきりとさせることです。 焦点は人ではなくプロセスと技術にあてられなければなりません。 また、完成したポストモーテムは記載されている教訓が役立つよう、可能な限り広い範囲に共有することが重要です。 ポストモーテムを導入したきっかけ 開発プロジェクトの体制は以下のようになっています。 PM配下に業務領域ごとの開発チーム、その開発チームを横断的に見ているTech Leadがいます。 ※私のポジションはTech Leadです これまでインシデントが発生した場合、原因となった機能を担当している各開発チームごとに振り返りを実施し、再発防止策を作成していました。そうすると同じチーム内では再発しないのですが、振り返りの内容や再発防止策が他チームに浸透しておらず、同様の原因によるインシデントが他チームで発生するという課題がありました。 上記を解決するための方法を検討していた中で、ポストモーテムを導入してみようと思ったことがきっかけです。 どのようにしてポストモーテムを作成しているか 以下のフォーマットに沿って、関係者が各項目について対面で会話しながら作成しています。 ファシリテーター はTech Leadが担当しています。 # インシデント名 ## インシデント発生日 ## 作成日 ## 作者 ## ステータス → インシデントの現在のステータス ## サマリ → インシデントの概要 ## インパクト → インシデントによってどんな影響があったか ## 検出 → インシデントを検出した方法 ## 対応 → インシデントを収束させるために実施したこと ## タイムライン → インシデント発生から復旧までのタイムラインを書く ## 教訓 ### うまくいったこと ### うまくいかなかったこと ## 根本原因 → インシデントが発生した根本原因 ## 発生要因 → 根本原因が発生した要因 ## 再発防止策 特に重要な根本原因・発生要因・再発防止策については、 マインドマップ を使って深掘りを行っています。 まず根本原因(Where)が何かを突き止めます。次に根本原因となった事象がなぜ発生したのか(Why)を突き止め、最後に再発させないために何をするべきか(How)を決定します。 上記手順を踏まないと、根本原因や発生要因を明らかにしないまま、再発防止策ありきで話が進んでしまい、効果的な対策を打てない可能性があるため、注意が必要です。 問題解決の手段は下記の書籍を参考にしました。 問題解決(英治出版) ポストモーテムが作成できたら、可能な限り広い範囲に共有したいため、各開発チームのメンバー全員が集まっているデイリー スクラム の中で内容の説明を行います。 導入してよかったこと ポストモーテムを導入した目的である、同じ原因によるインシデントが他チームで発生するということは今のところ発生していません。また、しっかりと時間をかけて振り返りを行うことで、効果的な再発防止策を作成することができていると感じています。 今後の課題 実際にポストモーテムを作成してみて難しいなと思ったことなのですが、インシデントが発生した原因を突き止めるために、結局は特定のメンバーに当時の様子を細かく ヒアリ ングする必要があります。 ヒアリ ングするメンバーに 心理的 負担をかけてしまうと、本音を包み隠さず話すことができなくなってしまいます。 いかにメンバーに 心理的 負担をかけずに振り返りを実施できるかは、 ファシリテーター である私にかかっているため、改善していきたいと思っています。 まとめ まだ導入して3ヵ月しか経っていないため、今後もポストモーテムを実施する上で課題が出てくるかと思いますが、プロダクトを改善するためにどうすればよいかを軸に、改善を進めていきたいと思います。 最後までお読みいただき、ありがとうございました。 執筆: @takasaki.keisuke 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
X(クロス) イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの耿です。 以前の記事 では、 AWS Security Hubを検証した際に気付いたことを山口さんよりご紹介しました。今回はその続編として、Security Hubの実用に向けた取り組みをお話しします。 社内プロジェクトへのSecurity Hub導入 検出結果の集約 検出結果を通知する仕組みの構築 構築上のTips 一度に取得できる検出結果は100件まで 一度にフィルタリングできるアカウントIDは20件まで 今後に向けて 社内プロジェクトへのSecurity Hub導入 普段ならつい見過ごしてしまいがちな、不十分なセキュリティ設定をきっちり警告してくれるため、ISIDでは AWS を使用している全てのプロジェクトにSecurity Hubを導入することを目指しています。 Security Hubは導入するだけなら非常に簡単です。しかし本当に重要なのはその検出結果を確認し、確実に改善に繋げることです。そのためには少なくとも以下のことが必要になります。 定期的にSecurity Hubの検出結果を確認する運用手順や仕組み 検出結果の内容の理解 修正すべきポイントと、修正することによる影響の理解 セキュリティリスクと修正コストを総合的に判断し、対応方針を決定すること ISIDには数多くのプロジェクトがあり、担当メンバーも異なるため、1~4をプロジェクト内で個別に対応するのは望ましい姿とはいえません。そこで組織横断的な支援を行う体制により、1~4の実施を各プロジェクトに対してサポートしています。 定期的にSecurity Hubの検出結果を確認する運用手順や仕組み → 各プロジェクトの検出結果を集約し、定期的に通知する仕組みの導入(のちに詳述) 検出結果の内容の理解 → Security Hubのセキュリティ基準 をさらに詳細化したノウハウ集の作成と展開 修正すべきポイントと、修正することによる影響の理解 → 2.と同じ セキュリティリスクと修正コストを総合的に判断し、対応方針を決定すること → 対応方針の相談窓口の設置 2.と3.については検証用の AWS アカウントを利用して、各検出項目の発火の条件と改善方法を調査してきました。Security Hubのセキュリティ基準の項目は 不定 期に追加されますので、今後も継続的に調査を行っていくことになります。 4.については Microsoft Teamsに専用のチームを作成し、プロジェクトからの相談を随時受け付ける体制にしています。検出結果に対応するにあたって、各プロジェクトに共通する課題なども見えてくるのではないかと期待しています。 ここからは 1. の「検出結果を集約し、通知する仕組み」について、詳細をお話しします。 検出結果の集約 ※注:以下の記述は AWS Organizationsと統合されていない場合です。 Security Hubには 複数のメンバーアカウントの検出結果を管理者アカウントに集約する機能 がありますので、これを利用します。 いわゆる管理者アカウントから各プロジェクトのメンバーアカウントに招待を送り、メンバーアカウントから承認することで、Security Hubの検出項目を管理者アカウントからも確認できるようになります。この際、メンバーアカウントにてSecurity HubとConfigの有効化が必要になります。 注意が必要なのは、Security Hubはリージョナルサービスであるため、メンバーアカウントの複数リージョンから結果を集約したい場合は リージョンごとに招待・承認 しなければなりません。 複数のメンバーアカウントを取り扱うため、 管理者アカウントの方は当然、全リージョンでSecurity Hubを有効 にしておきます。 管理者アカウントに集約された結果を、リージョンを切り替えながら確認するのは手間がかかるので、 結果をリージョン間で集約する機能 を利用します。 これにより、 複数のメンバーアカウントの複数リージョンの検出結果を、1つの管理者アカウントの1リージョンから取得できる ようになります。 検出結果を通知する仕組みの構築 1箇所に集約された検出結果を、定期的に取得してプロジェクトに通知する仕組みを構築しました。 AWS SDK for JavaScript を利用し、ECSタスクからSecurity Hub検出結果の取得、レポートの生成と保存、配信までを行います。 ①ECSタスクを定期実行します ②プロジェクトと AWS アカウントID、および結果配信先を関連付ける情報を取得します。今回はS3 バケット に CSV ファイルとして配置することにしました ③プロジェクトごとに、Security Hubの検出結果を取得します ④⑤プロジェクトごとに検出結果を見やすい形でまとめた Excel レポートを作成し、S3 バケット に保存します ⑥レポートにプロジェクトの担当者がアクセスできるように、署名付きURLを生成します ⑦レポートへの署名付きURLをプロジェクト担当者に通知します。今回はメールで配信することにしました ⑧将来的にプロジェクトの対応状況を分析できるように、検出履歴をDynamoDBに保存しておきます ⑨プロジェクト担当者は署名付きURLからレポートをダウンロードします。万が一署名付きURLが漏れても社外の第 三者 がレポートを取得できないように、 バケット ポリシーを設定しsource IPをISID社内からのアクセスに限定しておきます この仕組みにより、以下のようなメリットが発生します プロジェクトが個別にSecurity Hubを確認する負荷を軽減できる 複数アカウント を利用しているプロジェクトの場合、1つのレポートに検出結果がまとまる Excel のレポートを生成するため、検出結果をフィルターしやすい 組織横断的に検出結果への対応状況を集計、分析できる(今後の期待) 構築上のTips AWS SDK for JavaScript から Security Hub の検出結果を取得する際のTipsを2つ記します。 一度に取得できる検出結果は100件まで @aws-sdk/client-securityhub モジュールの GetFindingsCommand から受け取る結果の最大数を MaxResults として指定できるのですが、最大100件までという制約があります。 const command = new GetFindingsCommand ( { MaxResults: 100 , // 最大100まで NextToken: nextToken , Filters: filters , } ); 100件を超える検出結果を取得したい場合は、結果に NextToken というプロパティに値が入った状態で返ってきます。これを GetFindingsCommand の入力に追加してもう一度送ることで、続きの検出結果を取得できます。 const data = await client.send ( command ); if ( data.NextToken === undefined ) { // 結果が100件以内 } else { // 結果が100件を超えている } すなわち、 再帰 的に GetFindingsCommand を送信することで、全ての検出結果を取得できます。 import { SecurityHubClient , GetFindingsCommand , AwsSecurityFinding , AwsSecurityFindingFilters , StringFilter , } from "@aws-sdk/client-securityhub" ; const client = new SecurityHubClient ( { region: "ap-northeast-1" } ); export async function getNextFindings ( awsAccountIds: string [] , nextToken?: string ) : Promise < AwsSecurityFinding [] > { const accountsFilter: StringFilter [] = awsAccountIds.map (( id ) => { return { Value: id , Comparison: "EQUALS" } ; } ); // AWSアカウントID、レコードの状態、ワークフローステータスでフィルタリング const filters: AwsSecurityFindingFilters = { AwsAccountId: accountsFilter , RecordState: [{ Value: "ACTIVE" , Comparison: "EQUALS" }] , WorkflowStatus: [ { Value: "NEW" , Comparison: "EQUALS" } , { Value: "NOTIFIED" , Comparison: "EQUALS" } , ] , } ; const command = new GetFindingsCommand ( { MaxResults: 100 , NextToken: nextToken , Filters: filters , } ); // コマンド送信 const data = await client.send ( command ); const findings: AwsSecurityFinding [] = data.Findings ?? [] ; if ( data.NextToken === undefined ) { return findings ; } else { // 100件を超える場合は再帰的に呼び出す return findings.concat (await getNextFindings ( awsAccountIds , data.NextToken )); } } 一度にフィルタリングできるアカウントIDは20件まで プロジェクトごとに検出結果をSecurity Hubから取得したいので、 AWS アカウントIDで検出結果をフィルタリングしてクエリしていますが、アカウントIDの数が多いと以下のようなエラーになりました。 UnhandledPromiseRejectionWarning: InvalidInputException: Invalid parameter 'Filters'. data.AwsAccountId should NOT have more than 20 items アカウントIDは一度に20件までしかフィルタリングに利用できないとのことなので、20件を超えるアカウントIDの検出結果を取得したい場合は、20件以下に分割してから複数回クエリする必要があります。 今後に向けて 今回お話しした仕組みの運用はまだ始まったばかりで、今後新たな課題が発生するかもしれません。ISIDでは引き続き、組織横断的に AWS 環境をセキュアにするための取り組みを実施していきます。 執筆: @kou.kinyo2 、レビュー: @higa ( Shodo で執筆されました )
X(クロス) イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの耿です。 以前の記事 では、 AWS Security Hubを検証した際に気付いたことを山口さんよりご紹介しました。今回はその続編として、Security Hubの実用に向けた取り組みをお話しします。 社内プロジェクトへのSecurity Hub導入 検出結果の集約 検出結果を通知する仕組みの構築 構築上のTips 一度に取得できる検出結果は100件まで 一度にフィルタリングできるアカウントIDは20件まで 今後に向けて 社内プロジェクトへのSecurity Hub導入 普段ならつい見過ごしてしまいがちな、不十分なセキュリティ設定をきっちり警告してくれるため、ISIDでは AWS を使用している全てのプロジェクトにSecurity Hubを導入することを目指しています。 Security Hubは導入するだけなら非常に簡単です。しかし本当に重要なのはその検出結果を確認し、確実に改善に繋げることです。そのためには少なくとも以下のことが必要になります。 定期的にSecurity Hubの検出結果を確認する運用手順や仕組み 検出結果の内容の理解 修正すべきポイントと、修正することによる影響の理解 セキュリティリスクと修正コストを総合的に判断し、対応方針を決定すること ISIDには数多くのプロジェクトがあり、担当メンバーも異なるため、1~4をプロジェクト内で個別に対応するのは望ましい姿とはいえません。そこで組織横断的な支援を行う体制により、1~4の実施を各プロジェクトに対してサポートしています。 定期的にSecurity Hubの検出結果を確認する運用手順や仕組み → 各プロジェクトの検出結果を集約し、定期的に通知する仕組みの導入(のちに詳述) 検出結果の内容の理解 → Security Hubのセキュリティ基準 をさらに詳細化したノウハウ集の作成と展開 修正すべきポイントと、修正することによる影響の理解 → 2.と同じ セキュリティリスクと修正コストを総合的に判断し、対応方針を決定すること → 対応方針の相談窓口の設置 2.と3.については検証用の AWS アカウントを利用して、各検出項目の発火の条件と改善方法を調査してきました。Security Hubのセキュリティ基準の項目は 不定 期に追加されますので、今後も継続的に調査を行っていくことになります。 4.については Microsoft Teamsに専用のチームを作成し、プロジェクトからの相談を随時受け付ける体制にしています。検出結果に対応するにあたって、各プロジェクトに共通する課題なども見えてくるのではないかと期待しています。 ここからは 1. の「検出結果を集約し、通知する仕組み」について、詳細をお話しします。 検出結果の集約 ※注:以下の記述は AWS Organizationsと統合されていない場合です。 Security Hubには 複数のメンバーアカウントの検出結果を管理者アカウントに集約する機能 がありますので、これを利用します。 いわゆる管理者アカウントから各プロジェクトのメンバーアカウントに招待を送り、メンバーアカウントから承認することで、Security Hubの検出項目を管理者アカウントからも確認できるようになります。この際、メンバーアカウントにてSecurity HubとConfigの有効化が必要になります。 注意が必要なのは、Security Hubはリージョナルサービスであるため、メンバーアカウントの複数リージョンから結果を集約したい場合は リージョンごとに招待・承認 しなければなりません。 複数のメンバーアカウントを取り扱うため、 管理者アカウントの方は当然、全リージョンでSecurity Hubを有効 にしておきます。 管理者アカウントに集約された結果を、リージョンを切り替えながら確認するのは手間がかかるので、 結果をリージョン間で集約する機能 を利用します。 これにより、 複数のメンバーアカウントの複数リージョンの検出結果を、1つの管理者アカウントの1リージョンから取得できる ようになります。 検出結果を通知する仕組みの構築 1箇所に集約された検出結果を、定期的に取得してプロジェクトに通知する仕組みを構築しました。 AWS SDK for JavaScript を利用し、ECSタスクからSecurity Hub検出結果の取得、レポートの生成と保存、配信までを行います。 ①ECSタスクを定期実行します ②プロジェクトと AWS アカウントID、および結果配信先を関連付ける情報を取得します。今回はS3 バケット に CSV ファイルとして配置することにしました ③プロジェクトごとに、Security Hubの検出結果を取得します ④⑤プロジェクトごとに検出結果を見やすい形でまとめた Excel レポートを作成し、S3 バケット に保存します ⑥レポートにプロジェクトの担当者がアクセスできるように、署名付きURLを生成します ⑦レポートへの署名付きURLをプロジェクト担当者に通知します。今回はメールで配信することにしました ⑧将来的にプロジェクトの対応状況を分析できるように、検出履歴をDynamoDBに保存しておきます ⑨プロジェクト担当者は署名付きURLからレポートをダウンロードします。万が一署名付きURLが漏れても社外の第 三者 がレポートを取得できないように、 バケット ポリシーを設定しsource IPをISID社内からのアクセスに限定しておきます この仕組みにより、以下のようなメリットが発生します プロジェクトが個別にSecurity Hubを確認する負荷を軽減できる 複数アカウント を利用しているプロジェクトの場合、1つのレポートに検出結果がまとまる Excel のレポートを生成するため、検出結果をフィルターしやすい 組織横断的に検出結果への対応状況を集計、分析できる(今後の期待) 構築上のTips AWS SDK for JavaScript から Security Hub の検出結果を取得する際のTipsを2つ記します。 一度に取得できる検出結果は100件まで @aws-sdk/client-securityhub モジュールの GetFindingsCommand から受け取る結果の最大数を MaxResults として指定できるのですが、最大100件までという制約があります。 const command = new GetFindingsCommand ( { MaxResults: 100 , // 最大100まで NextToken: nextToken , Filters: filters , } ); 100件を超える検出結果を取得したい場合は、結果に NextToken というプロパティに値が入った状態で返ってきます。これを GetFindingsCommand の入力に追加してもう一度送ることで、続きの検出結果を取得できます。 const data = await client.send ( command ); if ( data.NextToken === undefined ) { // 結果が100件以内 } else { // 結果が100件を超えている } すなわち、 再帰 的に GetFindingsCommand を送信することで、全ての検出結果を取得できます。 import { SecurityHubClient , GetFindingsCommand , AwsSecurityFinding , AwsSecurityFindingFilters , StringFilter , } from "@aws-sdk/client-securityhub" ; const client = new SecurityHubClient ( { region: "ap-northeast-1" } ); export async function getNextFindings ( awsAccountIds: string [] , nextToken?: string ) : Promise < AwsSecurityFinding [] > { const accountsFilter: StringFilter [] = awsAccountIds.map (( id ) => { return { Value: id , Comparison: "EQUALS" } ; } ); // AWSアカウントID、レコードの状態、ワークフローステータスでフィルタリング const filters: AwsSecurityFindingFilters = { AwsAccountId: accountsFilter , RecordState: [{ Value: "ACTIVE" , Comparison: "EQUALS" }] , WorkflowStatus: [ { Value: "NEW" , Comparison: "EQUALS" } , { Value: "NOTIFIED" , Comparison: "EQUALS" } , ] , } ; const command = new GetFindingsCommand ( { MaxResults: 100 , NextToken: nextToken , Filters: filters , } ); // コマンド送信 const data = await client.send ( command ); const findings: AwsSecurityFinding [] = data.Findings ?? [] ; if ( data.NextToken === undefined ) { return findings ; } else { // 100件を超える場合は再帰的に呼び出す return findings.concat (await getNextFindings ( awsAccountIds , data.NextToken )); } } 一度にフィルタリングできるアカウントIDは20件まで プロジェクトごとに検出結果をSecurity Hubから取得したいので、 AWS アカウントIDで検出結果をフィルタリングしてクエリしていますが、アカウントIDの数が多いと以下のようなエラーになりました。 UnhandledPromiseRejectionWarning: InvalidInputException: Invalid parameter 'Filters'. data.AwsAccountId should NOT have more than 20 items アカウントIDは一度に20件までしかフィルタリングに利用できないとのことなので、20件を超えるアカウントIDの検出結果を取得したい場合は、20件以下に分割してから複数回クエリする必要があります。 今後に向けて 今回お話しした仕組みの運用はまだ始まったばかりで、今後新たな課題が発生するかもしれません。ISIDでは引き続き、組織横断的に AWS 環境をセキュアにするための取り組みを実施していきます。 執筆: @kou.kinyo2 、レビュー: @higa ( Shodo で執筆されました )
電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの 比嘉康雄 です。 それでは、 ブロックチェーン 週報4/22いってみようか。 NFTラッシュ その他のニュース NFTラッシュ NFTプロジェクトのニュースがラッシュですね。BAYC(Bored Ape Yacht Club)ベースのアニメが映画で全3部作とか、嫌な予感しかしませんね。失敗してもNFTのせいにされませんように。 米コインベース、人気NFT「BAYC」のアニメ映画製作へ 米 メジャーリーグ ( MLB )のNFTが販売されます。 これは、 NBA Top Shotの柳の下のどじょうを狙ったものですが、どうなるか要注目。 NBA Top Shot自体、2021年の8月以降、下降線です。 米メジャーリーグ今季NFT、キャンディデジタルで発売 WWE (World Wrestling Entertainment, Inc.)も同じスキーム。 WWEがNFT事業展開へ 日本でもIPのNFT化が進んでますね。ただ、IPがNFTになって本当に意味があるのかはみんな考える必要があると思います。単に売れればOKは良くない。 「LINE NFT」 吉本、パトレイバーなど限定NFT動画、約4万点を順次販売 パティ・ボイドの写真のNFTは、買う人いそうな気はする。雑談ですが、 テイラー・スウィフト はパティ・ボイドのファンらしいです。顔がちょっと似てるよね。 ビートルズの「女神」パティ・ボイド、NFTで革命を再び 時代のミューズとともに:テイラー・スウィフトが憧れのパティ・ボイドと対談 きゃりー君もか。 きゃりーぱみゅぱみゅ、米国の音楽祭でメタバースNFTとコラボ 浜崎あゆみ とピコ太郎もですか。だんだん疲れてきた。 浜崎あゆみ、ピコ太郎がNFT・メタバースに──エイベックスがThe Sandboxに「エイベックスランド」構想 その他のニュース 観光特化デジタル通貨「ルーラコイン」、3エリアで実証成功--平均消費単価1万4900円 「アバランチ」開発のアバラボ、3.5億ドルの調達に動く-関係者 歩いてトークン稼ぐSTEPN、プレーに必要なNFTスニーカーが高騰──1足最低14万円 高すぎNFTは、NFTに価値を認めているんじゃなくて、転売目的な気がして好きになれない。本当に価値を認めて買っている人もいると思いますが。 執筆: @higa ( Shodo で執筆されました )
電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの 比嘉康雄 です。 それでは、 ブロックチェーン 週報4/22いってみようか。 NFTラッシュ その他のニュース NFTラッシュ NFTプロジェクトのニュースがラッシュですね。BAYC(Bored Ape Yacht Club)ベースのアニメが映画で全3部作とか、嫌な予感しかしませんね。失敗してもNFTのせいにされませんように。 米コインベース、人気NFT「BAYC」のアニメ映画製作へ 米 メジャーリーグ ( MLB )のNFTが販売されます。 これは、 NBA Top Shotの柳の下のどじょうを狙ったものですが、どうなるか要注目。 NBA Top Shot自体、2021年の8月以降、下降線です。 米メジャーリーグ今季NFT、キャンディデジタルで発売 WWE (World Wrestling Entertainment, Inc.)も同じスキーム。 WWEがNFT事業展開へ 日本でもIPのNFT化が進んでますね。ただ、IPがNFTになって本当に意味があるのかはみんな考える必要があると思います。単に売れればOKは良くない。 「LINE NFT」 吉本、パトレイバーなど限定NFT動画、約4万点を順次販売 パティ・ボイドの写真のNFTは、買う人いそうな気はする。雑談ですが、 テイラー・スウィフト はパティ・ボイドのファンらしいです。顔がちょっと似てるよね。 ビートルズの「女神」パティ・ボイド、NFTで革命を再び 時代のミューズとともに:テイラー・スウィフトが憧れのパティ・ボイドと対談 きゃりー君もか。 きゃりーぱみゅぱみゅ、米国の音楽祭でメタバースNFTとコラボ 浜崎あゆみ とピコ太郎もですか。だんだん疲れてきた。 浜崎あゆみ、ピコ太郎がNFT・メタバースに──エイベックスがThe Sandboxに「エイベックスランド」構想 その他のニュース 観光特化デジタル通貨「ルーラコイン」、3エリアで実証成功--平均消費単価1万4900円 「アバランチ」開発のアバラボ、3.5億ドルの調達に動く-関係者 歩いてトークン稼ぐSTEPN、プレーに必要なNFTスニーカーが高騰──1足最低14万円 高すぎNFTは、NFTに価値を認めているんじゃなくて、転売目的な気がして好きになれない。本当に価値を認めて買っている人もいると思いますが。 執筆: @higa ( Shodo で執筆されました )
Salesforce で承認ワークフローシステムを構築しているまたはしようと思っている皆様、ワークフロー要件が複雑なために Salesforce の承認プロセス等の標準機能では構築できず、専用のワークフローツールを使用していませんか? Spring22のアップデートで、 Salesforce の機能を利用して高度な承認ワークフローを構築できるようになりました。 今回は、その新機能である『Flow Orchestrator』と既存機能を組み合わせることでどんなことができるのかを紹介します。 1. なぜ、今まで Salesforce で複雑な承認ワークフローを作成できなかったのか? 1-1. ワークフローシステムツールでよくある機能 承認ワークフローを構築する際、以下のような要件を思い浮かべる方が多いと思います。 ・申請内容によって承認の流れを分岐する機能 ・承認者の複数設定や代理承認者を設定する機能 ・承認状況をリアルタイムに確認でき、承認時のコメントを受信する機能 しかし、これらの機能を組み合わせ、複雑な業務要件を満たす承認ワークフローを Salesforce で実現することは困難でした。 1-2. なぜ、今までは Salesforce で複雑な承認ワークフローを実現できなかったのか?  日本は特に、承認ワークフローが複雑だと言われています。例えば、最終承認者に到達するまでの段階の多さが特徴としてあげられます。また、申請金額の大小により、承認の段階の数が変わることもあるでしょう。 もともと、 Salesforce には承認プロセスという簡単なワークフローを作成できる機能が用意されています。しかし、承認プロセスでは、承認時はコメント以外入力できなかったり、複雑な承認者の設定ができなかったりと制限がありました。そのため、複雑なワークフローの構築は専用のワークフローツールを使用するしかなかったのです。 2. 『Flow Orchestrator』の概要 『Flow Orchestrator』とは、Spring22で正式リリースされた複雑なワークフローを作成できる Salesforce のローコード開発ツールです。 この新機能と Salesforce の既存機能を組み合わせることで、例えば、以下を実現できます。 ・金額等の条件によりフローを分岐できる機能 ・ Salesforce 上からリアルタイムで承認状況を確認できる機能 ・承認時の入力項目を自由にカスタマイズできる機能 ・ユーザ/グループ単位の割り当て・手動割り当て・代理承認者割り当てができる機能 ・申請者/承認者に通知する機能 ・複数のユーザが並行して承認する機能 今回、これらの機能を取り込んだ承認ワークフローシステムを実装してみました。 3. 簡単な承認ワークフローシステムを実装してみた 3-1. 承認フロー図 今回は下図のようなフローを想定し作成してみました。 この後のGIFでは、フロー図の赤線の流れをお見せします。 3-2. 実際の承認の流れ ※今回はDeveloper環境のため、ユーザを使い回しています。ユーザの氏名に役職を記載しています。 ①申請者は交通費(250,000円)を申請する ②グループ長は長期休暇中のため、グループ長代理が承認する 次承認者(部長)を手動で選択する ③部長が承認する 次承認者(事業部長)は手動で選択する ※ 事業部長・社長に並行して承認依頼されていることが確認できる ④事業部長が承認する ⑤社長が承認する ⑥事業部長・社長が承認を終えたので、 経理 担当者が決済をする 以上の通り、実装しました。 4. まとめ Salesforce の機能でも日本の複雑な承認ワークフローシステムを実現できることを理解していただけたでしょうか? 承認ワークフローシステムを Salesforce 上で構築するメリットとしては、 Salesforce 上で全ての情報を参照できることだと考えております。メール通知はもちろん、Chatter通知も可能です。また、レコードの詳細画面にパス(ステータス)を設定することで、承認状況をリアルタイムに表示できます。 今回の記事には書かれていない皆様の会社特有のワークフロー機能も実現できるかもしれません。 ぜひ、 Salesforce でワークフローシステムを構築する際は、『Flow Orchestrator』の利用を検討してみてください! 5. 構築の際に参考になる Salesforce 公式サイト * Salesforce Spring'22 リリースノート | オーケストレータ (正式リリース) * Trailblazer Community のグループ | Orchestrator * TrailheaDX | Flow and Orchestrator (1) * TrailheaDX | Flow and Orchestrator (2) 執筆: @kitakado.maho 、レビュー: @kumakura.koki.isid ( Shodo で執筆されました )
Salesforce で承認ワークフローシステムを構築しているまたはしようと思っている皆様、ワークフロー要件が複雑なために Salesforce の承認プロセス等の標準機能では構築できず、専用のワークフローツールを使用していませんか? Spring22のアップデートで、 Salesforce の機能を利用して高度な承認ワークフローを構築できるようになりました。 今回は、その新機能である『Flow Orchestrator』と既存機能を組み合わせることでどんなことができるのかを紹介します。 1. なぜ、今まで Salesforce で複雑な承認ワークフローを作成できなかったのか? 1-1. ワークフローシステムツールでよくある機能 承認ワークフローを構築する際、以下のような要件を思い浮かべる方が多いと思います。 ・申請内容によって承認の流れを分岐する機能 ・承認者の複数設定や代理承認者を設定する機能 ・承認状況をリアルタイムに確認でき、承認時のコメントを受信する機能 しかし、これらの機能を組み合わせ、複雑な業務要件を満たす承認ワークフローを Salesforce で実現することは困難でした。 1-2. なぜ、今までは Salesforce で複雑な承認ワークフローを実現できなかったのか?  日本は特に、承認ワークフローが複雑だと言われています。例えば、最終承認者に到達するまでの段階の多さが特徴としてあげられます。また、申請金額の大小により、承認の段階の数が変わることもあるでしょう。 もともと、 Salesforce には承認プロセスという簡単なワークフローを作成できる機能が用意されています。しかし、承認プロセスでは、承認時はコメント以外入力できなかったり、複雑な承認者の設定ができなかったりと制限がありました。そのため、複雑なワークフローの構築は専用のワークフローツールを使用するしかなかったのです。 2. 『Flow Orchestrator』の概要 『Flow Orchestrator』とは、Spring22で正式リリースされた複雑なワークフローを作成できる Salesforce のローコード開発ツールです。 この新機能と Salesforce の既存機能を組み合わせることで、例えば、以下を実現できます。 ・金額等の条件によりフローを分岐できる機能 ・ Salesforce 上からリアルタイムで承認状況を確認できる機能 ・承認時の入力項目を自由にカスタマイズできる機能 ・ユーザ/グループ単位の割り当て・手動割り当て・代理承認者割り当てができる機能 ・申請者/承認者に通知する機能 ・複数のユーザが並行して承認する機能 今回、これらの機能を取り込んだ承認ワークフローシステムを実装してみました。 3. 簡単な承認ワークフローシステムを実装してみた 3-1. 承認フロー図 今回は下図のようなフローを想定し作成してみました。 この後のGIFでは、フロー図の赤線の流れをお見せします。 3-2. 実際の承認の流れ ※今回はDeveloper環境のため、ユーザを使い回しています。ユーザの氏名に役職を記載しています。 ①申請者は交通費(250,000円)を申請する ②グループ長は長期休暇中のため、グループ長代理が承認する 次承認者(部長)を手動で選択する ③部長が承認する 次承認者(事業部長)は手動で選択する ※ 事業部長・社長に並行して承認依頼されていることが確認できる ④事業部長が承認する ⑤社長が承認する ⑥事業部長・社長が承認を終えたので、 経理 担当者が決済をする 以上の通り、実装しました。 4. まとめ Salesforce の機能でも日本の複雑な承認ワークフローシステムを実現できることを理解していただけたでしょうか? 承認ワークフローシステムを Salesforce 上で構築するメリットとしては、 Salesforce 上で全ての情報を参照できることだと考えております。メール通知はもちろん、Chatter通知も可能です。また、レコードの詳細画面にパス(ステータス)を設定することで、承認状況をリアルタイムに表示できます。 今回の記事には書かれていない皆様の会社特有のワークフロー機能も実現できるかもしれません。 ぜひ、 Salesforce でワークフローシステムを構築する際は、『Flow Orchestrator』の利用を検討してみてください! 5. 構築の際に参考になる Salesforce 公式サイト * Salesforce Spring'22 リリースノート | オーケストレータ (正式リリース) * Trailblazer Community のグループ | Orchestrator * TrailheaDX | Flow and Orchestrator (1) * TrailheaDX | Flow and Orchestrator (2) 執筆: @kitakado.maho 、レビュー: @kumakura.koki.isid ( Shodo で執筆されました )
こんにちは。X(クロス) イノベーション 本部 クラウド イノベーション センターの柴田です。本記事ではTeleportを使って Kubernetes クラスタ へアクセスする際の再認証方式を設定する方法を紹介します。 Teleportとは 前提条件 Teleportを使ってGitHub SSOでKubernetesクラスタへアクセスする 再認証時の認証方式を指定する 再認証時はデフォルトの認証方式が使用される 原因 再認証時の認証方式を指定する おわりに 参考 Teleportとは Teleport はGravitational社が開発するソフトウェアです。 OSS 版、Enterprise版、Cloud版の3種類が存在します。 Teleportはざっくりいうと高機能かつ現代的な踏み台サーバです。 SSH サーバ、データベース、 Kubernetes クラスタ などへアクセスする際の踏み台として機能します。また シングルサインオン やセッションレコードの記録などの機能も提供します。 例えば以下の表は Amazon EKS クラスタ へアクセスする際にTeleportを使う場合と使わない場合を比較したものです。 AWS にも AWS Systems Manager Session Manager などの機能があります。一方で Amazon EKS上のコンテナへ kubectl exec でログインした際のセッションレコードを記録したい場合などはTeleportが必要になります。 Teleportを使わずに Amazon EKS クラスタ へアクセスする Teleportを使って Amazon EKS クラスタ へアクセスする 認証方法 IAM user、IAM role ローカルユーザー、 GitHub OAuth(Enterprise版は Google OAuth、OIDC、 SAML にも対応) ノードへのログイン AWS Systems Manager Session Managerでログインできる。セッションレコードはCloudWatch Logs、S3へ記録される。 できる。セッションレコードはS3へ記録される。 コンテナへのログイン kubectl exec でログインできる。セッションレコードは記録されない。 kubectl exec でログインできる。セッションレコードはS3へ記録される。 kube-apiserveへの アクセスログ の記録 コントロールプレーンのログ記録 を有効化することでCloudWatch Logsへ記録される DynamoDBへ記録される セッションレコードの形式 AWS Systems Manager Session Managerのセッションレコードはテキスト形式で記録される。 エス ケープシーケンスもテキストとして記録されており、若干見づらい。テキスト検索はできるが、動画として再生はできない。 独自形式で記録される。TeleportのWeb UIや tsh play コマンドで動画として再生できる。テキスト検索はできない。 運用の手間 踏み台サーバの運用は不要 1 Teleport クラスタ の運用が必要 このように便利なTeleportですが、実際に使ってみたところ、 Kubernetes クラスタ へアクセスする際の再認証方式の設定に少しハマりどころがありました。本記事ではそれを紹介します。 前提条件 本記事では以下の環境を使用します。 Amazon EKS v1.21 Teleport v9.0.1 Teleport クラスタ は 公式ドキュメント に従って既にEKS クラスタ 上へ構築されているものとします。 以降では例として以下の値を使用します。実際には各自の環境に置き換えてください。 名前 サンプル値 Teleport クラスタ のURL teleport.example.com GitHub アカウント名 octocat Teleportを使って GitHub SSOで Kubernetes クラスタ へアクセスする Teleportを使って GitHub SSOで Kubernetes クラスタ へアクセスする際は、まず以下のコマンドを実行します。 tsh はTeleportの CLI ツールで Teleport Downloads からダウンロードできます。 # Teleportクラスタへログインする $ tsh login --proxy teleport.example.com --auth github --user octocat # 必要な設定をkubeconfigファイルへ書き込む $ tsh kube login teleport.example.com kubeconfigファイルへ新しくcontextが追加されるので、これを使ってTeleport経由で Kubernetes クラスタ へアクセスできます。 $ kubectl config current-context teleport.example.com-teleport.example.com $ kubectl get pods No resources found in default namespace. 再認証時の認証方式を指定する 再認証時はデフォルトの認証方式が使用される Teleport クラスタ の認証情報には有効期限があります。有効期限を過ぎてから Kubernetes クラスタ へアクセスしようとすると、再認証を要求されます。 しかし実際にやってみると、初回認証時の認証方式( GitHub SSO)ではなく、デフォルトの認証方式(Teleportに登録されたローカルユーザーのパスワード認証)が要求されます。 $ kubectl get pods Enter password for Teleport user octocat: これでは GitHub SSOによる再認証ができずに困ってしまいます。 原因 なぜそうなるのか調べてみましょう。kubeconfigファイル(デフォルトでは $HOME/.kube/config )の users を見てみます。 users : - name : teleport.example.com-teleport.example.com user : exec : apiVersion : client.authentication.k8s.io/v1beta1 args : - kube - credentials - --kube-cluster=teleport.example.com - --teleport-cluster=teleport.example.com - --proxy=teleport.example.com command : /usr/local/bin/tsh interactiveMode : IfAvailable provideClusterInfo : false kubectl は client-goクレデンシャルプラグイン の仕組みを使って tsh kube credentials コマンドからユーザーの認証情報を受け取ります。Teleport クラスタ の認証情報の有効期限が切れている場合、このコマンドはTeleport クラスタ への再ログインを試みます。デフォルトの認証方式が要求されたのは、このコマンドに auth などが指定されていないためです。 再認証時の認証方式を指定する tsh kube credentials コマンドに適切な認証方式を指定することでこの問題を解決できます。今回は 環境変数 経由で認証方式を設定します。なお tsh コマンドが参照する 環境変数 の一覧は Teleport CLI Reference を参照してください。 以下のコマンドを実行します。 kubectl config set-credentials teleport.example.com-teleport.example.com --exec-env=TELEPORT_AUTH=github kubectl config set-credentials teleport.example.com-teleport.example.com --exec-env=TELEPORT_USER=octocat するとkubeconfigファイルが以下のとおり更新されます。 users : - name : teleport.example.com-teleport.example.com user : exec : apiVersion : client.authentication.k8s.io/v1beta1 args : - kube - credentials - --kube-cluster=teleport.example.com - --teleport-cluster=teleport.example.com - --proxy=teleport.example.com command : /usr/local/bin/tsh env : - name : TELEPORT_AUTH value : github - name : TELEPORT_USER value : octocat interactiveMode : IfAvailable provideClusterInfo : false これにより、Teleport クラスタ の認証情報の有効期限が切れた後、 GitHub SSOによる再認証が要求されるようになりました。 おわりに 本記事ではTeleportを使って Kubernetes クラスタ へアクセスする際の再認証方式を設定する方法を紹介しました。この記事が皆様のお役に立てば幸いです。 参考 Introduction to Teleport | Teleport Docs TeleportでKubernetesクラスタへのユーザーアクセスを管理する - Cybozu Inside Out | サイボウズエンジニアのブログ 執筆: @shibata.takao 、レビュー: @higa ( Shodo で執筆されました ) コン トロール プレーンのエンドポイントのパブリックアクセスが有効になっているものとします。 ↩
こんにちは。X(クロス) イノベーション 本部 クラウド イノベーション センターの柴田です。本記事ではTeleportを使って Kubernetes クラスタ へアクセスする際の再認証方式を設定する方法を紹介します。 Teleportとは 前提条件 Teleportを使ってGitHub SSOでKubernetesクラスタへアクセスする 再認証時の認証方式を指定する 再認証時はデフォルトの認証方式が使用される 原因 再認証時の認証方式を指定する おわりに 参考 Teleportとは Teleport はGravitational社が開発するソフトウェアです。 OSS 版、Enterprise版、Cloud版の3種類が存在します。 Teleportはざっくりいうと高機能かつ現代的な踏み台サーバです。 SSH サーバ、データベース、 Kubernetes クラスタ などへアクセスする際の踏み台として機能します。また シングルサインオン やセッションレコードの記録などの機能も提供します。 例えば以下の表は Amazon EKS クラスタ へアクセスする際にTeleportを使う場合と使わない場合を比較したものです。 AWS にも AWS Systems Manager Session Manager などの機能があります。一方で Amazon EKS上のコンテナへ kubectl exec でログインした際のセッションレコードを記録したい場合などはTeleportが必要になります。 Teleportを使わずに Amazon EKS クラスタ へアクセスする Teleportを使って Amazon EKS クラスタ へアクセスする 認証方法 IAM user、IAM role ローカルユーザー、 GitHub OAuth(Enterprise版は Google OAuth、OIDC、 SAML にも対応) ノードへのログイン AWS Systems Manager Session Managerでログインできる。セッションレコードはCloudWatch Logs、S3へ記録される。 できる。セッションレコードはS3へ記録される。 コンテナへのログイン kubectl exec でログインできる。セッションレコードは記録されない。 kubectl exec でログインできる。セッションレコードはS3へ記録される。 kube-apiserveへの アクセスログ の記録 コントロールプレーンのログ記録 を有効化することでCloudWatch Logsへ記録される DynamoDBへ記録される セッションレコードの形式 AWS Systems Manager Session Managerのセッションレコードはテキスト形式で記録される。 エス ケープシーケンスもテキストとして記録されており、若干見づらい。テキスト検索はできるが、動画として再生はできない。 独自形式で記録される。TeleportのWeb UIや tsh play コマンドで動画として再生できる。テキスト検索はできない。 運用の手間 踏み台サーバの運用は不要 1 Teleport クラスタ の運用が必要 このように便利なTeleportですが、実際に使ってみたところ、 Kubernetes クラスタ へアクセスする際の再認証方式の設定に少しハマりどころがありました。本記事ではそれを紹介します。 前提条件 本記事では以下の環境を使用します。 Amazon EKS v1.21 Teleport v9.0.1 Teleport クラスタ は 公式ドキュメント に従って既にEKS クラスタ 上へ構築されているものとします。 以降では例として以下の値を使用します。実際には各自の環境に置き換えてください。 名前 サンプル値 Teleport クラスタ のURL teleport.example.com GitHub アカウント名 octocat Teleportを使って GitHub SSOで Kubernetes クラスタ へアクセスする Teleportを使って GitHub SSOで Kubernetes クラスタ へアクセスする際は、まず以下のコマンドを実行します。 tsh はTeleportの CLI ツールで Teleport Downloads からダウンロードできます。 # Teleportクラスタへログインする $ tsh login --proxy teleport.example.com --auth github --user octocat # 必要な設定をkubeconfigファイルへ書き込む $ tsh kube login teleport.example.com kubeconfigファイルへ新しくcontextが追加されるので、これを使ってTeleport経由で Kubernetes クラスタ へアクセスできます。 $ kubectl config current-context teleport.example.com-teleport.example.com $ kubectl get pods No resources found in default namespace. 再認証時の認証方式を指定する 再認証時はデフォルトの認証方式が使用される Teleport クラスタ の認証情報には有効期限があります。有効期限を過ぎてから Kubernetes クラスタ へアクセスしようとすると、再認証を要求されます。 しかし実際にやってみると、初回認証時の認証方式( GitHub SSO)ではなく、デフォルトの認証方式(Teleportに登録されたローカルユーザーのパスワード認証)が要求されます。 $ kubectl get pods Enter password for Teleport user octocat: これでは GitHub SSOによる再認証ができずに困ってしまいます。 原因 なぜそうなるのか調べてみましょう。kubeconfigファイル(デフォルトでは $HOME/.kube/config )の users を見てみます。 users : - name : teleport.example.com-teleport.example.com user : exec : apiVersion : client.authentication.k8s.io/v1beta1 args : - kube - credentials - --kube-cluster=teleport.example.com - --teleport-cluster=teleport.example.com - --proxy=teleport.example.com command : /usr/local/bin/tsh interactiveMode : IfAvailable provideClusterInfo : false kubectl は client-goクレデンシャルプラグイン の仕組みを使って tsh kube credentials コマンドからユーザーの認証情報を受け取ります。Teleport クラスタ の認証情報の有効期限が切れている場合、このコマンドはTeleport クラスタ への再ログインを試みます。デフォルトの認証方式が要求されたのは、このコマンドに auth などが指定されていないためです。 再認証時の認証方式を指定する tsh kube credentials コマンドに適切な認証方式を指定することでこの問題を解決できます。今回は 環境変数 経由で認証方式を設定します。なお tsh コマンドが参照する 環境変数 の一覧は Teleport CLI Reference を参照してください。 以下のコマンドを実行します。 kubectl config set-credentials teleport.example.com-teleport.example.com --exec-env=TELEPORT_AUTH=github kubectl config set-credentials teleport.example.com-teleport.example.com --exec-env=TELEPORT_USER=octocat するとkubeconfigファイルが以下のとおり更新されます。 users : - name : teleport.example.com-teleport.example.com user : exec : apiVersion : client.authentication.k8s.io/v1beta1 args : - kube - credentials - --kube-cluster=teleport.example.com - --teleport-cluster=teleport.example.com - --proxy=teleport.example.com command : /usr/local/bin/tsh env : - name : TELEPORT_AUTH value : github - name : TELEPORT_USER value : octocat interactiveMode : IfAvailable provideClusterInfo : false これにより、Teleport クラスタ の認証情報の有効期限が切れた後、 GitHub SSOによる再認証が要求されるようになりました。 おわりに 本記事ではTeleportを使って Kubernetes クラスタ へアクセスする際の再認証方式を設定する方法を紹介しました。この記事が皆様のお役に立てば幸いです。 参考 Introduction to Teleport | Teleport Docs TeleportでKubernetesクラスタへのユーザーアクセスを管理する - Cybozu Inside Out | サイボウズエンジニアのブログ 執筆: @shibata.takao 、レビュー: @higa ( Shodo で執筆されました ) コン トロール プレーンのエンドポイントのパブリックアクセスが有効になっているものとします。 ↩