TECH PLAY

電通総研

電通総研 の技術ブログ

822

テックブログ編集部です。今回は弊社社員が登壇するイベントを紹介します。詳細およびお申込みはリンク先サイトを参照してください。 techplay.jp ご興味あれば、ぜひ登録おねがいします。 基本情報 タイトル:《研究開発から社会実装まで》AIを活用した五感拡張デ バイス や VR を用いた遠隔 幻肢痛 セラピーシステムの開発事例大公開! 日時:2023/02/15(水) 19:00〜20:30 形態:オンライン開催 概要 深刻化する社会課題の解決には一企業の力だけでは限界があり、立場は違えど、社会を形成するさまざまな ステークホルダー の知恵を集結し共創することが不可欠です。 幅広い業界のトップクラスの企業へ最適なソリューションを提案する 電通国際情報サービス (ISID)に先端技術を活用して社会課題の解決をミッションとする「 イノベーション ラボ」という組織があることはご存じでしょうか?「イノラボ」はまだオープン イノベーション が日本に浸透していない2011年4月に設立された先駆的な組織であり、課題発見から社会実装までを 一気通貫 で支援しています。 本勉強会では、世界的アワードの日本版である「Innovators Under 35」​でISID賞を受賞した 神戸大学 大西氏より、現在の研究開発事例についてお話します。 事例(一部) "AIを活用して人間の 疲労 を克服する ウェアラブル デ バイス "の開発 またイノラボ岡田氏からは研究開発に留めることなく、プロダクトとして実現していく上で直面した課題や乗り越えるための工夫について事例をもとにお話します。 事例(一部) 実空間でト ラッキング した体の情報を VR 空間に反映させ、異なる地点間にいる人の細かな動きを伝え合うことを可能にする"遠隔 VR 幻肢痛 セラピーシステム"の開発 勉強会の後半では、大学と企業と立場は違えど、他者と共創することに共通点を持つ両者から、共創する上での難しさと乗り越え方についてパネルディスカッションを行います。 執筆: @nakamura.toshihiro 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
アバター
テックブログ編集部です。今回は弊社社員が登壇するイベントを紹介します。詳細およびお申込みはリンク先サイトを参照してください。 techplay.jp ご興味あれば、ぜひ登録おねがいします。 基本情報 タイトル:《研究開発から社会実装まで》AIを活用した五感拡張デ バイス や VR を用いた遠隔 幻肢痛 セラピーシステムの開発事例大公開! 日時:2023/02/15(水) 19:00〜20:30 形態:オンライン開催 概要 深刻化する社会課題の解決には一企業の力だけでは限界があり、立場は違えど、社会を形成するさまざまな ステークホルダー の知恵を集結し共創することが不可欠です。 幅広い業界のトップクラスの企業へ最適なソリューションを提案する 電通国際情報サービス (ISID)に先端技術を活用して社会課題の解決をミッションとする「 イノベーション ラボ」という組織があることはご存じでしょうか?「イノラボ」はまだオープン イノベーション が日本に浸透していない2011年4月に設立された先駆的な組織であり、課題発見から社会実装までを 一気通貫 で支援しています。 本勉強会では、世界的アワードの日本版である「Innovators Under 35」​でISID賞を受賞した 神戸大学 大西氏より、現在の研究開発事例についてお話します。 事例(一部) "AIを活用して人間の 疲労 を克服する ウェアラブル デ バイス "の開発 またイノラボ岡田氏からは研究開発に留めることなく、プロダクトとして実現していく上で直面した課題や乗り越えるための工夫について事例をもとにお話します。 事例(一部) 実空間でト ラッキング した体の情報を VR 空間に反映させ、異なる地点間にいる人の細かな動きを伝え合うことを可能にする"遠隔 VR 幻肢痛 セラピーシステム"の開発 勉強会の後半では、大学と企業と立場は違えど、他者と共創することに共通点を持つ両者から、共創する上での難しさと乗り越え方についてパネルディスカッションを行います。 執筆: @nakamura.toshihiro 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
アバター
はじめに こんにちは、ISID 金融ソリューション事業部の岡崎です。 今回はEpicGames社が提供する ゲームエンジン 、Unreal Engine5 を利用して VR や メタバース のベースとなる、ワールドの地形を作成する手順を紹介します。 手順 今回は下記手順でUnrealEngine上にワールドを作成しました。 ランドスケープ モードを使用して地形作成 地形のマテリアル作成 マテリアルを使用してペイント 3Dアセットの追加 海を追加 ランドスケープ モードを使用して地形作成 ワールドの地形を生成するためにはまず、ワールドを生成するためのファイルを作成する必要があります。 Epic Games Launcherから Unreal Editorを起動し、左側の「ゲーム」のパネルから「Blank」を選びプロジェクトを始めます。 生成されたプロジェクトから地形を生成するためにはまず、 ランドスケープ ツールを使用します。 ランドスケープ モードには ・管理 ・スカルプト ・ペイント という3つのモードがあります。 まずは、フィールドの基盤になるメッシュを作成するために、管理モードから コンポーネント 数を指定し、メッシュを作成します。今回は コンポーネント 数を8x8で行いました。 メッシュの作成が終わると、 コンポーネント で選択した領域にメッシュが作成され、選択されていた管理モードから、自動的にスカルプトモードに変更されます。 今回はスカルプトモードと侵食モードを利用して、島や山を表現しています。 基本的にはスカルプトモードで山や、島の突起を作成し、侵食モードで山肌や谷を作成していく流れで作業を行いました。 (山の輪郭を作成します) (侵食モードで山肌を作成します) 次に作成した山や谷のワールドに海を追加します。本格的な海は後続の処理で作成するので、今回は仮の状態として海を追加しました。 海の追加方法は、上記タブのコンテンツ作成ボタンから「形状」→「Plane」を選択します。次に右側のトランスフォームの位置と大きさの数値を任意のものに変更します。 今回は海面の高さを陸地より少し上にしたかったので、位置のZ数値を150と設定しました。 作成が完了すると、海ができるはずの箇所に薄いグレーの「Plane」コンテンツが見えます。次にこの薄いグレーのコンテンツに海のマテリアルを追加します。 右側の詳細タブから「マテリアル」を選択し、検索欄に「water」と入力し、「M_Water_Ocean」というマテリアルを選択します。 以上の工程で、海の追加が完了しました。 地形のマテリアル作成 スカルプトモードで作成した地形にマテリアルを使って岩肌や草、海岸などを作成していきます。 まず、マテリアルを使うためには、プロジェクト内にマテリアルの追加を行わないといけません。 マテリアルの追加方法は画面上部のコンテンツ作成ボタンから「Quixel Bridge」を開きます。 「Quixel Bridge」内で任意のマテリアルを選択し、プロジェクト内で使用します。今回は草のマテリアルである「Grass」を追加しました。 画面下のコンテンツドロワーから追加したマテリアルを確認することができます。 追加したマテリアルをそのままプロジェクトでは使うことができないので、 岩肌や草、海岸など、使用するマテリアルを全て一つのプロジェクト用のマテリアルに集約をしました。 コンテンツ配下に「M_landscape」という本プロジェクト用のマテリアルを作成します。 次にマテリアル作成画面に移動し、エディタ上で右クリックを押し「Layer Blend」を作成します。 ここでプロジェクトで使用するひとつひとつのマテリアル(岩肌や草など)に対して、影の強さや発色の強さ、2つのマテリアルの ブレンド などを行います。 本作業はプロジェクト独自の絵の具パレットを作成するようなイメージです。 独自のマテリアル作成が完了すると、いよいよマテリアルを使用したペイント作業になります。   マテリアルを使用してペイント マテリアルを使用したペイントを行うためには、 ランドスケープ モードに変更して、ペイントタブを選択することでマテリアルのレイヤー(色のついた筆のイメージ)を選択できます。 レイヤーの中には先ほどマテリアル作成で行った「Layer Blend」を選ぶことができます。 ここで任意のレイヤーを選択し、作成した地形にペイントを行っていきます。 また、スカルプトモードと同様で、ツールの強度やブラシサイズなどもここで変更できます。ツールの強度を弱くすることで、複数のレイヤーのマテリアルを重ね塗りすることができます。 ここでは、浜辺を作成するために、「sand1」レイヤーを使い砂のマテリアルを塗った上から、「Glass1」の芝生を薄く重ね塗りを行いました。 山肌も同様にペイントをしていき、岩のレイヤーや草野レイヤー、砂浜のレイヤーを重ねて塗っていきワールド地形を仕上げていきます。 3Dアセットの追加 地形のスカルプト、ペイントが完了し完成に近づいたので、次は作成した地形に3Dアセットを設置します。 もちろん別の3Dオブジェクト作成ツールなどを使って作成したアセットを設置しても良いですが、今回は Unreal Engine でデフォルトで用意されている3Dアセットを追加し設置します。 マテリアルの作成でも使用した「Quixel Bridge」を開き、「3D Assets」を選択することで、作成した地形にあったアセットを探すことができます。 今回は「Nature」の中から「ROCK」を選択し、任意の岩のアセットを探し追加します。 追加したアセットは「コンテンツドロワー」内の「Megascans」→「3D_Assets」内に保存されているのでドラッグして任意の場所に配置します。 海を追加 最後に海の追加を行います。 前の手順で追加した「M_Water_Ocean」でも良いのですが、 Unreal Engine には別の海の機能も搭載されているので、そちらを利用します。 上部の編集タブから プラグイン を選択し、検索欄に「water」と入力し、「Water」の プラグイン を有効にします。現段階ではまだ実験段階と表示がありますが、問題なく使用できるので、今回は使用します。 次にコンテンツ作成ボタンから「アクタ配置パネル」を選択し、「Water Body Custom」を選択することで、新しい海をワールドに追加することができます。 以上で、ワールド上に地形を作成するための工程が完了しました。 おわりに 今回は、Unreal Engine5 を使用して、ゼロからワールドに地形を生成する方法を紹介しました。 初めて使用してみましたが、初心者でも簡単にハイクオリティな地形を作ることができました。 私は macOS 12.6 Monterey のPCで地形制作を行いました。 ランドスケープ モードのスカルプトを行う際にカーソルの操作が早すぎて上手くいかない点がありましたが、ペンタブなどで対応することで特に不自由なく作業を行うことができました。 今回の実践では、まだまだ Unreal Engine5 の一部の機能しか触れていないので、他の機能のキャッチアップも行っていき、ゲーム以外の領域でも効率的な使用方法を探っていきたいとおもいます。 最後までお読みいただき、ありがとうございました。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ(Web3/メタバース/AI) 参考 ・ ランドスケープの作成 | Unreal Engine ドキュメント ・ 【はじめて学ぶ人のための】Unreal Engine 5 風景制作 基礎講座 執筆: @okazaki.wataru 、レビュー: @okazaki.wataru ( Shodo で執筆されました )
アバター
はじめに こんにちは、ISID 金融ソリューション事業部の岡崎です。 今回はEpicGames社が提供する ゲームエンジン 、Unreal Engine5 を利用して VR や メタバース のベースとなる、ワールドの地形を作成する手順を紹介します。 手順 今回は下記手順でUnrealEngine上にワールドを作成しました。 ランドスケープ モードを使用して地形作成 地形のマテリアル作成 マテリアルを使用してペイント 3Dアセットの追加 海を追加 ランドスケープ モードを使用して地形作成 ワールドの地形を生成するためにはまず、ワールドを生成するためのファイルを作成する必要があります。 Epic Games Launcherから Unreal Editorを起動し、左側の「ゲーム」のパネルから「Blank」を選びプロジェクトを始めます。 生成されたプロジェクトから地形を生成するためにはまず、 ランドスケープ ツールを使用します。 ランドスケープ モードには ・管理 ・スカルプト ・ペイント という3つのモードがあります。 まずは、フィールドの基盤になるメッシュを作成するために、管理モードから コンポーネント 数を指定し、メッシュを作成します。今回は コンポーネント 数を8x8で行いました。 メッシュの作成が終わると、 コンポーネント で選択した領域にメッシュが作成され、選択されていた管理モードから、自動的にスカルプトモードに変更されます。 今回はスカルプトモードと侵食モードを利用して、島や山を表現しています。 基本的にはスカルプトモードで山や、島の突起を作成し、侵食モードで山肌や谷を作成していく流れで作業を行いました。 (山の輪郭を作成します) (侵食モードで山肌を作成します) 次に作成した山や谷のワールドに海を追加します。本格的な海は後続の処理で作成するので、今回は仮の状態として海を追加しました。 海の追加方法は、上記タブのコンテンツ作成ボタンから「形状」→「Plane」を選択します。次に右側のトランスフォームの位置と大きさの数値を任意のものに変更します。 今回は海面の高さを陸地より少し上にしたかったので、位置のZ数値を150と設定しました。 作成が完了すると、海ができるはずの箇所に薄いグレーの「Plane」コンテンツが見えます。次にこの薄いグレーのコンテンツに海のマテリアルを追加します。 右側の詳細タブから「マテリアル」を選択し、検索欄に「water」と入力し、「M_Water_Ocean」というマテリアルを選択します。 以上の工程で、海の追加が完了しました。 地形のマテリアル作成 スカルプトモードで作成した地形にマテリアルを使って岩肌や草、海岸などを作成していきます。 まず、マテリアルを使うためには、プロジェクト内にマテリアルの追加を行わないといけません。 マテリアルの追加方法は画面上部のコンテンツ作成ボタンから「Quixel Bridge」を開きます。 「Quixel Bridge」内で任意のマテリアルを選択し、プロジェクト内で使用します。今回は草のマテリアルである「Grass」を追加しました。 画面下のコンテンツドロワーから追加したマテリアルを確認することができます。 追加したマテリアルをそのままプロジェクトでは使うことができないので、 岩肌や草、海岸など、使用するマテリアルを全て一つのプロジェクト用のマテリアルに集約をしました。 コンテンツ配下に「M_landscape」という本プロジェクト用のマテリアルを作成します。 次にマテリアル作成画面に移動し、エディタ上で右クリックを押し「Layer Blend」を作成します。 ここでプロジェクトで使用するひとつひとつのマテリアル(岩肌や草など)に対して、影の強さや発色の強さ、2つのマテリアルの ブレンド などを行います。 本作業はプロジェクト独自の絵の具パレットを作成するようなイメージです。 独自のマテリアル作成が完了すると、いよいよマテリアルを使用したペイント作業になります。   マテリアルを使用してペイント マテリアルを使用したペイントを行うためには、 ランドスケープ モードに変更して、ペイントタブを選択することでマテリアルのレイヤー(色のついた筆のイメージ)を選択できます。 レイヤーの中には先ほどマテリアル作成で行った「Layer Blend」を選ぶことができます。 ここで任意のレイヤーを選択し、作成した地形にペイントを行っていきます。 また、スカルプトモードと同様で、ツールの強度やブラシサイズなどもここで変更できます。ツールの強度を弱くすることで、複数のレイヤーのマテリアルを重ね塗りすることができます。 ここでは、浜辺を作成するために、「sand1」レイヤーを使い砂のマテリアルを塗った上から、「Glass1」の芝生を薄く重ね塗りを行いました。 山肌も同様にペイントをしていき、岩のレイヤーや草野レイヤー、砂浜のレイヤーを重ねて塗っていきワールド地形を仕上げていきます。 3Dアセットの追加 地形のスカルプト、ペイントが完了し完成に近づいたので、次は作成した地形に3Dアセットを設置します。 もちろん別の3Dオブジェクト作成ツールなどを使って作成したアセットを設置しても良いですが、今回は Unreal Engine でデフォルトで用意されている3Dアセットを追加し設置します。 マテリアルの作成でも使用した「Quixel Bridge」を開き、「3D Assets」を選択することで、作成した地形にあったアセットを探すことができます。 今回は「Nature」の中から「ROCK」を選択し、任意の岩のアセットを探し追加します。 追加したアセットは「コンテンツドロワー」内の「Megascans」→「3D_Assets」内に保存されているのでドラッグして任意の場所に配置します。 海を追加 最後に海の追加を行います。 前の手順で追加した「M_Water_Ocean」でも良いのですが、 Unreal Engine には別の海の機能も搭載されているので、そちらを利用します。 上部の編集タブから プラグイン を選択し、検索欄に「water」と入力し、「Water」の プラグイン を有効にします。現段階ではまだ実験段階と表示がありますが、問題なく使用できるので、今回は使用します。 次にコンテンツ作成ボタンから「アクタ配置パネル」を選択し、「Water Body Custom」を選択することで、新しい海をワールドに追加することができます。 以上で、ワールド上に地形を作成するための工程が完了しました。 おわりに 今回は、Unreal Engine5 を使用して、ゼロからワールドに地形を生成する方法を紹介しました。 初めて使用してみましたが、初心者でも簡単にハイクオリティな地形を作ることができました。 私は macOS 12.6 Monterey のPCで地形制作を行いました。 ランドスケープ モードのスカルプトを行う際にカーソルの操作が早すぎて上手くいかない点がありましたが、ペンタブなどで対応することで特に不自由なく作業を行うことができました。 今回の実践では、まだまだ Unreal Engine5 の一部の機能しか触れていないので、他の機能のキャッチアップも行っていき、ゲーム以外の領域でも効率的な使用方法を探っていきたいとおもいます。 最後までお読みいただき、ありがとうございました。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! 私たちは同じ事業部で共に働いていただける仲間を募集しています! みなさまのご応募、お待ちしています! 電通総研中途採用ページ 参考 ・ ランドスケープの作成 | Unreal Engine ドキュメント ・ 【はじめて学ぶ人のための】Unreal Engine 5 風景制作 基礎講座 執筆: @okazaki.wataru 、レビュー: @okazaki.wataru ( Shodo で執筆されました )
アバター
こんにちは。X(クロス) イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの耿です。 2022年12月始めに AWS CDK の GitHub リポジトリ の wiki に公開された Security And Safety Dev Guide を読んでみました。CDKアプリをデプロイする時の権限と、CDKアプリ内で作成する権限の両方について、管理方法と推奨事項が書かれています。 この記事ではざっくりとした要約と感想を筆者の観点で書いていきます(分かりやすさのために、幾分か内容の再構築や意訳が入っています)。翻訳記事ではないので、正確で詳細な内容は元のドキュメントをご確認ください。 https://github.com/aws/aws-cdk/wiki/Security-And-Safety-Dev-Guide イントロダクション CDKのデプロイではどのような権限を使うべきか 権限昇格することなくIAMロールの作成を許可する CDKデプロイで使われる権限の管理 DefaultStackSynthesizer デプロイのフロー Bootstrap CliCredentialsStackSynthesizer CDK内のIAMアイデンティティとポリシーを取り扱う CDKにIAMロールとポリシーの管理を任せる 事前に手動で作成したロールを利用する Permissions boundary と SCP ざっくり要約をさらに要約 イントロダクション <ざっくり要約> CDKはあらゆる AWS サービスを構築・設定できる強力なツールで、効率的な開発に寄与する一方、組織は コンプライアンス や コストコ ン トロール の目的で開発者の権限を制限したい場合もあり、セキュリティと生産性はしばしば競合する。このドキュメントでは開発者の生産性を損なうことなく、大半のセキュリティに関する ユースケース を満たすだろう推奨事項を紹介する。 <感想> CDKに限らず、組織内のセキュリティ施策が開発を阻害するものとして捉えられる傾向があるのは、セキュリティ担当と開発担当で見ている景色が違うからだろうと思います。セキュリティ担当は最悪の事態を想像して対策を提示するのに対して、開発担当は普段の日々の開発を楽にすることにより価値を置きます。セキュリティ担当の立場としては、開発担当の気持ちを理解し、 原理主義 にならずに対話型でセキュリティ対策を考える状態を目指したいと考えています。ちなみに筆者が所属するセキュリティを担当するグループでは、開発側の気持ちを理解する方法の一つとして自ら社内向けに システム開発 も行っています。 CDKのデプロイではどのような権限を使うべきか <ざっくり要約> 権限付与の方法は一般的に、許可リスト方式と拒否リスト方式の2種類ある。 CDK/CloudFormationにおいては ロールバック もあり、許可リストでは最小権限を網羅するのは難しい。 AWS Config, AWS CloudTrail, AWS Security Hub, AWS CloudFormation Hooksなどによってガードレール、 コンプライアンス ルール、監査、モニタリングを実施した上で、それらを変更する以外の全ての権限を付与する拒否リスト方式の方が推奨される。 コンプライアンス に適合する範囲で開発者に自由を与えることができる。 <感想> IaCの経験がある方であれば、許可リスト方式での権限付与は厳しいことはよく分かると思います。特に CDK/CloudFormation における ロールバック は Terraform にはない特徴の一つなので、権限付与に限らず、CDKを使うときはそれを意識するのが良いでしょう。 権限昇格することなくIAMロールの作成を許可する <ざっくり要約> CDKでリソースをデプロイするときは、デフォルトで最小権限になるように必要なIAMロールを自動作成する。手動でロールを作らずに、このデフォルトの挙動に任せるのが推奨である。 アプリ開発 者にロールを作成させない運用ルールがある場合、その目的は主に開発者の権限昇格を防ぐことである。権限昇格を防ぐ代替手段としてPermissions boundary(アクセス許可境界)とSCP(サー ビスコ ン トロール ポリシー)がある。開発者のロールにPermissions boundaryをアタッチすることで、開発者自身の権限と、開発者のロールが作成するロールの権限両方を制限できる。 <感想> IAMロールやポリシーはIaCで作る他のリソースを参照するため、手動で管理せずにIaCの開発サイクルに含めた方が管理しやすいのは納得できる説明です。 CDKでインフラをデプロイすると、いつの間にかたくさんのIAMロールが作られていて把握しきれないと感じていましたが、そもそも人間が把握できる程度のシンプルさでは最小権限は実現できていないのだろうと説明を読んで思いました。 CDKデプロイで使われる権限の管理 <ざっくり要約> CDKはCloudFormationを使って変更をデプロイする。 デプロイを開始するアクター(ユーザーか自動化システム)はIAM アイデンティティ (ユーザーかロール)を持ち、それとは別にデプロイを実行する CloudFormation にもロールが与えられる。 スタックデプロイ時にCDKが使用するロールとアセットコンテナ(後述)は、Stack Synthesizer が決定する。 <感想> cdk deploy を実行する時の権限と、実際に CloudFormation がリソースをデプロイする時の権限は分けられることが書いてあります。これも Terraform と比較した時の CDK の特徴ですね。意識的に2つの権限を区別して考えるとこの後の説明が理解しやすいと思います。 Stack Synthesizer については DefaultStackSynthesizer と CliCredentialsStackSynthesizer の2種類の説明がこの後に続きます。 DefaultStackSynthesizer デプロイのフロー <ざっくり要約> DefaultStackSynthesizer は CDK v2 のデフォルトのStack Synthesizerであり、基本的にはこれを使うことになる。 CDKによるデプロイは次のフローの通りである CDKデプロイを開始するアクターの AWS 権限を認可する CDKデプロイを開始するアクターは「CDKデプロイロール」を引き受け(AssumeRole)、「CDKデプロイロール」は「CFN実行ロール」をCloudFormationに渡す(PassRole)。 「CFN実行ロール」は CloudFormationサービスロール で、スタックをデプロイする時にCloudFormationに利用される これ以降、デプロイに使われるのはデプロイを開始したアクターの権限ではなく、「CFN実行ロール」の権限になる 必要に応じてCDKデプロイを開始したアクターは「file-publishing-role」「image-publishing-role」「lookup-role」をそれぞれ引き受ける(AssumeRole) 「file-publishing-role」と「image-publishing-role」は、デプロイで使われるファイルとDockerイメージをS3 バケット とECR リポジトリ にプッシュする時に使われる。ここのS3 バケット とECR リポジトリ はbootstrap時に作られたものである。「CFN実行ロール」にはこれらのアセットを参照する権限が必要である 「lookup-role」はCDKのsynth時に既存のリソースを参照する場合に使われる。デフォルトではReadOnly管理ポリシーが付与されている (図は https://github.com/aws/aws-cdk/wiki/Security-And-Safety-Dev-Guide より) <感想> 「CDKデプロイを開始するアクターの権限」「CDKデプロイロール」「CFN実行ロール」「file-publishing-role」「image-publishing-role」「lookup-role」と権限が6種類登場しています。 「CDKデプロイを開始するアクターの権限」はCDKを利用する前に手動で作成するもので、「CDKデプロイロール」「file-publishing-role」「image-publishing-role」「lookup-role」の4つをAssumeRoleできれば良いです。すなわち、 cdk deploy を実行する時の権限は AdministratorAccess である必要はありません。 「CDKデプロイロール」「CFN実行ロール」「file-publishing-role」「image-publishing-role」「lookup-role」の5つは cdk bootstrap するときに自動で作成されるもので、手で管理する必要はありません。bootstrapの説明はこの後続きます。 Bootstrap <ざっくり要約> DefaultStackSynthesizer を使うためにはまず AWS 環境を bootstrap する必要がある。bootstrap は各リージョンに一度だけ必要な操作で、Synthesizerに必要なIAMロール群とアセットコンテナ(S3 バケット とECR リポジトリ )が作成される。 cdk boostrap することでCloudFormationスタックがデプロイされる。デフォルトのテンプレートを使うこともできるし、 カスタマイズ することもできる。 コンプライアンス 管理をする場合、bootstrap時のテンプレートをカスタマイズする必要がある。例えばカスタマイズによって「CFN実行ロール」の権限を制限できる(ポリシーの変更、Permission boundaryの追加などによって権限昇格を防ぐ)。デフォルトでは「CFN実行ロール」はAdministratorAccessとなる。 また「CDKデプロイロール」「file-publishing-role」「image-publishing-role」を誰が AssumeRole できるのかを制限することもできる。デフォルトでは同じ AWS アカウントの全ての アイデンティティ が AssumeRole できる。 CDKがbootstrapしたロールを引き受けるためには、以下のポリシー ステートメント を アイデンティティ に追加する(=CDKデプロイを開始するアクターは以下の権限を持てば良い) { " Version ": " 2012-10-17 ", " Statement ": [{ " Sid ": " AssumeCDKRoles ", " Effect ": " Allow ", " Action ": " sts:AssumeRole ", " Resource ": " * ", " Condition ": { " ForAnyValue:StringEquals ": { " iam:ResourceTag/aws-cdk:bootstrap-role ": [ " image-publishing ", " file-publishing ", " deploy ", " lookup " ] } } }] } cdk bootstrap の実行はAdministratorAccessの権限を使うことを推奨する。bootstrapスタックの内容は変わりうるので、将来的に必要な権限は予測できない。またbootstrapによって任意の権限を持った新しいロールが作られるので、bootstrapを実行する権限を制限する実メリットがない。 <感想> cdk bootstrap は CDKToolkit という名前のCloudFormationスタックを作る程度の認識でしたが、実際に何をやっているのかの説明がされていました。デフォルト設定で作成された CDKToolkit スタックを実際に見てみると、確かに説明されていた通りのリソースが作られています。 ECR リポジトリ 「ContainerAssetsRepository」 S3 バケット 「StagingBucket」 CDKデプロイロール「DeploymentActionRole」 CloudFormation、S3、KMSの権限や、CFN実行ロールをPassRoleする権限が付いている aws-cdk:bootstrap-role : deploy リソースタグが付いている CFN実行ロール「CloudFormationExecutionRole」 AdministratorAccess ポリシーが付いている リソースタグは付いていない file-publishing-role「FilePublishingRole」 S3とKMSへの権限が付いている aws-cdk:bootstrap-role : file-publishing リソースタグが付いている image-publishing-role「ImagePublishingRole」 ECRへの権限が付いている aws-cdk:bootstrap-role : image-publishing リソースタグが付いている lookup-role「LookupRole」 AWS 管理の ReadOnlyAccess ポリシーが付いている aws-cdk:bootstrap-role : lookup リソースタグが付いている 注目すべきは、紹介されているポリシー ステートメント ではリソースタグで「CDKデプロイロール」「file-publishing-role」「image-publishing-role」「lookup-role」のAssumeRoleを許可していて、AdministratorAccess を持つ「CFN実行ロール」をAssumeRoleできないようになっている点です。つまりこれを使うことで、「CDKデプロイを開始するアクター」はAdministratorAccess権限をAssumeRoleできません。 (しかし厳密に考えると、「CDKデプロイロール」は CloudFormationスタックを作ることができて、「CFN実行ロール」をPassRoleできるため、CloudFormationに強権限のIAMロールを作らせて然るべきリソースタグを付けることで、「CDKデプロイを開始するアクター」から強権限のロールに最終的にAssumeRoleできるように思います。AssumeRoleを許可する対象リソースはリソースタグではなくロール名で指定した方がより安全でしょう) bootstrapで作成されるリソースは将来的に変わる可能性もあるとのことですが、「CDKデプロイを開始するアクター」がAssumeすべきロールの種類が増えていかないかは気になるところです。 CliCredentialsStackSynthesizer <ざっくり要約> DefaultStackSynthesizer の代わりに CliCredentialsStackSynthesizer を使うことができる。IAMロールをAssumeするのではなく、「CDKデプロイを開始するアクター」の権限を利用する。CloudFormationコールは直接実行され、サービスロールは渡されない。つまり「CDKデプロイを開始するアクター」は bootstrap が本来作成するロールの全ての権限を持つ必要がある。なお --role-arn パラメータを利用することで「CFN実行ロール」を別のロールとすることはできる。 <感想> CliCredentialsStackSynthesizer を使いたいケースがどのような場合があるのか気になります。「CDKデプロイを開始するアクター」(ローカルやデプロイパイプラインに保存するアクセスキー)が強い権限を持つ必要があるので、基本的には DefaultStackSynthesizer の方を使うのが良いのではないでしょうか。 CDK内のIAM アイデンティティ とポリシーを取り扱う <ざっくり要約> CDKにIAMロールとポリシーの作成を任せるのが推奨。もしそれを許可できない場合、事前に人の手で作成し、CDKアプリから参照するようにする。 <感想> CDKデプロイ自体の権限についての説明は終わり、ここからはなじみやすいイン フラリ ソースの権限についてです。 CDKにIAMロールとポリシーの管理を任せる <ざっくり要約> CDKに権限の生成を任せる場合、 grant メソッドを活用するのが良い。例えば暗号化されたS3 バケット からの読み取りをLambda関数に許可する場合、 bucket.grantRead(handler) のように書ける。 import { aws_s3 as s3 , aws_lambda as lambda , aws_kms as kms , Stack , } from 'aws-cdk-lib' ; const stack = new Stack ( app , 'LambdaStack' ); const key = new kms.Key ( stack , 'BucketKey' ); const bucket = new s3.Bucket ( stack , 'Bucket' , { encryptionKey: key , } ); const handler = new lambda. Function ( stack , 'Handler' , { runtime: lambda.Runtime.NODEJS_16_X , handler: 'index.handler' , code: lambda.Code.fromAsset ( path.join ( __dirname , 'lambda-handler' )), } ); bucket.grantRead ( handler ); handler.addToRolePolicy() でLambda関数に直接権限を与えることもできるが、 grant メソッドが使える場合はそれが推奨される。 <感想> CDKには明示的に権限を付与しなくても、(なるべく)最小権限を自動で付与される方法が多く用意されています。例のS3 バケット の grantRead では、以下の権限がLambda関数の実行ロールに付与されます。 対象 バケット への s3:GetObject* 対象 バケット への s3:GetBucket* 対象 バケット への s3:List* 対象 バケット が利用するKMSキーへの kms:Decrypt 対象 バケット が利用するKMSキーへの kms:DescribeKey もしLambda関数が GetObject しか実行しない場合、 GetBucket* や List* の権限も付与されているので厳密には最小権限ではありませんが、読み取りしか許可されていない意味では気になる状況は少ないでしょう。 grand メソッドの名前だけでは具体的に付与される権限が分からなかったりするので、メソッドの説明などで確認すると良いでしょう。例えば現状、DynamoDBテーブルのコンスト ラク トには grantReadWriteData メソッドが用意されており、実際に付与される権限がメソッドの説明で分かります。 アイテムをPutするだけで、Deleteする権限を与えたくない場合もあるかと思いますので、そのような時は addToRolePolicy などを使うことになります。 事前に手動で作成したロールを利用する <ざっくり要約> CDKでIAMロールとポリシーの作成が許可されていない場合、事前に手動で作成し、 Role.fromRoleName() で参照する。 あるいは Role.customizeRoles() を利用して、CDKアプリに必要となる全てのロールとポリシーを実際に作成せずに、レポートとして書き出してIAMロールを管理する担当者に連携することができる。 const stack = new Stack(app, 'LambdaStack'); // ロールのsynthをしないようにこれを追加する iam.Role.customizeRoles(stack); // 以下のコードは同じ const key = new kms.Key(stack, 'BucketKey'); const bucket = new s3.Bucket(stack, 'Bucket', { encryptionKey: key, }); const handler = new lambda.Function(stack, 'Handler', { runtime: lambda.Runtime.NODEJS_16_X, handler: 'index.handler', code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), }); // 権限が必要であることをCDKに教えるため、通常通り grantRead() などは必要 bucket.grantRead(handler); 人の手によってロールが作成されたら、そのロール名を customizeRoles に追加することでCDKで利用できるようになる。 const stack = new Stack ( app , 'LambdaStack' ); iam.Role.customizeRoles ( stack , { usePrecreatedRoles: { 'LambdaStack/Handler/ServiceRole' : 'lambda-service-role' , } , } ); <感想> customizeRoles はCDK v2.51.0でリリースされた機能です。IAM権限を開発者が自由に作成できないような環境では役に立ちそうです。 Permissions boundary と SCP <ざっくり要約> セキュリティガードレールのためにPermissions boundaryを使うことができる。 権限昇格を防ぐために、同じPermissions boundaryを含まないようなユーザーやロールを作ることを禁止できる。 cdk bootstrap で --custom-permissions-boundary フラグを追加することで、「CFN実行ロール」にPermissions boundaryをアタッチできる。 CDKアプリ内で作るロールにPermissions boundaryをアタッチする場合は以下のとおりになる。 const stack = new Stack ( app , 'MyStack' ); new iam.Role ( stack , 'Role' , { assumeRolePolicy: new iam.ServicePrincipal ( 'lambda.amazonaws.com' , permissionsBoundary: iam.ManagedPolicy.fromManagedPolicyName ( `cdk- ${ stack.synthesizer.bootstrapQualifier } -permissions-boundary- ${ stack.account } - ${ stack.region } ` ); } ); cdk.json にてグローバルで設定もできる。 { " context ": { " @aws-cdk/core:permissionsBoundary ": { " name ": " cdk-permissions-boundary " } } } App や Stage レベルで設定もできる。 <感想> Permissions boundary をCDKで利用する方法について詳細に書かれていました。 --custom-permissions-boundary フラグは CDK v2.54.0 に追加された機能 です。 ざっくり要約をさらに要約 CDKのデプロイに与える権限は許可リストではなく、拒否リストが推奨である IAMロールは手動で作るのではなく、CDKの自動作成に任せるのが推奨である 開発者の権限昇格を防ぎたい場合、Permissions boundary(アクセス許可境界)とSCP(サー ビスコ ン トロール ポリシー)を利用する bootstrap 時のCloudFormationテンプレートをカスタマイズする cdk bootstrap はAdministratorAccessの権限で行う 基本的に cdk deploy にAdministratorAccessは必要なく、bootstrapで作成された4種類のIAMロールをAssumeRoleできれば良い CDKに権限の生成を任せる場合、なるべく grant メソッドを利用する Role.customizeRoles() を利用することで、CDKデプロイせずに必要となる権限一覧をレポート出力できる お読みいただいてありがとうございました。 私たちは同じチームで働いてくれる仲間を大募集しています!たくさんのご応募をお待ちしています。 セキュリティエンジニア(セキュリティ設計) 執筆: @kou.kinyo 、レビュー: @wakamoto.ryosuke ( Shodo で執筆されました )
アバター
こんにちは。X(クロス) イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの耿です。 2022年12月始めに AWS CDK の GitHub リポジトリ の wiki に公開された Security And Safety Dev Guide を読んでみました。CDKアプリをデプロイする時の権限と、CDKアプリ内で作成する権限の両方について、管理方法と推奨事項が書かれています。 この記事ではざっくりとした要約と感想を筆者の観点で書いていきます(分かりやすさのために、幾分か内容の再構築や意訳が入っています)。翻訳記事ではないので、正確で詳細な内容は元のドキュメントをご確認ください。 https://github.com/aws/aws-cdk/wiki/Security-And-Safety-Dev-Guide イントロダクション CDKのデプロイではどのような権限を使うべきか 権限昇格することなくIAMロールの作成を許可する CDKデプロイで使われる権限の管理 DefaultStackSynthesizer デプロイのフロー Bootstrap CliCredentialsStackSynthesizer CDK内のIAMアイデンティティとポリシーを取り扱う CDKにIAMロールとポリシーの管理を任せる 事前に手動で作成したロールを利用する Permissions boundary と SCP ざっくり要約をさらに要約 イントロダクション <ざっくり要約> CDKはあらゆる AWS サービスを構築・設定できる強力なツールで、効率的な開発に寄与する一方、組織は コンプライアンス や コストコ ン トロール の目的で開発者の権限を制限したい場合もあり、セキュリティと生産性はしばしば競合する。このドキュメントでは開発者の生産性を損なうことなく、大半のセキュリティに関する ユースケース を満たすだろう推奨事項を紹介する。 <感想> CDKに限らず、組織内のセキュリティ施策が開発を阻害するものとして捉えられる傾向があるのは、セキュリティ担当と開発担当で見ている景色が違うからだろうと思います。セキュリティ担当は最悪の事態を想像して対策を提示するのに対して、開発担当は普段の日々の開発を楽にすることにより価値を置きます。セキュリティ担当の立場としては、開発担当の気持ちを理解し、 原理主義 にならずに対話型でセキュリティ対策を考える状態を目指したいと考えています。ちなみに筆者が所属するセキュリティを担当するグループでは、開発側の気持ちを理解する方法の一つとして自ら社内向けに システム開発 も行っています。 CDKのデプロイではどのような権限を使うべきか <ざっくり要約> 権限付与の方法は一般的に、許可リスト方式と拒否リスト方式の2種類ある。 CDK/CloudFormationにおいては ロールバック もあり、許可リストでは最小権限を網羅するのは難しい。 AWS Config, AWS CloudTrail, AWS Security Hub, AWS CloudFormation Hooksなどによってガードレール、 コンプライアンス ルール、監査、モニタリングを実施した上で、それらを変更する以外の全ての権限を付与する拒否リスト方式の方が推奨される。 コンプライアンス に適合する範囲で開発者に自由を与えることができる。 <感想> IaCの経験がある方であれば、許可リスト方式での権限付与は厳しいことはよく分かると思います。特に CDK/CloudFormation における ロールバック は Terraform にはない特徴の一つなので、権限付与に限らず、CDKを使うときはそれを意識するのが良いでしょう。 権限昇格することなくIAMロールの作成を許可する <ざっくり要約> CDKでリソースをデプロイするときは、デフォルトで最小権限になるように必要なIAMロールを自動作成する。手動でロールを作らずに、このデフォルトの挙動に任せるのが推奨である。 アプリ開発 者にロールを作成させない運用ルールがある場合、その目的は主に開発者の権限昇格を防ぐことである。権限昇格を防ぐ代替手段としてPermissions boundary(アクセス許可境界)とSCP(サー ビスコ ン トロール ポリシー)がある。開発者のロールにPermissions boundaryをアタッチすることで、開発者自身の権限と、開発者のロールが作成するロールの権限両方を制限できる。 <感想> IAMロールやポリシーはIaCで作る他のリソースを参照するため、手動で管理せずにIaCの開発サイクルに含めた方が管理しやすいのは納得できる説明です。 CDKでインフラをデプロイすると、いつの間にかたくさんのIAMロールが作られていて把握しきれないと感じていましたが、そもそも人間が把握できる程度のシンプルさでは最小権限は実現できていないのだろうと説明を読んで思いました。 CDKデプロイで使われる権限の管理 <ざっくり要約> CDKはCloudFormationを使って変更をデプロイする。 デプロイを開始するアクター(ユーザーか自動化システム)はIAM アイデンティティ (ユーザーかロール)を持ち、それとは別にデプロイを実行する CloudFormation にもロールが与えられる。 スタックデプロイ時にCDKが使用するロールとアセットコンテナ(後述)は、Stack Synthesizer が決定する。 <感想> cdk deploy を実行する時の権限と、実際に CloudFormation がリソースをデプロイする時の権限は分けられることが書いてあります。これも Terraform と比較した時の CDK の特徴ですね。意識的に2つの権限を区別して考えるとこの後の説明が理解しやすいと思います。 Stack Synthesizer については DefaultStackSynthesizer と CliCredentialsStackSynthesizer の2種類の説明がこの後に続きます。 DefaultStackSynthesizer デプロイのフロー <ざっくり要約> DefaultStackSynthesizer は CDK v2 のデフォルトのStack Synthesizerであり、基本的にはこれを使うことになる。 CDKによるデプロイは次のフローの通りである CDKデプロイを開始するアクターの AWS 権限を認可する CDKデプロイを開始するアクターは「CDKデプロイロール」を引き受け(AssumeRole)、「CDKデプロイロール」は「CFN実行ロール」をCloudFormationに渡す(PassRole)。 「CFN実行ロール」は CloudFormationサービスロール で、スタックをデプロイする時にCloudFormationに利用される これ以降、デプロイに使われるのはデプロイを開始したアクターの権限ではなく、「CFN実行ロール」の権限になる 必要に応じてCDKデプロイを開始したアクターは「file-publishing-role」「image-publishing-role」「lookup-role」をそれぞれ引き受ける(AssumeRole) 「file-publishing-role」と「image-publishing-role」は、デプロイで使われるファイルとDockerイメージをS3 バケット とECR リポジトリ にプッシュする時に使われる。ここのS3 バケット とECR リポジトリ はbootstrap時に作られたものである。「CFN実行ロール」にはこれらのアセットを参照する権限が必要である 「lookup-role」はCDKのsynth時に既存のリソースを参照する場合に使われる。デフォルトではReadOnly管理ポリシーが付与されている (図は https://github.com/aws/aws-cdk/wiki/Security-And-Safety-Dev-Guide より) <感想> 「CDKデプロイを開始するアクターの権限」「CDKデプロイロール」「CFN実行ロール」「file-publishing-role」「image-publishing-role」「lookup-role」と権限が6種類登場しています。 「CDKデプロイを開始するアクターの権限」はCDKを利用する前に手動で作成するもので、「CDKデプロイロール」「file-publishing-role」「image-publishing-role」「lookup-role」の4つをAssumeRoleできれば良いです。すなわち、 cdk deploy を実行する時の権限は AdministratorAccess である必要はありません。 「CDKデプロイロール」「CFN実行ロール」「file-publishing-role」「image-publishing-role」「lookup-role」の5つは cdk bootstrap するときに自動で作成されるもので、手で管理する必要はありません。bootstrapの説明はこの後続きます。 Bootstrap <ざっくり要約> DefaultStackSynthesizer を使うためにはまず AWS 環境を bootstrap する必要がある。bootstrap は各リージョンに一度だけ必要な操作で、Synthesizerに必要なIAMロール群とアセットコンテナ(S3 バケット とECR リポジトリ )が作成される。 cdk boostrap することでCloudFormationスタックがデプロイされる。デフォルトのテンプレートを使うこともできるし、 カスタマイズ することもできる。 コンプライアンス 管理をする場合、bootstrap時のテンプレートをカスタマイズする必要がある。例えばカスタマイズによって「CFN実行ロール」の権限を制限できる(ポリシーの変更、Permission boundaryの追加などによって権限昇格を防ぐ)。デフォルトでは「CFN実行ロール」はAdministratorAccessとなる。 また「CDKデプロイロール」「file-publishing-role」「image-publishing-role」を誰が AssumeRole できるのかを制限することもできる。デフォルトでは同じ AWS アカウントの全ての アイデンティティ が AssumeRole できる。 CDKがbootstrapしたロールを引き受けるためには、以下のポリシー ステートメント を アイデンティティ に追加する(=CDKデプロイを開始するアクターは以下の権限を持てば良い) { " Version ": " 2012-10-17 ", " Statement ": [{ " Sid ": " AssumeCDKRoles ", " Effect ": " Allow ", " Action ": " sts:AssumeRole ", " Resource ": " * ", " Condition ": { " ForAnyValue:StringEquals ": { " iam:ResourceTag/aws-cdk:bootstrap-role ": [ " image-publishing ", " file-publishing ", " deploy ", " lookup " ] } } }] } cdk bootstrap の実行はAdministratorAccessの権限を使うことを推奨する。bootstrapスタックの内容は変わりうるので、将来的に必要な権限は予測できない。またbootstrapによって任意の権限を持った新しいロールが作られるので、bootstrapを実行する権限を制限する実メリットがない。 <感想> cdk bootstrap は CDKToolkit という名前のCloudFormationスタックを作る程度の認識でしたが、実際に何をやっているのかの説明がされていました。デフォルト設定で作成された CDKToolkit スタックを実際に見てみると、確かに説明されていた通りのリソースが作られています。 ECR リポジトリ 「ContainerAssetsRepository」 S3 バケット 「StagingBucket」 CDKデプロイロール「DeploymentActionRole」 CloudFormation、S3、KMSの権限や、CFN実行ロールをPassRoleする権限が付いている aws-cdk:bootstrap-role : deploy リソースタグが付いている CFN実行ロール「CloudFormationExecutionRole」 AdministratorAccess ポリシーが付いている リソースタグは付いていない file-publishing-role「FilePublishingRole」 S3とKMSへの権限が付いている aws-cdk:bootstrap-role : file-publishing リソースタグが付いている image-publishing-role「ImagePublishingRole」 ECRへの権限が付いている aws-cdk:bootstrap-role : image-publishing リソースタグが付いている lookup-role「LookupRole」 AWS 管理の ReadOnlyAccess ポリシーが付いている aws-cdk:bootstrap-role : lookup リソースタグが付いている 注目すべきは、紹介されているポリシー ステートメント ではリソースタグで「CDKデプロイロール」「file-publishing-role」「image-publishing-role」「lookup-role」のAssumeRoleを許可していて、AdministratorAccess を持つ「CFN実行ロール」をAssumeRoleできないようになっている点です。つまりこれを使うことで、「CDKデプロイを開始するアクター」はAdministratorAccess権限をAssumeRoleできません。 (しかし厳密に考えると、「CDKデプロイロール」は CloudFormationスタックを作ることができて、「CFN実行ロール」をPassRoleできるため、CloudFormationに強権限のIAMロールを作らせて然るべきリソースタグを付けることで、「CDKデプロイを開始するアクター」から強権限のロールに最終的にAssumeRoleできるように思います。AssumeRoleを許可する対象リソースはリソースタグではなくロール名で指定した方がより安全でしょう) bootstrapで作成されるリソースは将来的に変わる可能性もあるとのことですが、「CDKデプロイを開始するアクター」がAssumeすべきロールの種類が増えていかないかは気になるところです。 CliCredentialsStackSynthesizer <ざっくり要約> DefaultStackSynthesizer の代わりに CliCredentialsStackSynthesizer を使うことができる。IAMロールをAssumeするのではなく、「CDKデプロイを開始するアクター」の権限を利用する。CloudFormationコールは直接実行され、サービスロールは渡されない。つまり「CDKデプロイを開始するアクター」は bootstrap が本来作成するロールの全ての権限を持つ必要がある。なお --role-arn パラメータを利用することで「CFN実行ロール」を別のロールとすることはできる。 <感想> CliCredentialsStackSynthesizer を使いたいケースがどのような場合があるのか気になります。「CDKデプロイを開始するアクター」(ローカルやデプロイパイプラインに保存するアクセスキー)が強い権限を持つ必要があるので、基本的には DefaultStackSynthesizer の方を使うのが良いのではないでしょうか。 CDK内のIAM アイデンティティ とポリシーを取り扱う <ざっくり要約> CDKにIAMロールとポリシーの作成を任せるのが推奨。もしそれを許可できない場合、事前に人の手で作成し、CDKアプリから参照するようにする。 <感想> CDKデプロイ自体の権限についての説明は終わり、ここからはなじみやすいイン フラリ ソースの権限についてです。 CDKにIAMロールとポリシーの管理を任せる <ざっくり要約> CDKに権限の生成を任せる場合、 grant メソッドを活用するのが良い。例えば暗号化されたS3 バケット からの読み取りをLambda関数に許可する場合、 bucket.grantRead(handler) のように書ける。 import { aws_s3 as s3 , aws_lambda as lambda , aws_kms as kms , Stack , } from 'aws-cdk-lib' ; const stack = new Stack ( app , 'LambdaStack' ); const key = new kms.Key ( stack , 'BucketKey' ); const bucket = new s3.Bucket ( stack , 'Bucket' , { encryptionKey: key , } ); const handler = new lambda. Function ( stack , 'Handler' , { runtime: lambda.Runtime.NODEJS_16_X , handler: 'index.handler' , code: lambda.Code.fromAsset ( path.join ( __dirname , 'lambda-handler' )), } ); bucket.grantRead ( handler ); handler.addToRolePolicy() でLambda関数に直接権限を与えることもできるが、 grant メソッドが使える場合はそれが推奨される。 <感想> CDKには明示的に権限を付与しなくても、(なるべく)最小権限を自動で付与される方法が多く用意されています。例のS3 バケット の grantRead では、以下の権限がLambda関数の実行ロールに付与されます。 対象 バケット への s3:GetObject* 対象 バケット への s3:GetBucket* 対象 バケット への s3:List* 対象 バケット が利用するKMSキーへの kms:Decrypt 対象 バケット が利用するKMSキーへの kms:DescribeKey もしLambda関数が GetObject しか実行しない場合、 GetBucket* や List* の権限も付与されているので厳密には最小権限ではありませんが、読み取りしか許可されていない意味では気になる状況は少ないでしょう。 grand メソッドの名前だけでは具体的に付与される権限が分からなかったりするので、メソッドの説明などで確認すると良いでしょう。例えば現状、DynamoDBテーブルのコンスト ラク トには grantReadWriteData メソッドが用意されており、実際に付与される権限がメソッドの説明で分かります。 アイテムをPutするだけで、Deleteする権限を与えたくない場合もあるかと思いますので、そのような時は addToRolePolicy などを使うことになります。 事前に手動で作成したロールを利用する <ざっくり要約> CDKでIAMロールとポリシーの作成が許可されていない場合、事前に手動で作成し、 Role.fromRoleName() で参照する。 あるいは Role.customizeRoles() を利用して、CDKアプリに必要となる全てのロールとポリシーを実際に作成せずに、レポートとして書き出してIAMロールを管理する担当者に連携することができる。 const stack = new Stack(app, 'LambdaStack'); // ロールのsynthをしないようにこれを追加する iam.Role.customizeRoles(stack); // 以下のコードは同じ const key = new kms.Key(stack, 'BucketKey'); const bucket = new s3.Bucket(stack, 'Bucket', { encryptionKey: key, }); const handler = new lambda.Function(stack, 'Handler', { runtime: lambda.Runtime.NODEJS_16_X, handler: 'index.handler', code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), }); // 権限が必要であることをCDKに教えるため、通常通り grantRead() などは必要 bucket.grantRead(handler); 人の手によってロールが作成されたら、そのロール名を customizeRoles に追加することでCDKで利用できるようになる。 const stack = new Stack ( app , 'LambdaStack' ); iam.Role.customizeRoles ( stack , { usePrecreatedRoles: { 'LambdaStack/Handler/ServiceRole' : 'lambda-service-role' , } , } ); <感想> customizeRoles はCDK v2.51.0でリリースされた機能です。IAM権限を開発者が自由に作成できないような環境では役に立ちそうです。 Permissions boundary と SCP <ざっくり要約> セキュリティガードレールのためにPermissions boundaryを使うことができる。 権限昇格を防ぐために、同じPermissions boundaryを含まないようなユーザーやロールを作ることを禁止できる。 cdk bootstrap で --custom-permissions-boundary フラグを追加することで、「CFN実行ロール」にPermissions boundaryをアタッチできる。 CDKアプリ内で作るロールにPermissions boundaryをアタッチする場合は以下のとおりになる。 const stack = new Stack ( app , 'MyStack' ); new iam.Role ( stack , 'Role' , { assumeRolePolicy: new iam.ServicePrincipal ( 'lambda.amazonaws.com' , permissionsBoundary: iam.ManagedPolicy.fromManagedPolicyName ( `cdk- ${ stack.synthesizer.bootstrapQualifier } -permissions-boundary- ${ stack.account } - ${ stack.region } ` ); } ); cdk.json にてグローバルで設定もできる。 { " context ": { " @aws-cdk/core:permissionsBoundary ": { " name ": " cdk-permissions-boundary " } } } App や Stage レベルで設定もできる。 <感想> Permissions boundary をCDKで利用する方法について詳細に書かれていました。 --custom-permissions-boundary フラグは CDK v2.54.0 に追加された機能 です。 ざっくり要約をさらに要約 CDKのデプロイに与える権限は許可リストではなく、拒否リストが推奨である IAMロールは手動で作るのではなく、CDKの自動作成に任せるのが推奨である 開発者の権限昇格を防ぎたい場合、Permissions boundary(アクセス許可境界)とSCP(サー ビスコ ン トロール ポリシー)を利用する bootstrap 時のCloudFormationテンプレートをカスタマイズする cdk bootstrap はAdministratorAccessの権限で行う 基本的に cdk deploy にAdministratorAccessは必要なく、bootstrapで作成された4種類のIAMロールをAssumeRoleできれば良い CDKに権限の生成を任せる場合、なるべく grant メソッドを利用する Role.customizeRoles() を利用することで、CDKデプロイせずに必要となる権限一覧をレポート出力できる お読みいただいてありがとうございました。 私たちは同じチームで働いてくれる仲間を大募集しています!たくさんのご応募をお待ちしています。 セキュリティエンジニア(セキュリティ設計) 執筆: @kou.kinyo 、レビュー: @wakamoto.ryosuke ( Shodo で執筆されました )
アバター
X イノベーション 本部デジタルエンゲージメントセンターの橋詰です。普段は Salesforce (Financial Services Cloud)を利用した システム開発 を金融機関のお客様向けに行っています。2022年12月に業務の一環でScrum Allienceの認定 スクラム プロダクトオーナー研修を受講してきたので簡単なレポートをお届けします。 受講の動機 何を受講したの? 印象的だったのはプロダクトオーナーの振る舞い方 もっと勉強したいのはトヨタ生産方式のこと おわりに 受講の動機 ここ数年金融ソリューション事業部において アジャイル 開発を普及するお仕事をしていました。主に開発事例を収集したり、 ガイドライン を作成したり、新人さん向けに アジャイル 開発に関する研修(これは後日記事にするつもりです)を実施したりしています。 現在は CRM / SFA システムを構築するプロジェクトを担当しており、システム全体を構築するミッションに加えて、お客様側の開発チームを支援するミッション(Scrumで開発しているチームの内製化支援を実施)も持っています。絵にすると下記のようなイメージで、私は左側の本体開発チームのPMを担当しています。 またこれ以外にもサイドワークとして新規事業でプロダクトを開発中であり、プロダクトオーナーチームの一員として活動しています。これまではどちらかというと開発者よりの立場が多かったため スクラム マスターとしての知識を主に身につけようとしていました。ただ最近はプロダクトオーナー側の知識が必要になりつつあり、研修で補完しようと思ったことが受講の動機です。 何を受講したの? 以前にScrum Allienceの認定資格を取得していることから、今回もScrum Allienceのコース(オンライン セミ ナー:認定 スクラム プロダクトオーナー)を選択しました。 アギレルゴコンサルティング 社が主催するト レーニン グを受講しました。アギレルゴさんは継続的かつ定期的に スクラム マスター・ デベロッパ ー・プロダクトオーナー等の研修コースを提供してくださるので、比較的研修計画を立てやすくいつも助かっています。 講師は「組織パターン」や「A Scrum Book」で有名なJames Coplienさんです。Zoomによる研修で、1日4時間(14-18時)×4日間の講義を受けます。英語での講義になりますが、同時通訳がつくため日本語での参加も問題ないです。 なお研修の費用は22万円でしたが、全額会社の教育費で受講しました。私は自部署の教育費で受講しましたが、これ以外にも、年に1度全社的に受講者の募集もあります。そのほかの資格で セミ ナー等の受講が必要な場合も同様の仕組みで受講できるため、エンジニアの育成に力を入れてくれているなとよく思います。 印象的だったのはプロダクトオーナーの振る舞い方 合計16時間の講義があるため内容は盛りだくさんです。わたしが特にこの研修で刷り込まれたのは、プロダクトオーナーの振る舞い方です。 プロダクトオーナーのもっとも重要なことは、顧客へ届けたい価値(作りたいもの)を開発者のみなさんの脳みそに刻み込むこと。そのために(プロダクト担当の)ミニCEOとしてあらゆる手段と ステークホルダー の力を駆使して準備を密度濃く実施すること。 これに尽きます。個人的にはこの説明でとても霧が晴れたと感じました。以前まではどちらかというと、プロダクト バックログ アイテムを分かりやすく表現するにはどういう手法やツールがあるのだろうか…と悩むことが多かったのですが意識する方向性が間違ってました。あまりにしっくりきたため、研修の翌日にプロダクトオーナー向けのちょっとした社内研修をしたのですが、この気持ちをくどくどと説明していました😅 もっと勉強したいのは トヨタ生産方式 のこと コプリエンさんが担当する研修の特徴の一つかもしれませんが、 トヨタ や製造業に関する考え方がたくさん出てきます。私の担当するお客様の業種は金融機関が多いため、仕事で製造業の知識に触れる機会は少ないです。 アジャイル やLeanの文脈で自習的に学ぶことはありましたが、コプリエンさんの説明を聞いていると脇が甘かったなと反省しました。今後自分としても継続的に学んでいく対象としたいなと思いました。例えば下記のような言葉や考え方です。 - プロダクトの主査 - 5ゲン主義(現場・現物・現実・原理・原則という5つの視点) - 3つのM(ムリ・ムダ・ムラ)などのLeanの考え方 - スウォーミング(モブ)、あんどん、1個流しなどの TOC (制約理論)につながる話 特に5ゲン主義は図らずも自分が大切にしている考え方なので、2023年はより深堀したいです。 おわりに 研修を受けた結果いつもとは違うまなざしを得られたことはとてもためになりました。学んだことを実業でも活かしていきたいです。 さて、私が所属するデジタルエンゲージメントセンターではたくさんの 中途採用 を行っています。さまざまなプロジェクトがあり、 アジャイル 開発に関する認定資格は必須ではありませんがお持ちの方も大歓迎です。下記に採用リンクも貼っておりますので、ぜひご参考にしてください。 一緒に働いてくれる仲間を募集しています!下記以外にも多くの募集を行っていますので、ぜひ採用サイトもご覧ください。 【全社集約】CRMソリューションコンサルタント 執筆: @hashizume.hideki 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
アバター
X イノベーション 本部デジタルエンゲージメントセンターの橋詰です。普段は Salesforce (Financial Services Cloud)を利用した システム開発 を金融機関のお客様向けに行っています。2022年12月に業務の一環でScrum Allienceの認定 スクラム プロダクトオーナー研修を受講してきたので簡単なレポートをお届けします。 受講の動機 何を受講したの? 印象的だったのはプロダクトオーナーの振る舞い方 もっと勉強したいのはトヨタ生産方式のこと おわりに 受講の動機 ここ数年金融ソリューション事業部において アジャイル 開発を普及するお仕事をしていました。主に開発事例を収集したり、 ガイドライン を作成したり、新人さん向けに アジャイル 開発に関する研修(これは後日記事にするつもりです)を実施したりしています。 現在は CRM / SFA システムを構築するプロジェクトを担当しており、システム全体を構築するミッションに加えて、お客様側の開発チームを支援するミッション(Scrumで開発しているチームの内製化支援を実施)も持っています。絵にすると下記のようなイメージで、私は左側の本体開発チームのPMを担当しています。 またこれ以外にもサイドワークとして新規事業でプロダクトを開発中であり、プロダクトオーナーチームの一員として活動しています。これまではどちらかというと開発者よりの立場が多かったため スクラム マスターとしての知識を主に身につけようとしていました。ただ最近はプロダクトオーナー側の知識が必要になりつつあり、研修で補完しようと思ったことが受講の動機です。 何を受講したの? 以前にScrum Allienceの認定資格を取得していることから、今回もScrum Allienceのコース(オンライン セミ ナー:認定 スクラム プロダクトオーナー)を選択しました。 アギレルゴコンサルティング 社が主催するト レーニン グを受講しました。アギレルゴさんは継続的かつ定期的に スクラム マスター・ デベロッパ ー・プロダクトオーナー等の研修コースを提供してくださるので、比較的研修計画を立てやすくいつも助かっています。 講師は「組織パターン」や「A Scrum Book」で有名なJames Coplienさんです。Zoomによる研修で、1日4時間(14-18時)×4日間の講義を受けます。英語での講義になりますが、同時通訳がつくため日本語での参加も問題ないです。 なお研修の費用は22万円でしたが、全額会社の教育費で受講しました。私は自部署の教育費で受講しましたが、これ以外にも、年に1度全社的に受講者の募集もあります。そのほかの資格で セミ ナー等の受講が必要な場合も同様の仕組みで受講できるため、エンジニアの育成に力を入れてくれているなとよく思います。 印象的だったのはプロダクトオーナーの振る舞い方 合計16時間の講義があるため内容は盛りだくさんです。わたしが特にこの研修で刷り込まれたのは、プロダクトオーナーの振る舞い方です。 プロダクトオーナーのもっとも重要なことは、顧客へ届けたい価値(作りたいもの)を開発者のみなさんの脳みそに刻み込むこと。そのために(プロダクト担当の)ミニCEOとしてあらゆる手段と ステークホルダー の力を駆使して準備を密度濃く実施すること。 これに尽きます。個人的にはこの説明でとても霧が晴れたと感じました。以前まではどちらかというと、プロダクト バックログ アイテムを分かりやすく表現するにはどういう手法やツールがあるのだろうか…と悩むことが多かったのですが意識する方向性が間違ってました。あまりにしっくりきたため、研修の翌日にプロダクトオーナー向けのちょっとした社内研修をしたのですが、この気持ちをくどくどと説明していました😅 もっと勉強したいのは トヨタ生産方式 のこと コプリエンさんが担当する研修の特徴の一つかもしれませんが、 トヨタ や製造業に関する考え方がたくさん出てきます。私の担当するお客様の業種は金融機関が多いため、仕事で製造業の知識に触れる機会は少ないです。 アジャイル やLeanの文脈で自習的に学ぶことはありましたが、コプリエンさんの説明を聞いていると脇が甘かったなと反省しました。今後自分としても継続的に学んでいく対象としたいなと思いました。例えば下記のような言葉や考え方です。 - プロダクトの主査 - 5ゲン主義(現場・現物・現実・原理・原則という5つの視点) - 3つのM(ムリ・ムダ・ムラ)などのLeanの考え方 - スウォーミング(モブ)、あんどん、1個流しなどの TOC (制約理論)につながる話 特に5ゲン主義は図らずも自分が大切にしている考え方なので、2023年はより深堀したいです。 おわりに 研修を受けた結果いつもとは違うまなざしを得られたことはとてもためになりました。学んだことを実業でも活かしていきたいです。 さて、私が所属するデジタルエンゲージメントセンターではたくさんの 中途採用 を行っています。さまざまなプロジェクトがあり、 アジャイル 開発に関する認定資格は必須ではありませんがお持ちの方も大歓迎です。下記に採用リンクも貼っておりますので、ぜひご参考にしてください。 一緒に働いてくれる仲間を募集しています!下記以外にも多くの募集を行っていますので、ぜひ採用サイトもご覧ください。 【全社集約】CRMソリューションコンサルタント 執筆: @hashizume.hideki 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
アバター
こんにちは!金融ソリューション事業部の孫です。 ゲームが好きなみなさま、クライアント・サーバーモデルの マルチプレイ ゲームの制作に興味を持っていますか? 本記事では、熱意を持っていますが「難しそう・・・どうやって始めたらいいんだろうか、ゲームサーバーの構築はどうすればいいのか」という状況の読者向けに開発を体験するのハンズオンを紹介します。 皆さまの熱い気持ちを早く形にするため、 AWS が提供する マルチプレイ ーゲーム用の クラウド サーバー管理サービスである Amazon GameLiftと ゲームエンジン であるUnreal Engines5を使用し、オンライン マルチプレイ 環境を構築する最低限の手順でご紹介します。 注意事項 本記事では以下の操作が行えることと、環境が整っていることを前提としています。 AWS のマネジメントコンソールの使用 対話型シェルの使用 Unreal Engine の利用とプロジェクトのビルド また、本検証を行う場合、使用する AWS の利用料金が発生する点に注意してください。 Amazon GameLiftとは 冒頭でも紹介した通り、 Amazon GameLift (以下 GameLift ) は、 マルチプレイ 環境に必要なサーバー側のゲームアプリケーションならびにその実行環境を管理するサービスです。 本来、 マルチプレイ 用ゲームサーバーの構築にあたり、プレイヤーアカウントの作成、プレイヤー認証、プレイヤーマッチング、プレイヤーのスコアなど様々な要素を同時に検討する必要がありますが、GameLiftの採用によってそれらの手間が要らなくなって以前より実装するハードルが下がってきています。 GameLiftを利用した開発の流れは、以下図のように4stepがあります。とてもシンプルにゲームの開発ができます。 更にクライアント側で専用の SDK を使用することで接続管理やメッセージの送受信を手軽に実装することが可能となっています。本記事では、GameLiftSDKの組込みでオンライン マルチプレイ 環境を実現しました。 Unreal Engine5 とは Unreal Engine は、 Epic Games によって開発されている ゲームエンジン です。 そもそも、 ゲームエンジン が何かというと簡単に言うとゲームを作るためのソフトです。 ゲームエンジン を使用することで、ゲームを作るためのツールや環境が準備された状態でゲーム制作をすることができます。いわゆる、0からプログラミングをしなくて済みます。 Unreal Engine の特徴として、下記のようなものが挙げられます。 無料で使用できる ソースコード が公開されている プログラミングなしでもコンテンツ制作ができる グラフィックスが断トツで高品質 高品質なアセットが無料、有料ともに豊富 更に近年 メタバース による変革がリアルタイムの 3D技術が強く求められています。 Unreal Engine によって高品質な VR コンテンツの制作が可能になります。 Unreal Engine5(以下 UE5 )は Unreal Engine の最新バージョンです。 実施手順 手順は、以下の通りです。 UE5 ソースコード のビルド UE5テンプレートからゲームサーバーを作成する GameLiftSDKをビルドし プラグイン を生成する ゲームサーバーにGameLift プラグイン の組込み ローカルでゲームのテスト及びGameLiftへのアップロード AWS CLI コマンドによるゲームセッション作成と接続 AWS アーキテクチャ 本記事では、 マルチプレイ ゲーム開発を体験することのみに注力し、以下の通りほぼGameLiftのみを利用して構築します。 ※Lambda、 API Gateway 、Cognitoに構築については別記事でご紹介します。 使用環境/ツール Unreal Engine 5.1.0 windows10 21H2 x64 RAM 16GM, SSD 1TB NVIDIA GeForce GTX 980M Gamelift SDK GameLift Cpp ServerSDK 3.4.2 GameLift Unreal plugin 3.4.0 Visual Studio 2019 version 16.11.21(以下VS2019) JavaSDK 1.8.0 手順1. UE5 ソースコード のビルド Unreal Engine の公式 GitHub リポジトリ より、 Unreal Engine ソースをクローンして コンパイル します。 クローン: git clone https://github.com/EpicGames/UnrealEngine.git コンパイル : UnrealEngineフォルダに移動 Setup.batをダブルクリックして実行 GenerateProjectFiles.batをダブルクリックして実行 UE5.slnをクリックしてVS2019で開いて以下の図の通りにビルド実行 ※ Unreal Engine の リポジトリ へのアクセスは、権限が必要なので、済ではない方は、 SignUp の手順に従ってアクセス権限を設定してください。 ※ビルド時間はマシンのスペックによるが、参考までに、 Epicの推奨スペック の情報があります(ビルド時間を短縮するため、最低限は500GB SSD 、16GB RAMをおすすめします)。 手順2.UE5テンプレートからゲームサーバーを作成する 手順1で無事にUE5のビルドが完了後、「Local Windows Debugger」をクリックして Unreal Editorを立ち上げます。 ※Configure情報は以下であることを確認して Unreal Editorを立ち上げてください。 Unreal Editorの画面から「 ゲーム 」⇒ 「 サードパーソン 」⇒「 C++ 」⇒「 新プロジェクト名入力 」(今回は、プロジェクト名を「Gamelift_UE5」としました)でゲームサーバーのプロジェクトを作成します。 プロジェクト作成完了後、vs2019と Unreal Editorをクロースしてプロジェクトフォルダに移動します。 SourceフォルダのGamelift_UE5Editor.Target.csファイルを複製して、ゲームサーバー用の Gamelift_UE5Server.Target.cs ビルドファイルを作成します。 任意の テキストエディタ でGamelift_UE5Server.Target.csを開いて、「Editor」⇒「Server」を書き換えます プロジェクトフォルダに戻して、プロジェクトファイルを右クリックし「Generate Visual Studio project files」でプロジェクトを再生成します プロジェクトフォルダの Gamelift_UE5.sln ファイルをクリックし、VS2019を立ち上げます、そこで先ほど新規追加したゲームサーバー用のプロジェクトファイルが見えることを確認します プロジェクトをビルドします プロジェクトを再ビルドして後、 Gamelift_UE5.uproject をクリックして Unreal Editorを立ち上げます クライアントがゲームサーバーとの接続に成功したかを判別するため、"ゲームサーバー接続前の「オフラインマップ」"と"接続後の「オンラインマップ」"を別々に作成します(既存のマップの複製で作成) プロジェクトの「マップ&モード」でマップの利用ルールを設定します(「サーバーのデフォルトマップ」を、先ほど複製して作成したレベルに変更します) パッケージ化の時に、作成したマップを含まれるように、「パッケージ化」で「マップのパス」を設定します。 Windows 向けにプロジェクトをパッケージ化します バイナリコンフィグレーション:開発 ビルドターゲット: Gamelift_UE5Server ※パッケージ化の所要時間はマシンのスペックによります。 手順3.GameLiftSDKをビルドし プラグイン を生成する ※GameLiftSDK開発ドキュメントのセットアップ要件で、現在 UE4 .25のみの対応となっておりますが、筆者の検証によってUE5も利用可能です!ただし、ビルド用 Visual studio はVS2019を推奨します(筆者はVS2022のビルドでエラーだらけになった)。 GameLiftサーバーSDK から、GameLift Managed Servers SDK をダウンロードします。 CMDでダウンロード先のフォルダに移動して、以下のコマンドでビルドを実施します。 mkdir out cd out cmake -G "Visual Studio 16 2019" -A x64 -DBUILD_FOR_UNREAL=1 .. msbuild ALL_BUILD.vcxproj /p:Configuration=Release ※ビルドにあたり、VS2019のmsvc C++ ツールのバージョンがVS2017と違うのが原因で、以下のエラーが発生します。 msvc initialization: parameter version inconsistent 本エラーは、GameLift-Cpp-ServerSDK-3.4.2\out\thirdparty\boost配下のproject-config.jamにmsvcのバージョンを指定することで解決できます。 using msvc : 14.0 ; 無事にビルドが終わりましたら、生成したDLLとLibファイル out\prefix\bin\aws-cpp-sdk-gamelift-server.dll out\prefix\lib\aws-cpp-sdk-gamelift-server.lib を、 プラグイン のフォルダ(以下はパス)に複製して、セットアップが完了となります。 GameLift-SDK-Release-4.0.2\GameLift-Unreal-plugin-3.4.0\GameLiftServerSDK\ThirdParty\GameLiftServerSDK\Win64 手順4.ゲームサーバーにGameLift プラグイン の組込み UE5のプロジェクトルートフォルダの配下に「 Plugins 」フォルダを新規作成し、手順3でセットアップ完了した プラグイン をそこに移動します プロジェクトフォルダの Gamelift_UE5.sln ァイルをクリックし、VS2019を立ち上げて、 プラグイン をインポートします 以下の プラグイン 定義をゲームの Gamelift_UE5.uproject ファイルに追加します { "Name": "GameLiftServerSDK", "Enabled": true } b. Gamelift_UE5.Build.csファイルに プラグイン 名「 GameLiftServerSDK 」をゲームリストに依存関係として追加します c. 以下のGameLift を使用して Unreal Engine ゲームサーバーを初期化するコードを「 Gamelift_UE5GameMode.cpp 」に追加します #if WITH_GAMELIFT //Getting the module first. FGameLiftServerSDKModule* gameLiftSdkModule = &FModuleManager::LoadModuleChecked<FGameLiftServerSDKModule>(FName("GameLiftServerSDK")); //InitSDK establishes a local connection with GameLift's agent to enable communication. gameLiftSdkModule->InitSDK(); //Respond to new game session activation request. GameLift sends activation request //to the game server along with a game session object containing game properties //and other settings. Once the game server is ready to receive player connections, //invoke GameLiftServerAPI.ActivateGameSession() auto onGameSession = [=](Aws::GameLift::Server::Model::GameSession gameSession) { gameLiftSdkModule->ActivateGameSession(); }; FProcessParameters* params = new FProcessParameters(); params->OnStartGameSession.BindLambda(onGameSession); //OnProcessTerminate callback. GameLift invokes this before shutting down the instance //that is hosting this game server to give it time to gracefully shut down on its own. //In this example, we simply tell GameLift we are indeed going to shut down. params->OnTerminate.BindLambda([=](){gameLiftSdkModule->ProcessEnding();}); //HealthCheck callback. GameLift invokes this callback about every 60 seconds. By default, //GameLift API automatically responds 'true'. A game can optionally perform checks on //dependencies and such and report status based on this info. If no response is received //within 60 seconds, health status is recorded as 'false'. //In this example, we're always healthy! params->OnHealthCheck.BindLambda([](){return true; }); //Here, the game server tells GameLift what port it is listening on for incoming player //connections. In this example, the port is hardcoded for simplicity. Since active game //that are on the same instance must have unique ports, you may want to assign port values //from a range, such as: //const int32 port = FURL::UrlConfig.DefaultPort; //params->port; params->port = 7777; //Here, the game server tells GameLift what set of files to upload when the game session //ends. GameLift uploads everything specified here for the developers to fetch later. TArray<FString> logfiles; logfiles.Add(TEXT("aLogFile.txt")); params->logParameters = logfiles; //Call ProcessReady to tell GameLift this game server is ready to receive game sessions! gameLiftSdkModule->ProcessReady(*params); #endif d.GameLiftServerSDKのヘッドフォルダ(Plugins\GameLiftServerSDK\Source\GameLiftServerSDK\Public)をビルドのincludeパスに追加します。 e. UE5プロジェクトをビルドします 3. UE5プロジェクトのルートフォルダに戻して Gamelift_UE5.uproject をクリックして Unreal Editorを立ち上げます、「Edit」⇒「Plugins」をクリックして、GameLiftSDK プラグイン にチェックが入っていることを確認します 手順5.ローカルでゲームのテスト及びGameLiftへのアップロード ここまでは、UE5ゲームサーバーの開発とGameLiftSDKの組込みは全部完了しました。 GameLiftへゲームサーバーをプッシュする前に、一応ローカルで次の点を確認します。 ゲームサーバーが Server SDK と正常に統合されるか ゲームクライアントは新しいゲームセッションのスタート、プレイヤーのゲームへの参加、ゲームセッションへのConnectができるか 確認完了後に、以下の手順でGameLiftへアップロードを実施する CMDでGameLiftローカルのセットアップ cd {gameliftSDKダウンロード先}\GameLiftLocal-1.0.5 java -jar GameLiftLocal.jar -p 9080 ゲームサーバーを起動します 手順2でパッケージ化したゲームサーバーフォルダに移動します ゲームサーバーのログを出力したいため、起動exeのショットカットを作成して、 リンク先の後ろに「-log」を追加します ショットカットをクリックして、ゲームサーバーを起動します UE5プロジェクトのルートフォルダに戻して、 Gamelift_UE5.uproject をクリックして Unreal Editorを立ち上げます、 をクリックして、出た画面でプレイヤー数を2に設定して でクライアントを起動します CMDでゲームセッションを作成します AWS gamelift describe-game-sessions --endpoint-url http://localhost:9080 --fleet-id fleet-123 AWS gamelift create-game-session --endpoint-url http://localhost:9080 --maximum-player-session-count 2 --fleet-id fleet-1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d クライアントからゲームサーバーに接続してみます。 クライアントで **~** キーを押して、 コマンドライン が表示されます、そこにローカルホストIP( 127.0.0.1 )を入力すれば、上記作成したゲームルームに入ります ※下記の図ではメモリ不足に関するエラーが発生していますが、検証に影響はないため無視して進めます。 接続確認します ローカルの検証はできたので、ここから AWS 側で必要なリソースを作成します。 GameLift側で起動用 スクリプト 作成 手順2でパッケージ化したゲームサーバーフォルダに移動します その配下にinstall.batを配置します、以下は中身です。 Engine\Extras\Redist\en-us\UEPrereqSetup_x64.exe /install /quiet /norestart /log c:\game\UE5PrereqSetup.log 以下の aws コマンドでゲームサーバーをGameLiftへアップロードします ※ AWS の基本的な知識(IAMアカウント作成、 aws cli セットアップなど)の説明は割愛いたします。 operating-system: ゲームサーバーの稼働OS(筆者はwindows2012を採用します) build-root: 手順2で作ったパッケージのパス name: GameLiftでの表示名 build-version: バージョン定義 region: AWS のリージョン名 aws gamelift upload-build \ --operating-system WINDOWS_2012 \ --build-root "E:\UnrealBuilds\WindowsServer" \ --name "gamelift-Unreal-engine" \ --build-version "0.01" \ --region ap-northeast-1 aws consoleにログインして、GameLiftに開いてアップロードしたゲームサーバーを確認します。 ビルド数の隣に「 フリートを作成する 」をクリックしてGameLiftのFleetを作成します。 名前: Fleet名 フリートタイプ: オンデマンド 証明書タイプ: 無効 バイナリ型: ビルド ビルド: 上記2でアップロードしたゲームサーバーを選択する インスタンス タイプ: 無料のタイプでより ロケーション管理: 日本のリージョン プロセス管理 起動パス: Gamelift_UE5\Binaries\ Win64 \Gamelift_UE5Server.exe 同時プロセス: 1 EC2ポート設定 ポート範囲: 7777 プロトコル : UDP IPアドレス 範囲: 0.0.0.0/0 その他デフォルト値でよい 数十分ほど待つとフリートが完成します。こちらは以下マネジメントコンソールのページからも確認することができます。 ここまでで、GameLift側の構築は完了となります。 手順6. AWS CLI コマンドによるゲームセッション作成と接続 まず マルチプレイ を始めるにあたって、プレイヤーが集合するためのルーム、つまりGameLiftのゲームセッションを作成する必要があります(以降、ゲームセッションとして記載します)。次に、ゲームに接続するプレイヤーは、ゲームルームの「 IPアドレス 」を指定し、ゲームに参加することができます。 本来であれば、冒頭の AWS アーキテクチャ 図のように別途APIGatewayとlambdaを用意し、ユーザー認証を実施した上でGameLiftへ接続するなどセキュリ ティー を考慮する必要がありますが、今回は検証のため AWS CLI を用いたコマンドベースで接続します。 ゲームセッション作成 以下のコマンドを、手順5で作成したフリートのIDを取得し変数として設定してください(マネジメントコンソールのフリートの一覧ページから作成したフリート ID の確認が可能) aws gamelift create-game-session --fleet-id fleet-5f14fed2-30d6-4314-9220-47a261a9e6ee --maximum-player-session-count 2 aのコマンドを実行しフリートにゲームセッションを作成します。 ゲームクライアントの起動とゲームサーバーへの接続 ローカル検証する時と同様に、 Unreal Editorで をクリックして、出た画面でプレイヤー数を2に設定して でクライアントを起動します。 クライアントで **~** キーを押して、 コマンドライン が表示されます、そこに「open IPアドレス 」と入力することでゲームサーバーへ接続できます。 うまく接続できない場合、まずは以下の点を確認してみてください。 クライアント側OSやプロキシなどのネットワークの経路上で接続をブロックしている設定がないか確認する GameLiftのフリートではEC2 ポート設定が反映できたか確認する 終わりに 今回、UE5とGameLiftを利用し、オンライン マルチプレイ ゲームの構築する方法をご紹介しました。 冒頭で記載した通り、 メタバース においてよりよい没入感を実現するため、高精細なリアルタイム レンダリング が必要でこの辺はUnrealEngineの強みだと思います。 また、 メタバース 上でユーザーは「 SecondLife 」として生活していく上、運営側は大規模大人数同時オンライン可能のサーバーサイドの構築は不可欠で、今後ゲームサーバー技術の活用は増えていくと思われます。 そのため、引き続きゲーム領域のサーバーサイド技術をウォッチしていきたいと思います。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ(Web3/メタバース/AI) 参考 Amazon GameLift Developer Guider Unreal Engine5.1 Documentation GitHub aws-gamelift-samples 執筆: @chen.sun 、レビュー: @wakamoto.ryosuke ( Shodo で執筆されました )
アバター
こんにちは!金融ソリューション事業部の孫です。 ゲームが好きなみなさま、クライアント・サーバーモデルの マルチプレイ ゲームの制作に興味を持っていますか? 本記事では、熱意を持っていますが「難しそう・・・どうやって始めたらいいんだろうか、ゲームサーバーの構築はどうすればいいのか」という状況の読者向けに開発を体験するのハンズオンを紹介します。 皆さまの熱い気持ちを早く形にするため、 AWS が提供する マルチプレイ ーゲーム用の クラウド サーバー管理サービスである Amazon GameLiftと ゲームエンジン であるUnreal Engines5を使用し、オンライン マルチプレイ 環境を構築する最低限の手順でご紹介します。 注意事項 本記事では以下の操作が行えることと、環境が整っていることを前提としています。 AWS のマネジメントコンソールの使用 対話型シェルの使用 Unreal Engine の利用とプロジェクトのビルド また、本検証を行う場合、使用する AWS の利用料金が発生する点に注意してください。 Amazon GameLiftとは 冒頭でも紹介した通り、 Amazon GameLift (以下 GameLift ) は、 マルチプレイ 環境に必要なサーバー側のゲームアプリケーションならびにその実行環境を管理するサービスです。 本来、 マルチプレイ 用ゲームサーバーの構築にあたり、プレイヤーアカウントの作成、プレイヤー認証、プレイヤーマッチング、プレイヤーのスコアなど様々な要素を同時に検討する必要がありますが、GameLiftの採用によってそれらの手間が要らなくなって以前より実装するハードルが下がってきています。 GameLiftを利用した開発の流れは、以下図のように4stepがあります。とてもシンプルにゲームの開発ができます。 更にクライアント側で専用の SDK を使用することで接続管理やメッセージの送受信を手軽に実装することが可能となっています。本記事では、GameLiftSDKの組込みでオンライン マルチプレイ 環境を実現しました。 Unreal Engine5 とは Unreal Engine は、 Epic Games によって開発されている ゲームエンジン です。 そもそも、 ゲームエンジン が何かというと簡単に言うとゲームを作るためのソフトです。 ゲームエンジン を使用することで、ゲームを作るためのツールや環境が準備された状態でゲーム制作をすることができます。いわゆる、0からプログラミングをしなくて済みます。 Unreal Engine の特徴として、下記のようなものが挙げられます。 無料で使用できる ソースコード が公開されている プログラミングなしでもコンテンツ制作ができる グラフィックスが断トツで高品質 高品質なアセットが無料、有料ともに豊富 更に近年 メタバース による変革がリアルタイムの 3D技術が強く求められています。 Unreal Engine によって高品質な VR コンテンツの制作が可能になります。 Unreal Engine5(以下 UE5 )は Unreal Engine の最新バージョンです。 実施手順 手順は、以下の通りです。 UE5 ソースコード のビルド UE5テンプレートからゲームサーバーを作成する GameLiftSDKをビルドし プラグイン を生成する ゲームサーバーにGameLift プラグイン の組込み ローカルでゲームのテスト及びGameLiftへのアップロード AWS CLI コマンドによるゲームセッション作成と接続 AWS アーキテクチャ 本記事では、 マルチプレイ ゲーム開発を体験することのみに注力し、以下の通りほぼGameLiftのみを利用して構築します。 ※Lambda、 API Gateway 、Cognitoに構築については別記事でご紹介します。 使用環境/ツール Unreal Engine 5.1.0 windows10 21H2 x64 RAM 16GM, SSD 1TB NVIDIA GeForce GTX 980M Gamelift SDK GameLift Cpp ServerSDK 3.4.2 GameLift Unreal plugin 3.4.0 Visual Studio 2019 version 16.11.21(以下VS2019) JavaSDK 1.8.0 手順1. UE5 ソースコード のビルド Unreal Engine の公式 GitHub リポジトリ より、 Unreal Engine ソースをクローンして コンパイル します。 クローン: git clone https://github.com/EpicGames/UnrealEngine.git コンパイル : UnrealEngineフォルダに移動 Setup.batをダブルクリックして実行 GenerateProjectFiles.batをダブルクリックして実行 UE5.slnをクリックしてVS2019で開いて以下の図の通りにビルド実行 ※ Unreal Engine の リポジトリ へのアクセスは、権限が必要なので、済ではない方は、 SignUp の手順に従ってアクセス権限を設定してください。 ※ビルド時間はマシンのスペックによるが、参考までに、 Epicの推奨スペック の情報があります(ビルド時間を短縮するため、最低限は500GB SSD 、16GB RAMをおすすめします)。 手順2.UE5テンプレートからゲームサーバーを作成する 手順1で無事にUE5のビルドが完了後、「Local Windows Debugger」をクリックして Unreal Editorを立ち上げます。 ※Configure情報は以下であることを確認して Unreal Editorを立ち上げてください。 Unreal Editorの画面から「 ゲーム 」⇒ 「 サードパーソン 」⇒「 C++ 」⇒「 新プロジェクト名入力 」(今回は、プロジェクト名を「Gamelift_UE5」としました)でゲームサーバーのプロジェクトを作成します。 プロジェクト作成完了後、vs2019と Unreal Editorをクロースしてプロジェクトフォルダに移動します。 SourceフォルダのGamelift_UE5Editor.Target.csファイルを複製して、ゲームサーバー用の Gamelift_UE5Server.Target.cs ビルドファイルを作成します。 任意の テキストエディタ でGamelift_UE5Server.Target.csを開いて、「Editor」⇒「Server」を書き換えます プロジェクトフォルダに戻して、プロジェクトファイルを右クリックし「Generate Visual Studio project files」でプロジェクトを再生成します プロジェクトフォルダの Gamelift_UE5.sln ファイルをクリックし、VS2019を立ち上げます、そこで先ほど新規追加したゲームサーバー用のプロジェクトファイルが見えることを確認します プロジェクトをビルドします プロジェクトを再ビルドして後、 Gamelift_UE5.uproject をクリックして Unreal Editorを立ち上げます クライアントがゲームサーバーとの接続に成功したかを判別するため、"ゲームサーバー接続前の「オフラインマップ」"と"接続後の「オンラインマップ」"を別々に作成します(既存のマップの複製で作成) プロジェクトの「マップ&モード」でマップの利用ルールを設定します(「サーバーのデフォルトマップ」を、先ほど複製して作成したレベルに変更します) パッケージ化の時に、作成したマップを含まれるように、「パッケージ化」で「マップのパス」を設定します。 Windows 向けにプロジェクトをパッケージ化します バイナリコンフィグレーション:開発 ビルドターゲット: Gamelift_UE5Server ※パッケージ化の所要時間はマシンのスペックによります。 手順3.GameLiftSDKをビルドし プラグイン を生成する ※GameLiftSDK開発ドキュメントのセットアップ要件で、現在 UE4 .25のみの対応となっておりますが、筆者の検証によってUE5も利用可能です!ただし、ビルド用 Visual studio はVS2019を推奨します(筆者はVS2022のビルドでエラーだらけになった)。 GameLiftサーバーSDK から、GameLift Managed Servers SDK をダウンロードします。 CMDでダウンロード先のフォルダに移動して、以下のコマンドでビルドを実施します。 mkdir out cd out cmake -G "Visual Studio 16 2019" -A x64 -DBUILD_FOR_UNREAL=1 .. msbuild ALL_BUILD.vcxproj /p:Configuration=Release ※ビルドにあたり、VS2019のmsvc C++ ツールのバージョンがVS2017と違うのが原因で、以下のエラーが発生します。 msvc initialization: parameter version inconsistent 本エラーは、GameLift-Cpp-ServerSDK-3.4.2\out\thirdparty\boost配下のproject-config.jamにmsvcのバージョンを指定することで解決できます。 using msvc : 14.0 ; 無事にビルドが終わりましたら、生成したDLLとLibファイル out\prefix\bin\aws-cpp-sdk-gamelift-server.dll out\prefix\lib\aws-cpp-sdk-gamelift-server.lib を、 プラグイン のフォルダ(以下はパス)に複製して、セットアップが完了となります。 GameLift-SDK-Release-4.0.2\GameLift-Unreal-plugin-3.4.0\GameLiftServerSDK\ThirdParty\GameLiftServerSDK\Win64 手順4.ゲームサーバーにGameLift プラグイン の組込み UE5のプロジェクトルートフォルダの配下に「 Plugins 」フォルダを新規作成し、手順3でセットアップ完了した プラグイン をそこに移動します プロジェクトフォルダの Gamelift_UE5.sln ァイルをクリックし、VS2019を立ち上げて、 プラグイン をインポートします 以下の プラグイン 定義をゲームの Gamelift_UE5.uproject ファイルに追加します { "Name": "GameLiftServerSDK", "Enabled": true } b. Gamelift_UE5.Build.csファイルに プラグイン 名「 GameLiftServerSDK 」をゲームリストに依存関係として追加します c. 以下のGameLift を使用して Unreal Engine ゲームサーバーを初期化するコードを「 Gamelift_UE5GameMode.cpp 」に追加します #if WITH_GAMELIFT //Getting the module first. FGameLiftServerSDKModule* gameLiftSdkModule = &FModuleManager::LoadModuleChecked<FGameLiftServerSDKModule>(FName("GameLiftServerSDK")); //InitSDK establishes a local connection with GameLift's agent to enable communication. gameLiftSdkModule->InitSDK(); //Respond to new game session activation request. GameLift sends activation request //to the game server along with a game session object containing game properties //and other settings. Once the game server is ready to receive player connections, //invoke GameLiftServerAPI.ActivateGameSession() auto onGameSession = [=](Aws::GameLift::Server::Model::GameSession gameSession) { gameLiftSdkModule->ActivateGameSession(); }; FProcessParameters* params = new FProcessParameters(); params->OnStartGameSession.BindLambda(onGameSession); //OnProcessTerminate callback. GameLift invokes this before shutting down the instance //that is hosting this game server to give it time to gracefully shut down on its own. //In this example, we simply tell GameLift we are indeed going to shut down. params->OnTerminate.BindLambda([=](){gameLiftSdkModule->ProcessEnding();}); //HealthCheck callback. GameLift invokes this callback about every 60 seconds. By default, //GameLift API automatically responds 'true'. A game can optionally perform checks on //dependencies and such and report status based on this info. If no response is received //within 60 seconds, health status is recorded as 'false'. //In this example, we're always healthy! params->OnHealthCheck.BindLambda([](){return true; }); //Here, the game server tells GameLift what port it is listening on for incoming player //connections. In this example, the port is hardcoded for simplicity. Since active game //that are on the same instance must have unique ports, you may want to assign port values //from a range, such as: //const int32 port = FURL::UrlConfig.DefaultPort; //params->port; params->port = 7777; //Here, the game server tells GameLift what set of files to upload when the game session //ends. GameLift uploads everything specified here for the developers to fetch later. TArray<FString> logfiles; logfiles.Add(TEXT("aLogFile.txt")); params->logParameters = logfiles; //Call ProcessReady to tell GameLift this game server is ready to receive game sessions! gameLiftSdkModule->ProcessReady(*params); #endif d.GameLiftServerSDKのヘッドフォルダ(Plugins\GameLiftServerSDK\Source\GameLiftServerSDK\Public)をビルドのincludeパスに追加します。 e. UE5プロジェクトをビルドします 3. UE5プロジェクトのルートフォルダに戻して Gamelift_UE5.uproject をクリックして Unreal Editorを立ち上げます、「Edit」⇒「Plugins」をクリックして、GameLiftSDK プラグイン にチェックが入っていることを確認します 手順5.ローカルでゲームのテスト及びGameLiftへのアップロード ここまでは、UE5ゲームサーバーの開発とGameLiftSDKの組込みは全部完了しました。 GameLiftへゲームサーバーをプッシュする前に、一応ローカルで次の点を確認します。 ゲームサーバーが Server SDK と正常に統合されるか ゲームクライアントは新しいゲームセッションのスタート、プレイヤーのゲームへの参加、ゲームセッションへのConnectができるか 確認完了後に、以下の手順でGameLiftへアップロードを実施する CMDでGameLiftローカルのセットアップ cd {gameliftSDKダウンロード先}\GameLiftLocal-1.0.5 java -jar GameLiftLocal.jar -p 9080 ゲームサーバーを起動します 手順2でパッケージ化したゲームサーバーフォルダに移動します ゲームサーバーのログを出力したいため、起動exeのショットカットを作成して、 リンク先の後ろに「-log」を追加します ショットカットをクリックして、ゲームサーバーを起動します UE5プロジェクトのルートフォルダに戻して、 Gamelift_UE5.uproject をクリックして Unreal Editorを立ち上げます、 をクリックして、出た画面でプレイヤー数を2に設定して でクライアントを起動します CMDでゲームセッションを作成します AWS gamelift describe-game-sessions --endpoint-url http://localhost:9080 --fleet-id fleet-123 AWS gamelift create-game-session --endpoint-url http://localhost:9080 --maximum-player-session-count 2 --fleet-id fleet-1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d クライアントからゲームサーバーに接続してみます。 クライアントで **~** キーを押して、 コマンドライン が表示されます、そこにローカルホストIP( 127.0.0.1 )を入力すれば、上記作成したゲームルームに入ります ※下記の図ではメモリ不足に関するエラーが発生していますが、検証に影響はないため無視して進めます。 接続確認します ローカルの検証はできたので、ここから AWS 側で必要なリソースを作成します。 GameLift側で起動用 スクリプト 作成 手順2でパッケージ化したゲームサーバーフォルダに移動します その配下にinstall.batを配置します、以下は中身です。 Engine\Extras\Redist\en-us\UEPrereqSetup_x64.exe /install /quiet /norestart /log c:\game\UE5PrereqSetup.log 以下の aws コマンドでゲームサーバーをGameLiftへアップロードします ※ AWS の基本的な知識(IAMアカウント作成、 aws cli セットアップなど)の説明は割愛いたします。 operating-system: ゲームサーバーの稼働OS(筆者はwindows2012を採用します) build-root: 手順2で作ったパッケージのパス name: GameLiftでの表示名 build-version: バージョン定義 region: AWS のリージョン名 aws gamelift upload-build \ --operating-system WINDOWS_2012 \ --build-root "E:\UnrealBuilds\WindowsServer" \ --name "gamelift-Unreal-engine" \ --build-version "0.01" \ --region ap-northeast-1 aws consoleにログインして、GameLiftに開いてアップロードしたゲームサーバーを確認します。 ビルド数の隣に「 フリートを作成する 」をクリックしてGameLiftのFleetを作成します。 名前: Fleet名 フリートタイプ: オンデマンド 証明書タイプ: 無効 バイナリ型: ビルド ビルド: 上記2でアップロードしたゲームサーバーを選択する インスタンス タイプ: 無料のタイプでより ロケーション管理: 日本のリージョン プロセス管理 起動パス: Gamelift_UE5\Binaries\ Win64 \Gamelift_UE5Server.exe 同時プロセス: 1 EC2ポート設定 ポート範囲: 7777 プロトコル : UDP IPアドレス 範囲: 0.0.0.0/0 その他デフォルト値でよい 数十分ほど待つとフリートが完成します。こちらは以下マネジメントコンソールのページからも確認することができます。 ここまでで、GameLift側の構築は完了となります。 手順6. AWS CLI コマンドによるゲームセッション作成と接続 まず マルチプレイ を始めるにあたって、プレイヤーが集合するためのルーム、つまりGameLiftのゲームセッションを作成する必要があります(以降、ゲームセッションとして記載します)。次に、ゲームに接続するプレイヤーは、ゲームルームの「 IPアドレス 」を指定し、ゲームに参加することができます。 本来であれば、冒頭の AWS アーキテクチャ 図のように別途APIGatewayとlambdaを用意し、ユーザー認証を実施した上でGameLiftへ接続するなどセキュリ ティー を考慮する必要がありますが、今回は検証のため AWS CLI を用いたコマンドベースで接続します。 ゲームセッション作成 以下のコマンドを、手順5で作成したフリートのIDを取得し変数として設定してください(マネジメントコンソールのフリートの一覧ページから作成したフリート ID の確認が可能) aws gamelift create-game-session --fleet-id fleet-5f14fed2-30d6-4314-9220-47a261a9e6ee --maximum-player-session-count 2 aのコマンドを実行しフリートにゲームセッションを作成します。 ゲームクライアントの起動とゲームサーバーへの接続 ローカル検証する時と同様に、 Unreal Editorで をクリックして、出た画面でプレイヤー数を2に設定して でクライアントを起動します。 クライアントで **~** キーを押して、 コマンドライン が表示されます、そこに「open IPアドレス 」と入力することでゲームサーバーへ接続できます。 うまく接続できない場合、まずは以下の点を確認してみてください。 クライアント側OSやプロキシなどのネットワークの経路上で接続をブロックしている設定がないか確認する GameLiftのフリートではEC2 ポート設定が反映できたか確認する 終わりに 今回、UE5とGameLiftを利用し、オンライン マルチプレイ ゲームの構築する方法をご紹介しました。 冒頭で記載した通り、 メタバース においてよりよい没入感を実現するため、高精細なリアルタイム レンダリング が必要でこの辺はUnrealEngineの強みだと思います。 また、 メタバース 上でユーザーは「 SecondLife 」として生活していく上、運営側は大規模大人数同時オンライン可能のサーバーサイドの構築は不可欠で、今後ゲームサーバー技術の活用は増えていくと思われます。 そのため、引き続きゲーム領域のサーバーサイド技術をウォッチしていきたいと思います。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ(Web3/メタバース/AI) 参考 Amazon GameLift Developer Guider Unreal Engine5.1 Documentation GitHub aws-gamelift-samples 執筆: @chen.sun 、レビュー: @wakamoto.ryosuke ( Shodo で執筆されました )
アバター
みなさんこんにちは、 電通国際情報サービス (ISID)X イノベーション 本部ソフトウェアデザインセンターの佐藤太一です。 最近は少しずつRustにさわっているので、 コンパイラ などのツールチェインを更新する方法と、それを元に戻す方法を併せて紹介します。 構築済みの開発環境 Rustツールチェインを更新する方法 バージョンの確認 Rustツールチェインを元に戻す方法 バージョンの確認 まとめ 構築済みの開発環境 私の開発環境は Microsoft が提供するセットアップ手順にそって構築してあります。 Windows で Rust 用の開発環境を設定する 記事執筆時点でインストールしてあるrustupは 1.24.3 です。 Rustツールチェインを更新する方法 まずは、ツールチェインを最新の安定版に更新するコマンドを紹介しましょう。 rustup update stable このコマンドを実行すると以下のようにログが出力されます。 Rust標準のタ スクラン ナーであるcargoや コンパイラ であるrustc、標準ライブラリであるrust-stdがアップデートされています。 この実行では、記事執筆時における最新の安定版である 1.59.0 がインストールされていますね。 バージョンの確認 rustcのバージョンを確認してみましょう。 rustc --version rustcのバージョンが 1.59.0 になっています。バージョンアップは成功です。 Rustツールチェインを元に戻す方法 次は、ツールチェンを元に戻す方法を紹介しましょう。 まず、以下のコマンドを実行してインストール済みのツールチェインの一覧を確認します。 rustup toolchain list 筆者の環境では、一つ前のバージョンと最新の安定版をインストールしてあるので以下のように出力されます。 stable-x86_64-pc-windows-msvc の後ろに (default) と表示されていることから、現在利用中のツールチェインが最新の安定版を使っていることが分かります。 それでは、インストール済みの古いバージョンにツールチェインを戻してみましょう。 rustup default 1.58.1- x86 _64-pc- windows -msvc rustup default コマンドの引数として、先ほどのツールチェイン一覧から読み取れる古いバージョンを指定します。 古いバージョンが使われるように切り替わりましたね。最後にインストール済みのツールチェインをもう一度一覧してみましょう。 古いバージョンのツールチェインを使うようになりましたね。 バージョンの確認 本当に古いバージョンへ戻せているか、rustcのバージョンを確認してみましょう。 rustc --version rustcのバージョンが 1.58.1 になっていますので、古いものへ戻せています。 まとめ 今回は、ツールチェインを更新する方法とそれを元に戻す方法を説明しました。 rustupコマンドの詳細情報が知りたいなら The rustup book を確認してください。 執筆: @sato.taichi 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
アバター
みなさんこんにちは、 電通国際情報サービス (ISID)X イノベーション 本部ソフトウェアデザインセンターの佐藤太一です。 最近は少しずつRustにさわっているので、 コンパイラ などのツールチェインを更新する方法と、それを元に戻す方法を併せて紹介します。 構築済みの開発環境 Rustツールチェインを更新する方法 バージョンの確認 Rustツールチェインを元に戻す方法 バージョンの確認 まとめ 構築済みの開発環境 私の開発環境は Microsoft が提供するセットアップ手順にそって構築してあります。 Windows で Rust 用の開発環境を設定する 記事執筆時点でインストールしてあるrustupは 1.24.3 です。 Rustツールチェインを更新する方法 まずは、ツールチェインを最新の安定版に更新するコマンドを紹介しましょう。 rustup update stable このコマンドを実行すると以下のようにログが出力されます。 Rust標準のタ スクラン ナーであるcargoや コンパイラ であるrustc、標準ライブラリであるrust-stdがアップデートされています。 この実行では、記事執筆時における最新の安定版である 1.59.0 がインストールされていますね。 バージョンの確認 rustcのバージョンを確認してみましょう。 rustc --version rustcのバージョンが 1.59.0 になっています。バージョンアップは成功です。 Rustツールチェインを元に戻す方法 次は、ツールチェンを元に戻す方法を紹介しましょう。 まず、以下のコマンドを実行してインストール済みのツールチェインの一覧を確認します。 rustup toolchain list 筆者の環境では、一つ前のバージョンと最新の安定版をインストールしてあるので以下のように出力されます。 stable-x86_64-pc-windows-msvc の後ろに (default) と表示されていることから、現在利用中のツールチェインが最新の安定版を使っていることが分かります。 それでは、インストール済みの古いバージョンにツールチェインを戻してみましょう。 rustup default 1.58.1- x86 _64-pc- windows -msvc rustup default コマンドの引数として、先ほどのツールチェイン一覧から読み取れる古いバージョンを指定します。 古いバージョンが使われるように切り替わりましたね。最後にインストール済みのツールチェインをもう一度一覧してみましょう。 古いバージョンのツールチェインを使うようになりましたね。 バージョンの確認 本当に古いバージョンへ戻せているか、rustcのバージョンを確認してみましょう。 rustc --version rustcのバージョンが 1.58.1 になっていますので、古いものへ戻せています。 まとめ 今回は、ツールチェインを更新する方法とそれを元に戻す方法を説明しました。 rustupコマンドの詳細情報が知りたいなら The rustup book を確認してください。 執筆: @sato.taichi 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
アバター
X イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの福山です。 先日、米政府(米サイバーセキュリティインフラスト ラク チャセキュリティ庁( CISA )や米 連邦捜査局 (FBI)、 MS-ISAC(Multi-State ISAC)の共同)から、 DDoS攻撃 に対するガイダンス「 Understanding and Responding to Distributed Denial-of-Service Attacks 」が公開されました。 業務で AWS に触れる機会が多いので、この機会に AWS における DDoS攻撃 対策を調査したいと思いました。 そこで今回は、 AWS WAF、GuardDutyを有効活用できていない AWS 上のWebアプリケーションに対して DDoS攻撃 を受けた際に、対策となるリソースを追加するためのCloudFormationテンプレートや後続作業を調査しましたので、紹介したいと思います。 前提 初動対応 ①隔離用のネットワークACLを関連付け(主にL3の防御) 【概要】 【目的】 【構成図】 【注意点】 【手順】 【ポイント解説】 ②AWS WAFの関連付け(主にL7の防御) 【概要】 【目的】 【構成図】 【注意点】 【手順】 【ポイント解説】 ③GuardDutyの全リージョン有効化 保全 事後調査 事後対策 まとめ 前提 AWS における DDoS攻撃 とその対策について知るため、以下の資料を確認しました。 こちらをベースに対策を考えました。 参考: AWS BlackBelt AWS上でのDDoS対策 上記P9によると、 AWS ではインフラ層(L3/L4)とアプリ層(L6/L7)について対策する必要があるようです。 上図(P12引用)のL3( ネットワーク層 )を狙った DDoS攻撃 として、 UDP 反射攻撃などの処理能力を超えた トラフィック を送りつける攻撃が一般的です。これらの対策としては、セキュリティグループやネットワーク ACL などの境界防御が挙げられます。 また、L7(アプリケーション層)に対してはHTTP GET、 DNS クエリフラッドなど悪意のある要求を使用して、アプリケーションリソースを使用する攻撃が挙げられます。これらの対策サービスとして、 AWS WAFなどがあります。 上記2点が標的となるWebアプリケーション構成として、EC2を利用しているケースは多いかと思います。そこで今回はEC2を利用しているケースで考えたいと思います。 攻撃者が AWS 外から DDoS攻撃 を行っているケースを想定しています。 本執筆では主に初動対応に焦点を当てており、いかに素早く対処できるかを重視した内容となっています。 対応の自動化にあたりCloudFormationを利用します。CloudFormationはインフラをコードで管理できるサービスとなっています。なお、 AWS CDKの利用が広がってきている中ではありますが、環境準備の手間が不要で、開発経験がない方でも手軽に作業ができる点を考慮し、CloudFormationを採用しました。 AWS Shield Advancedと呼ばれるDDoS対策を提供する AWS の有償サービス(月額3,000USD)がありますが、 今回は契約していない状態を想定しています。 初動対応 ①隔離用のネットワーク ACL を関連付け(主にL3の防御) 【概要】  攻撃対象のリソースが設置されているサブネットに、自動で新規ネットワーク ACL が適用されます。 【目的】  悪用可能性のあるポート、 プロトコル からの通信を遮断します。 【構成図】  作成されるリソースは下図の赤枠部分となります。 【注意点】  以下の手順でCloudFormationスタックを作成すると、元々アタッチされていたネットワーク ACL は  デタッチされます。その後、CloudFormationスタックを削除すると、defaultのネットワーク ACL が  アタッチされますのでご注意ください(元々default以外のネットワーク ACL をアタッチしていた場合も、  defaultのネットワーク ACL に切り替わります)。 【手順】  CloudFormationでリソースのあるリージョンを選択し、スタックの作成、テンプレートファイルのアップロード  から下記コードをyml形式でアップロードし実行します。詳細な手順を確認したい場合は以下をご参考ください。  参考: AWS CloudFormation コンソールでのスタックの作成  コードを表示 AWSTemplateFormatVersion : '2010-09-09' Metadata : AWS::CloudFormation::Interface : ParameterGroups : - Label : default : NACL Configuration Parameters : - Prefix - VpcId - SubnetId - VpcCidr Parameters : Prefix : Type : String Default : ddos VpcId : Type : AWS::EC2::VPC::Id SubnetId : Type : AWS::EC2::Subnet::Id Description : "Select the subnet to which you want to attach the NACL" ### VPC Cidrは手動で入力する VpcCidr : Type : String Default : xx.xx.xx.xx/xx Description : "Set the VPCCidrBlok to allow inbound traffic within the VPC" Resources : Nacl : Type : AWS::EC2::NetworkAcl Properties : VpcId : !Ref VpcId Tags : - Key : Name Value : !Sub ${Prefix}-nacl NaclAssoc : Type : AWS::EC2::SubnetNetworkAclAssociation Properties : NetworkAclId : !Ref Nacl SubnetId : !Ref SubnetId ### ここからインバウンドルール #### VPC内通信を許可 NaclEntryInbound001 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 1 RuleAction : allow Protocol : -1 CidrBlock : !Ref VpcCidr NetworkAclId : !Ref Nacl #### MemcachedのUDP通信をブロック NaclEntryInbound005 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 5 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 11211 To : 11211 NetworkAclId : !Ref Nacl #### NTPのUDP通信を許可 NaclEntryInbound010 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 10 RuleAction : allow Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 123 To : 123 NetworkAclId : !Ref Nacl #### CharGENのUDP通信をブロック NaclEntryInbound015 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 15 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 19 To : 19 NetworkAclId : !Ref Nacl #### QOTDのUDP通信をブロック NaclEntryInbound020 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 20 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 17 To : 17 NetworkAclId : !Ref Nacl #### RIPv1のUDP通信をブロック NaclEntryInbound025 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 25 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 520 To : 520 NetworkAclId : !Ref Nacl #### RIPv1のUDP通信をブロック NaclEntryInbound030 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 30 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 389 To : 389 NetworkAclId : !Ref Nacl #### CLDAPのUDP通信をブロック NaclEntryInbound035 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 35 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 389 To : 389 NetworkAclId : !Ref Nacl #### DNSのUDP通信を許可 NaclEntryInbound040 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 40 RuleAction : allow Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 53 To : 53 NetworkAclId : !Ref Nacl #### Quake Network ProtocolのUDP通信をブロック NaclEntryInbound045 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 45 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 27960 To : 27960 NetworkAclId : !Ref Nacl #### TFTPのUDP通信をブロック NaclEntryInbound050 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 50 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 69 To : 69 NetworkAclId : !Ref Nacl #### SSDPのUDP通信をブロック NaclEntryInbound055 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 55 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 1900 To : 1900 NetworkAclId : !Ref Nacl #### MSSQLのUDP通信をブロック NaclEntryInbound060 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 60 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 1434 To : 1434 NetworkAclId : !Ref Nacl #### Kad (P2P)のUDP通信をブロック NaclEntryInbound065 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 65 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 751 To : 751 NetworkAclId : !Ref Nacl #### Portmap (RPCbind)のUDP通信をブロック NaclEntryInbound070 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 70 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 111 To : 111 NetworkAclId : !Ref Nacl #### Multicast DNSのUDP通信をブロック NaclEntryInbound075 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 75 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 5353 To : 5353 NetworkAclId : !Ref Nacl #### ICMPのエコー応答をブロック NaclEntryInbound080 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 80 RuleAction : deny Protocol : 1 CidrBlock : 0.0.0.0/0 Icmp : Type : 0 Code : -1 NetworkAclId : !Ref Nacl #### ICMPのエコー要求をブロック NaclEntryInbound085 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 85 RuleAction : deny Protocol : 1 CidrBlock : 0.0.0.0/0 Icmp : Type : 8 Code : -1 NetworkAclId : !Ref Nacl #### デフォルトの許可ルール NaclEntryInbound100 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 100 RuleAction : allow Protocol : -1 CidrBlock : 0.0.0.0/0 NetworkAclId : !Ref Nacl ### ここからアウトバウンドルール #### デフォルトの許可ルール NaclEntryOutbound100 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : true RuleNumber : 100 RuleAction : allow Protocol : -1 CidrBlock : 0.0.0.0/0 NetworkAclId : !Ref Nacl   【ポイント解説】 ネットワーク ACL を選んだ理由   ホワイトリスト により少ない定義量で書けるセキュリティグループも検討しましたが、以下の理由から  ネットワーク ACL を採用しました。  ・明示的に拒否ルールが書ける  ・今後EC2が増えても追加設定なしで境界防御を実現できる  ・NLBのようなセキュリティグループをサポートしないリソースも保護できる  ・汎用性を重視したい ルール全般について  全ての通信を遮断するわけではなく、悪用実績のある UDP サービスを増幅率の高い順でルール設定しています。  (念のためICMPも拒否ルールを設定しています)  参考: UDP-Based Amplification Attacks  ただし、 VPC 内通信、53/ udp 、123/ udp については、システムへの影響を考慮して許可しています。 VPC Cidrについて  対象 VPC 内の通信を許可するため、ParametersのVpcCidrには IPアドレス レンジを入力します。  こちらは最優先で適用されるルールとなるため、誤って0.0.0.0/0と入力してしまうと通信が全て許可されて  しまいますので、ご注意ください。 ② AWS WAFの関連付け(主にL7の防御)  攻撃者がレイヤーを変えてくる可能性があるため、①に続いて下記を速やかに実施します。 【概要】   AWS WAFを作成し、適用します。 【目的】   Bot からの攻撃の遮断や地域制限を行うことができ、アプリケーションリソースを保護します。 【構成図】  作成されるリソースは、下図A、Bの場合赤枠部分となります。  CのケースはEC2が丸裸の構成です。  (A)最前段がCloudFront構成 (B)最前段がALBで、CloudFrontなしの構成 (C)CloudFront、ALBが両方ともない構成 【注意点】  以下の手順でCloudFormationスタックを作成すると、元々 ディストリビューション またはALBに関連付け  されていたWeb ACL はデタッチされます。その後、CloudFormationスタックを削除しても、  元のWeb ACL は変わらずデタッチされた状態となりますのでご注意ください。 【手順】  以下A、B、Cの構成において、該当する作業を実施します。   (A)最前段がCloudFront構成   1. CloudFormationでus-east-1( バージニア 北部)リージョンを選択し、スタックの作成、テンプレート    ファイルのアップロードから、下記コードをyml形式でアップロードし実行します。  コードを表示 AWSTemplateFormatVersion : 2010-09-09 Metadata : AWS::CloudFormation::Interface : ParameterGroups : - Label : default : WAF Configuration Parameters : - Prefix - WhiteListIP - RateLimit - SwitchGeoRestriction - WhiteListGeoRestriction Parameters : Prefix : Type : String Default : ddos ### 社内のIP等、許可するIPを設定する WhiteListIP : Type : CommaDelimitedList Default : xx.xx.xx.xx/xx Description : Set IPs to Whitelist. Commas allow multiple sets(e.g. xx.xx.0.0/16, xx.xx.xx.xx/32). RateLimit : Type : Number Default : 100 Description : Set value of WAF Rate Limit ### 地理的一致ルールを有効化したい場合はONにする SwitchGeoRestriction : Type : String AllowedValues : [ "ON" , "OFF" ] Description : Select "ON" to block access except in designated countries, or "OFF" to not configure. ### アクセス許可したい国のコードを入力する(SwitchGeoRestrictionがOFFの場合はデフォルトのまま変更不要) WhiteListGeoRestriction : Type : CommaDelimitedList Default : JP Description : Set CountryCodes to which access is allowed. Commas allow multiple sets(e.g. JP, US). - https://docs.aws.amazon.com/ja_jp/waf/latest/APIReference/API_GeoMatchStatement.html Conditions : GeoRestriction : !Equals [ "ON" , !Ref SwitchGeoRestriction ] Resources : WebACL : Type : AWS::WAFv2::WebACL Properties : Name : !Ref Prefix DefaultAction : Allow : {} Scope : CLOUDFRONT VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : !Ref Prefix SampledRequestsEnabled : true Rules : - Name : Custom-WhiteListIPSet Action : Allow : {} Priority : 0 Statement : IPSetReferenceStatement : Arn : !GetAtt WhiteListIPSet.Arn VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : Custom-WhiteListIPSet SampledRequestsEnabled : true - Name : AWS-AWSManagedRulesCommonRuleSet Priority : 1 Statement : ManagedRuleGroupStatement : VendorName : AWS Name : AWSManagedRulesCommonRuleSet OverrideAction : None : {} VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : AWSManagedRulesCommonRuleSet SampledRequestsEnabled : true - Name : AWS-AWSManagedRulesKnownBadInputsRuleSet Priority : 2 Statement : ManagedRuleGroupStatement : VendorName : AWS Name : AWSManagedRulesKnownBadInputsRuleSet OverrideAction : None : {} VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : AWSManagedRulesKnownBadInputsRuleSet SampledRequestsEnabled : true - Name : AWS-AWSManagedRulesAmazonIpReputationList Priority : 3 Statement : ManagedRuleGroupStatement : VendorName : AWS Name : AWSManagedRulesAmazonIpReputationList OverrideAction : None : {} VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : AWSManagedRulesAmazonIpReputationList SampledRequestsEnabled : true - Name : Custom-Ratebased Action : Block : {} Priority : 4 Statement : RateBasedStatement : AggregateKeyType : IP Limit : !Ref RateLimit ScopeDownStatement : NotStatement : Statement : IPSetReferenceStatement : Arn : !GetAtt WhiteListIPSet.Arn VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : Custom-Ratebased SampledRequestsEnabled : true - !If - GeoRestriction - Name : Custom-GeoRestriction Action : Block : {} Priority : 5 Statement : NotStatement : Statement : GeoMatchStatement : CountryCodes : !Ref WhiteListGeoRestriction VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : Custom-GeoRestriction SampledRequestsEnabled : true - Ref : AWS::NoValue WhiteListIPSet : Type : "AWS::WAFv2::IPSet" Properties : Name : Custom-ipaddress-whitelist Scope : CLOUDFRONT IPAddressVersion : IPV4 Addresses : !Ref WhiteListIP   2. 作成されたWeb ACL を、対象のCloudFront ディストリビューション に手動でアタッチします。    詳細な手順を確認したい場合は下記をご参考ください。    参考: Web ACLとCloudFrontディストリビューションとの関連付け   (B)最前段がALBで、CloudFrontなしの構成   CloudFormationでリソースがあるリージョンを選択し、スタックの作成、テンプレートファイルの   アップロードから下記コードをyml形式でアップロードし実行します。   ※作成されるWeb ACL は、対象のALBに自動でアタッチされます。  コードを表示 AWSTemplateFormatVersion : 2010-09-09 Metadata : AWS::CloudFormation::Interface : ParameterGroups : - Label : default : WAF Configuration Parameters : - Prefix - WebAclAssociationResourceArn - WhiteListIP - RateLimit - SwitchGeoRestriction - WhiteListGeoRestriction Parameters : Prefix : Type : String Default : ddos ### ALBのARNを入力する WebAclAssociationResourceArn : Type : String Default : "arn:aws:elasticloadbalancing:ap-northeast-1:XXXXXXXXXXXX:loadbalancer/app/XXXXXXXXXXXX" Description : Enter RegionalResource(ALB) ARN to associate with WEBACL. ### 社内のIP等、許可するIPを設定する WhiteListIP : Type : CommaDelimitedList Default : xx.xx.xx.xx/xx Description : Set IPs to Whitelist. Commas allow multiple sets(e.g. xx.xx.0.0/16, xx.xx.xx.xx/32). RateLimit : Type : Number Default : 100 Description : Set value of WAF Rate Limit ### 地理的一致ルールを有効化したい場合はONにする SwitchGeoRestriction : Type : String AllowedValues : [ "ON" , "OFF" ] Description : Select "ON" to block access except in designated countries, or "OFF" to not configure. ### アクセス許可したい国のコードを入力する(SwitchGeoRestrictionがOFFの場合はデフォルトの値で変更不要) WhiteListGeoRestriction : Type : CommaDelimitedList Default : JP Description : Set CountryCodes to which access is allowed. Commas allow multiple sets(e.g. JP, US). - https://docs.aws.amazon.com/ja_jp/waf/latest/APIReference/API_GeoMatchStatement.html Conditions : GeoRestriction : !Equals [ "ON" , !Ref SwitchGeoRestriction ] Resources : WebACL : Type : AWS::WAFv2::WebACL Properties : Name : !Ref Prefix DefaultAction : Allow : {} Scope : REGIONAL VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : !Ref Prefix SampledRequestsEnabled : true Rules : - Name : Custom-WhiteListIPSet Action : Allow : {} Priority : 0 Statement : IPSetReferenceStatement : Arn : !GetAtt WhiteListIPSet.Arn VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : Custom-WhiteListIPSet SampledRequestsEnabled : true - Name : AWS-AWSManagedRulesCommonRuleSet Priority : 1 Statement : ManagedRuleGroupStatement : VendorName : AWS Name : AWSManagedRulesCommonRuleSet OverrideAction : None : {} VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : AWSManagedRulesCommonRuleSet SampledRequestsEnabled : true - Name : AWS-AWSManagedRulesKnownBadInputsRuleSet Priority : 2 Statement : ManagedRuleGroupStatement : VendorName : AWS Name : AWSManagedRulesKnownBadInputsRuleSet OverrideAction : None : {} VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : AWSManagedRulesKnownBadInputsRuleSet SampledRequestsEnabled : true - Name : AWS-AWSManagedRulesAmazonIpReputationList Priority : 3 Statement : ManagedRuleGroupStatement : VendorName : AWS Name : AWSManagedRulesAmazonIpReputationList OverrideAction : None : {} VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : AWSManagedRulesAmazonIpReputationList SampledRequestsEnabled : true - Name : Custom-Ratebased Action : Block : {} Priority : 4 Statement : RateBasedStatement : AggregateKeyType : IP Limit : !Ref RateLimit ScopeDownStatement : NotStatement : Statement : IPSetReferenceStatement : Arn : !GetAtt WhiteListIPSet.Arn VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : Custom-Ratebased SampledRequestsEnabled : true - !If - GeoRestriction - Name : Custom-GeoRestriction Action : Block : {} Priority : 5 Statement : NotStatement : Statement : GeoMatchStatement : CountryCodes : !Ref WhiteListGeoRestriction VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : Custom-GeoRestriction SampledRequestsEnabled : true - Ref : AWS::NoValue WhiteListIPSet : Type : "AWS::WAFv2::IPSet" Properties : Name : Custom-ipaddress-whitelist Scope : REGIONAL IPAddressVersion : IPV4 Addresses : !Ref WhiteListIP WebACLAssociation : Type : AWS::WAFv2::WebACLAssociation Properties : ResourceArn : !Ref WebAclAssociationResourceArn WebACLArn : !GetAtt WebACL.Arn   (C)CloudFront、ALBが両方ともない構成(A、Bで解消しない場合もこちら)   この場合、 AWS WAFはアタッチできないため、他の手を打つ必要があります。   なお、上段A、Bで解消しない場合も最終手段として下記の作業を行うことになると考えます。   以下α、βいずれかを判断の上、対応してください。   (α)コストが掛かってもシステム稼働を優先したい    ・複数 インスタンス 構成かつAuto Scaling Groupで稼働している場合      Auto Scalingの インスタンス 最大台数を増やします。    ・単一 インスタンス 等、Auto Scaling Groupを利用せずに稼働している場合       インスタンス タイプのスケールアップを実施します。   (β)システム稼働よりもDDoS被害(コスト)軽減を優先したい     対象EC2を停止します。 【ポイント解説】 Aに関して、CloudFormationでは既存のCloudFrontに AWS WAFをアタッチすることができません。 スタック作成後、手動でCloudFrontにアタッチする必要があります。 A、B共通して以下のルールが作成されます。優先度順に記載します。 ホワイトリスト IP(許可) ・ParametersのWhiteListIPに社内のIP等、許可するIPを入力(複数可) AWS マネージドルール(拒否) ・AWSManagedRulesCommonRuleSet ・AWSManagedRulesKnownBadInputsRuleSet ・AWSManagedRulesAmazonIpReputationList レートベースのルール(アクセス制限) ・ParametersのRateLimitにレート制限値を入力 ・ParametersのWhiteListIPで設定したIPは対象外 地理的一致ルール(許可) ・ParametersのSwitchGeoRestrictionをONにすることで有効化 ・ParametersのWhiteListGeoRestrictionにアクセス許可する国のコードを入力(複数可)  参考: CountryCodes ・ParametersのSwitchGeoRestrictionをOFFにする場合、デフォルトの値から変更不要 ③GuardDutyの全リージョン有効化   ガイダンス によると、より悪意のある攻撃から注意を反らすために DDoS攻撃 が使用されることもある  との記載がありました(P4)。 AWS の脅威検知サービスであるGuardDutyを全リージョン有効化  していない場合は、このタイミングで有効にすることをお勧めします。  以下のサイトでは、全リージョン一括で有効化して通知設定する方法が紹介されていました。  参考: https://dev.classmethod.jp/articles/set-guardduty-all-region/ 保全 ・CloudWatch Logs等、関連するログのエクスポート(ログローテーションによる消失を回避するため)。 事後調査 ・ログの分析、原因調査。 事後対策 ・今回適用したネットワーク ACL と AWS WAFについて、アタッチを継続するか、設定変更するか等を判断。  今回作成したリソースは、CloudFormationスタックを削除することで消すことができる。 ・ アーキテクチャ の見直し( インスタンス をプライベートサブネットに設置、CloudFrontの導入、Route53への移行等)。 ・Auto Scalingの最大台数、 インスタンス タイプの見直し。 ・セキュリティグループの設定見直し。 まとめ DDoS攻撃 を受けた時の初動対応をできるだけ自動化してみました。 本記事が皆様のお役に立てれば幸いです。 〜最後に〜 私たちは同じチームで働いてくれる仲間を大募集しています!たくさんのご応募お待ちしています。 - セキュリティエンジニア(セキュリティ設計) 執筆: @fuku.dancho 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
アバター
X イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの福山です。 先日、米政府(米サイバーセキュリティインフラスト ラク チャセキュリティ庁( CISA )や米 連邦捜査局 (FBI)、 MS-ISAC(Multi-State ISAC)の共同)から、 DDoS攻撃 に対するガイダンス「 Understanding and Responding to Distributed Denial-of-Service Attacks 」が公開されました。 業務で AWS に触れる機会が多いので、この機会に AWS における DDoS攻撃 対策を調査したいと思いました。 そこで今回は、 AWS WAF、GuardDutyを有効活用できていない AWS 上のWebアプリケーションに対して DDoS攻撃 を受けた際に、対策となるリソースを追加するためのCloudFormationテンプレートや後続作業を調査しましたので、紹介したいと思います。 前提 初動対応 ①隔離用のネットワークACLを関連付け(主にL3の防御) 【概要】 【目的】 【構成図】 【注意点】 【手順】 【ポイント解説】 ②AWS WAFの関連付け(主にL7の防御) 【概要】 【目的】 【構成図】 【注意点】 【手順】 【ポイント解説】 ③GuardDutyの全リージョン有効化 保全 事後調査 事後対策 まとめ 前提 AWS における DDoS攻撃 とその対策について知るため、以下の資料を確認しました。 こちらをベースに対策を考えました。 参考: AWS BlackBelt AWS上でのDDoS対策 上記P9によると、 AWS ではインフラ層(L3/L4)とアプリ層(L6/L7)について対策する必要があるようです。 上図(P12引用)のL3( ネットワーク層 )を狙った DDoS攻撃 として、 UDP 反射攻撃などの処理能力を超えた トラフィック を送りつける攻撃が一般的です。これらの対策としては、セキュリティグループやネットワーク ACL などの境界防御が挙げられます。 また、L7(アプリケーション層)に対してはHTTP GET、 DNS クエリフラッドなど悪意のある要求を使用して、アプリケーションリソースを使用する攻撃が挙げられます。これらの対策サービスとして、 AWS WAFなどがあります。 上記2点が標的となるWebアプリケーション構成として、EC2を利用しているケースは多いかと思います。そこで今回はEC2を利用しているケースで考えたいと思います。 攻撃者が AWS 外から DDoS攻撃 を行っているケースを想定しています。 本執筆では主に初動対応に焦点を当てており、いかに素早く対処できるかを重視した内容となっています。 対応の自動化にあたりCloudFormationを利用します。CloudFormationはインフラをコードで管理できるサービスとなっています。なお、 AWS CDKの利用が広がってきている中ではありますが、環境準備の手間が不要で、開発経験がない方でも手軽に作業ができる点を考慮し、CloudFormationを採用しました。 AWS Shield Advancedと呼ばれるDDoS対策を提供する AWS の有償サービス(月額3,000USD)がありますが、 今回は契約していない状態を想定しています。 初動対応 ①隔離用のネットワーク ACL を関連付け(主にL3の防御) 【概要】  攻撃対象のリソースが設置されているサブネットに、自動で新規ネットワーク ACL が適用されます。 【目的】  悪用可能性のあるポート、 プロトコル からの通信を遮断します。 【構成図】  作成されるリソースは下図の赤枠部分となります。 【注意点】  以下の手順でCloudFormationスタックを作成すると、元々アタッチされていたネットワーク ACL は  デタッチされます。その後、CloudFormationスタックを削除すると、defaultのネットワーク ACL が  アタッチされますのでご注意ください(元々default以外のネットワーク ACL をアタッチしていた場合も、  defaultのネットワーク ACL に切り替わります)。 【手順】  CloudFormationでリソースのあるリージョンを選択し、スタックの作成、テンプレートファイルのアップロード  から下記コードをyml形式でアップロードし実行します。詳細な手順を確認したい場合は以下をご参考ください。  参考: AWS CloudFormation コンソールでのスタックの作成  コードを表示 AWSTemplateFormatVersion : '2010-09-09' Metadata : AWS::CloudFormation::Interface : ParameterGroups : - Label : default : NACL Configuration Parameters : - Prefix - VpcId - SubnetId - VpcCidr Parameters : Prefix : Type : String Default : ddos VpcId : Type : AWS::EC2::VPC::Id SubnetId : Type : AWS::EC2::Subnet::Id Description : "Select the subnet to which you want to attach the NACL" ### VPC Cidrは手動で入力する VpcCidr : Type : String Default : xx.xx.xx.xx/xx Description : "Set the VPCCidrBlok to allow inbound traffic within the VPC" Resources : Nacl : Type : AWS::EC2::NetworkAcl Properties : VpcId : !Ref VpcId Tags : - Key : Name Value : !Sub ${Prefix}-nacl NaclAssoc : Type : AWS::EC2::SubnetNetworkAclAssociation Properties : NetworkAclId : !Ref Nacl SubnetId : !Ref SubnetId ### ここからインバウンドルール #### VPC内通信を許可 NaclEntryInbound001 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 1 RuleAction : allow Protocol : -1 CidrBlock : !Ref VpcCidr NetworkAclId : !Ref Nacl #### MemcachedのUDP通信をブロック NaclEntryInbound005 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 5 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 11211 To : 11211 NetworkAclId : !Ref Nacl #### NTPのUDP通信を許可 NaclEntryInbound010 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 10 RuleAction : allow Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 123 To : 123 NetworkAclId : !Ref Nacl #### CharGENのUDP通信をブロック NaclEntryInbound015 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 15 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 19 To : 19 NetworkAclId : !Ref Nacl #### QOTDのUDP通信をブロック NaclEntryInbound020 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 20 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 17 To : 17 NetworkAclId : !Ref Nacl #### RIPv1のUDP通信をブロック NaclEntryInbound025 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 25 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 520 To : 520 NetworkAclId : !Ref Nacl #### RIPv1のUDP通信をブロック NaclEntryInbound030 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 30 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 389 To : 389 NetworkAclId : !Ref Nacl #### CLDAPのUDP通信をブロック NaclEntryInbound035 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 35 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 389 To : 389 NetworkAclId : !Ref Nacl #### DNSのUDP通信を許可 NaclEntryInbound040 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 40 RuleAction : allow Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 53 To : 53 NetworkAclId : !Ref Nacl #### Quake Network ProtocolのUDP通信をブロック NaclEntryInbound045 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 45 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 27960 To : 27960 NetworkAclId : !Ref Nacl #### TFTPのUDP通信をブロック NaclEntryInbound050 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 50 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 69 To : 69 NetworkAclId : !Ref Nacl #### SSDPのUDP通信をブロック NaclEntryInbound055 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 55 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 1900 To : 1900 NetworkAclId : !Ref Nacl #### MSSQLのUDP通信をブロック NaclEntryInbound060 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 60 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 1434 To : 1434 NetworkAclId : !Ref Nacl #### Kad (P2P)のUDP通信をブロック NaclEntryInbound065 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 65 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 751 To : 751 NetworkAclId : !Ref Nacl #### Portmap (RPCbind)のUDP通信をブロック NaclEntryInbound070 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 70 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 111 To : 111 NetworkAclId : !Ref Nacl #### Multicast DNSのUDP通信をブロック NaclEntryInbound075 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 75 RuleAction : deny Protocol : 17 CidrBlock : 0.0.0.0/0 PortRange : From : 5353 To : 5353 NetworkAclId : !Ref Nacl #### ICMPのエコー応答をブロック NaclEntryInbound080 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 80 RuleAction : deny Protocol : 1 CidrBlock : 0.0.0.0/0 Icmp : Type : 0 Code : -1 NetworkAclId : !Ref Nacl #### ICMPのエコー要求をブロック NaclEntryInbound085 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 85 RuleAction : deny Protocol : 1 CidrBlock : 0.0.0.0/0 Icmp : Type : 8 Code : -1 NetworkAclId : !Ref Nacl #### デフォルトの許可ルール NaclEntryInbound100 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : false RuleNumber : 100 RuleAction : allow Protocol : -1 CidrBlock : 0.0.0.0/0 NetworkAclId : !Ref Nacl ### ここからアウトバウンドルール #### デフォルトの許可ルール NaclEntryOutbound100 : Type : AWS::EC2::NetworkAclEntry Properties : Egress : true RuleNumber : 100 RuleAction : allow Protocol : -1 CidrBlock : 0.0.0.0/0 NetworkAclId : !Ref Nacl   【ポイント解説】 ネットワーク ACL を選んだ理由   ホワイトリスト により少ない定義量で書けるセキュリティグループも検討しましたが、以下の理由から  ネットワーク ACL を採用しました。  ・明示的に拒否ルールが書ける  ・今後EC2が増えても追加設定なしで境界防御を実現できる  ・NLBのようなセキュリティグループをサポートしないリソースも保護できる  ・汎用性を重視したい ルール全般について  全ての通信を遮断するわけではなく、悪用実績のある UDP サービスを増幅率の高い順でルール設定しています。  (念のためICMPも拒否ルールを設定しています)  参考: UDP-Based Amplification Attacks  ただし、 VPC 内通信、53/ udp 、123/ udp については、システムへの影響を考慮して許可しています。 VPC Cidrについて  対象 VPC 内の通信を許可するため、ParametersのVpcCidrには IPアドレス レンジを入力します。  こちらは最優先で適用されるルールとなるため、誤って0.0.0.0/0と入力してしまうと通信が全て許可されて  しまいますので、ご注意ください。 ② AWS WAFの関連付け(主にL7の防御)  攻撃者がレイヤーを変えてくる可能性があるため、①に続いて下記を速やかに実施します。 【概要】   AWS WAFを作成し、適用します。 【目的】   Bot からの攻撃の遮断や地域制限を行うことができ、アプリケーションリソースを保護します。 【構成図】  作成されるリソースは、下図A、Bの場合赤枠部分となります。  CのケースはEC2が丸裸の構成です。  (A)最前段がCloudFront構成 (B)最前段がALBで、CloudFrontなしの構成 (C)CloudFront、ALBが両方ともない構成 【注意点】  以下の手順でCloudFormationスタックを作成すると、元々 ディストリビューション またはALBに関連付け  されていたWeb ACL はデタッチされます。その後、CloudFormationスタックを削除しても、  元のWeb ACL は変わらずデタッチされた状態となりますのでご注意ください。 【手順】  以下A、B、Cの構成において、該当する作業を実施します。   (A)最前段がCloudFront構成   1. CloudFormationでus-east-1( バージニア 北部)リージョンを選択し、スタックの作成、テンプレート    ファイルのアップロードから、下記コードをyml形式でアップロードし実行します。  コードを表示 AWSTemplateFormatVersion : 2010-09-09 Metadata : AWS::CloudFormation::Interface : ParameterGroups : - Label : default : WAF Configuration Parameters : - Prefix - WhiteListIP - RateLimit - SwitchGeoRestriction - WhiteListGeoRestriction Parameters : Prefix : Type : String Default : ddos ### 社内のIP等、許可するIPを設定する WhiteListIP : Type : CommaDelimitedList Default : xx.xx.xx.xx/xx Description : Set IPs to Whitelist. Commas allow multiple sets(e.g. xx.xx.0.0/16, xx.xx.xx.xx/32). RateLimit : Type : Number Default : 100 Description : Set value of WAF Rate Limit ### 地理的一致ルールを有効化したい場合はONにする SwitchGeoRestriction : Type : String AllowedValues : [ "ON" , "OFF" ] Description : Select "ON" to block access except in designated countries, or "OFF" to not configure. ### アクセス許可したい国のコードを入力する(SwitchGeoRestrictionがOFFの場合はデフォルトのまま変更不要) WhiteListGeoRestriction : Type : CommaDelimitedList Default : JP Description : Set CountryCodes to which access is allowed. Commas allow multiple sets(e.g. JP, US). - https://docs.aws.amazon.com/ja_jp/waf/latest/APIReference/API_GeoMatchStatement.html Conditions : GeoRestriction : !Equals [ "ON" , !Ref SwitchGeoRestriction ] Resources : WebACL : Type : AWS::WAFv2::WebACL Properties : Name : !Ref Prefix DefaultAction : Allow : {} Scope : CLOUDFRONT VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : !Ref Prefix SampledRequestsEnabled : true Rules : - Name : Custom-WhiteListIPSet Action : Allow : {} Priority : 0 Statement : IPSetReferenceStatement : Arn : !GetAtt WhiteListIPSet.Arn VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : Custom-WhiteListIPSet SampledRequestsEnabled : true - Name : AWS-AWSManagedRulesCommonRuleSet Priority : 1 Statement : ManagedRuleGroupStatement : VendorName : AWS Name : AWSManagedRulesCommonRuleSet OverrideAction : None : {} VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : AWSManagedRulesCommonRuleSet SampledRequestsEnabled : true - Name : AWS-AWSManagedRulesKnownBadInputsRuleSet Priority : 2 Statement : ManagedRuleGroupStatement : VendorName : AWS Name : AWSManagedRulesKnownBadInputsRuleSet OverrideAction : None : {} VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : AWSManagedRulesKnownBadInputsRuleSet SampledRequestsEnabled : true - Name : AWS-AWSManagedRulesAmazonIpReputationList Priority : 3 Statement : ManagedRuleGroupStatement : VendorName : AWS Name : AWSManagedRulesAmazonIpReputationList OverrideAction : None : {} VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : AWSManagedRulesAmazonIpReputationList SampledRequestsEnabled : true - Name : Custom-Ratebased Action : Block : {} Priority : 4 Statement : RateBasedStatement : AggregateKeyType : IP Limit : !Ref RateLimit ScopeDownStatement : NotStatement : Statement : IPSetReferenceStatement : Arn : !GetAtt WhiteListIPSet.Arn VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : Custom-Ratebased SampledRequestsEnabled : true - !If - GeoRestriction - Name : Custom-GeoRestriction Action : Block : {} Priority : 5 Statement : NotStatement : Statement : GeoMatchStatement : CountryCodes : !Ref WhiteListGeoRestriction VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : Custom-GeoRestriction SampledRequestsEnabled : true - Ref : AWS::NoValue WhiteListIPSet : Type : "AWS::WAFv2::IPSet" Properties : Name : Custom-ipaddress-whitelist Scope : CLOUDFRONT IPAddressVersion : IPV4 Addresses : !Ref WhiteListIP   2. 作成されたWeb ACL を、対象のCloudFront ディストリビューション に手動でアタッチします。    詳細な手順を確認したい場合は下記をご参考ください。    参考: Web ACLとCloudFrontディストリビューションとの関連付け   (B)最前段がALBで、CloudFrontなしの構成   CloudFormationでリソースがあるリージョンを選択し、スタックの作成、テンプレートファイルの   アップロードから下記コードをyml形式でアップロードし実行します。   ※作成されるWeb ACL は、対象のALBに自動でアタッチされます。  コードを表示 AWSTemplateFormatVersion : 2010-09-09 Metadata : AWS::CloudFormation::Interface : ParameterGroups : - Label : default : WAF Configuration Parameters : - Prefix - WebAclAssociationResourceArn - WhiteListIP - RateLimit - SwitchGeoRestriction - WhiteListGeoRestriction Parameters : Prefix : Type : String Default : ddos ### ALBのARNを入力する WebAclAssociationResourceArn : Type : String Default : "arn:aws:elasticloadbalancing:ap-northeast-1:XXXXXXXXXXXX:loadbalancer/app/XXXXXXXXXXXX" Description : Enter RegionalResource(ALB) ARN to associate with WEBACL. ### 社内のIP等、許可するIPを設定する WhiteListIP : Type : CommaDelimitedList Default : xx.xx.xx.xx/xx Description : Set IPs to Whitelist. Commas allow multiple sets(e.g. xx.xx.0.0/16, xx.xx.xx.xx/32). RateLimit : Type : Number Default : 100 Description : Set value of WAF Rate Limit ### 地理的一致ルールを有効化したい場合はONにする SwitchGeoRestriction : Type : String AllowedValues : [ "ON" , "OFF" ] Description : Select "ON" to block access except in designated countries, or "OFF" to not configure. ### アクセス許可したい国のコードを入力する(SwitchGeoRestrictionがOFFの場合はデフォルトの値で変更不要) WhiteListGeoRestriction : Type : CommaDelimitedList Default : JP Description : Set CountryCodes to which access is allowed. Commas allow multiple sets(e.g. JP, US). - https://docs.aws.amazon.com/ja_jp/waf/latest/APIReference/API_GeoMatchStatement.html Conditions : GeoRestriction : !Equals [ "ON" , !Ref SwitchGeoRestriction ] Resources : WebACL : Type : AWS::WAFv2::WebACL Properties : Name : !Ref Prefix DefaultAction : Allow : {} Scope : REGIONAL VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : !Ref Prefix SampledRequestsEnabled : true Rules : - Name : Custom-WhiteListIPSet Action : Allow : {} Priority : 0 Statement : IPSetReferenceStatement : Arn : !GetAtt WhiteListIPSet.Arn VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : Custom-WhiteListIPSet SampledRequestsEnabled : true - Name : AWS-AWSManagedRulesCommonRuleSet Priority : 1 Statement : ManagedRuleGroupStatement : VendorName : AWS Name : AWSManagedRulesCommonRuleSet OverrideAction : None : {} VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : AWSManagedRulesCommonRuleSet SampledRequestsEnabled : true - Name : AWS-AWSManagedRulesKnownBadInputsRuleSet Priority : 2 Statement : ManagedRuleGroupStatement : VendorName : AWS Name : AWSManagedRulesKnownBadInputsRuleSet OverrideAction : None : {} VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : AWSManagedRulesKnownBadInputsRuleSet SampledRequestsEnabled : true - Name : AWS-AWSManagedRulesAmazonIpReputationList Priority : 3 Statement : ManagedRuleGroupStatement : VendorName : AWS Name : AWSManagedRulesAmazonIpReputationList OverrideAction : None : {} VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : AWSManagedRulesAmazonIpReputationList SampledRequestsEnabled : true - Name : Custom-Ratebased Action : Block : {} Priority : 4 Statement : RateBasedStatement : AggregateKeyType : IP Limit : !Ref RateLimit ScopeDownStatement : NotStatement : Statement : IPSetReferenceStatement : Arn : !GetAtt WhiteListIPSet.Arn VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : Custom-Ratebased SampledRequestsEnabled : true - !If - GeoRestriction - Name : Custom-GeoRestriction Action : Block : {} Priority : 5 Statement : NotStatement : Statement : GeoMatchStatement : CountryCodes : !Ref WhiteListGeoRestriction VisibilityConfig : CloudWatchMetricsEnabled : true MetricName : Custom-GeoRestriction SampledRequestsEnabled : true - Ref : AWS::NoValue WhiteListIPSet : Type : "AWS::WAFv2::IPSet" Properties : Name : Custom-ipaddress-whitelist Scope : REGIONAL IPAddressVersion : IPV4 Addresses : !Ref WhiteListIP WebACLAssociation : Type : AWS::WAFv2::WebACLAssociation Properties : ResourceArn : !Ref WebAclAssociationResourceArn WebACLArn : !GetAtt WebACL.Arn   (C)CloudFront、ALBが両方ともない構成(A、Bで解消しない場合もこちら)   この場合、 AWS WAFはアタッチできないため、他の手を打つ必要があります。   なお、上段A、Bで解消しない場合も最終手段として下記の作業を行うことになると考えます。   以下α、βいずれかを判断の上、対応してください。   (α)コストが掛かってもシステム稼働を優先したい    ・複数 インスタンス 構成かつAuto Scaling Groupで稼働している場合      Auto Scalingの インスタンス 最大台数を増やします。    ・単一 インスタンス 等、Auto Scaling Groupを利用せずに稼働している場合       インスタンス タイプのスケールアップを実施します。   (β)システム稼働よりもDDoS被害(コスト)軽減を優先したい     対象EC2を停止します。 【ポイント解説】 Aに関して、CloudFormationでは既存のCloudFrontに AWS WAFをアタッチすることができません。 スタック作成後、手動でCloudFrontにアタッチする必要があります。 A、B共通して以下のルールが作成されます。優先度順に記載します。 ホワイトリスト IP(許可) ・ParametersのWhiteListIPに社内のIP等、許可するIPを入力(複数可) AWS マネージドルール(拒否) ・AWSManagedRulesCommonRuleSet ・AWSManagedRulesKnownBadInputsRuleSet ・AWSManagedRulesAmazonIpReputationList レートベースのルール(アクセス制限) ・ParametersのRateLimitにレート制限値を入力 ・ParametersのWhiteListIPで設定したIPは対象外 地理的一致ルール(許可) ・ParametersのSwitchGeoRestrictionをONにすることで有効化 ・ParametersのWhiteListGeoRestrictionにアクセス許可する国のコードを入力(複数可)  参考: CountryCodes ・ParametersのSwitchGeoRestrictionをOFFにする場合、デフォルトの値から変更不要 ③GuardDutyの全リージョン有効化   ガイダンス によると、より悪意のある攻撃から注意を反らすために DDoS攻撃 が使用されることもある  との記載がありました(P4)。 AWS の脅威検知サービスであるGuardDutyを全リージョン有効化  していない場合は、このタイミングで有効にすることをお勧めします。  以下のサイトでは、全リージョン一括で有効化して通知設定する方法が紹介されていました。  参考: https://dev.classmethod.jp/articles/set-guardduty-all-region/ 保全 ・CloudWatch Logs等、関連するログのエクスポート(ログローテーションによる消失を回避するため)。 事後調査 ・ログの分析、原因調査。 事後対策 ・今回適用したネットワーク ACL と AWS WAFについて、アタッチを継続するか、設定変更するか等を判断。  今回作成したリソースは、CloudFormationスタックを削除することで消すことができる。 ・ アーキテクチャ の見直し( インスタンス をプライベートサブネットに設置、CloudFrontの導入、Route53への移行等)。 ・Auto Scalingの最大台数、 インスタンス タイプの見直し。 ・セキュリティグループの設定見直し。 まとめ DDoS攻撃 を受けた時の初動対応をできるだけ自動化してみました。 本記事が皆様のお役に立てれば幸いです。 〜最後に〜 私たちは同じチームで働いてくれる仲間を大募集しています!たくさんのご応募お待ちしています。 - セキュリティエンジニア(セキュリティ設計) 執筆: @fuku.dancho 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
アバター
おはようございます!こんにちは!こんばんは! 電通国際情報サービス 、X(クロス) イノベーション 本部 デジタルエンゲージメントセンターの根本康平です。 先日、 Salesforce 資格の 1 つ「 Salesforce 認定 アドミニストレーター 」を受験し合格しました。どのような対策をしたのか・試験がどのような感じで行われたのかを共有します。 他のブログで書かれていた情報とはかなりイメージが違いました!  その点についても共有します。あくまでも個人的な見解ですので、信用しすぎないようにしてください。また、リンク先のURLが変更され情報が閲覧できなくなる場合もあります。ご了承ください。 そもそもどんな試験? 試験概要・私の試験結果 試験当日の流れ 試験申し込み 事前準備 試験開始 勉強方法 試験を終えて 一言アドバイス 参考 10 月に取り組んだ Trailhead そもそもどんな試験? 公式サイトには「管理者、 コンサルタント 、アーキテクトにおすすめのファーストステップ」と書いてあります。 つまり、 Salesforce 初学者が最初に受けるべき試験かと思います。 試験概要・私の試験結果 内容:多肢選択/複数選択方式で 60 問 試験時間:105 分 合格ライン:65% 受験方法:オンライン(自宅やオフィス) or テストセンター 前提資格や条件:なし 次に出題範囲とその割合についてです。(括弧内に私の試験での正答率を示します) 範囲 出題割合 私の正答率 組織の設定 3% 50% ユーザの設定 7% 66% セキュリティとアクセス 13% 37% 標準オブジェクトとカスタムオブジェクト 14% 88% 営業アプリケーションと マーケティング アプリケーション 14% 75% サービスアプリケーションとサポートアプリケーション 13% 75% 活動の管理 3% 100% データの管理 10% 83% 分析 - レポートと ダッシュ ボード 10% 83% ワークフロー / プロセスの自動化 8% 100% デスクトップとモバイルの管理 3% 0% APPEXCHANGE 2% 100% なお、試験を受ける時期によって出題範囲と割合は大きく変わります!ここに記載しているのは Summer'22 の情報です。 Winter'23では出題割合は大きく変化しています。必ず公式ドキュメントを確認して出題範囲と割合を確認しましょう! 試験当日の流れ 受験方法は 2 種類 オンラインで自宅やオフィスから受験 → 今回私はこちらを選択 テストセンターで受験 試験申し込み オンライン試験は 24 時間、いつでも受験可能です。 申し込み可能な日程は随時更新されます。数分前には予約できなかった日程もページを更新すると申し込み可能になっていたりします! オンライン試験は、試験予定時間の 24 時間より前であれば無料でキャンセル・日程変更が可能です。 事前準備 試験前までに 2 つの作業をする必要があります。この事前準備は数分で完了しますが、試験直前に慌てないよう早めに準備しておくべきです。 顔認証システムへの登録(PCカメラに自分の顔を映すだけ。数十秒でOK!) 試験用のソフトをダウンロード(数分で完了します) 試験開始 オンライン試験は予約時間の 10 分前から受験用サイトを開くことができます。 試験開始サイトを開くとまずは顔認証です。事前準備で登録した顔と受験者の顔が一致するかシステムで判断されます。 顔認証が終われば実際に問題を解いていきます。試験中カメラとマイク機能は常にオンですが、自分の顔や試験官の顔が表示されるようなことはなく、集中して試験を受けることができました。 とあるブログには「カメラで机の上を映し本や携帯がないことを試験官に見せなければならない」と書いてありましたが、そのような場面はありませんでした! (せっかく机の上をきれいにしたのでせっかくなら見ていただきたかった・・) また「試験中のトラブルが多発」とも書いてありましたが、私はとてもスムーズに受験することができました! (記事で書かれていたのが 1・2 年前の話だったのでだいぶ改善されたのだと思います) 試験の文章は日本語ですが、所々翻訳が微妙な部分があります。ただ、問題を解くのに支障があるレベルではないので心配しなくて大丈夫だと思います。 全て解き終わったら試験時間をカットして回答を提出できます。回答を提出すると、次の画面に試験結果が即表示されます。合格の場合、【合格】と表示されて得点分布を確認できます。(後ほどメールにも送られてくるのでメモする必要はないです) 勉強方法 私は 10/1 にデジタルエンゲージメントセンターに配属となり、そこから Salesforce の学習を始めました。10/1 から試験を受けた 11/20 までの過程を書いていきます。 10月 Salesforce には E ラーニングのようなサイトがあります。「Trailhead」です。10 月は Trailhead を通して学習をしました。Trailhead で学習したコースについては本投稿の下部「参考」に書いています。10 月は試験に受かることよりも Salesforce を知るという目的が強かったです。 11月 大きく分けて 3 つのことに取り組みました。試験 2 週間前くらいから「試験に受かる」を目的に勉強しました。 Trailhead Trailmix 【Salesforce公式】認定アドミニストレーター資格 対策 Salesforce Certification Days 認定 アドミニストレーター 試験対策 セミ ナー ネットにある模擬問題演習 1 つ目の Trailmix については、非常に量が多く、2 週間前からでは終わりませんでした( 64% 分実施してやめました)。もし、この Trailmix を完全に終えてから試験に挑みたい場合は 2 週間以上前から取り組んだ方が良いと思います。ちなみに、1 日あたりの勉強に充てた時間は平均 5~6 時間程度です。 2 つ目の「 Salesforce Certification Days」とは Salesforce 社が実施している無料の資格対策 セミ ナーです( 詳細はこちら )。非常にわかりやすく、試験に出るポイントも教えてくれるのでぜひ参加することをお勧めします!さらに、私が受けたときには本試験 70% 引きクーポンコードも貰えました! 3 つ目の模擬問題演習は、ネットで「 アドミニストレーター 試験 模擬問題」と検索して表示されたサイトに書かれている問題をひたすらに解くということをやりました。そのサイトの解答が必ずしも正しいかはわかりませんが、自分なりに理解して回答できるまで 3 周くらい繰り返し取り組みました。 試験を終えて 試験で問題を解いていた感覚としては「8 割は確実に取れているな」と思っていたものの、出題割合を考慮して総合正答率を計算すると 73% でした。思っていた以上に低い結果だったなというのが感想です。特に、「セキュリティとアクセス」の正答率が低く衝撃を受けています。今後、セキュリティとアクセスの分野の知識をさらに吸収していきたいと思います! 一言アド バイス 試験勉強や無料試験対策 セミ ナー等を通して「これは覚えてた方がいい!」と思ったポイントを書いてみます! アクセスを制限するのがプロファイル 制限されたアクセスを緩和・開放するのが権限セット ログイン可否はプロファイルのIP制限とプロファイルの時間のみに依存する!(組織の信頼した IPアドレス 範囲内でも外でもログインはできる!範囲内なら即ログイン、範囲外なら追加の処理を通してログイン可) インポートウィザードは、ケース・商談オブジェクトのインポートできない! これを覚えるだけで 60 問中 4~5 問は解けると思います!ぜひ覚えてみてください! 参考 10 月に取り組んだ Trailhead Trailhead を使用した Salesforce の学習 Salesforce の概要 システム管理者初級 開発者初級 【Salesforce公式】認定Platformアプリケーションビルダー資格 対策 これから アドミニストレーター 試験を受ける方々にとって、何か1つでもプラスになれば嬉しいです。 私たちは同じチームで働いてくれる仲間を探しています。今回のエントリで紹介したような仕事に興味のある方、ご応募をお待ちしています。 CRMソリューションコンサルタント 【新卒採用】ISID 採用ページ 執筆: @nemoto.kouhei 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
アバター
おはようございます!こんにちは!こんばんは! 電通国際情報サービス 、X(クロス) イノベーション 本部 デジタルエンゲージメントセンターの根本康平です。 先日、 Salesforce 資格の 1 つ「 Salesforce 認定 アドミニストレーター 」を受験し合格しました。どのような対策をしたのか・試験がどのような感じで行われたのかを共有します。 他のブログで書かれていた情報とはかなりイメージが違いました!  その点についても共有します。あくまでも個人的な見解ですので、信用しすぎないようにしてください。また、リンク先のURLが変更され情報が閲覧できなくなる場合もあります。ご了承ください。 そもそもどんな試験? 試験概要・私の試験結果 試験当日の流れ 試験申し込み 事前準備 試験開始 勉強方法 試験を終えて 一言アドバイス 参考 10 月に取り組んだ Trailhead そもそもどんな試験? 公式サイトには「管理者、 コンサルタント 、アーキテクトにおすすめのファーストステップ」と書いてあります。 つまり、 Salesforce 初学者が最初に受けるべき試験かと思います。 試験概要・私の試験結果 内容:多肢選択/複数選択方式で 60 問 試験時間:105 分 合格ライン:65% 受験方法:オンライン(自宅やオフィス) or テストセンター 前提資格や条件:なし 次に出題範囲とその割合についてです。(括弧内に私の試験での正答率を示します) 範囲 出題割合 私の正答率 組織の設定 3% 50% ユーザの設定 7% 66% セキュリティとアクセス 13% 37% 標準オブジェクトとカスタムオブジェクト 14% 88% 営業アプリケーションと マーケティング アプリケーション 14% 75% サービスアプリケーションとサポートアプリケーション 13% 75% 活動の管理 3% 100% データの管理 10% 83% 分析 - レポートと ダッシュ ボード 10% 83% ワークフロー / プロセスの自動化 8% 100% デスクトップとモバイルの管理 3% 0% APPEXCHANGE 2% 100% なお、試験を受ける時期によって出題範囲と割合は大きく変わります!ここに記載しているのは Summer'22 の情報です。 Winter'23では出題割合は大きく変化しています。必ず公式ドキュメントを確認して出題範囲と割合を確認しましょう! 試験当日の流れ 受験方法は 2 種類 オンラインで自宅やオフィスから受験 → 今回私はこちらを選択 テストセンターで受験 試験申し込み オンライン試験は 24 時間、いつでも受験可能です。 申し込み可能な日程は随時更新されます。数分前には予約できなかった日程もページを更新すると申し込み可能になっていたりします! オンライン試験は、試験予定時間の 24 時間より前であれば無料でキャンセル・日程変更が可能です。 事前準備 試験前までに 2 つの作業をする必要があります。この事前準備は数分で完了しますが、試験直前に慌てないよう早めに準備しておくべきです。 顔認証システムへの登録(PCカメラに自分の顔を映すだけ。数十秒でOK!) 試験用のソフトをダウンロード(数分で完了します) 試験開始 オンライン試験は予約時間の 10 分前から受験用サイトを開くことができます。 試験開始サイトを開くとまずは顔認証です。事前準備で登録した顔と受験者の顔が一致するかシステムで判断されます。 顔認証が終われば実際に問題を解いていきます。試験中カメラとマイク機能は常にオンですが、自分の顔や試験官の顔が表示されるようなことはなく、集中して試験を受けることができました。 とあるブログには「カメラで机の上を映し本や携帯がないことを試験官に見せなければならない」と書いてありましたが、そのような場面はありませんでした! (せっかく机の上をきれいにしたのでせっかくなら見ていただきたかった・・) また「試験中のトラブルが多発」とも書いてありましたが、私はとてもスムーズに受験することができました! (記事で書かれていたのが 1・2 年前の話だったのでだいぶ改善されたのだと思います) 試験の文章は日本語ですが、所々翻訳が微妙な部分があります。ただ、問題を解くのに支障があるレベルではないので心配しなくて大丈夫だと思います。 全て解き終わったら試験時間をカットして回答を提出できます。回答を提出すると、次の画面に試験結果が即表示されます。合格の場合、【合格】と表示されて得点分布を確認できます。(後ほどメールにも送られてくるのでメモする必要はないです) 勉強方法 私は 10/1 にデジタルエンゲージメントセンターに配属となり、そこから Salesforce の学習を始めました。10/1 から試験を受けた 11/20 までの過程を書いていきます。 10月 Salesforce には E ラーニングのようなサイトがあります。「Trailhead」です。10 月は Trailhead を通して学習をしました。Trailhead で学習したコースについては本投稿の下部「参考」に書いています。10 月は試験に受かることよりも Salesforce を知るという目的が強かったです。 11月 大きく分けて 3 つのことに取り組みました。試験 2 週間前くらいから「試験に受かる」を目的に勉強しました。 Trailhead Trailmix 【Salesforce公式】認定アドミニストレーター資格 対策 Salesforce Certification Days 認定 アドミニストレーター 試験対策 セミ ナー ネットにある模擬問題演習 1 つ目の Trailmix については、非常に量が多く、2 週間前からでは終わりませんでした( 64% 分実施してやめました)。もし、この Trailmix を完全に終えてから試験に挑みたい場合は 2 週間以上前から取り組んだ方が良いと思います。ちなみに、1 日あたりの勉強に充てた時間は平均 5~6 時間程度です。 2 つ目の「 Salesforce Certification Days」とは Salesforce 社が実施している無料の資格対策 セミ ナーです( 詳細はこちら )。非常にわかりやすく、試験に出るポイントも教えてくれるのでぜひ参加することをお勧めします!さらに、私が受けたときには本試験 70% 引きクーポンコードも貰えました! 3 つ目の模擬問題演習は、ネットで「 アドミニストレーター 試験 模擬問題」と検索して表示されたサイトに書かれている問題をひたすらに解くということをやりました。そのサイトの解答が必ずしも正しいかはわかりませんが、自分なりに理解して回答できるまで 3 周くらい繰り返し取り組みました。 試験を終えて 試験で問題を解いていた感覚としては「8 割は確実に取れているな」と思っていたものの、出題割合を考慮して総合正答率を計算すると 73% でした。思っていた以上に低い結果だったなというのが感想です。特に、「セキュリティとアクセス」の正答率が低く衝撃を受けています。今後、セキュリティとアクセスの分野の知識をさらに吸収していきたいと思います! 一言アド バイス 試験勉強や無料試験対策 セミ ナー等を通して「これは覚えてた方がいい!」と思ったポイントを書いてみます! アクセスを制限するのがプロファイル 制限されたアクセスを緩和・開放するのが権限セット ログイン可否はプロファイルのIP制限とプロファイルの時間のみに依存する!(組織の信頼した IPアドレス 範囲内でも外でもログインはできる!範囲内なら即ログイン、範囲外なら追加の処理を通してログイン可) インポートウィザードは、ケース・商談オブジェクトのインポートできない! これを覚えるだけで 60 問中 4~5 問は解けると思います!ぜひ覚えてみてください! 参考 10 月に取り組んだ Trailhead Trailhead を使用した Salesforce の学習 Salesforce の概要 システム管理者初級 開発者初級 【Salesforce公式】認定Platformアプリケーションビルダー資格 対策 これから アドミニストレーター 試験を受ける方々にとって、何か1つでもプラスになれば嬉しいです。 私たちは同じチームで働いてくれる仲間を探しています。今回のエントリで紹介したような仕事に興味のある方、ご応募をお待ちしています。 CRMソリューションコンサルタント 【新卒採用】ISID 採用ページ 執筆: @nemoto.kouhei 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
アバター
電通国際情報サービス 、オープン イノベーション ラボの 比嘉康雄 です。 Stable Diffusion シリーズ、今回のテーマは、 Waifu Diffusion 1.3.5_80000 です。 Waifu Diffusion というのは、 Stable Diffusion から派生していて、 美少女アニメ 画に強いという特徴を持っています。 80000 というのは、学習の度合いを表していて、「まだ完成してないけど、みんなの反応を見たい」ということで、プレビューとしてリリースされたんだと思います。 Hugging Face 上のページは、 こちら 。 バージョンが1.4になっているので、学習が進んで完成すると、 1.3.5 が 1.4 になるんでしょうね。 Stable Diffusionのおすすめコンテンツはこちら。 Waifu Diffusion 1.3.5_80000 v2.1 金髪美女写真 v2.1 美少女アニメ画 v2.1 AUTOMATIC1111 v2.0 美少女イラスト v1.5 美少女画検証 美少女アニメ画改善版 美少女を高確率で出す呪文編 美少女アニメ画編 美少女写真編 女性イラスト編 長い呪文は切り捨てられる編 AUTOMATIC1111に対応したColabノートブック VAEの比較 仲間募集 Stable Diffusionの全コンテンツ AUTOMATIC1111に対応したColabノートブック 今回の Waifu Diffusion 1.3.5_80000 には、2つのVAEが存在します。 kl-f8-anime.ckpt と kl-f8-anime2.ckpt です。 kl-f8-anime.ckpt は、元のVAEをファインチューニングしたものです。ファインチューニングとは、元のVAEに追加で、いくつか画像を学習させたという意味です。 kl-f8-anime2.ckpt は、元のVAEを 刈り込んだ(pruned) ものです。 刈り込んだ の意味は、たぶん、元のVAEの学習に使った画像のうち、イマイチなものを取り除いて学習させたという意味なんじゃないかと思います。 kl-f8-anime.ckpt を使ったAUTOMATIC1111に対応したColabノートブックは、 こちら 。 kl-f8-anime2.ckpt を使ったAUTOMATIC1111に対応したColabノートブックは、 こちら 。 VAEの比較 SeedをふくめたすべてのパラメータをVAE以外は同じにして比べてみました。 kl-f8-anime.ckpt その一 kl-f8-anime2.ckpt その一 kl-f8-anime.ckpt その二 kl-f8-anime2.ckpt その二 kl-f8-anime.ckpt その三 kl-f8-anime2.ckpt その三 ぼくの感想としては、 kl-f8-anime.ckpt の方が、全体的に明るいが、ちょっとチープ感があるなぁという感じです。 表現が難しいんですが、もう少し垢抜けた感じがほしいところです。同じ呪文で、 Cool Japan Diffusion 2.0で出すとこんな感じです。 垢抜けたという感じが伝わるでしょうか。 今回使った通常呪文 masterpiece high quality highly detailed kawaii princess white glowing skin kawaii face with blush blue eyes with eyelashes long waved hair (cleavage breasts:0.7) open shoulders gothic lolita glossy dress with ruffles gorgeous jewelry accessories anime gorgeous background centered composition lim lighting intense shadows 通常呪文の改行版 masterpiece high quality highly detailed kawaii princess white glowing skin kawaii face with blush blue eyes with eyelashes long waved hair (cleavage breasts:0.7) open shoulders gothic lolita glossy dress with ruffles gorgeous jewelry accessories anime gorgeous background centered composition lim lighting intense shadows 今回使ったネガティブ呪文 blender deformed mutated disfigured lowres blurred repetitive double mutated hands bad hands missing hands extra hands liquid hands poorly drawn hands mutated fingers bad fingers missing fingers extra fingers liquid fingers poorly drawn fingers partial head bad face small face partial face bad eyes missing eyes too big eyes bad eyebrows bad eyelashes bad nose missing nose bad mouth missing mouth open mouth bad ears thick lips chest pad bad legs missing legs extra legs bad arms missing arms extra arms low quality normal quality crown black and white 今回使ったネガティブ呪文の改行版 blender deformed mutated disfigured lowres blurred repetitive double mutated hands bad hands missing hands extra hands liquid hands poorly drawn hands mutated fingers bad fingers missing fingers extra fingers liquid fingers poorly drawn fingers partial head bad face small face partial face bad eyes missing eyes too big eyes bad eyebrows bad eyelashes bad nose missing nose bad mouth missing mouth open mouth bad ears thick lips bad legs missing legs extra legs bad arms missing arms extra arms low quality normal quality crown black and white 仲間募集 私たちは一緒に働いてくれる仲間を募集しています! ソリューションアーキテクト Stable Diffusionの全コンテンツ 人物写真編 レンズ編 画像タイプ編 美少女アニメ画編 美少女写真編 女性イラスト編 美しい夜空を見渡す男編 魅惑的な女アニメ画(トゥーンレンダリング)編 美少女を高確率で出す呪文編 長い呪文は切り捨てられる編 蒸気機関が高度に発達したレトロなアニメ(スチームパンク)の世界観編 A as Bの呪文による画像合成編 かわいい動物の擬人化編 バベルの塔のイラスト編 TPU版の使い方 美少女アニメ画改善版 v1.5 美少女画検証 東京タワーの写真 折り紙合体変形ロボ v2.0 美少女イラスト v2.1 AUTOMATIC1111 v2.1 美少女アニメ画 v2.1 金髪美女写真 Waifu Diffusion 1.3.5_80000 執筆: @higa 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
アバター
電通国際情報サービス 、オープン イノベーション ラボの 比嘉康雄 です。 Stable Diffusion シリーズ、今回のテーマは、 Waifu Diffusion 1.3.5_80000 です。 Waifu Diffusion というのは、 Stable Diffusion から派生していて、 美少女アニメ 画に強いという特徴を持っています。 80000 というのは、学習の度合いを表していて、「まだ完成してないけど、みんなの反応を見たい」ということで、プレビューとしてリリースされたんだと思います。 Hugging Face 上のページは、 こちら 。 バージョンが1.4になっているので、学習が進んで完成すると、 1.3.5 が 1.4 になるんでしょうね。 Stable Diffusionのおすすめコンテンツはこちら。 Waifu Diffusion 1.3.5_80000 v2.1 金髪美女写真 v2.1 美少女アニメ画 v2.1 AUTOMATIC1111 v2.0 美少女イラスト v1.5 美少女画検証 美少女アニメ画改善版 美少女を高確率で出す呪文編 美少女アニメ画編 美少女写真編 女性イラスト編 長い呪文は切り捨てられる編 AUTOMATIC1111に対応したColabノートブック VAEの比較 仲間募集 Stable Diffusionの全コンテンツ AUTOMATIC1111に対応したColabノートブック 今回の Waifu Diffusion 1.3.5_80000 には、2つのVAEが存在します。 kl-f8-anime.ckpt と kl-f8-anime2.ckpt です。 kl-f8-anime.ckpt は、元のVAEをファインチューニングしたものです。ファインチューニングとは、元のVAEに追加で、いくつか画像を学習させたという意味です。 kl-f8-anime2.ckpt は、元のVAEを 刈り込んだ(pruned) ものです。 刈り込んだ の意味は、たぶん、元のVAEの学習に使った画像のうち、イマイチなものを取り除いて学習させたという意味なんじゃないかと思います。 kl-f8-anime.ckpt を使ったAUTOMATIC1111に対応したColabノートブックは、 こちら 。 kl-f8-anime2.ckpt を使ったAUTOMATIC1111に対応したColabノートブックは、 こちら 。 VAEの比較 SeedをふくめたすべてのパラメータをVAE以外は同じにして比べてみました。 kl-f8-anime.ckpt その一 kl-f8-anime2.ckpt その一 kl-f8-anime.ckpt その二 kl-f8-anime2.ckpt その二 kl-f8-anime.ckpt その三 kl-f8-anime2.ckpt その三 ぼくの感想としては、 kl-f8-anime.ckpt の方が、全体的に明るいが、ちょっとチープ感があるなぁという感じです。 表現が難しいんですが、もう少し垢抜けた感じがほしいところです。同じ呪文で、 Cool Japan Diffusion 2.0で出すとこんな感じです。 垢抜けたという感じが伝わるでしょうか。 今回使った通常呪文 masterpiece high quality highly detailed kawaii princess white glowing skin kawaii face with blush blue eyes with eyelashes long waved hair (cleavage breasts:0.7) open shoulders gothic lolita glossy dress with ruffles gorgeous jewelry accessories anime gorgeous background centered composition lim lighting intense shadows 通常呪文の改行版 masterpiece high quality highly detailed kawaii princess white glowing skin kawaii face with blush blue eyes with eyelashes long waved hair (cleavage breasts:0.7) open shoulders gothic lolita glossy dress with ruffles gorgeous jewelry accessories anime gorgeous background centered composition lim lighting intense shadows 今回使ったネガティブ呪文 blender deformed mutated disfigured lowres blurred repetitive double mutated hands bad hands missing hands extra hands liquid hands poorly drawn hands mutated fingers bad fingers missing fingers extra fingers liquid fingers poorly drawn fingers partial head bad face small face partial face bad eyes missing eyes too big eyes bad eyebrows bad eyelashes bad nose missing nose bad mouth missing mouth open mouth bad ears thick lips chest pad bad legs missing legs extra legs bad arms missing arms extra arms low quality normal quality crown black and white 今回使ったネガティブ呪文の改行版 blender deformed mutated disfigured lowres blurred repetitive double mutated hands bad hands missing hands extra hands liquid hands poorly drawn hands mutated fingers bad fingers missing fingers extra fingers liquid fingers poorly drawn fingers partial head bad face small face partial face bad eyes missing eyes too big eyes bad eyebrows bad eyelashes bad nose missing nose bad mouth missing mouth open mouth bad ears thick lips bad legs missing legs extra legs bad arms missing arms extra arms low quality normal quality crown black and white 仲間募集 私たちは一緒に働いてくれる仲間を募集しています! ソリューションアーキテクト Stable Diffusionの全コンテンツ 人物写真編 レンズ編 画像タイプ編 美少女アニメ画編 美少女写真編 女性イラスト編 美しい夜空を見渡す男編 魅惑的な女アニメ画(トゥーンレンダリング)編 美少女を高確率で出す呪文編 長い呪文は切り捨てられる編 蒸気機関が高度に発達したレトロなアニメ(スチームパンク)の世界観編 A as Bの呪文による画像合成編 かわいい動物の擬人化編 バベルの塔のイラスト編 TPU版の使い方 美少女アニメ画改善版 v1.5 美少女画検証 東京タワーの写真 折り紙合体変形ロボ v2.0 美少女イラスト v2.1 AUTOMATIC1111 v2.1 美少女アニメ画 v2.1 金髪美女写真 Waifu Diffusion 1.3.5_80000 執筆: @higa 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )
アバター
皆様こんにちは。 XI本部 AIトランスフォーメーションセンター AI製品開発グループの福竹と申します。 本記事は ISID Techblogの2022年アドベントカレンダー 12/23の記事となります。しかしクリスマスどころか2022年の営業日も残りわずかですね。皆様の2022年はいかがでしたか? もう残り少ないですが、ここらで2022年を「ふりかえって」おきたいところですね?(強引なアイスブレイク) という訳で本記事のテーマは「ふりかえり」です。 今年一年、執筆者はオンラインホワイトボードツールのmiroを使って、開発チームで「ふりかえり」を行うことがよくありました。この試行錯誤の中で、特に企画側として意識するようになったTipsや課題意識について、本記事では共有したいと思います。あくまで私個人のTipsであり、チーム状況や志向性によって適用できる/できないはあるかと思いますが、このテーマに関心のあるかたへのア イデア や考察につながれば幸いです。 はじめに:ふりかえりとは はじめに:miroとは 事前:ふりかえりのアジェンダを設計する 目的を明確に決めて、スコープを想起できるよう工夫する バッファを見込んだアジェンダを組む miroのテンプレートを活かして、ホワイトボードを設計する 事中:ふりかえりをファシリテートする Bring everyone to meを要所で使う(乱用しない) 意識して非同期コミュニケーションの時間を作る(コメント機能を活用する) タイマーを意識的に使う(無実にしない) 事後:ふりかえりを、やりっぱなしにしない 折に触れて使う(コンテキストを呼びだすショートカットにする) 収束の段階で出てきたアイデアの種は、無理に皆でまとめない おわりに 参考文献:ふりかえりのアジェンダを組む はじめに:ふりかえりとは チームの活動をより良くするために、チームで企画・実施するプ ラク ティスです。特に「 KPT 」「FUN/DONE/LEARN」など、 アジャイル レトロスペクティブに端を発するアクティビティを、本記事では想定しています。 アジャイル の文脈で生まれたプ ラク ティスですが、チーム活動であれば何にでも汎用的に使えます。入門編については、 昨年の拙記事 をご参考にどうぞ。 はじめに:miroとは オンラインホワイトボードツールの一つです。 https://miro.com/ 同様のツールには Google Jamboard、 Microsoft Whiteboard 、MURAL、 Apple フリーボード、あたりが挙がります。本記事の主眼ではないので細かく触れませんが、個人的に「2022年ベストバイ」の一つに挙げたいくらい気に入っているツールです。本記事の内容はmiroなしでも実践できるものを含みますが、お手元にmiroがあると、より実践が近付くと思います。 前置きはこのくらいにしましょう。ここからは実際のTipsや課題意識について、実際にふりかえりを企画〜実施する時にステップに沿いながら書いていきます。基本的なプロセスは、昨年の記事でも引用した ふりかえりガイドブック が下敷きにありますので、お持ちの方はご参考にしてください。 事前:ふりかえりの アジェンダ を設計する チームの状況にもよりますが「大きめのリリースも終わるし、ここらで次に向けて改善できる所がないか考えたいな」のようなシチュエーションは多いと思います。となると関係者に MTG を設定して、 アジェンダ を決めておく所から始まるでしょう。かっこよく言えば『ふりかえりの設計』です。 目的を明確に決めて、スコープを想起できるよう工夫する アジェンダ を設計するにあたり、最初に 「なぜ、ふりかえりをやるんだっけ?」という目的は 言語化 しておきましょう 。そして目的から逆算した時の 「意識してほしいスコープ」を決めておきましょう 。例を挙げます。 (目的)製品Aの大きめのリリースが完了した。メンバの功績を 言語化 するとともに、次のスプリントで活かせそうなア イデア を考えておく。 (スコープ)前回のふりかえり実施後から、リリース当日までの製品Aに関するアクティビティ こうしてスコープが明瞭になっていれば、例えばこういった工夫ができます。 期間中に取り組んだ製品Aの バックログ 、バーンダウンチャート、前回のふりかえり完了時のmiroボードを用意しておこう。 アジェンダ の最初に、これらを見てもらえる時間も追加しておこう。 メンバの状況にもよりますが、事前ワークのない「ふりかえり」であれば特に効果的だと思います。 バッファを見込んだ アジェンダ を組む 次に アジェンダ を組みます。ワークの選び方は割愛しますが、慣れた フレームワーク や、後述の参考資料からピックアップしていくことになるでしょう。やりたいワークが決まったら、当日の アジェンダ を組むことになります。 この時、 アジェンダ には必ずバッファを入れましょう 。Keep/Problem/Tryで例を挙げます。 Keepをmiroに書く:5分 書かれたKeepを読む:10分 Problemをmiroに書く:5 書かれたProblemを読む:10分 Tryをmiroに書く:5分 書かれたTryを読む:10分 よし!45分!と考えそうになりますが、少なくとも私の場合、この通りになったことがありません。参加者の状況にもよりますが「Problemを読むのに時間がかかる」「Tryを書くのに時間がかかる」なんてことはよくあると思います。なので合計45分でも、思い切って60分取ります。あとは、重要な議論の時間が広がりやすいProblemやTryの時間を先に増やしておくのもいいでしょう。ここで作った余裕を、当日うまく使います(後述)。 miroのテンプレートを活かして、ホワイトボードを設計する アジェンダ が決まったら、事前にmiroのホワイトボードに、当日使うボードを作る必要があります。この時、 なるべくイチからは作らず、miroのテンプレートを利用しましょう 。自作してもいいのですが、ボードの自作は結構楽しく、時間泥棒です。暇な時以外はやめておきましょう。 コミュニティのテンプレートであるMiroverseも有用です。Miroverseは長年英語のボードしかありませんでしたが、ここ最近は日本語のテンプレートも出始めています。ふりかえりガイドブック著者の森さんが KPT のテンプレートを公開してくれています。 Miroverse:KPTふりかえり(日本語) 余談ですが、miroverseには面白いボードも多く、これまた時間泥棒です。ついでなので、私がいつか、訓練されたマグルの集まりで使ってみたいと思っているボードの例を紹介します。 Miroverse:Harry Potter Retrospective 最後に、ここで用意したテンプレートは、編集をロックしておきましょう。ロックしておくことで、メンバが誤って背景のアイテムを消したり、変更してしまったりを防ぐことが出来ます。 事中:ふりかえりをファシリテートする さて、当日です。企画者が ファシリテーター も兼任するケースは多いでしょう。皆がmiroにやってきます。事前に作った アジェンダ を手元に、ふりかえりを開始します。 Bring everyone to meを要所で使う(乱用しない) miroには、参加者全員の画面を強制的に自分の見ている範囲に移動させる Bring everyone to me という機能があります。 アジェンダ の説明やBoard内の誘導には、こちらを 有効に使いましょう 。ただ「最初の説明」「議論の導入」の時など限られたタイミングだけで使うのがおすすめめです。 『メンバーが迷子になることを防ぐ』目的にとどめて使う ほうが、参加側には負荷がかからないように思います。 意識して非同期コミュニケーションの時間を作る(コメント機能を活用する) チームの慣れ具合にもよるのですが、miroボードを前にワークしている時は 「喋らない時間」を意図的に設けたほうが総コミュニケーション量を増やせます 。全てを発話で済ませるのではなく、 miroのコメント機能を有効に使いましょう 。 KPT の例であれば、次のようなイメージです。 Keepをmiroに書く 他のメンバのKeepを読み、コメントを入れる時間を作る Keepをピックアップして発話に入る。どうしても時間がない時はコメントを見ながらピックアップ対象を絞る。 付箋の内容をあえて発話してもらう事で参加を促したいケースは、この限りではありません。ただ、チームメンバーがワークに慣れている等の状況では、このステップを踏んだほうが時間単位でできる議論の量は増えます。 タイマーを意識的に使う(無実にしない) miroには タイマー機能 があります。これも 是非活用しましょう 。タイマーが0になると、アラームでボードを見ている人全員に時間を知らせることができます。 ただタイマーの設定については、 アジェンダ の時間枠を杓子定規に設定するよりは、 議論の様子を見て柔軟に設定時間を変えたほうが効果的 です。どういうことかというと、「この議論はまだ続きそうだな」と思ったら、いたずらに終了のタイマーを鳴らさず、タイマーの時間をそっと追加してしまうのです(ここで最初に作ったバッファを使います)。 この方法がベストであるかは残り時間などの状況にもよります。いっぽうで、頻繁にアラームの音が鳴ってしまうと、それはそれで参加者がアラームの音を気にしなくなる(無実になる)傾向にあります。全体を時間内にきれいに収めるためにも、タイマーは意識的に アジェンダ が切り替わってほしいタイミングでのみ鳴るようにしましょう。 事後:ふりかえりを、やりっぱなしにしない 無事ふりかえりの時間が終わりました。miroボードにメンバーの色々な思いが書き出され、議論も白熱し、良い感じの達成感が残ります。ちょっと消化不良に終わった? そんな時もあります。また挫けずやってみましょう。 折に触れて使う(コンテキストを呼びだすショートカットにする) 使ったホワイトボードは 実施日が分かるようにしておき 、折に触れて「この時こんな議論があったと思うんだけど」と 思い出す時に使いましょう 。ホワイトボードツールの良い所は、議論の過程が、直感的に理解しやすいホワイトボードの形で残ることです。特に定期的なふりかえりの場合、前回のふりかえりボードが同じホワイトボード上にあると非常に便利です。ボードを見ただけで当時のコンテキストをある程度呼び出せるので「前回はこう考えてたけど、結局こうなったな」といった仮説検証的な思考を自然とメンバに想起できます。 また、こういった状態を作るためにも、付箋へのコメント機能は有効活用しておきたい所です。意識してコメント機能を使っていれば、おそらくパッと見て気になった付箋には、コメントが残っているでしょう。議論の過程も残っているとなおよいです。 収束の段階で出てきたア イデア の種は、無理に皆でまとめない 発散→収束の収束のプロセスで、ふと単純なToDoにはなっていない、 ア イデア めいた付箋 が生まれることがあります。こうしたアイテムは 無闇にToDoに落としこまず 、議論の過程をコメントに書くに留めて、 そのまま残してよい と思います。例が出しづらいですが、例えば「AをBと組み合わせてみる」みたいな、まだ妥当性がわからない、実験めいた記述のものが該当するかもしれません。 なぜそうするかというと、こうした ア イデア めいた内容をグループワークの限られた時間内で無理にToDoに落とし込もうとすると、工夫の余地を削った平均値的なものに収束してしまう事が多い からです。なので焦って 言語化 するよりは、挙がった議論の過程だけ残しア イデア の種に留めておきたいのです。実際のところ本当に面白いア イデア は、書いた当人が後日、おもむろにやりはじめたりします(これは弊チームの場合かもしれません)。 (ふりかえりとは少し異なりますが)このあたりは最近読んだ 妄想する頭 思考する手 想像を超えるアイデアのつくり方 という書籍でも、ア イデア づくりの文脈で近い考え方が示されており、非常に共感できました( 第3章2節「ブレストはワークしない」 )。ご興味が有れば、是非。 おわりに いかがでしたか?(定型文) ワークの文脈はチームの数だけありますし、どこまで一般的に適用できるノウハウとなっているかはチームそれぞれかもしれません。ただ私達の試行錯誤が、少しでも同好の士のご参考となっていれば幸いです。 そのまま宣伝ですが、こういった試行錯誤を日々重ねながら、AI技術の社会実装をAIトランスフォーメーションセンターでは進めています。新卒、中途問わず一緒に働いてくださる方を募集しており、ご興味が湧いた方は AITC採用サイト も是非御覧ください。カジュアル面談の申込みもお受付しています。 さらに宣伝ですが、私個人も スクラム マスターとして日々修行しており、今年はチームメンバーと共に アジャイルとスクラムによる開発手法 という書籍の翻訳出版をしました。鈍器一歩手前の分量ですが、とても良い本ですので、ご興味が有れば是非手にとってみてください。 では。メリー・クリスマス!🎅 参考文献:ふりかえりの アジェンダ を組む アジャイルなチームをつくる ふりかえりガイドブック 始め方・ふりかえりの型・手法・マインドセット :まずはここから。購入者特典の「ふりかえり チートシート 」も是非。 ふりかえりカタログ :同著者が無料公開している、ふりかえりのカタログです。 執筆: @fhiroaki 、レビュー: @hashizume.hideki ( Shodo で執筆されました )
アバター
皆様こんにちは。 XI本部 AIトランスフォーメーションセンター AI製品開発グループの福竹と申します。 本記事は ISID Techblogの2022年アドベントカレンダー 12/23の記事となります。しかしクリスマスどころか2022年の営業日も残りわずかですね。皆様の2022年はいかがでしたか? もう残り少ないですが、ここらで2022年を「ふりかえって」おきたいところですね?(強引なアイスブレイク) という訳で本記事のテーマは「ふりかえり」です。 今年一年、執筆者はオンラインホワイトボードツールのmiroを使って、開発チームで「ふりかえり」を行うことがよくありました。この試行錯誤の中で、特に企画側として意識するようになったTipsや課題意識について、本記事では共有したいと思います。あくまで私個人のTipsであり、チーム状況や志向性によって適用できる/できないはあるかと思いますが、このテーマに関心のあるかたへのア イデア や考察につながれば幸いです。 はじめに:ふりかえりとは はじめに:miroとは 事前:ふりかえりのアジェンダを設計する 目的を明確に決めて、スコープを想起できるよう工夫する バッファを見込んだアジェンダを組む miroのテンプレートを活かして、ホワイトボードを設計する 事中:ふりかえりをファシリテートする Bring everyone to meを要所で使う(乱用しない) 意識して非同期コミュニケーションの時間を作る(コメント機能を活用する) タイマーを意識的に使う(無実にしない) 事後:ふりかえりを、やりっぱなしにしない 折に触れて使う(コンテキストを呼びだすショートカットにする) 収束の段階で出てきたアイデアの種は、無理に皆でまとめない おわりに 参考文献:ふりかえりのアジェンダを組む はじめに:ふりかえりとは チームの活動をより良くするために、チームで企画・実施するプ ラク ティスです。特に「 KPT 」「FUN/DONE/LEARN」など、 アジャイル レトロスペクティブに端を発するアクティビティを、本記事では想定しています。 アジャイル の文脈で生まれたプ ラク ティスですが、チーム活動であれば何にでも汎用的に使えます。入門編については、 昨年の拙記事 をご参考にどうぞ。 はじめに:miroとは オンラインホワイトボードツールの一つです。 https://miro.com/ 同様のツールには Google Jamboard、 Microsoft Whiteboard 、MURAL、 Apple フリーボード、あたりが挙がります。本記事の主眼ではないので細かく触れませんが、個人的に「2022年ベストバイ」の一つに挙げたいくらい気に入っているツールです。本記事の内容はmiroなしでも実践できるものを含みますが、お手元にmiroがあると、より実践が近付くと思います。 前置きはこのくらいにしましょう。ここからは実際のTipsや課題意識について、実際にふりかえりを企画〜実施する時にステップに沿いながら書いていきます。基本的なプロセスは、昨年の記事でも引用した ふりかえりガイドブック が下敷きにありますので、お持ちの方はご参考にしてください。 事前:ふりかえりの アジェンダ を設計する チームの状況にもよりますが「大きめのリリースも終わるし、ここらで次に向けて改善できる所がないか考えたいな」のようなシチュエーションは多いと思います。となると関係者に MTG を設定して、 アジェンダ を決めておく所から始まるでしょう。かっこよく言えば『ふりかえりの設計』です。 目的を明確に決めて、スコープを想起できるよう工夫する アジェンダ を設計するにあたり、最初に 「なぜ、ふりかえりをやるんだっけ?」という目的は 言語化 しておきましょう 。そして目的から逆算した時の 「意識してほしいスコープ」を決めておきましょう 。例を挙げます。 (目的)製品Aの大きめのリリースが完了した。メンバの功績を 言語化 するとともに、次のスプリントで活かせそうなア イデア を考えておく。 (スコープ)前回のふりかえり実施後から、リリース当日までの製品Aに関するアクティビティ こうしてスコープが明瞭になっていれば、例えばこういった工夫ができます。 期間中に取り組んだ製品Aの バックログ 、バーンダウンチャート、前回のふりかえり完了時のmiroボードを用意しておこう。 アジェンダ の最初に、これらを見てもらえる時間も追加しておこう。 メンバの状況にもよりますが、事前ワークのない「ふりかえり」であれば特に効果的だと思います。 バッファを見込んだ アジェンダ を組む 次に アジェンダ を組みます。ワークの選び方は割愛しますが、慣れた フレームワーク や、後述の参考資料からピックアップしていくことになるでしょう。やりたいワークが決まったら、当日の アジェンダ を組むことになります。 この時、 アジェンダ には必ずバッファを入れましょう 。Keep/Problem/Tryで例を挙げます。 Keepをmiroに書く:5分 書かれたKeepを読む:10分 Problemをmiroに書く:5 書かれたProblemを読む:10分 Tryをmiroに書く:5分 書かれたTryを読む:10分 よし!45分!と考えそうになりますが、少なくとも私の場合、この通りになったことがありません。参加者の状況にもよりますが「Problemを読むのに時間がかかる」「Tryを書くのに時間がかかる」なんてことはよくあると思います。なので合計45分でも、思い切って60分取ります。あとは、重要な議論の時間が広がりやすいProblemやTryの時間を先に増やしておくのもいいでしょう。ここで作った余裕を、当日うまく使います(後述)。 miroのテンプレートを活かして、ホワイトボードを設計する アジェンダ が決まったら、事前にmiroのホワイトボードに、当日使うボードを作る必要があります。この時、 なるべくイチからは作らず、miroのテンプレートを利用しましょう 。自作してもいいのですが、ボードの自作は結構楽しく、時間泥棒です。暇な時以外はやめておきましょう。 コミュニティのテンプレートであるMiroverseも有用です。Miroverseは長年英語のボードしかありませんでしたが、ここ最近は日本語のテンプレートも出始めています。ふりかえりガイドブック著者の森さんが KPT のテンプレートを公開してくれています。 Miroverse:KPTふりかえり(日本語) 余談ですが、miroverseには面白いボードも多く、これまた時間泥棒です。ついでなので、私がいつか、訓練されたマグルの集まりで使ってみたいと思っているボードの例を紹介します。 Miroverse:Harry Potter Retrospective 最後に、ここで用意したテンプレートは、編集をロックしておきましょう。ロックしておくことで、メンバが誤って背景のアイテムを消したり、変更してしまったりを防ぐことが出来ます。 事中:ふりかえりをファシリテートする さて、当日です。企画者が ファシリテーター も兼任するケースは多いでしょう。皆がmiroにやってきます。事前に作った アジェンダ を手元に、ふりかえりを開始します。 Bring everyone to meを要所で使う(乱用しない) miroには、参加者全員の画面を強制的に自分の見ている範囲に移動させる Bring everyone to me という機能があります。 アジェンダ の説明やBoard内の誘導には、こちらを 有効に使いましょう 。ただ「最初の説明」「議論の導入」の時など限られたタイミングだけで使うのがおすすめめです。 『メンバーが迷子になることを防ぐ』目的にとどめて使う ほうが、参加側には負荷がかからないように思います。 意識して非同期コミュニケーションの時間を作る(コメント機能を活用する) チームの慣れ具合にもよるのですが、miroボードを前にワークしている時は 「喋らない時間」を意図的に設けたほうが総コミュニケーション量を増やせます 。全てを発話で済ませるのではなく、 miroのコメント機能を有効に使いましょう 。 KPT の例であれば、次のようなイメージです。 Keepをmiroに書く 他のメンバのKeepを読み、コメントを入れる時間を作る Keepをピックアップして発話に入る。どうしても時間がない時はコメントを見ながらピックアップ対象を絞る。 付箋の内容をあえて発話してもらう事で参加を促したいケースは、この限りではありません。ただ、チームメンバーがワークに慣れている等の状況では、このステップを踏んだほうが時間単位でできる議論の量は増えます。 タイマーを意識的に使う(無実にしない) miroには タイマー機能 があります。これも 是非活用しましょう 。タイマーが0になると、アラームでボードを見ている人全員に時間を知らせることができます。 ただタイマーの設定については、 アジェンダ の時間枠を杓子定規に設定するよりは、 議論の様子を見て柔軟に設定時間を変えたほうが効果的 です。どういうことかというと、「この議論はまだ続きそうだな」と思ったら、いたずらに終了のタイマーを鳴らさず、タイマーの時間をそっと追加してしまうのです(ここで最初に作ったバッファを使います)。 この方法がベストであるかは残り時間などの状況にもよります。いっぽうで、頻繁にアラームの音が鳴ってしまうと、それはそれで参加者がアラームの音を気にしなくなる(無実になる)傾向にあります。全体を時間内にきれいに収めるためにも、タイマーは意識的に アジェンダ が切り替わってほしいタイミングでのみ鳴るようにしましょう。 事後:ふりかえりを、やりっぱなしにしない 無事ふりかえりの時間が終わりました。miroボードにメンバーの色々な思いが書き出され、議論も白熱し、良い感じの達成感が残ります。ちょっと消化不良に終わった? そんな時もあります。また挫けずやってみましょう。 折に触れて使う(コンテキストを呼びだすショートカットにする) 使ったホワイトボードは 実施日が分かるようにしておき 、折に触れて「この時こんな議論があったと思うんだけど」と 思い出す時に使いましょう 。ホワイトボードツールの良い所は、議論の過程が、直感的に理解しやすいホワイトボードの形で残ることです。特に定期的なふりかえりの場合、前回のふりかえりボードが同じホワイトボード上にあると非常に便利です。ボードを見ただけで当時のコンテキストをある程度呼び出せるので「前回はこう考えてたけど、結局こうなったな」といった仮説検証的な思考を自然とメンバに想起できます。 また、こういった状態を作るためにも、付箋へのコメント機能は有効活用しておきたい所です。意識してコメント機能を使っていれば、おそらくパッと見て気になった付箋には、コメントが残っているでしょう。議論の過程も残っているとなおよいです。 収束の段階で出てきたア イデア の種は、無理に皆でまとめない 発散→収束の収束のプロセスで、ふと単純なToDoにはなっていない、 ア イデア めいた付箋 が生まれることがあります。こうしたアイテムは 無闇にToDoに落としこまず 、議論の過程をコメントに書くに留めて、 そのまま残してよい と思います。例が出しづらいですが、例えば「AをBと組み合わせてみる」みたいな、まだ妥当性がわからない、実験めいた記述のものが該当するかもしれません。 なぜそうするかというと、こうした ア イデア めいた内容をグループワークの限られた時間内で無理にToDoに落とし込もうとすると、工夫の余地を削った平均値的なものに収束してしまう事が多い からです。なので焦って 言語化 するよりは、挙がった議論の過程だけ残しア イデア の種に留めておきたいのです。実際のところ本当に面白いア イデア は、書いた当人が後日、おもむろにやりはじめたりします(これは弊チームの場合かもしれません)。 (ふりかえりとは少し異なりますが)このあたりは最近読んだ 妄想する頭 思考する手 想像を超えるアイデアのつくり方 という書籍でも、ア イデア づくりの文脈で近い考え方が示されており、非常に共感できました( 第3章2節「ブレストはワークしない」 )。ご興味が有れば、是非。 おわりに いかがでしたか?(定型文) ワークの文脈はチームの数だけありますし、どこまで一般的に適用できるノウハウとなっているかはチームそれぞれかもしれません。ただ私達の試行錯誤が、少しでも同好の士のご参考となっていれば幸いです。 そのまま宣伝ですが、こういった試行錯誤を日々重ねながら、AI技術の社会実装をAIトランスフォーメーションセンターでは進めています。新卒、中途問わず一緒に働いてくださる方を募集しており、ご興味が湧いた方は AITC採用サイト も是非御覧ください。カジュアル面談の申込みもお受付しています。 さらに宣伝ですが、私個人も スクラム マスターとして日々修行しており、今年はチームメンバーと共に アジャイルとスクラムによる開発手法 という書籍の翻訳出版をしました。鈍器一歩手前の分量ですが、とても良い本ですので、ご興味が有れば是非手にとってみてください。 では。メリー・クリスマス!🎅 参考文献:ふりかえりの アジェンダ を組む アジャイルなチームをつくる ふりかえりガイドブック 始め方・ふりかえりの型・手法・マインドセット :まずはここから。購入者特典の「ふりかえり チートシート 」も是非。 ふりかえりカタログ :同著者が無料公開している、ふりかえりのカタログです。 執筆: @fhiroaki 、レビュー: @hashizume.hideki ( Shodo で執筆されました )
アバター