TECH PLAY

電通総研

電通総研 の技術ブログ

822

こんにちは。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 で執筆されました ) コン トロール プレーンのエンドポイントのパブリックアクセスが有効になっているものとします。 ↩
アバター
電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの 比嘉康雄 です。 それでは、 ブロックチェーン 週報4/12いってみようか。 エンタメの最新アイテムはNFT その他のニュース エンタメの最新アイテムはNFT 先週、 NFTが身近に という記事を書いたんですが、さらにそれが進んでエンタメ化されてきました。 ロスで開かれたNFTイベントがカオスだった理由:現地レポート ハリウッドセレブの登場です。これは、NFTバブルが続くことを期待している人たちがかなりいることを示していると思います。 グラミー賞とNFTの夜:現地レポート 音楽アーティストもNFT。アーティストはNFTバブルに浮かれている人たちだけでなく、まじめにNFTに取り組んでいる人もそれなりにいると思ってますが、 グラミー賞 の夜だと派手な感じにはどうしてもなっちゃいますね。 エンタメ業界は、タレントの人気をお金に変えるビジネスだと思っているので、一連の動きは全く違和感ないのですが、NFTがボロクソに言われる日が来なければいいなと個人的には思っています。NFTはテク ノロ ジー の一つで、良い/悪いという存在ではないので。 その他のニュース マイクロソフトが「Web3」投資を加速。ブロックチェーン企業への投資や人材拡充へ スターバックス、年内にNFTビジネス参入 アニモカと韓国CUBE合弁会社、K-POPアーティスト動画NFTをエアドロップへ パンクがNFTでアーティストの経済的自立を可能にする【コラム】 人気メタバース、ユーザー数が伸びず──市場の期待を下回る 100億ドルのビットコイン購入を進めるLFG、週末に1億7000万ドル相当を購入──TerraUSDの裏付け資産として 執筆: @higa ( Shodo で執筆されました )
アバター
電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの 比嘉康雄 です。 それでは、 ブロックチェーン 週報4/12いってみようか。 エンタメの最新アイテムはNFT その他のニュース エンタメの最新アイテムはNFT 先週、 NFTが身近に という記事を書いたんですが、さらにそれが進んでエンタメ化されてきました。 ロスで開かれたNFTイベントがカオスだった理由:現地レポート ハリウッドセレブの登場です。これは、NFTバブルが続くことを期待している人たちがかなりいることを示していると思います。 グラミー賞とNFTの夜:現地レポート 音楽アーティストもNFT。アーティストはNFTバブルに浮かれている人たちだけでなく、まじめにNFTに取り組んでいる人もそれなりにいると思ってますが、 グラミー賞 の夜だと派手な感じにはどうしてもなっちゃいますね。 エンタメ業界は、タレントの人気をお金に変えるビジネスだと思っているので、一連の動きは全く違和感ないのですが、NFTがボロクソに言われる日が来なければいいなと個人的には思っています。NFTはテク ノロ ジー の一つで、良い/悪いという存在ではないので。 その他のニュース マイクロソフトが「Web3」投資を加速。ブロックチェーン企業への投資や人材拡充へ スターバックス、年内にNFTビジネス参入 アニモカと韓国CUBE合弁会社、K-POPアーティスト動画NFTをエアドロップへ パンクがNFTでアーティストの経済的自立を可能にする【コラム】 人気メタバース、ユーザー数が伸びず──市場の期待を下回る 100億ドルのビットコイン購入を進めるLFG、週末に1億7000万ドル相当を購入──TerraUSDの裏付け資産として 執筆: @higa ( Shodo で執筆されました )
アバター
はいどーもー! X イノベーション 本部の宮澤響です! 本記事では、株式会社 電通国際情報サービス (以下、ISID)の社内ラジオであるTecHuman.fmと、そこでのコンテンツ制作に利用しているサービスについて、簡単にご紹介します! TecHuman.fmって何? コンテンツ制作に利用しているサービス Miro Zoom Audacity Figma AviUtil Microsoft Stream Microsoft SharePoint まとめ TecHuman.fmって何? TecHuman.fmとは、ISIDのビジョンである「HUMANOLOGY for the future」に照らし、ISIDの最大の強みである人(Human)と技術(Technology)の両観点をもって、インプットを得ること、学び合うことをテーマに制作している社内ラジオです。 忙しい方でも業務の隙間時間などに気軽に参加してほしい、という思いから、耳だけで参加できる音声形式のコンテンツを展開する形でスタートしました。 ですが、最近では紙芝居(音声+静止画)形式のコンテンツや動画形式のコンテンツも展開されてきています。 コンテンツの制作は社内公募により集まった有志メンバーが行っており、2021年3月末時点で50本以上のコンテンツが公開されています。 最近では、このISIDテックブログの紹介コンテンツも公開されました。 コンテンツ制作に利用しているサービス Miro メンバーが仕事の合間に作業を進めたり、企画をしたりできるように、 Miro を共同作業の ワークスペース にしています。 コンテンツのコンセプトメイキングをしたり、台本の下書きをしたり、出演者との調整に利用したりしています。 miro.com Zoom 収録には、皆さんご存知の Zoom の有料プランを利用しています。 有料プランにすることで、3名以上での40分以上の収録にも対応できます。 各出演者ごとの音声トラックを個別に録音できるため、後続の音声編集をしやすいというメリットがあります。 Audacity 音声編集には、 オープンソース の音声編集・録音ソフトウェアである Audacity を利用しています。 収録した音声の音量を調整したり、BGMやSEを追加したり、言い直し部分をカットしたりします。 なお、BGMやSEに関しては、ISIDの同好会の一つである JAZZ部 の皆さんに制作いただいたものを利用することが多いです。 Figma サムネイル画像の作成には、ブラウザ上で動作するプロトタイピングツールである Figma の無料プランを利用しています。 操作感としては Adobe XDに近く、UIデザイナーになったような感覚で画像を作成できます。 紙芝居形式のコンテンツの場合には、コンテンツ内で表示する画像も Figma で作成しています。 AviUtil 動画編集には、動画編集ソフトウェアである AviUtil を利用しています。 基本的には編集済みの音声ファイルとサムネイル画像を合わせるだけですが、動画形式のコンテンツの場合には、より複雑な処理をすることになります。 Microsoft Stream 完成したコンテンツは、動画共有サービスである Microsoft Stream にアップロードし、全社に公開します。 再生数やいいねの数は運営メンバーもたびたび確認しますが、やはり反響があると嬉しいものです。 Microsoft SharePoint コラボレーション・ファイル共有サービスである Microsoft SharePoint にTecHuman.fm専用の広報ページをもっています。 過去に配信したコンテンツを一か所に集めて、社員が気軽に、いつでも好きなコンテンツを視聴できるようにしています。 まとめ 本記事では、ISIDの社内ラジオであるTecHuman.fmと、そこでのコンテンツ制作に利用しているサービスについて、簡単にご紹介しました! TecHuman.fmに関しては、ISIDの採用ページの中でも紹介されている( こちら )ので、ぜひ目を通していただければと思います。 最後までお読みいただき、本当にありがとうございました! 執筆: @miyazawa.hibiki 、レビュー: @sato.taichi ( Shodo で執筆されました )
アバター
はいどーもー! X イノベーション 本部の宮澤響です! 本記事では、株式会社 電通国際情報サービス (以下、ISID)の社内ラジオであるTecHuman.fmと、そこでのコンテンツ制作に利用しているサービスについて、簡単にご紹介します! TecHuman.fmって何? コンテンツ制作に利用しているサービス Miro Zoom Audacity Figma AviUtil Microsoft Stream Microsoft SharePoint おわりに TecHuman.fmって何? TecHuman.fmとは、ISIDのビジョンである「HUMANOLOGY for the future」に照らし、ISIDの最大の強みである人(Human)と技術(Technology)の両観点をもって、インプットを得ること、学び合うことをテーマに制作している社内ラジオです。 忙しい方でも業務の隙間時間などに気軽に参加してほしい、という思いから、耳だけで参加できる音声形式のコンテンツを展開する形でスタートしました。 ですが、最近では紙芝居(音声+静止画)形式のコンテンツや動画形式のコンテンツも展開されてきています。 コンテンツの制作は社内公募により集まった有志メンバーが行っており、2021年3月末時点で50本以上のコンテンツが公開されています。 最近では、このISIDテックブログの紹介コンテンツも公開されました。 コンテンツ制作に利用しているサービス Miro メンバーが仕事の合間に作業を進めたり、企画をしたりできるように、 Miro を共同作業の ワークスペース にしています。 コンテンツのコンセプトメイキングをしたり、台本の下書きをしたり、出演者との調整に利用したりしています。 miro.com Zoom 収録には、皆さんご存知の Zoom の有料プランを利用しています。 有料プランにすることで、3名以上での40分以上の収録にも対応できます。 各出演者ごとの音声トラックを個別に録音できるため、後続の音声編集をしやすいというメリットがあります。 Audacity 音声編集には、 オープンソース の音声編集・録音ソフトウェアである Audacity を利用しています。 収録した音声の音量を調整したり、BGMやSEを追加したり、言い直し部分をカットしたりします。 なお、BGMやSEに関しては、ISIDの同好会の一つである JAZZ部 の皆さんに制作いただいたものを利用することが多いです。 Figma サムネイル画像の作成には、ブラウザ上で動作するプロトタイピングツールである Figma の無料プランを利用しています。 操作感としては Adobe XDに近く、UIデザイナーになったような感覚で画像を作成できます。 紙芝居形式のコンテンツの場合には、コンテンツ内で表示する画像も Figma で作成しています。 AviUtil 動画編集には、動画編集ソフトウェアである AviUtil を利用しています。 基本的には編集済みの音声ファイルとサムネイル画像を合わせるだけですが、動画形式のコンテンツの場合には、より複雑な処理をすることになります。 Microsoft Stream 完成したコンテンツは、動画共有サービスである Microsoft Stream にアップロードし、全社に公開します。 再生数やいいねの数は運営メンバーもたびたび確認しますが、やはり反響があると嬉しいものです。 Microsoft SharePoint コラボレーション・ファイル共有サービスである Microsoft SharePoint にTecHuman.fm専用の広報ページをもっています。 過去に配信したコンテンツを一か所に集めて、社員が気軽に、いつでも好きなコンテンツを視聴できるようにしています。 おわりに 本記事では、ISIDの社内ラジオであるTecHuman.fmと、そこでのコンテンツ制作に利用しているサービスについて、簡単にご紹介しました! TecHuman.fmに関しては、ISIDの採用ページの中でも紹介されている( こちら )ので、ぜひ目を通していただければと思います。 最後までお読みいただき、本当にありがとうございました! 私たちは同じ事業部で共に働いていただける仲間を募集しています! みなさまのご応募、お待ちしています! フルサイクルエンジニア 執筆: @miyazawa.hibiki 、レビュー: @sato.taichi ( Shodo で執筆されました )
アバター
電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの 比嘉康雄 です。 それでは、 ブロックチェーン 週報4/5いってみようか。 NFTが身近に デジタルでも“本物保証” LINE参入でNFTが身近に?【WBS】 「LINE Blockchainの展望と未来の経済圏」LVCインタビュー LINE、4月にNFT電子取引市場開始-ペイペイ決済検討 「LINE NFT」 はソフトバンク経済圏の確立か CEOに聞く、真の狙い 【取材】加藤ミリヤや松井秀喜がNFT活用へ、ナッジがクレカ特典の実証実施 インスタグラム、NFTのメインストリーム化を加速:ドイツ銀行 その他のニュース OpenSea、ソラナNFTの取り扱い開始へ 業績絶好調の暗号通貨取引所が社員に高額ボーナスを支給 ゲームをやるだけでお金が稼げる!?」ビジネス系YouTuberが教えるWeb3.0時代の副業のヒント NFTが身近に LINEがNFTに参入することで、NFTがより身近になることが期待されています。LINEのIDを持っていて、LINE BITMAXに口座を開けば、使えるようになるので、これまでより身近になったのは間違いないと思います。 デジタルでも“本物保証” LINE参入でNFTが身近に?【WBS】 「LINE Blockchainの展望と未来の経済圏」LVCインタビュー LINE、4月にNFT電子取引市場開始-ペイペイ決済検討 「LINE NFT」 はソフトバンク経済圏の確立か CEOに聞く、真の狙い 有名人がNFTを発行する例も増えてきました。 【取材】加藤ミリヤや松井秀喜がNFT活用へ、ナッジがクレカ特典の実証実施 Instagram がNFTをサポートすることで、NFTのメインストリーム化が進むことも期待されています。 インスタグラム、NFTのメインストリーム化を加速:ドイツ銀行 その他のニュース OpenSea、ソラナNFTの取り扱い開始へ 業績絶好調の暗号通貨取引所が社員に高額ボーナスを支給 ゲームをやるだけでお金が稼げる!?」ビジネス系YouTuberが教えるWeb3.0時代の副業のヒント 自民党、Web3時代のNFT戦略でホワイトペーパー案を公表──ルール整備と規制緩和急ぐ 執筆: @higa ( Shodo で執筆されました )
アバター