20210906のAWSに関する記事は21件です。

OSSのライブラリを作ったので、立ち上げからリリースまでを時系列に書いていく

まえがき ちょうど3年前に「初心者3人でwebサービス(webアプリ)を作ったので、立ち上げからリリースまでを時系列に書いていく」なる記事を書いたことがあり、いまだにいいねをつけてもらえることがあります。そこで、3年の時を経て似たような記事を書いてみようと思いました。 Webアプリの開発経験はあるものの、npmパッケージを公開したことはありませんでした。手探りからどのようにリリースまで、残したドキュメントをもとに振り返っていきたいと思います。 これを読んで「OSSを作ってみたいけどどう進めていけばいいか分からない」という人の一助になれば嬉しいです。誰か0から10までの流れを書いててくれないかな〜と思っていたので、きっと誰かには届く気がします。 作ったOSSについて Realtimelyという、Reactアプリに楽しいリアルタイム要素を簡単に導入できるライブラリを開発しました。 Realtimelyの裏側ではGraphQLとWebsocketでAWSクラウドと通信していますが、プログラマはそれを意識することなくRealtimelyの提供するhooks関数を使うだけでwebsocketベースのリアルタイムな体験を実装することができるようになります。 例えば、下のgifのようにマウスカーソルの位置を共有する機能を10行程度のコードで実現できます。 import { useRealtimeCursor } from 'realtimely'; export default () => { const { onMouseMove, renderCursors } = useRealtimeCursor() return ( <div onMouseMove={onMouseMove}> {renderCursors()} </div> ) } デモページを作っているので、よかったら触ってみてください。 立ち上げからリリースまで さて、ここからは実際にどのように企画を立ててリリースしていったかを時系列に書いていきたいと思います。 人数 1人 制作日数 18日 かかったお金 AWS無料枠 1日にかけた時間 平日1時間 休日3時間 8/19(開始から0日目) 計画 初日に決めたことは以下になります。 ユースケース → どのような場面でこのライブラリを使うのかイメージ プロダクトイメージ → プログラマがどのようなインターフェイスでこのライブラリを使うかをイメージ アーキテクチャ → 何を使って実現するか。 今回は可能な限り(楽をするため)ローコードでスケーラブルにしたいという思いがありました。 必要なタスク洗い出しとスケジュール 何をやらないといけないか列挙 何にどれくらい時間がかかりそうか見積もり(正直個人開発で見積もりすることに意味はないですが、どれくらいかかりそうか把握するためにやりました) 今回はかなりプロダクトアウト的な発想でユースケースを検討しましたが、実際には以下の手順でやるのが理想かと思います。 ① 実際の開発で困っている課題を考える ② 誰かがすでに実現していないか調べる ③ 実現していたとして、それが本当に便利か、より使いやすいプロダクトイメージがないか考える OSSは誰にでも公開できますが、すでに実現されていたり、さほど困っていないことをベースにしたものを作って公開しても検索の邪魔になるプロダクトができてしまう恐れがあります。 8/20 (開始から1日目) 競合(?)調査 自分がやりたいことをやれそうなライブラリを調べ、ドキュメントを読み、実際に使ってみました。 そのライブラリは「パフォーマンスの高いリアルタイムアプリ」を作るためにRESTベースで作られたライブラリでした。 高いパフォーマンスが目的だったのでキャッシュ等を利用した状態管理も機能の中に入っておりtoo muchであることや、バックエンドもフルスクラッチで開発しなければならず簡単に使えるものではないことがわかりました。 ここで自分のプロダクトイメージを手軽に使えるようにするところに尖らせるなど方向修正したりしました。 また方向性は違えど、実現することは似ているので参考にできることがたくさんあります。HTTPレスポンスなども見て、どういったデータ構造が良さそうかなどの参考にしました。 8/21-8/26 (開始から6日目) First iteration 「リアルタイムにカーソルの動きを共有する」というスプリントゴールを最初の7日で実装しました。 AWS AppSyncを触る AppSyncはGraphQLサーバのマネージドサービスです。 DynamoDBのテーブルと接続することで、自動でGraphQLスキーマとリゾルバを生成する機能があります。 今回はローコードでなるべく楽しようと考えていたので、AppSyncを採用してみました。 ノーコード、ローコード系あるあるですが、どうしても限界というかサービスの特徴があり、そこからはみ出すと一気に実装が難しくなります。AppSyncもその例に漏れず、AppSyncの特徴を捉えながら設計をする必要がありました。 触ってみて感じたことはこんな感じ。 自分で作ってないものは挙動を理解するのに時間がかかる → DynamoDBを手動で更新してもSubscriptionが更新してくれなくてハテナとなった → DynamoDBを監視しているわけではなくMutaitonを監視していた カスタムロジックを書こうとしたらVTLを書かないといけない → 基本的なコードはネットから拾えるが、自分で一からVTLでロジックを書くのはしんどすぎる できることの範囲に限界があり、追加要件が走った瞬間に破綻するのではないかという不安から実務で採用は難しそう。 自動生成されたリゾルバに勝手にロジックが書かれていてハマる → 自動生成系は何が実装されているか分からない 不可思議な挙動にも身体で慣れていくしかない。このノウハウにあまり再利用性がない。 AppSyncでweb socket通信をするためのハンドシェイクプロトコルが独特 Subscriptionの挙動が奇妙(StackOverflow) 設計する 「リアルタイムにカーソルを移動させる」を実装させるために必要なAPIとフロントでの処理を書き出し、実現できそうか検討していきました。この辺は「実現したいこと」と「AppSyncでできること」を両睨みして考えていく形でした。 ユーザがURL(Host + Path)にアクセス 誰かが入室したら通知(onCreateRealtimeUser) 誰かの所在更新を通知(onUpdateRealtimeUser) → 所在が古いものはローカルで削除する そのURLへアクセスしていることを報告(CreateRealtimeUser) カーソルの移動に合わせて位置を報告(createRealtimeCursor, updateRealtimeCursor) 他の人がカーソル移動したら通知(onUpdateRealtimeCursor) 自分が存在していることをpoke (updateRealtimeUser) DB設計 DynamoDBはキーバリューストアのスケーラブルなNoSQLデータベースです。 DynamoDBのキーはHashKeyとSortKeyがあり、この組み合わせが一意であるようにDB設計を行います。 RealtimeCursorは次のようなスキーマにしました。 HashKey SortKey URL#{URL} UserId#{UserId} {URL}と{UserId}には実際の値が入ります。 このキーに対して、マウスのカーソル位置(X,Y)やユーザ情報をAttributeとして保存していきます。 高速実装 僕は実装は何よりもまず最初はスピードだけを意識してやります。 どれだけ汚くてもいいので、とにかくやりたいことができればOKです。 なぜかというと綺麗な設計というのは全てを書き終えてからスクラップアンドビルドをするのが一番効率的だと思っているからです。 最初から何が共通化できるかなんて、僕はわかりません。 リファクタリング ざっくりと汚いコードでやりたいことが実現できたらリファクタリングをしました。 Webサービスであれば最悪リファクタリングをしなくても動くものを先にリリースするという判断もありかと思います。 今回はOSSライブラリとして使いやすくなければいけないため、責務とインターフェイスをよく考えて再設計しました。 8/27-8/30 (開始から11日目) Second iteration 「ユーザアクションの可視化を実装する(ボタンを押すと他の人にも押されたように見えるとか、テキストを入力するとそれが他の人の画面に見えるとか)」というスプリントゴールに2回目のイテレーションを回します。 リファクタリングされて整理されているのと、おおよそAppSyncで何ができるかわかっているのでスムーズに開発が進みました。 8/31 (開始から12日目) デモページを作る 開発に使っていたNext.jsプロジェクトを多少整理してそのままデプロイします。 Serverless Frameworkを使うことで5分でAWSにデプロイできました。 (デモページ)[https://d2vfno2gco8009.cloudfront.net/] 9/1-9/4 (開発から16日目) ドキュメントを作る docusaurusというライブラリを使ってドキュメントを作成しました。docusaurusはfacebookがメンテしており、めちゃくちゃよくできてます。 まず、大項目で書くことを列挙してからゴリゴリと書いていきました。 書くことを考える Introduction Getting Started Installation Demo Realtime Cursor Realtime User Presence Realtime User Action API Guides useXXX How it works Architecture Self hosted Backend RoadMap ゴリゴリ書く ゴリゴリ書きます。一番しんどかったところ。 英語にする docusaurusにi18n機能があるので、英語のドキュメントも作成しました。 基本的にgoogle translateに翻訳させて、ざっと見直しするだけです。 Github Pagesにデプロイする これもdocusaurusに機能としてあったので簡単にできました。 その他のタスク ロゴを作る これは適当にロゴgeneratorを活用しました。 寄付の窓口を作る ko-fiを使って寄付の窓口も作ってみました。 Stripeと接続してクレジットカードで寄付ができるようになります。 9/5-6 (開発から18日目) npm公開 いよいよ公開です。詳細なnpmへの公開方法は別の記事を参照ください。今回は荒く書いていきます。 npmアカウントの作成 https://www.npmjs.com/ でアカウントを作成 TypeScriptをコンパイルして.jsファイルにする tsconfig.jsonを書いてから tsc -d yarn publish npmのログインを求められるのでEmail, Passwordを入力するだけ、、 公開 これでnpmに公開することができました。 公開後の姿 めちゃくちゃ簡単でびびります。npmのライブラリって今まで利用させて頂くばかりで、その土俵に僕なんかがあがっていいのか不安になるような、土俵に汚い土足で乗り上げたような、そんな罪悪感がありました。 デバッグ 意気揚々と別リポジトリでrealtimelyをインストールして使ってみると、エラーが出て使えない・・・ この辺のデバッグで1日溶けました。 ライブラリの依存関係 CSS読み込めないエラー 依存しているライブラリのエラー これから 公開へのスピード優先で開発を進めたので、現在は到底Production Readyなライブラリになっていません。あくまでもPoCレベルで、アプリにリアルタイム要素を入れるとどんな感じになるのか確かめて頂く用途で使っていただければと思います。 これからはProduction Readyにするための課題の解決と、より使いやすい機能の開発を細々とやっていこうと思います。温かい目で見守ってください。 Document Demo
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

リアルタイムなWebアプリを簡単に作れるOSSを作ったので、立ち上げからリリースまでを時系列に書いていく

まえがき ちょうど3年前に「初心者3人でwebサービス(webアプリ)を作ったので、立ち上げからリリースまでを時系列に書いていく」なる記事を書いたことがあり、いまだにいいねをつけてもらえることがあります。そこで、3年の時を経て似たような記事を書いてみようと思いました。 Webアプリの開発経験はあるものの、npmパッケージを公開したことはありませんでした。手探りからどのようにリリースまで、残したドキュメントをもとに振り返っていきたいと思います。 これを読んで「OSSを作ってみたいけどどう進めていけばいいか分からない」という人の一助になれば嬉しいです。誰か0から10までの流れを書いててくれないかな〜と思っていたので、きっと誰かには届く気がします。 作ったOSSについて Realtimelyという、Reactアプリに楽しいリアルタイム要素を簡単に導入できるライブラリを開発しました。 Realtimelyの裏側ではGraphQLとWebsocketでAWSクラウドと通信していますが、プログラマはそれを意識することなくRealtimelyの提供するhooks関数を使うだけでwebsocketベースのリアルタイムな体験を実装することができるようになります。 例えば、下のgifのようにマウスカーソルの位置を共有する機能を10行程度のコードで実現できます。 import { useRealtimeCursor } from 'realtimely'; export default () => { const { onMouseMove, renderCursors } = useRealtimeCursor() return ( <div onMouseMove={onMouseMove}> {renderCursors()} </div> ) } デモページを作っているので、よかったら触ってみてください。 立ち上げからリリースまで さて、ここからは実際にどのように企画を立ててリリースしていったかを時系列に書いていきたいと思います。 人数 1人 制作日数 18日 かかったお金 AWS無料枠 1日にかけた時間 平日1時間 休日3時間 8/19(開始から0日目) 計画 初日に決めたことは以下になります。 ユースケース → どのような場面でこのライブラリを使うのかイメージ プロダクトイメージ → プログラマがどのようなインターフェイスでこのライブラリを使うかをイメージ アーキテクチャ → 何を使って実現するか。 今回は可能な限り(楽をするため)ローコードでスケーラブルにしたいという思いがありました。 必要なタスク洗い出しとスケジュール 何をやらないといけないか列挙 何にどれくらい時間がかかりそうか見積もり(正直個人開発で見積もりすることに意味はないですが、どれくらいかかりそうか把握するためにやりました) 今回はかなりプロダクトアウト的な発想でユースケースを検討しましたが、実際には以下の手順でやるのが理想かと思います。 ① 実際の開発で困っている課題を考える ② 誰かがすでに実現していないか調べる ③ 実現していたとして、それが本当に便利か、より使いやすいプロダクトイメージがないか考える OSSは誰にでも公開できますが、すでに実現されていたり、さほど困っていないことをベースにしたものを作って公開しても検索の邪魔になるプロダクトができてしまう恐れがあります。 8/20 (開始から1日目) 競合(?)調査 自分がやりたいことをやれそうなライブラリを調べ、ドキュメントを読み、実際に使ってみました。 そのライブラリは「パフォーマンスの高いリアルタイムアプリ」を作るためにRESTベースで作られたライブラリでした。 高いパフォーマンスが目的だったのでキャッシュ等を利用した状態管理も機能の中に入っておりtoo muchであることや、バックエンドもフルスクラッチで開発しなければならず簡単に使えるものではないことがわかりました。 ここで自分のプロダクトイメージを手軽に使えるようにするところに尖らせるなど方向修正したりしました。 また方向性は違えど、実現することは似ているので参考にできることがたくさんあります。HTTPレスポンスなども見て、どういったデータ構造が良さそうかなどの参考にしました。 8/21-8/26 (開始から6日目) First iteration 「リアルタイムにカーソルの動きを共有する」というスプリントゴールを最初の7日で実装しました。 AWS AppSyncを触る AppSyncはGraphQLサーバのマネージドサービスです。 DynamoDBのテーブルと接続することで、自動でGraphQLスキーマとリゾルバを生成する機能があります。 今回はローコードでなるべく楽しようと考えていたので、AppSyncを採用してみました。 ノーコード、ローコード系あるあるですが、どうしても限界というかサービスの特徴があり、そこからはみ出すと一気に実装が難しくなります。AppSyncもその例に漏れず、AppSyncの特徴を捉えながら設計をする必要がありました。 触ってみて感じたことはこんな感じ。 自分で作ってないものは挙動を理解するのに時間がかかる → DynamoDBを手動で更新してもSubscriptionが更新してくれなくてハテナとなった → DynamoDBを監視しているわけではなくMutaitonを監視していた カスタムロジックを書こうとしたらVTLを書かないといけない → 基本的なコードはネットから拾えるが、自分で一からVTLでロジックを書くのはしんどすぎる できることの範囲に限界があり、追加要件が走った瞬間に破綻するのではないかという不安から実務で採用は難しそう。 自動生成されたリゾルバに勝手にロジックが書かれていてハマる → 自動生成系は何が実装されているか分からない 不可思議な挙動にも身体で慣れていくしかない。このノウハウにあまり再利用性がない。 AppSyncでweb socket通信をするためのハンドシェイクプロトコルが独特 Subscriptionの挙動が奇妙(StackOverflow) 設計する 「リアルタイムにカーソルを移動させる」を実装させるために必要なAPIとフロントでの処理を書き出し、実現できそうか検討していきました。この辺は「実現したいこと」と「AppSyncでできること」を両睨みして考えていく形でした。 ユーザがURL(Host + Path)にアクセス 誰かが入室したら通知(onCreateRealtimeUser) 誰かの所在更新を通知(onUpdateRealtimeUser) → 所在が古いものはローカルで削除する そのURLへアクセスしていることを報告(CreateRealtimeUser) カーソルの移動に合わせて位置を報告(createRealtimeCursor, updateRealtimeCursor) 他の人がカーソル移動したら通知(onUpdateRealtimeCursor) 自分が存在していることをpoke (updateRealtimeUser) DB設計 DynamoDBはキーバリューストアのスケーラブルなNoSQLデータベースです。 DynamoDBのキーはHashKeyとSortKeyがあり、この組み合わせが一意であるようにDB設計を行います。 RealtimeCursorは次のようなスキーマにしました。 HashKey SortKey URL#{URL} UserId#{UserId} {URL}と{UserId}には実際の値が入ります。 このキーに対して、マウスのカーソル位置(X,Y)やユーザ情報をAttributeとして保存していきます。 高速実装 僕は実装は何よりもまず最初はスピードだけを意識してやります。 どれだけ汚くてもいいので、とにかくやりたいことができればOKです。 なぜかというと綺麗な設計というのは全てを書き終えてからスクラップアンドビルドをするのが一番効率的だと思っているからです。 最初から何が共通化できるかなんて、僕はわかりません。 リファクタリング ざっくりと汚いコードでやりたいことが実現できたらリファクタリングをしました。 Webサービスであれば最悪リファクタリングをしなくても動くものを先にリリースするという判断もありかと思います。 今回はOSSライブラリとして使いやすくなければいけないため、責務とインターフェイスをよく考えて再設計しました。 8/27-8/30 (開始から11日目) Second iteration 「ユーザアクションの可視化を実装する(ボタンを押すと他の人にも押されたように見えるとか、テキストを入力するとそれが他の人の画面に見えるとか)」というスプリントゴールに2回目のイテレーションを回します。 リファクタリングされて整理されているのと、おおよそAppSyncで何ができるかわかっているのでスムーズに開発が進みました。 8/31 (開始から12日目) デモページを作る 開発に使っていたNext.jsプロジェクトを多少整理してそのままデプロイします。 Serverless Frameworkを使うことで5分でAWSにデプロイできました。 (デモページ)[https://d2vfno2gco8009.cloudfront.net/] 9/1-9/4 (開発から16日目) ドキュメントを作る docusaurusというライブラリを使ってドキュメントを作成しました。docusaurusはfacebookがメンテしており、めちゃくちゃよくできてます。 まず、大項目で書くことを列挙してからゴリゴリと書いていきました。 書くことを考える Introduction Getting Started Installation Demo Realtime Cursor Realtime User Presence Realtime User Action API Guides useXXX How it works Architecture Self hosted Backend RoadMap ゴリゴリ書く ゴリゴリ書きます。一番しんどかったところ。 英語にする docusaurusにi18n機能があるので、英語のドキュメントも作成しました。 基本的にgoogle translateに翻訳させて、ざっと見直しするだけです。 Github Pagesにデプロイする これもdocusaurusに機能としてあったので簡単にできました。 その他のタスク ロゴを作る これは適当にロゴgeneratorを活用しました。 寄付の窓口を作る ko-fiを使って寄付の窓口も作ってみました。 Stripeと接続してクレジットカードで寄付ができるようになります。 9/5-6 (開発から18日目) npm公開 いよいよ公開です。詳細なnpmへの公開方法は別の記事を参照ください。今回は荒く書いていきます。 npmアカウントの作成 https://www.npmjs.com/ でアカウントを作成 TypeScriptをコンパイルして.jsファイルにする tsconfig.jsonを書いてから tsc -d yarn publish npmのログインを求められるのでEmail, Passwordを入力するだけ、、 公開 これでnpmに公開することができました。 公開後の姿 めちゃくちゃ簡単でびびります。npmのライブラリって今まで利用させて頂くばかりで、その土俵に僕なんかがあがっていいのか不安になるような、土俵に汚い土足で乗り上げたような、そんな罪悪感がありました。 デバッグ 意気揚々と別リポジトリでrealtimelyをインストールして使ってみると、エラーが出て使えない・・・ この辺のデバッグで1日溶けました。 ライブラリの依存関係 CSS読み込めないエラー 依存しているライブラリのエラー これから 公開へのスピード優先で開発を進めたので、現在は到底Production Readyなライブラリになっていません。あくまでもPoCレベルで、アプリにリアルタイム要素を入れるとどんな感じになるのか確かめて頂く用途で使っていただければと思います。 これからはProduction Readyにするための課題の解決と、より使いやすい機能の開発を細々とやっていこうと思います。温かい目で見守ってください。 Document Demo
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS認定 SAP, DOP, SCS合格しました

概要 以下のAWSの認定試験を受けて合格しました。 AWS認定ソリューションアーキテクト プロフェショナル - 2021年5月 AWS認定DevOpsエンジニア プロフェッショナル - 2021年8月 AWS認定セキュリティ 専門知識 - 2021年8月 受験した理由 実際の仕事内容が試験範囲と重なってきつつあったので、AWSのベストプラクティスを理解したかったためです。 試験勉強 使った教材 AWS認定ソリューションアーキテクト プロフェショナル AWS認定ソリューションアーキテクト-プロフェッショナル ~試験特性から導き出した演習 AWS 認定ソリューションアーキテクト プロフェッショナル模擬試験問題集(全5回分375問) AWS認定DevOpsエンジニア プロフェッショナル AWS認定 DevOpsエンジニア – プロフェッショナル (DOP-C01) 模擬試験 (2021年試験対応版) AWS認定セキュリティ 専門知識 要点整理から攻略する『AWS認定 セキュリティ-専門知識』 AWS Security Speciality(SCS-C01) 2021 with Explanations 勉強方法 問題を解いて、不正解の問題はもちろん、正解した問題も解答説明を隅々まで読んで解き方に慣れる、自信を持って正解できるようにしていく。 知らないことや理解できないことは、AWS公式のドキュメントを読み込んで大事なことをノートやScrapboxにどんどん書いて覚える、理解する。 さらにイメージが湧かないものは、クラスメソッドさん、クラウドワークスさんなど、噛み砕いて説明して下さっているブログを参考に、自分でも触ってみる。 これをひたすら理解するまで繰り返す。 受験 受験時期 実は、もっと前から受験したい気持ちはあったのですが、長らく仕事がハードな状況が続いていて、時間的にも精神的にも余裕がなかったので自分なりの気運を待ってベストな状態で予約して受験しました。 プロフェッショナルや専門知識は3時間と長い上に問題文が長文で脳が疲労するので、心身ともに健康であることも重要だと思います(少なくとも私はそうです)。 受験場所 コロナ禍ということもあり、自宅で受験しました。 初回は、試験より試験開始までの試験官とのやりとりの方が緊張したかもしれません、それぐらい緊張しました。しかし、体験された方のブログを参考にさせていたおかげで問題なく受験することができました。 DevOpsエンジニアプロフェッショナルとセキュリティ専門知識は、日本語試験官の予約が取れず、英語の試験官を選択しましたが、こちらAWSオンライン試験監督との英会話例を事前に見ておいたので英語が得意ではない自分でも問題ありませんでした。 自宅で受験すると、慣れたPCで、エアコンも自分で適温に設定できるので快適で、試験に集中できたと思います。 感想 セキュリティ専門知識は本当に楽しかった。 難しいイメージがあって敬遠していたけど、もっと早く勉強すればよかったと思いました。 ソリューションアーキテクトプロフェッショナルとDevOpsエンジニアプロフェッショナルは、自分がまだ経験していないような構成や規模のシステムの問題が範囲に入っていたので、今後、この勉強が役に立つ時がくるといいな、という思いになりました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS EC2インスタンス作成後にセキュリティグループを変更する方法

セキュリティグループの設定を間違えてEC2インスタンスを作成してしまった場合の変更方法です。 再度EC2インスタンスを作成し直す必要はありません。起動中のまま簡単に変更できます。 1. EC2インスタンス一覧画面を開く 色々と方法はあると思いますが、サービス検索窓にec2と入力しEC2をクリックすると表示させることができます。 2. 対象のインスタンスのチェックボックスをクリックする 以下のキャプチャのように、対象のインスタンスのチェックボックスをクリックしてください。 起動中のまま変更できます。停止する必要はありません。 一度に複数のインスタンスの設定を同時に変更することはできないようです。対象のインスタンスのチェックボックスを一つだけ選んでクリックしてください。 3. 「アクション」をクリックする 画面右上にある「アクション」をクリックします。 4. 「セキュリティ」をクリックする 次は「セキュリティ」をクリックしましょう。 5. 「セキュリティグループの変更」をクリックする 次は「セキュリティグループの変更」をクリックしましょう。 6. セキュリティグループの設定を変更し、「保存」をクリックする 以下のような設定画面が表示されていると思います。 この画面でセキュリティグループの変更ができます。 「削除」をクリックするとセキュリティグループを削除できます。 また、検索窓にセキュリティグループ名を入れて既存のセキュリティグループを選択し、「セキュリティグループを追加」をクリックすると追加できます。 最後にオレンジ色の「保存」をクリックしましょう。 <--これしないと変更されません! 「せキュリティーグループが正常に変更されました」というメッセージが出力されます。 これで設定変更できたはずです。ちなみに変更は即反映されます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

踏み台サーバーを経由して目的のサーバーへアクセスする

はじめに キーペア、公開鍵、秘密鍵の理解から始まりましたが、なんとか踏み台サーバーを経由して目的のサーバーへアクセスすることができました。 ローカル、ファイルパス等基本的な用語の理解を復習すると良いのかと思います。 流れ ローカル環境のキーペアを、踏み台サーバーへ送る 踏み台サーバーへアクセスする 受け取ったキーペアを持って目的のサーバーへアクセスする やったこと まずは、ローカル環境のキーペアを踏み台サーバーへ送ります。 ローカル環境?となりましたが、ec2に接続する前の状態がローカル環境です。 ちなみにキーペアは、 cd #ホームディレクトリへ移動 cd ~/.ssh #sshへ移動 ls #中身を確認 この中にEC2作成時に作成したキーペアが存在します。 このキーペアの理解も私は躓きました。 この記事を読みイメージがしやすくなりました。 送る鍵がわかったところで、実際に踏み台サーバーへキーペアを送ります。 scp -i [キーペアファイルのパス] [送信元先ローカルファイルパス] [ユーザ名@ドメイン]:[転送先EC2ファイルパス] scp -i ~/.ssh/lsで確認した送りたいキーペア ~/.ssh/lsで確認した送りたいキーペア ec2-user@送信先IPアドレス:.ssh/lsで確認した送りたいキーペア 私は、送りたい鍵を送信先でも同じように使用するため、 [転送先EC2ファイルパス]にも同様の名前を入力しました。 (理解が合っているかはわかりません、、、もっと調べます。) 一度、[送信元ローカルファイルパス]を送りたい鍵ではないものに設定し、 [転送先EC2ファイルパス]は使いたい名前、つまり.ssh/lsで確認した送りたいキーペアを指定して送信してしまい、 一見名前は合っているけど鍵の中身が異なっていて使えないという状況になったので、ファイルパス名はよく確認してください。 踏み台サーバーに接続し、 #ホームディレクトリへ移動 cd  #sshへ移動 cd ~/.ssh #中身を確認 ls で確認することで、先ほどまではなかった鍵が受け取れていると思います。 目的のサーバーへの接続は、踏み台サーバーへの接続と同様のコマンドで大丈夫です。 ssh -i ~/.ssh/キーペア ec2-user@IPアドレス 終わりに 理解があまりできていないところ、おかしいところがあるかと思いますが、 その際はご指摘いただけると幸いです。 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EC2接続時に[WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!]エラーになった時の解決法

はじめに 無事にEC2インスタンスを複製し、RDSの移動も終わったため、 新しいEC2へ接続しようとしたところ、 [WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!] となり、接続ができなかったため、その際の解決法を残しておこうと思います。 今回は、元々のEC2インスタンスにEIPを関連付けており、 そのEIPを新しいEC2に紐付けた際に生じたエラーです。 やったこと ホームディレクトリへ移動する cd sshへ移動 cd ~/.ssh lsで中身を確認 ls known_hosts の中身を確認 ターミナルに表示されたknown_hostsをクリックし、[Copy]を選択 cat XXX #コビーしたものを貼り付け known_hostsのレコードが表示されます。 該当のアドレスがあると思います。 一度アクセスされた時に作成されるのですが、 ここに含まれている情報が前回の接続時と異なっているため、エラーが出ています。 データがない場合は、接続時に作成されるため、一度接続したいアドレスの情報をリセットします。 接続したいアドレスの記録をリセットする ssh-keygen -R XXX #接続したいPublicアドレス これで再度EC2へ接続することで、Publicアドレスの記録が作成されます。 接続も無事完了しました。 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

新しいVPCにEC2インスタンスのコピーを作成する 

はじめに AWSのEC2画面からスタートします。 AMIを作成する サイドメニュー[インスタンス]から、コピーしたいインスタンスを選択 右上の[アクション]>[イメージとテンプレート]>[イメージを作成]を選択 [イメージ名]にどこのインスタンスのコピー情報かわかるよう任意の名前を入力 再起動しない/[有効化]にチェック 終了時に削除/[有効化]にチェックが入っているか確認(デフォルトで入っています) [イメージを作成]を選択 サイドメニュー[イメージ]>[AMI]を選択 先ほどのAMIが作成されていることを確認 ステータスが[available]になったら終了 EC2インスタンスを作成する サイドメニュー[イメージ]>[AMI]を選択 作成したAMIを選択 [アクション]>[起動]を選択し、インスタンスの情報を入力 無料枠の方は無料枠の設定に気をつけて、コピー元と同じように作成していくイメージ [インスタンスの作成]でインスタンス一覧に複製したEC2インスタンスが存在することを確認  終わりに 思っていたよりも簡単にコピーが作れました。 VPCについての理解がまだまだ浅いので何をやっているのかわかりませんでしたが、 ひとつずつ手順を踏んで、何度も復習することでイメージが少しずつできるようになってきました。 RDSも同じVPC内に移行することで作成した新しいEC2に接続し、作成物を閲覧することができるようになりました。 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CloudfrontをTerraformで構築

これは何 CFをTFで構築した時のメモです。あくまでメモなので、仮に参考にされる際には任意で設定を変更ください。 CFはそもそもそんなに構築したこともなく、忘れそうなのでメモ。 TFバージョンは0.12を想定。 やってみた # CloudFrontの作成  # オリジン=S3 resource "aws_cloudfront_distribution" "s3_distribution" { # 順序 # CFのデフォルトのドメイン名ではなく、任意のドメインを使用したい場合。 # その場合、任意のドメインのHosted zoneのAレコード=CFのデフォルトのドメイン とする。 # ACMで証明書を発行した場合、DNS検証として、CNAMEを該当のHosted zoneに追加する。 # ここでは、使用するドメインを書く。 aliases = ["使用するドメイン"] # Errorレスポンス custom_error_response { # CloudFrontがオリジンにクエリを実行してオブジェクトが更新されているかどうかを確認する前に、 # HTTPエラーコードをCloudFrontキャッシュに保持する最小時間。 error_caching_min_ttl = 360 #(任意) # 4xx か 5xxを記入。 error_code = 500 # CFがカスタムエラーページとともにビューアに返すHTTPステータスコード。 response_code = 200 # The path of the custom error page (for example,/custom_404.html). response_page_path = "/custom_404.html" } # キャッシュのデフォルト設定。 default_cache_behavior { # CFが処理してAmazonS3バケットまたはカスタムオリジンに転送するHTTPメソッドを制御。 allowed_methods = ["HEAD", "OPTIONS", "GET", "PUT", "POST", "DELETE", "PATCH"] # CFが指定されたHTTPメソッドを使用してリクエストへのレスポンスをキャッシュするかどうかを制御。 cached_methods = ["HEAD", "OPTIONS", "GET"] # CFで、リクエストヘッダーにAccept-Encoding:gzip(高速化)を含むWebリクエストのコンテンツを自動的に圧縮するかどうか(デフォルト:false)。 compress = true # Cache-Control or Expires がリクエストのヘッダーに無い時のデフォルトのTTL。 # Cache-Control max-ageまたはExpiresヘッダーがない場合に、 # CFが別のリクエストを転送する前に、オブジェクトがCloudFrontキャッシュにあるデフォルトの時間(秒単位)。1日=86400秒。 default_ttl = 86400 # CloudFrontが別のリクエストをオリジンに転送してオブジェクトが更新されているかどうかを判断する前に、 # オブジェクトがCloudFrontキャッシュにある最大時間(秒単位)。 # Cache-Control max-age、Cache-Control s-maxage、およびExpiresヘッダーが存在する場合にのみ有効。 # デフォルトの1年を指定。 max_ttl = 31536000 # デフォルトの0sを指定。 min_ttl = 0 forwarded_values { # CloudFrontがこのキャッシュ動作に関連付けられているオリジンにクエリ文字列を転送するかどうか。 query_string = false # CFがCookieを処理する方法を指定するCoo​​kie転送値(最大1つ)。 cookies { # 全てを転送。 forward = "all" # whitelistを設定する場合。 # whitelisted_names = [] } } # オリジン=S3より、リソース名記述。 target_origin_id = aws_s3_bucket.リソース名.id # 署名付きURLを使用してプライベートコンテンツを提供するようにディストリビューションが設定されている場合は、アクティブな信頼できる署名者を記述。 trusted_signers = [] # allow-all、https-only、またはredirect-to-https viewer_protocol_policy = "redirect-to-https" } default_root_object = "index.html" # Origin Shieldを有効にするか enabled = true # http1.1 か http2 http_version = "http2" # アクセスログ設定。for example, myawslogbucket.s3.amazonaws.com. logging_config { bucket = S3バケットリソース名 # Cookieもアクセスログに含めるかどうか。 include_cookies = true # 保存時のPrefix prefix = "cloudfront/" } origin { domain_name = S3バケットリソース名 origin_id = S3バケットリソース名.id # Originにアクセスする際のIAM設定。 s3_origin_config { origin_access_identity = aws_cloudfront_origin_access_identity.example.cloudfront_access_identity_path } } restrictions { # 地理的制限 geo_restriction { # none, whitelist, or blacklist restriction_type = "none" # locations = [] } } # SSL証明書の設定。 viewer_certificate { # ACMで作成した証明書を使用するため無効。 cloudfront_default_certificate = false # ARN acm_certificate_arn = "" # SSLの最小バージョン。 minimum_protocol_version = "TLSv1.2_2019" # SNI(名前ベース)のSSL機能を使用する。 ssl_support_method = "sni-only" } # WAFを使用する場合に設定が必要。今回は無効。 # web_acl_id = "" } resource "aws_cloudfront_origin_access_identity" "名前" { comment = "適当" } 総括 CFはデプロイに15分ほどかかることがあるので、もしお急ぎであれば把握しておくといいかもです。 それにしてもCF、設定項目が多いですね…これで全部ではないという…どこまで詳細に書くかで精度が変わりそう。 参考 https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution https://katsuya-place.com/terraform-cloudfront/ https://dev.classmethod.jp/articles/static-web-with-cf-s3-tf/ https://qiita.com/natsumisawa/items/404217208ab1c96d8719
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Container Guide For developer

前提条件 本記事では2021.09.01の情報をもとに執筆しております。 公式の情報と差異が発生した場合は公式の情報を優先とします。 随時更新をいたします。 今回ではcontainerを使ってWebAPIを公開してみる場合のユースケースを検討します。 対象 AWSでContainerを活用しようとしているdeveloper API公開を行う前提で記載してますが結構幅広いユースケースに対応できるかなと思っています。 前提知識 AWS基礎知識 AWSにおけるContainer WEBAPI公開において考えるべき事項 APIによっては他にも考えるべき事項はあるかと存じますが、これだけは外せないだろうというところを厳選させていただきました。 1. API公開・アクセス制御 2. 負荷分散 3. アプリケーション実行基盤 4. アプリケーション実行環境 5. イメージ管理 6. データベース 7. ストレージ 8. 監視 9. ルーティング・ドメイン制御 概念解説と使用想定サービス 1. API公開・アクセス制御 API Gatewayの公開はAWSの場合は基本的にAmazon API Gatewayを使用するほうがメリットが大きいです。 以下理由を記載しますが、AWSが簡単にデプロイできるように用意してくれているのなら使用したほうが車輪の再開発を防げると思います。 * 勉強用で作るのでは話が別です。 理由 低コストで利用可能 バージョン管理 モニタリングの容易性 柔軟なセキリュティ 特にアクセス制限や認証についてはAWS Cognitoやリソースポリシーを使用して管理することができる。またAWS WAFによる脆弱性対策も対応することが可能です。 AWS WAF を使用して API を保護する 負荷分散 AWSでの負荷分散はELBが担います。ELBには3種類あります。 1. Application Load Balancer(ALB) 2. Network Load Balancer(NLB) 3. Classic Load Balancer(CLB) それぞれに、どのレベルのレイヤで動作するかが変わります。 ELBについて理解することはAWSのアーキテクチャーを組むうえでも重要ですので、以下の公式ドキュメントを参照してください。 Elastic Load Balancing アプリケーション実行基盤 コンテナを動かすサービスは何か?という観点で整理するとAWSでは以下のサービスが挙げられます。 1. Amazon EKS 2. Amazon ECS 他にもAmazon RedHat OpenShift Platform Servicesなどがありますがこちらは、RedHatを使用するケースの際に登場します。まず検討するのはEKS,ECSのため割愛します。 特にkubernetesという概念が出てきますので、こちらは補足すると Kubernetesは、宣言的な構成管理と自動化を促進し、コンテナ化されたワークロードやサービスを管理するための、ポータブルで拡張性のあるオープンソースのプラットフォームです。 公式サイトより引用 : https://kubernetes.io/ja/docs/concepts/overview/what-is-kubernetes/ コンテナ化されたアプリケーションをいい感じに管理してくれるサービスだと思ってもらえれば大丈夫です。 アプリケーション実行環境 アプリケーション実行環境とは、実行基盤の上に乗せるアプリを動かすための環境のことです。今回はEC2かFargateが選択肢に上がります。 私は完全にFargate推しです。 EC2を選択する場合のデメリット EC2クラスターの管理コストがかかる デプロイ速度が遅い(EC2を先に起動してからという手間が入る) スパイクの対応品質が悪い(オートスケーリングはできるが、EC2の起動速度から対応が後手になりがち) Fargateにした場合の対応 コスト増の懸念があるもののEC2の際のデメリットをケアできるため、お金をはらってメリットを購入するイメージになります 特にEC2を選択した場合におけるデメリットをケアしつつ開発効率を上げるとなると嬉しい限りです。 イメージ管理 Amazon ECR一択になると思います。 Docker hubも使用が検討できると思いますが、AWSが提供しているサービスなので合わせたほうが無難だと思います。 データベース データベースはAmazon RDSを使用するケースとEC2などを使用し手組で入れる場合があると思います。基本的にはメンテナンス等も考えAmazon RDSの使用を検討するべきでしょう。 RDSの場合はAuroraかそれ以外かという選択肢もあります。要件に合わせて使用することが重要です。 Aurora推しなので、ここではAmazon Auroraをベースに説明します Amazon Aurora ってなんやねん! blackbeltの以下よりイメージ図を引用します。 https://www.slideshare.net/AmazonWebServicesJapan/20190828-aws-black-belt-online-seminar-amazon-aurora-with-postgresql-compatibility-168930538 Amazon RDS と Amazon Auroraの違いをアーキテクチャーの観点から見ていきたいと思います。 Amazon RDSのアーキテクチャー Amazon RDSですが、このアーキテクチャーだとプライマリーとスタンバイの2つが用意されています。それぞれにEBSストレージが紐づいていて、これらがミラーリングしていることによって耐久性を高めています。 Amazon Auroraのアーキテクチャー Amazon AuroraはDBクラスターを作成します。いわゆる大きな箱のようなイメージです。このなかにインスタンスとストレージが入っているのですが、RDSとちがい、インスタンスとストレージが分離しています。 ストレージがさらに1AZに2か所,それが東京リージョンだと3AZ分すべてにコピーされます。これらは同期的に通信をしているため、もし何かデータの消失が起こっても他のインスタンスが修復しあう関係になっています。 また書き込み自体も並列に行うため処理自体のパフォーマンス自体にも大きな影響は与えません。 Amazon Auroraにも独自機能があります。AWSが提供している分かなり高機能なのでアプリ要件を十分に検討したうえで、導入を検討する余地があります。 ストレージ ストレージについてはEBS,EFS,S3を使用する選択肢があります。アプリケーションにおいて使い分けることが大事です。 通常はEBSかS3を選択するケースが多いかなと思います。 ファイルディレクトリとしては、耐久性や疎結合にするといった観点からS3などをベースに検討されたほうがいいかと思います。 監視 基本的にAWS Cloudwatchがすべてを見ていると思ってもらってOKです。ECSの場合は、標準出力にしないとログが見れないのでその点注意しましょう。 EKSは自分でログを出すようにサービスと連携したり、コンテナをデプロイする必要があります。 ルーティング・ドメイン制御 Amazon Route53の出番ですね。結構奥が深いサービスです。 基本的にELBのサービスを使って紐づけることが前提なので、自分の好きなドメインを設定するのに使うんだなといういめーじを持ってもらえれば大丈夫です。 * AWSの場合はRoute53を使用してドメインの制御をするほうが何かと便利です。お名前.comなども使用することはできますが、ネイキッドドメインが公開できないなど制約がかかる場合がありますのでご注意ください。 AWS ECS,EKSを利用したアーキテクチャーイメージ アーキテクチャーのサンプルです。このような図になるイメージです。 注意点として 1. ALBはサブネット3つ分にわたって稼働できるように設計するという意味で3つ記載している 2. NAT Gatewayは冗長化している(高いので1個にしてもいいかもしれない) 3. ECSのところをEKSに置き換えてもらうことも可能(サブネット構成は若干変わります) 4. EKSの場合はIstioやApp meshなどがでてきたり、ingress controllerもでてきたりするのでもう少し複雑になる これらの点は注意してご確認ください、あくまでサンプルです。 AWS configの注意 AWS Configの設定に注意する必要があります。ECS、EKSはデプロイの回数が多く、パブリックIPやプライベートIPのIP割り当てもAWS Configはチェックします。 開発時期はとにかくテストして修正という数が多いので知らないうちにここまで料金が増えているというケースもあります。 AWS configについては公式ドキュメントを見ながら特に理解することが必要です。 料金見積もりについての考え方 AWSでこの料金を見積もるのは前提条件をもっと出さないといけませんが最低2500USDくらいから見る必要があります。 * 詳細な見積もりの考え方は別で執筆予定 AWS WAFセキリュティ考慮事項 AWS WAFにセキリュティ対策を任せるということを検討した場合は以下のルールを検討する必要があります。 参考に表にまとめていますがすべて対応する必要があるというわけではないです。 |セキュリティの虚弱性|対応方針| |------|-------| |インジェクション系SQLインジェクションOSコマンドインジェクションクロスサイトスクリプティングディレクトリトラバーサルクロスサイトリクエストフォージェリ|AWS Managed rulesで次のルールセットを有効化するCore Rule SetSQL DatabasePHP Application| |ウェブの管理者ページの保護|AWS Managed rulesのAdmin Protectionルールセットを有効化| |DDoS攻撃からの保護|Rate Based Rulesによる同一IPからの短時間での大量アクセス拒否IP Blacklistに追加して特定のIPを拒否するAWS Managed rulesの Amazon IP reputation list および Anonymous IP Listルールセットの有効化| |BOTによるアクセスの対策|Rate Based Rulesによる同一IPからの短時間での大量アクセス拒否IP Blacklistに追加して特定のIPを拒否するAWS Managed rulesの Amazon IP reputation list および Anonymous IP Listルールセット、Known Bad Inputsルールセットの有効化 まとめ 以上containerについてまとめてみました。まだ記載途中の部分もありますが、考えるべき点はあらかたまとまっていると存じます。 ご意見等ございましたら遠慮なくご指摘ください。よろしくお願いします。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS CloudwatchからChatbotを使ってコーディングなしでslackに通知を送る

はじめに ClowdwatchからSlackへ通知する方法はいくつかあるが、どれもコーディングを必要とする。 代表的な例は、ClowdwatchとLambdaを使用してSlackへ通知する方法である。 Lambdaを使用して通知を送ると通知の文面などをカスタマイズできるが、そこまでの必要がない場合、 Chatbotを使用することでコーディングなしでClowdwatchの通知を送る事ができる。 今回の例では、EC2インスタンスのCPU使用率が閾値を超えた場合にアラームを飛ばすように実装する  Chatbot設定 1.Chatbotページからチャットクライアント「Slack」を選択 2.Slackにリダイレクトされるので、使用したいSlackのチャンネルを選択して「Allow」 3.新しいチャネルを設定 4.任意の設定名を指定し、通知を送りたいチャネルを指定する 5.アクセス許可では任意のロール名を指定する(指定したいロールがある場合は、IAMロールのプルダウンから選択する) 6.Chatbot管理画面でチャネルの作成ができたことを確認 Amazon SNSの設定 Amazon SNSはClowdwatchとSlackを連携する機能で、Clowdwatchのアラームを拾ってChatbotへ渡して上げることができる。 1.トピックの作成 2.スタンダードを指定し、名前を決定する    他の項目は特に指定がなければデフォルトのままで良い 3.トピックが作成されたので、トピックに紐づくサブスクリプションの作成を行う 4.プロトコルを指定     直接Slackを指定したいができないため、仮でEメールを選択し、メールアドレスを入力する。(Eメール認証があるため、仮であっても正しいメールアドレスを入れること) 5.届いたメールでメール認証を行い、AmazonSNSでサブスクリプションが作成されたことを確認する ChatbotにSNS通知を紐付ける 1.Chatbotページに行き、先程作成したチャネル名をクリックする(この例だとslack-alert) 2.右上「編集」ボタンから編集ページへ遷移する 3.通知-オプションで先程作成したSNSトピックを選択する(この例だとclowdwatch-slack-sns) Clowdwatch アラームの作成  Clowdwatchからアラームを作成したいメトリクスを指定しても良いが、項目が沢山あり、探すのが大変なので、今回はEC2からメトリクスの作成を行う。 1.EC2画面でインスタンスを選択し、下部モニタリングタブからCPU使用率の右上3点・・・をクリック、「メトリクスで表示」を選択 2.指定したメトリクスのアクション列にあるベルマークを選択 3.Clowdwatchのメトリクスと条件の指定に遷移するので、期間、閾値などを指定する  今回の例では、5分間隔でチェックを行い、CPU使用率が10%以上のときにアラームを飛ばすように設定する 4.通知の送信先を作成したSNSにする 5.アラーム名を指定する 6.プレビュー画面で設定が間違っていなければ作成する 7.アラームが作成されたことを確認 Slackにエラーメッセージが飛んでくれば設定完了
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【EC2】EC2にrailsのアプリをデプロイする方法 No.2(デプロイ)

はじめに それでは前回に引き続き、EC2を使ってrailsのアプリをデプロイしたいと思います。 前回はEC2の環境構築までを行いました。 これまでの工程について、まだ実装されていない方はこちらの記事をぜひご覧ください それでは早速デプロイしていきます! 手順3 gitと連携をします EC2インスタンスにアプリケーションのコードを送るためにはGithubを使います。 連携したGithubからEC2へクローンすることでデプロイをします。 そのためにGitHubとの接続設定をします。 ターミナルで下記のコマンドを実行します。 gitの連携 [ec2-user@ip-172-31-23-189 www]$ git clone リポジトリURL リポジトリURLはご自身のGitHubのページで確認することができます。 Githubのアカウント名とPWを入力し、 ダウロードが開始されます remote: Enumerating objects: 298, done. remote: Counting objects: 100% (298/298), done. remote: Compressing objects: 100% (190/190), done. remote: Total 298 (delta 109), reused 274 (delta 86), pack-reused 0 Receiving objects: 100% (298/298), 58.53 KiB | 365.00 KiB/s, done. Resolving deltas: 100% (109/109), done. 完了 これで、EC2にAppがクローンされています。 手順4 アセットファイルをコンパイルします まずはcssやJavaScript、画像ファイルのコンパイルを行います。 ローカル環境ではこの作業は不要でしたが、本番環境では処理速度の関係で自動的に行われないので随時行う必要があります。 下記のコマンドでアセットファイルをコンパイルします。 アセットファイルのコンパイル # クローンしたアプリのディレクトリに移動 [ec2-user@ip-172-31-47-9 ~]$ cd /var/www/レポジトリ名 # アセットファイルのコンパイルを実行 [ec2-user@ip-172-31-47-9 レポジトリ名]$ rails assets:precompile RAILS_ENV=production コンパイルが無事終了すればOKです。 手順5 database.ymlを編集しよう 本番環境でもデータベースを作成する必要があるので、ローカルのconfig/database.ymlの本番環境の定義部分を下記のように編集します。 databaseの値は編集しないでください。 本番環境の編集 production: <<: *default database: アプリ名_production username: root password: <%= ENV['DATABASE_PASSWORD'] %> socket: /var/lib/mysql/mysql.sock ローカルのファイルを編集したのでcommitし、pushします。 そしてEC2インスタンスでpullをしましょう。 手順6 データベースの作成 これでデータベースサーバーに接続することができるようになりました。 次にEC2インスタンス内に今回のアプリで使用するデータベースを作成します。 下記のコマンドを実行します。 データベースの作成 [ec2-user@ip-172-31-47-9 レポジトリ名]$ rails db:create RAILS_ENV=production # 以下のように表示されればOK Created database 'アプリ名_production' 次にデータベースにテーブルを作成します。 テーブルの作成 [ec2-user@ip-172-31-47-9 レポジトリ名]$ rails db:migrate RAILS_ENV=production エラーなくテーブルが作成されればOKです。 終わりに/完成形 以上でデプロイの準備が完成です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS認定パートナー制度

■AWS(Amazon Web Services)とは Amazon.comにより提供されているクラウドコンピューティングインフラストラクチャーサービスです。 企業の特徴として「AWSのパートナー認定を受けている」等耳にすることが多いと思いますが、 パートナー認定の中でもパートナーランクが設けられております。 ■ランク 知識・経験・顧客の成功体験 等それぞれの要件が設けられております。 AWSトレーニングの力量や、カスタマーエンゲージメント、全体的事業投資などをそれぞれ判断されて以下4つの階層に分かれます。 1.Premier 2.Advanced 3.Select 4.Registered ■ランクの詳細 Premier 【知識】 ・AWSプロフェッショナル認定取得者数:20名(テクニカル10名、ビジネス10名) ・AWS基礎認定技術者数:10名 ・AWS認定技術者数:25名(最低10名はプロフェッショナル/専門知識) 【経験】 ・年間ローンチ案件数:50件(見込み月次収益$50,000) ・技術プログラム検証:3件(うち1つは、MSPまたはDevOpsコンピテンシー) ※プレミアへのアップグレード申請前に要件を6か月間満たし続ける必要あり 【顧客の成功カテゴリー】 ・公開可能な事例数:6件 ・顧客満足度(CSAT)回答数:30件 Advanced 【知識】 ・AWSプロフェッショナル認定取得者数:8名(テクニカル4名、ビジネス4名) ・AWS基礎認定技術者数:4名 ・AWS認定技術者数:6名(最低3名はプロフェッショナル/専門知識) 【経験】 ・年間ローンチ案件数:20件(見込み月次収益$10,000) 【顧客の成功カテゴリー】 ・公開可能な事例数:2件 ・顧客満足度(CSAT)回答数:20件 Select 【知識】 ・AWSプロフェッショナル認定取得者数:4名(テクニカル4名、ビジネス4名) ・AWS基礎認定技術者数:2名 ・AWS認定技術者数:2名 【経験】 ・年間ローンチ案件数:3件(見込み月次収益$1,500) 【顧客の成功カテゴリー】 ・公開可能な事例数:1件 ・顧客満足度(CSAT)回答数:5件"
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

自分用メモ: aws ssmの設定方法

ec2にAmazonEC2RoleforSSMポリシーがアタッチされているロールを与える. 資料: https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/getting-started-add-permissions-to-existing-profile.html フルプライベートサブネットの場合は、追加でそのサブネットにVPC Endpointを作成する. 詳しくはこちらの資料の以下の項目を参照して、VPCエンドポイントを作成してください. Systems Manager の VPC エンドポイントを作成します。 資料: https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-systems-manager-vpc-endpoints/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

aws ssmをフルプライベート環境で設定する

前提: ec2のイメージはAmazon Linux 2を想定しています. Amazon Linux 2以外の方はこちらの資料を参考にuserdataを定義してください ec2にAmazonEC2RoleforSSMポリシーがアタッチされているロールを与えてください 資料: https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/getting-started-add-permissions-to-existing-profile.html フルプライベートサブネットの場合は、追加でそのサブネットにVPC Endpointを作成してください 詳しくはこちらの資料の以下の項目を参照して、VPCエンドポイントを作成してください. Systems Manager の VPC エンドポイントを作成します。 資料: https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-systems-manager-vpc-endpoints/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

OWASP ZAPで診断するためにAWS CDKで実装が必須となる箇所

はじめに AWSのS3, CloudFront, API-Gateway, Lambdaなどを使って実装したサービスに対して、CICDパイプラインの一部として脆弱性診断を流せるか?という確認作業の中で、診断ツールの1つであるOWASP ZAPを試しています。 2021年8月時点、AWS CDKを使って定義したAPI Gatewayに対して、OWASP ZAP Dockerを使って脆弱性診断をおこなう際、API定義の内容によって診断できない場合がありました。 診断できない2つのケースとその対処法について説明します。 診断できないケース1:Status Codeの定義漏れ 診断できないケース2:Request Parametersの定義漏れ ※ 以下、動作確認で使用したコンテナイメージは owasp/zap2docker-stable になります。 診断できないケース1:Status Codeの定義漏れ 診断NGとなるCDKのソースコード // <中略> // GETメソッドが返すレスポンスの定義がない const userId = users.addResource("{userId}") userId.addMethod("GET") // <以下省略> 定義がないとどうなるか 2021/07月頃はNullPointerExceptionで落ちて終了していました 2021/08/19以降は、zap起動後に、以下のwarningが出て診断が実行されずに終了しました。 今回の問題解決のヒントとなるImport warningsのログはzapのシェルスクリプトを起動してすぐ出力されているのですが、その後Add-onのログが大量に出て流れてしまうので、見落としに注意が必要です。 2021-08-19 07:04:13,560 Import warnings: ['attribute openapi is missing', "attribute paths.'/users'(post).responses is missing", "attribute paths.'/users/{userId}'(get).responses is missing", "attribute paths.'/users/{userId}'(delete).responses is missing"] 2021-08-19 07:04:13,560 Failed to import any URLs Traceback (most recent call last): File "/zap/zap-api-scan.py", line 456, in main raise NoUrlsException() NoUrlsException # 中略:Add-onをロードするログが続く 9160 [ZAP-daemon] INFO org.parosproxy.paros.CommandLine - Add-on downloaded to: /home/zap/.ZAP_D/plugin/pscanrulesAlpha-alpha-33.zap 9161 [ZAP-daemon] INFO org.zaproxy.zap.DaemonBootstrap - ZAP is now listening on 0.0.0.0:37715 2021-08-19 07:04:13,562 Trigger hook: pre_exit, args: 3 診断OKなCDKのソースコード // --- 診断OKなCDKのソースコード --- const userId = users.addResource("{userId}") userId.addMethod("GET", integration, { // 最低限これがあれば診断エラーがでない状態。書き方の詳細はAPIドキュメント参照 methodResponses: [{statusCode: '200' }], } ); // <以下省略> 参考: MethodOptions#methodResponses 補足 API仕様的には以下のようにaddResourceの第二引数の中にdefaultMethodOptionsの値として定義することも可能のようですが、実際やってみると、API GatewayからエクスポートしたOpenAPI定義ファイルでは各メソッドのresponseとしては定義されず、上記と同じエラーになりました。 const userId = users.addResource("{userId}", { // NG:このようにaddResourceの引数で与えても各メソッドのレスポンス定義には // 反映されなかった defaultMethodOptions: { methodResponses: [{statusCode: '200' }] } }) 診断できないケース2:Request Parametersの定義漏れ OWASP ZAP(Docker)で診断する際は、パスやクエリにあるパラメータをCDKのコード上で定義してやる必要がありました。 例えば以下の例では、userIdというパスパラメータを使っています。 診断NGなCDKのソースコード // path parameter {userId}の定義をしていない const userId = users.addResource("{userId}") userId.addMethod("GET", integration, { methodResponses: [{statusCode: '200' }], } ); 定義がないとどうなるか api scan実行時に以下のような「parameterの定義がないよ」というwarningが出て、(add onをロードしたログが出た後に)診断されず処理が終わります。 2021/08/04ぐらいから発生し始めた現象です 2021-08-19 05:11:32,080 Import warnings: ['attribute openapi is missing', "attribute paths.'/users/{userId}'. Declared path parameter userId needs to be defined as a path parameter in path or operation level"] 2021-08-19 05:11:32,080 Failed to import any URLs Traceback (most recent call last): File "/zap/zap-api-scan.py", line 456, in main raise NoUrlsException() NoUrlsException <中略: Add-onの読み込みログ> 2021-08-19 05:11:43,562 Trigger hook: pre_exit, args: 3 診断OKなCDKのソースコードの書き方:その1 // addResourceの第二引数にresourceOptionsを定義してその中に // defaultMethodOptions>requestParametersを定義 const userId = users.addResource("{userId}", { defaultMethodOptions: { requestParameters:{'method.request.path.userId':true} } }) userId.addMethod("GET", integration, { methodResponses: [{statusCode: '200' }] } ); addResourceの第二引数がresourceOptionsになります。そのプロパティとして、defaultMethodOptions>requestParametersを追加してuserIdを宣言します。詳細な仕様は以下ドキュメントを参照してください。 参考: ResourceOptions#defaultmethodoptions 診断OKなCDKのソースコードの書き方:その2 // addResourceはそのまま。代わりに”GET"などメソッド毎に // requestParametersを定義する // ただしこの場合、(OPTIONS含め)定義する全てのメソッドに // requestParametersを定義する必要がある const userId = users.addResource("{userId}") userId.addMethod("GET", integration, { methodResponses: [{statusCode: '200' }], requestParameters:{'method.request.path.userId':true} } ); // 以下省略 こちらの書き方では、addResourceはそのまま。代わりに”GET"などメソッド毎に requestParametersを定義します。 参考: MethodOptions#requestparameters ただしこの場合、(OPTIONS含め)定義するすべてのメソッドにrequestParametersを定義する必要があります。 上記サンプルコード中のクエリパラメータを示すキー method.request.path.userIdの書き方は以下のサイトに書き方の例があります。 参考: request-response-data-mappings たとえばメソッドのクエリ文字列であれば、method.request.querystring.PARAM_NAMEのようになります booleanの値部分は必須パラメータかどうかを示しています おわりに 2021年7~8月にOWASP ZAP Dockerを使って遭遇した問題とその対処(結局は定義をちゃんと書きましょうということ)について共有させていただきました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

何となくわかった気になる週刊AWS – 2021/8/23週

はじめに こんにちは、なじむです。 今週も張り切ってやっていきましょう!AWS Japan さんがまとめている週刊AWSで確認した内容の自分用メモ。 今回は8/23週のアップデートです。 8/23(月) Happy 15th Birthday Amazon EC2 | AWS News Blog 8/23 は EC2 の誕生日です!今年で 15 歳になりました。 リンクはアップデートの内容ではなく、これまでのサービスの立ち上げから更改の話まで EC2 の歴史が書かれていますので、もし興味がありましたらぜひご覧ください。 Amazon Appflow を使用して SAP アプリケーションから AWS サービスにデータを送信する Datadog や Salesforce、Google Analytics 等、SaaS から S3 や Redshift にデータを転送することができる Appflow が、SAP アプリケーションからのデータ転送に対応しました。 SAP を使ったことないので、どの程度嬉しいのか、どの程度インアクトがあるのか等が分かりませんでした。 SAP について今後調べていこうと思います。 実際の画面は以下です。SAP のフロー作成も可能になっています。 日本リージョン対応状況 東京:対応 大阪:未対応 ※AppFlow 自体に未対応 AWS Database Migration Service がターゲットとして Redis のサポートを開始 AWS に Database のデータを移行するために使用する、AWS Database Migration Service でターゲットエンドポイントに Redis が指定できるようになりました。これにより、データを最小のダウンタイムで Elasticache for Redis や、先日発表された MemoryDB for Redis に移行できるようになりました そんな需要があるのか分からないのですが、例えば MySQL から Redis へのデータ移行とかも簡単にできるようになっているのだろうか…? 実際の画面は以下です。ターゲットエンドポイントとして、Redisが選択できるようになっています。 日本リージョン対応状況 東京:対応 大阪:対応 Amazon EC2 M6i インスタンスをご利用いただけるリージョンが 2 つ増えました 先週のブログで紹介した M6i インスタンスが東京でも利用可能になりました。8/16(月)時点では東京リージョンでは利用できなかったのですが、8/23(月)に利用可能できるようになりました。 日本リージョン対応状況 東京:対応 大阪:未対応 8/24(火) AWS Backup Audit Manager の紹介 EC2 や RDS 等のバックアップを自動で取得、管理してくれる AWS Backup に、バックアップが適切に取得できているかをチェックする AWS Backup Audit Manager の機能が追加になりました。 AWS Backup の画面の左下から設定ができます。 フレームワークを作成すると、各項目をチェックしてくれます。 レポートはバックアップジョブレポート等を作成できるようです。 私の環境はリソースが一つもなく動作を見てもつまらなかったのですが、Classmethod さんがやってみた記事を挙げていたので、ぜひご覧ください。 (参考)[アップデート]AWS BackupでAudit Manager機能が追加されたのでやってみた 日本リージョン対応状況 東京:対応 大阪:未対応 8/25(水) Amazon MSK が容量の可視性の向上のためのメトリクスを追加 Apache Kafka のマネージドサービスである Amazon Managed Streaming for Apache Kafka (Amazon MSK) で、Cloudwatch に CPU やストレージ、ネットワークのリソース使用状況を示す 19 個のメトリクスが追加になりました。 具体的に度のメトリクスが追加になったのか分からないのですが、この辺を調べる方法ってあるのでしょうか…? ちなみに、Apache Kafka はスケーラビリティに優れた分散メッセージキューで、例えば IoT 機器のセンサデータを高速に中継し、処理サーバへ受け渡すために使用されるオープンソースプラットフォームです。 イメージ図は NTT Data さんの図が分かりやすいかなと思います。 (参考)Apache Kafkaとは 日本リージョン対応状況 東京:対応 大阪:未対応 ※MSK自体に未対応 Amazon EC 2 Instance Metadata Service、Amazon Time Sync Service、および Amazon VPC DNS サーバーで IPv6 エンドポイントを使用できるようになりました EC2 で、IPv6 に対応した以下のエンドポイントが使用できるようになりました。それぞれのエンドポイントも記載します。 サービス IPv4 エンドポイント IPv6 エンドポイント Amazon EC 2 Instance Metadata Service 169.254.169.254 fd00:ec2::254 Amazon Time Sync Service 169.254.169.123 fd00:ec2::123 Amazon VPC DNS サーバー 169.254.169.253 fd00:ec2::253 やってみた系のブログは以下が参考になりました。ここまで調べてできるの凄いなと思います。 (参考) EC2 Instance Metadata Service と Amazon Time Sync Service で IPv6 エンドポイントが利用可能になりました 日本リージョン対応状況 東京:対応 大阪:対応 8/26(木) AWS Snowcone が AWS アジアパシフィック (シンガポール) リージョンと AWS アジアパシフィック (東京) リージョンで利用可能になりました AWS への大量のデータ転送やエッジコンピューティング、エッジストレージの機能を提供する Snow Family の内、Snowcone が東京リージョンで使用可能になりました。 大きさと容量は以下のような感じです。Snowcone のお手軽さが目立ちます。ちなみに、Snowcone をなくすと \$2,000 かかるようです(\$2,000 払えば Snowcone がお手元に!) 項目 Snowcone Snowball Edge Storage Optimized Snowmobile 画像 * 容量 8 TB 80 TB 100 PB 大きさ お弁当箱くらい スリムサイズPCを少し小さくした感じ 大型トラック 東京リージョン 対応 対応 不明 大阪リージョン 未対応 未対応 不明 (出典) AWS Snow ファミリー 実際の画面は以下です。 東京リージョン 大阪リージョン 大阪リージョンは Snowball Edge Compute Optimized は対応してましたが、Snowball Edge Storage Optimized は未対応のようでした。 日本リージョン対応状況 東京:対応 大阪:未対応 Amazon Aurora が、PostgreSQL 13 をサポート MySQL および PostgreSQL 互換のマネージド RDBMS である Aurora で、PostgreSQL 13 が利用できるようになりました。 PostgreSQL 13 では以下の機能が追加になっています。 B Tree インデックスエントリの重複排除 パーティションテーブルを使用するクエリのパフォーマンスの向上 データソートを高速化する増分ソート VACUUM コマンドによるインデックスの並列処理 PostgreSQL データベース内のアクティビティをモニタリングする方法の追加 新しいセキュリティ機能などの新しい機能や拡張機能による、改善された機能とパフォーマンス bool_plperl のサポート 「そもそも PostgreSQL の RDS とどう違うの?」と疑問に感じた方は以下を参照いただくと分かりやすいかと思います。 (参考) AuroraかRDSどちらを選ぶべきか比較する話をDevelopers.IO 2019 in OSAKAでしました 実際の画面は以下です。Aurora で PostgreSQL 13.3 が利用になっています。 日本リージョン対応状況 東京:対応 大阪:対応 AWS Compute Optimizer によって、お客様は、Graviton2 ベースのインスタンスへ移行した場合の影響を把握できるようになりました EC2 や Lambda のリソース使用状況を分析し、最適なリソースタイプを提案してくれる AWS Compute Optimizer で、Graviton2 ベースのインスタンスへ移行した場合の影響を把握できるようになりました。 Graviton2 は AWS がクラウドで利用するために独自開発した ARM ベースのプロセッサで、M5 や C5、R5 といった他の x86 ベースのインスタンスタイプと比較し、20% のコストダウンと 40% のコストパフォーマンスが向上しています。Graviton2 ベースのインスタンスは M6g や R6g、C6g 等の追加情報が "g" のインスタンスタイプのものが該当します。 なお、比較対象に選択できるのは Windows が Gravitation に対応していないということもあり、Linux インスタンスのみとなっています。 起動しているインスタンスがなく、実際の推奨事項は確認できませんでしたが、以下で設定できます。 実際の画面は Classmethod さんのブログが参考になりますので、ご覧ください。 (参考) [アップデート] AWS Compute Optimizerが東京リージョンに対応しました! 大阪リージョンは Gravitation2 に未対応のため、本機能も未対応です。 日本リージョン対応状況 東京:対応 大阪:未対応 8/20(金) Amazon Virtual Private Cloud (VPC) の利用時、プレフィックスリストのサイズ変更が可能に IP アドレスの集合を定義し、それをセキュリティグループなどで使用できるプレフィックスリストで以下アップデートがありました。 作成後に最大エントリ数を変更できるようになりました Resource Access Manager (RAM) を使用して他の AWS アカウントとプレフィックスリストを共有できるようになりました これまでは作成後にエントリ数を変更することはできず、その範囲を超える場合は再作成が必要でしたが、作成後にも変更できるようになったようです(赤枠の最大エントリが変更可能になった) ※現時点ではマネジメントコンソールからは変更ができず、SDK または AWS CLI での変更が必要な点に注意してください。 RAM での共有もできるようになっていますね。 やってみた系のブログは Classmethod さんのブログが参考になりますので、興味のある方はご覧ください。 (参考) [アップデート] VPCプレフィックスリストの最大エントリ数が変更可能になりました 日本リージョン対応状況 東京:対応 大阪:未対応 CloudWatch ダッシュボード向けカスタムウィジェットを発表 AWS リソースやアプリケーションのモニタリングサービスである Cloudwatch で、ダッシュボードにカスタムウィジェットを作成できるようになりました。カスタムウィジェットでは Lambda を指定できるようになっており、Lambda の結果を表示できるようになっています。Lambda の結果が表示されるので、実質何でも表示することができそうです。 やってみた系のブログは Classmethod さんのブログが参考になりますので、興味のある方はご覧ください。 (参考) [アップデート]CloudWatch dashboardに任意のLambda関数の結果を表示できるcustom widgetsが使えるようになりました (参考) CloudWatch dashboard custom widgetsのcwdb-actionで実行するLambda関数にパラメーターを渡したいときはどうするの? 日本リージョン対応状況 東京:対応 大阪:対応 感想 今週は DirectConnect の障害で結構大きなニュースになっていましたね。こういうのを経験するとマルチクラウド化って大事じゃない?という気持ちになります。費用対効果が高いかは分かりませんが。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

行レベルセキュリティーを考慮したQuickSightの登録済みユーザーの埋め込みダッシュボード機能を利用する

はじめに 前回この記事でQuickSightのRLSを考慮した匿名ユーザー向けの埋め込みダッシュボードの表示について説明しましたが、登録済みユーザーのダッシュボードも試したので記録として残しておきます。 前編及び後編で作成したダッシュボードやソースをもとに設定を追加していくので、実際に手を動かして確認する場合はまず前編及び後編を確認してみてください。 匿名ユーザーと登録済みユーザーの埋め込みダッシュボードの違い 前回作成した匿名ユーザーの埋め込みダッシュボードと、登録済みユーザーの埋め込みダッシュボードには次のような違いがあります。 登録済みユーザーの埋め込みダッシュボードは、 EnterpriseEditionは必須だが、セッションキャパシティープランでなくても利用できる ダッシュボード表示時にQuickSightのReader以上のアカウントを割り当てる必要がある セッションタグを利用した行レベルセキュリティー(RLS)は利用できないため、事前にユーザーごとのRLSを設定する必要がある やはり一番の違いはセッションキャパシティープランでなくても利用できる点だと思います。セッションキャパシティープランを必要とする匿名ユーザーの埋め込みダッシュボードでは開いたセッション数で課金されるのに対し、登録済みユーザーの埋め込みダッシュボードでは登録されたユーザーの数で課金されます。 QuickSight 料金 このため、ダッシュボードの利用人数は少ないんだけれど特定の人が良く見るとか、一人当たりのダッシュボード表示回数はあまりないんだけれどとにかく利用者数が多いといった埋め込みダッシュボードの表示パターンをもとにQuickSightの契約プランを検討する必要があります。 また、いつRLSを割り当てるかも重要な観点です。登録済みユーザーの埋め込みダッシュボードではセッションタグが利用できないため、RLSは事前に登録しておく必要があります。匿名ダッシュボードのようにダッシュボードURL発行時に割り当てるRLSを制御できない点も注意が必要です。 グループの追加 匿名ユーザーの埋め込みダッシュボードの場合、作成したダッシュボードはユーザーかグループに対して事前に共有しておく必要があります。ユーザーごとにダッシュボードを共有するとユーザー登録が煩雑になるため、ダッシュボードをグループに共有しそのグループにユーザーを登録してあげたほうが運用しやすいと思います。グループはUIからは追加できないのでAWS CLIから登録する必要があります。 aws quicksight create-group --aws-account-id $awsAccountId --namespace default --group-name SampleDashboard { "Status": 201, "Group": { "Arn": "arn:aws:quicksight:ap-northeast-1:xxxxxxxxxxxx:group/default/SampleDashboard", "GroupName": "SampleDashboard", "PrincipalId": "group/d-xxxxxxxxxx/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }, "RequestId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" } ダッシュボードをグループに公開 埋め込みたいダッシュボードを先ほど作成したグループに割り当てていきます。ここはUIからやったほうが分かりやすいのでUIで操作します。 ダッシュボードの共有メニューから 共有したいグループを検索して共有ボタンをクリックします。 ダッシュボードアクセスの管理ボタンをクリックすると、現在共有されているユーザー、もしくはグループの一覧を確認できます。 登録済みユーザーの埋め込みダッシュボードの表示 それではダッシュボードを表示していきましょう。 まずはダッシュボードを表示するためのユーザーを登録し、先ほどダッシュボードを公開したグループに所属させます。 ユーザーの登録やグループへの参加はあらかじめCLIから設定しておいてもよいのですが、アプリ側でダッシュボードURLの作成時にQuickSightのユーザーを登録してグループに参加させたほうが運用が楽になるケースが多いと思うので、ここからはアプリ側で実装していきます。 前回使った画面に登録済みユーザーでダッシュボードを表示するためのボタンを一つ配置しておきます。 Index.cshtml @page @model IndexModel @{ ViewData["Title"] = "Home page"; } <div class="text-center"> <form method="post"> <div><select asp-for="SelectedDashboard" asp-items="Model.DashboardList" name="dashboard" id="dashboard"></select></div> <div><input type="submit" value="表示(User)" asp-page-handler="ViewDashboardForUser"/></div> <div><input type="submit" value="表示(Admin)" asp-page-handler="ViewDashboardForAdmin"/></div> + <div><input type="submit" value="表示(test1ユーザー)" asp-page-handler="ViewDashboardForTest1User"/></div> </form> @if (!string.IsNullOrEmpty(Model.EmbedDashboardUrl)) { <div style="width: 100%"> <iframe style="width: 100%; height: 600px" src="@Model.EmbedDashboardUrl"></iframe> </div> } </div> このボタンを押されたときに実施するのは次の3つです。 1.ユーザーを取得(いなかったら登録) 2.ユーザーをグループに追加 3.埋め込みダッシュボードのURLを取得してページのEmbedDashboardUrlプロパティーに設定 ここでは固定でtest1@example.comというユーザーをQuickSightのユーザーとして作成していますが、実際はアプリ側で認証したユーザーのメールアドレスなどを使うことになると思います(アプリ側ではここで現在のユーザーが埋め込みダッシュボードを表示できるかのチェックを行ってもよいですね)。 Index.cshtml.cs public async Task OnPostViewDashboardForTest1User(string dashboard) { const string userName = "test1@example.com"; // STSからAWSのアカウントIDを取得し var account = await _amazonSecurityTokenService.GetCallerIdentityAsync(new GetCallerIdentityRequest()); await LoadDashBoardsAsync(account.Account); // 1.ユーザーを取得(いなかったら登録) var quickSightUserArn = await GetUserArnAsync(account.Account, "default", userName); if (string.IsNullOrEmpty(quickSightUserArn)) { quickSightUserArn = await RegisterUserAsync(account.Account, "default", userName, UserRole.READER); } // 2.ユーザーをグループに追加 await _amazonQuickSight.CreateGroupMembershipAsync( new CreateGroupMembershipRequest { AwsAccountId = account.Account, GroupName = "SampleDashboard", Namespace = "default", MemberName = userName }); // 3.埋め込みダッシュボードのURLを取得 var response = await _amazonQuickSight.GenerateEmbedUrlForRegisteredUserAsync(new GenerateEmbedUrlForRegisteredUserRequest { AwsAccountId = account.Account, ExperienceConfiguration = new RegisteredUserEmbeddingExperienceConfiguration { Dashboard = new RegisteredUserDashboardEmbeddingConfiguration { InitialDashboardId = dashboard, } }, UserArn = quickSightUserArn, SessionLifetimeInMinutes = 15, }); EmbedDashboardUrl = response.EmbedUrl; } ユーザーの存在を確認するにはユーザー一覧を取得するAPI(ListUserAsync)を呼んでもいいのですが、ユーザーでフィルターするインターフェイスが無いので全ユーザーをロードしてしまいます。ここではユーザーが存在するかはユーザーの詳細表示API(DescribeUserAsync)を呼び出して、ResourceNotFoundExceptionが発生したかどうかで判断しています。 public async Task<string> GetUserArnAsync(string awsAccountId, string @namespace, string userName) { try { var user = await _amazonQuickSight.DescribeUserAsync(new DescribeUserRequest { AwsAccountId = awsAccountId, Namespace = @namespace, UserName = userName }); return user.User.Arn; } catch (ResourceNotFoundException) { return null; } } public async Task<string> RegisterUserAsync(string awsAccountId, string @namespace, string userName, UserRole userRole) { var registerUserResponse = await _amazonQuickSight.RegisterUserAsync(new RegisterUserRequest { AwsAccountId = awsAccountId, Namespace = @namespace, IdentityType = IdentityType.QUICKSIGHT, Email = userName, UserName = userName, UserRole = userRole }); return registerUserResponse.User.Arn; } さっそく実行してあげましょう。ローカルで実行する場合はngrokでブリッジしQuickSightにドメインを登録するのを忘れないでください。 ... おや? あっ!肝心なRLSを追加するのを忘れていましたね。 RLSをCSVで設定している場合、新しいファイルをアップロードして更新する必要があるので新しいデータセットからデータセットを追加していきます。 今回はもとからいるqsadmin1に加え、今回アプリ側で利用するtest1@example.comユーザーを追加します。 bi_sample_dashboard_permission.csv UserName,role qsadmin1,"user,admin" test1@example.com,user 無事表示されましたね! まとめ 匿名ユーザーを利用するか登録済みユーザーを利用するかはダッシュボードの組み込み要件で決定する あらかじめグループを作成し、ダッシュボードをグループに対して共有する QuickSightユーザーはダッシュボードURL取得時に確認し、いなかったら登録してダッシュボードを共有したグループに所属させる
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS 日常タスク用IAMユーザーをつくる(Day1対応)

AWSアカウント作成時に作られるルートアカウントは日常タスクでは使用しないことが強く推奨されます。 ひとまず日常的なタスク用の管理者権限のIAMユーザーを作成します。 大まかな手順 *ルートユーザーでIAMのダッシュボードへ *IAMユーザーを新規に作成して、IAMポリシーにより管理者権限を設定する *IAMユーザーにログインする 今回つくるIAMユーザー ・IAMの操作権限あり ・ルートアカウントしかできない権限は付与されない ・IAMユーザー単体にポリシーを付けてIAMを機能させていく IAMダッシュボードの操作 *ユーザー>ユーザーを追加 ユーザー詳細の設定 ユーザー名:何用かとか入力 アクセスの種類:プログラムによるアクセス、AWS マネジメントコンソールへのアクセス両方選択 コンソールのパスワード:は好きな方を選択 パスワードのリセットが必要:自分ではない第三者に付与する場合などにチェックすることがよい アクセス権限の設定 「既存のポリシーを直接アタッチ」 をクリック 「AdministratorAccess」にチェックをして次へ (上記ポリシーはルートアカウントとほぼ変わらない権限を付与されているもの) タグの設定 情報を追加するようなもの。どの部署のユーザーなのかどこのリソースなのか。(Group:iOS department など) 管理しやすいものを入力する *ユーザー作成成功画面で表示される「アクセスキーID」と「シークレットアクセスキー」はAWS CLIで使うもの *作成が完了したらMFAを有効にする
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Security Hubとは

AWS Security Hubとは  組織内の様々なセキュリティデータを集約して、一元的に可視化してくれるAWSサービス 以下でAWS Security Hub利用の6つのステップについてのベストプラクティスをまとめる 1.AWS Security Hubをデプロイする 全リージョン、全アカウントでSecurity Hub、Configを有効化する セキュリティマスターアカウントを指定する 2.セキュリティツールと統合する GuardDuty・Inspector・Macie・IAM Access Analyzer・Firewall Manager・SystemsManagerなどのAWSサービスを統合する パートナーソリューションを統合する 3.セキュリティ基準を有効化する 「AWS基礎セキュリティのベストプラクティス」や「CIS AWS Founfations Benchmark」などのセキュリティ基準を有効化する 4.セキュリティ検出結果を取り扱う 高い重要度の検出結果を優先し、改善ガイダンスに従って対応する カスタムインサイトやワークフローステータスを使い、調査を効率化する 5.対応を自動化する カスタムアクションを定義し対応を自動化する 6.コス管理をする 無料期間を利用してコスト試算する セキュリティチェック項目を選別し、コストを最適化する おわりに SCS試験対策の自分用のメモとして記録しました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSで機械学習! Amazon Sagemaker【基本編】

はじめに 時は2021年、「PoC死」と言われていた AI事業も徐々に導入事例が増える一方で、 機械学習サービスの継続的運用 (MLOps) の重要性が増しつつある。 その中で、AWSの機械学習サービスといえば必ず名前が挙がるのが Amazon SageMakerである。 本記事ではこの SageMakerの具体的な使い方のイメージを掴むために、 自作のコンテナイメージを用いて学習/推論を行うまでの一連の手順を示す。 これから AWSで機械学習を始める初学者の方々にとって、少しでも参考になれば幸いである。 また、興味があれば Azure Machine Learning版のこちらの記事も是非ご参照いただきたい。 サマリ 完成図 本記事にて最終的に作成するアーキテクチャを下図に示す。 Amazon SageMakerでは最もオーソドックスな構成だと思われる。 ※ Imageはコンテナイメージ、Trainは学習コンテナ、Serveは推論コンテナを表している。 このアーキテクチャを作成するまでの手順を、本記事では以下の3段階に分けて説明する。 Step1/3. コンテナイメージの作成/動作確認 Step2/3. AWSリソースの登録 Step3/3. SageMaker上での学習/推論実行 本記事の前提 PC環境は Windows10 Proを使用し、Linux操作環境 (Git Bash) および pipコマンドを導入済とする。 AWSアカウントは作成済とし、アカウントIDは 222233334444とする。 AWSリソースの命名ルールは yamazo-qiita-{AWSリソース種別}を基本とする。 例えば S3バケット名は yamazo-qiita-s3、ECRリポジトリ名は yamazo-qiita-ecr 等とする。 機械学習の題材は Kaggleの自然言語コンペを扱う。コンペについての説明は割愛する。 Step1/3. コンテナイメージの作成/動作確認 Step1/3では以下のことを行う: Dockerのインストール コンテナイメージの作成 コンテナの動作確認 (ローカル) Dockerのインストール ローカルPC上で Dockerコンテナイメージを作成するために、 こちらの記事を参考に Docker Desktop for Windowsをインストールする。 基本的には Docker公式サイトにあるインストーラを実行するだけだが、 筆者のPC環境ではデフォルト設定だと警告 (WSL 2 installation is incomplete) が出力されて Docker Daemonが起動しなかったため、ひとまず [Settings] → [General] から [Use the WSL 2 based engine] のチェックを外して再起動したところ無事に起動した。 Git Bash $ docker --version Docker version 20.10.7, build f0df350 コンテナイメージの作成 詳細は Step3でも触れるが、SageMaker上でコンテナを用いた学習、あるいは推論を行うためには、 それぞれ下記 [要件1]、あるいは [要件2]~[要件4] を満たす必要がある: [要件1] docker run {コンテナイメージID} trainコマンドで学習処理を実行する [要件2] docker run {コンテナイメージID} serveコマンドでエンドポイントを起動する [要件3] healthcheck (/pingへのHTTP GET) に対して 200 OKを返す [要件4] 推論リクエスト (/invocationsへのHTTP POST) に対して 200 OKを返す これらを満たすために、最終的に作成するコンテナ内の構成要素を下記に示す。 なお、今回は管理を楽にするために学習/推論を 1つのコンテナイメージにまとめる。 コンテナ内のディレクトリ /opt/  ├ yamazo-qiita/  │ ├ train # (1) 学習時に呼ばれる学習処理用スクリプト (自分で実装)  │ ├ serve # (2) 推論エンドポイント作成時に呼ばれるサーバ起動用スクリプト (公式サンプルの丸写し)  │ ├ predictor.py # (3) 推論エンドポイントがリクエスト受信時に呼ばれる推論処理用スクリプト (自分で実装)  │ ├ wgsi.py # (4) 推論リクエスト受信用インタフェース設定ファイル (公式サンプルの丸写し)  │ └ nginx.conf # (5) 推論リクエスト受信用設定ファイル (公式サンプルの丸写し)  │    └ ml/ # (6) SageMakerが勝手に作成するディレクトリ    ├ input/data/{チャネル名}/ # (7) 学習前にS3からデータがDownloadされるパス    └ model/ # (8) 学習後にS3へデータがUploadされるパス   図中 (1)~(5) の学習/推論用スクリプトは本節にて後ほど作成する。 図中 (6)~(8) のディレクトリは SageMakerでコンテナ起動時に勝手に作成されるが、 ローカルで起動する際は代わりに以下ディレクトリをコンテナにマウントさせる。 なお、 {チャネル名} は yamazo-qiita-channelとする。 ローカルのディレクトリ /c/yamazo-qiita-dir/   ├ input/data/{チャネル名}/   │ └ train.csv # 今回使用する学習データ   └ model/   また、最終的な Dockerfileを以下に示す。 Dockerfile FROM nvidia/cuda:11.0-devel-ubuntu20.04 ENV PROGRAM_DIR=/opt/yamazo-qiita ENV DEBIAN_FRONTEND=noninteractive RUN mkdir -p $PROGRAM_DIR WORKDIR $PROGRAM_DIR RUN apt-get update RUN apt-get install -y python3 python3-pip tzdata nginx # 学習/推論の実装に必要なモジュール群をインストールする RUN pip3 install -U numpy==1.19.5 pandas==1.1.5 torch==1.7.0 torchvision transformers==4.5.1 scikit-learn==0.24.1 # SageMaker上で使用する AWS SDKのモジュール等をインストールする RUN pip3 install ipykernel && \ python3 -m ipykernel install --sys-prefix && \ pip3 install --quiet --no-cache-dir \ 'boto3>1.0<2.0' \ 'sagemaker>2.0<3.0' RUN pip3 --no-cache-dir install flask gunicorn # コンテナ内に学習/推論用スクリプト群を配置する COPY train.py $PROGRAM_DIR/train COPY serve.py $PROGRAM_DIR/serve COPY wsgi.py $PROGRAM_DIR/wsgi.py COPY predictor.py $PROGRAM_DIR/predictor.py COPY nginx.conf $PROGRAM_DIR/nginx.conf # train/serveを実行するためのパスを通す ENV PATH=$PATH:$PROGRAM_DIR # train/serveの実行権限を付与する RUN chmod +x train RUN chmod +x serve Dockerfileの準備が済んだら、コンテナに配置する以下スクリプト (1)~(5) を実装する。 ここでは AWS公式のサンプル実装およびその説明書きを参考に進める。   train.py # (1) 学習時に呼ばれる学習処理用スクリプト (自分で実装)   serve.py # (2) 推論エンドポイント作成時に呼ばれるサーバ起動用スクリプト (公式サンプルの丸写し)   predictor.py # (3) 推論エンドポイントがリクエスト受信時に呼ばれる推論処理用スクリプト (自分で実装)   wgsi.py # (4) 推論リクエスト受信用インタフェース設定ファイル (公式サンプルの丸写し)   nginx.conf # (5) 推論リクエスト受信用設定ファイル (公式サンプルの丸写し)   (1) train.pyには学習処理を実装する。 ただし、コンテナに配置時はファイルの拡張子 (.py) を取る必要があるため、 1行目には shebang (スクリプト実行時のインタプリタ指定) を記述する。 train.py #!/usr/bin/env python3 import pandas as pd import numpy as np import torch import torch.nn as nn DATA_PATH = "../ml/input/data/yamazo-qiita-channel/train.csv" # S3からDownloadされる学習データ MODEL_PATH = "../ml/model/model_1.pth" # S3へUploadされるモデル train_df = pd.read_csv(DATA_PATH) class MyModel(nn.Module): def train(): ... torch.save(model.state_dict(), MODEL_PATH) ... ... model = MyModel() model.train()   (2) serve.pyには推論用エンドポイントの起動処理を実装する。 今回は AWS公式サンプルの gunicorn + nginx構成をそのまま流用し、 設定ファイルのパスだけ修正する。1行目には train.pyと同様に shebangを書くこと。 serve.py #!/usr/bin/env python3 import multiprocessing import os import signal import subprocess import sys ... def start_server(): nginx = subprocess.Popen(['nginx', '-c', '/opt/yamazo-qiita/nginx.conf']) # ここだけ変更 gunicorn = subprocess.Popen(['gunicorn', '--timeout', str(model_server_timeout), '-k', 'sync', '-b', 'unix:/tmp/gunicorn.sock', '-w', str(model_server_workers), 'wsgi:app']) ... if __name__ == '__main__': start_server()   (3) predictor.pyには healthcheck処理と推論処理を実装する。 今回は AWS公式サンプルと同じく flaskでリクエストを振り分ける。 predictor.py import pandas as pd import numpy as np import torch import torch.nn as nn import flask MODEL_PATH = "../ml/model/model_1.pth" # S3からDownloadされるモデル class MyModel(nn.Module): ... model = MyModel() model.load_state_dict(torch.load(MODEL_PATH)) def predict(): # ここに推論処理を実装する model.eval() ... app = flask.Flask(__name__) @app.route("/ping", methods=["GET"]) # healthcheckリクエスト時の処理 def ping(): status = 200 return flask.Response(response="\n", status=status, mimetype="application/json") @app.route("/invocations", methods=["POST"]) # 推論リクエスト時の処理 def transformation(): data = flask.request.data.decode("utf-8") s = io.StringIO(data) data = pd.read_csv(s) predictions = predict(data) # 推論処理を呼び出す out = io.StringIO() pd.DataFrame({"results": predictions}).to_csv(out, header=False, index=False) result = out.getvalue() return flask.Response(response=result, status=200, mimetype="text/csv")   (4) wgsi.pyは predictor.pyのラッパーである。AWS公式サンプルを丸写しする。 wgsi.py import predictor as myapp app = myapp.app   (5) nginx.confは HTTPリクエストの制御設定 (例えばポート番号やタイムアウト値等) である。 こちらも AWS公式サンプルをそのまま丸写しする。 nginx.conf worker_processes 1; daemon off; ... http { ... server { ... listen 8080 deferred; client_max_body_size 5m; keepalive_timeout 5; proxy_read_timeout 1200s; location ~ ^/(ping|invocations) { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://gunicorn; } } } コンテナの動作確認 (ローカル) 全てのスクリプトを実装した後はコンテナイメージの動作確認を行う。 まずは docker buildコマンドで Dockerfileからコンテナイメージを作成する。 その後 docker imagesでイメージ一覧を出力し、コンテナイメージの IDを控える。 Git Bash $ docker build ./ -t yamazo-qiita-image $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE yamazo-qiita-image latest 3d61b4bfa011 57 seconds ago 6.82GB   続いて、コンテナイメージが以下 4つの要件 (再掲) を満たすことを確認する。 [要件1] docker run {コンテナイメージID} trainコマンドで学習処理を実行する [要件2] docker run {コンテナイメージID} serveコマンドでエンドポイントを起動する [要件3] healthcheck (/pingへのHTTP GET) に対して 200 OKを返す [要件4] 推論リクエスト (/invocationsへのHTTP POST) に対して 200 OKを返す まずは trainコマンドで学習処理を実行してみよう。 先述した通り、SageMaker上で学習処理を実行すると、S3上にある学習データが コンテナ内のディレクトリ /opt/ml/input/data/{チャネル名}にダウンロードされる。   ローカルの検証では、S3からコンテナ内にファイルがダウンロードされた状態を想定し、 前節で作成したローカルディレクトリを -vでコンテナにマウントさせて学習処理を実行する。 Git Bash $ docker run -v "C:\yamazo-qiita-dir":/opt/ml/ {コンテナイメージID} train   なお、Docker for Windowsを使用する場合、 コンテナにマウントするディレクトリを予め [FILE SHARING] に登録しないと起動できないため注意。   学習処理が完了したら、コンテナ上のパス /opt/ml/model/としてマウントしたディレクトリに モデルが保存されていることを確認する。SageMaker上で学習処理を実行した場合は、 このパスにあるファイル群が全て S3にアップロードされる。 Git Bash $ ls /c/yamazo-qiita-dir/model/ model_1.pth   次に、serveコマンドで推論用エンドポイント (つまりコンテナ) を起動する。 SageMakerでの推論時にはコンテナ上の /opt/ml/model/下にモデルがダウンロードされるため、 学習時と同様に、ローカルディレクトリをマウントすることで疑似的に同じ状況を作る。 コマンドを実行するとコンテナが起動し、HTTPリクエストを受信できる状態になるはずだ。 Git Bash $ docker run -v "C:\yamazo-qiita-dir":/opt/ml/ {コンテナイメージID} serve [2021-08-25 20:18:10 +0000] [13] [INFO] Starting gunicorn 20.1.0 [2021-08-25 20:18:10 +0000] [13] [INFO] Listening at: unix:/tmp/gunicorn.sock (13) [2021-08-25 20:18:10 +0000] [13] [INFO] Using worker: sync [2021-08-25 20:18:10 +0000] [16] [INFO] Booting worker with pid: 16 [2021-08-25 20:18:10 +0000] [17] [INFO] Booting worker with pid: 17   実際に推論用エンドポイントに healthcheck、および推論処理のリクエストを送信してみる。 それぞれ、 /pingへの HTTP GET、および /invocationsへの HTTP POSTを送信すればよい。 Docker内部からコマンド実行するために、ここではまず docker psコマンドで 起動したコンテナIDを特定後、docker execコマンドでコンテナ内部のコンソールを表示している。 Git Bash $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 78a7d3f6b360 3d61b4bfa011 "serve" 29 seconds ago Up 26 seconds dazzling_liskov $ winpty docker exec -it {コンテナID} bash # curl -v http://localhost:8080/ping # curl -v http://localhost:8080/invocations -X POST -H "Content-Type: text/csv" -d $'id,url_legal,license,excerpt\nID001, URL001, 1, I have a dream.\nID002, URL002, 2, I have a pen.' 0.20822687447071075 -0.02715710550546646   以上で Dockerコンテナの動作確認は完了だ。 もし途中でエラーが発生した場合、下記コマンドで Dockerコンテナの出力ログを確認できる。 Git Bash $ docker logs -f {コンテナID} Step2/3. AWSリソースの登録 Step2/3では以下のことを行う: AWSリソースの作成 (ECR/S3/IAM) AWS CLI設定 AWS上に学習データ/コンテナイメージを転送 AWSリソースの作成 (ECR/S3/IAM) 学習で使用するデータおよびコンテナイメージのストレージとして、 それぞれ S3バケットと ECRリポジトリを AWSコンソール画面上で作成する。 リージョンは東京リージョン (ap-northeast-1) を指定する。 これらの作業は GUI操作で非常に直感的に行えるため、手順の詳細は割愛する。 S3バケットは yamazo-qiita-s3という名前で作成し、 ECRリポジトリは yamazo-qiita-ecrという名前で作成する。 ちなみに、S3および ECRは作成しただけでは課金されない。 これらはストレージ保存ファイルの合計サイズ数におおよそ比例して課金される。 料金の目安として、例えば ECRに 100GBのイメージ、S3に 600GBのデータを保存した場合、 それぞれ 10USD/月、15USD/月程度のストレージ料金が発生する。 ※より厳密には無料枠やデータ転送料等も考慮が必要。 次に、ローカルPCから ECRや S3にデータを転送するための権限設定、つまり IAMユーザを作成する。 IAMユーザには S3FullAccessと AmazonEC2ContainerRegistryFullAccessをアタッチする。 作成した IAMユーザの Credential情報 (AccessKey/SecretKey) は次節にて使用するため控えておく。 AWS CLI設定 本節ではローカルPCから AWSコマンドを使用して AWS上にコンテナやデータを転送するための設定、 つまり AWS CLIの設定を行う。まずは pipコマンドで PCに AWS CLIをインストールする。 Git Bash $ pip install awscli   次に、AWS公式サイトを参考に、AWS CLIコマンドの権限 (Credential) を設定する。先ほど控えた AccessKey/SecretKeyを入力後、リージョンは東京リージョン (ap-northeast-1) を入力する。 Git Bash $ aws configure AWS Access Key ID [None]: AKIAXXXXXXXXXXXJBC AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXXXXXXXXXRJ1t Default region name [None]: ap-northeast-1 Default output format [None]: $   この設定の元、ローカルPC上で AWSコマンドを実行すると、 先ほど作成した IAMユーザの権限が適用されることになる。 試しに S3や ECRの一覧を取得すると、結果が出力されるはずである。 (ECRにはまだイメージを登録していないため、空の結果が出力されている) Git Bash $ aws s3 ls s3://yamazo-qiita-s3 PRE data/ PRE models/ $ aws ecr list-images --repository-name yamazo-qiita-ecr { "imageIds": [] } AWS上に学習データ/コンテナイメージを転送 ローカルPCに AWS CLIの設定が完了したら、AWS上に学習データとコンテナイメージを送信する。 ECRはログインを忘れると認証エラー (no basic auth credentials) で送信が失敗するため注意。 Git Bash $ aws s3 cp ./train.csv s3://yamazo-qiita-s3/data/train.csv $ aws ecr get-login-password | docker login --username AWS --password-stdin https://222233334444.dkr.ecr.ap-northeast-1.amazonaws.com Login Succeeded $ docker tag yamazo-qiita-image 222233334444.dkr.ecr.ap-northeast-1.amazonaws.com/yamazo-qiita-ecr $ docker push 222233334444.dkr.ecr.ap-northeast-1.amazonaws.com/yamazo-qiita-ecr Step3/3. SageMaker上での学習/推論実行 ここまで準備が済んだら、いよいよ SageMaker上で学習/推論処理を動かしてみる。 なお、SageMaker上の実装は非常に簡単である。Step3/3では以下のことを行う: SageMaker Studioの初期設定 学習処理 (トレーニングジョブ) の実行 推論用エンドポイントの作成&推論処理の実行 ここからは EC2インスタンスの停止忘れによる無駄な課金が発生しないように気を付ける。 [サービス] → [Billing] で課金状況を参照できるため、定期的にチェックしておくとよい。 閾値を超えるとメール通知する設定も可能だが、手順についてはこちらの記事を参照いただきたい。 SageMaker Studioの初期設定 SageMaker Studioとは SageMakerの統合開発環境 (IDE) である。 SageMaker Studioのリソース単位を理解するために、AWS公式サイトの概念図を以下に示す。 リソース名 単位 備考 ドメイン リージョン毎に1つ SageMaker Studioの 1プロジェクト。認証方法をSSO/IAMから選択可能。 ユーザ 1ドメインにNつ SageMaker Studioにログインするユーザ。 JupyterServerApp 1ユーザに1つ SageMaker Studioの操作画面。ユーザ毎に独立している。 KernelGatewayApp 1ユーザにNつ Notebook Kernelを起動する EC2インスタンス。EC2内ではコンテナが動作している。起動時間に比例して課金される。 Notebook Kernel 1KernelGatewayAppにNつ コンテナ上の Jupyter Notebookプロセス。同一インスタンスタイプの Notebookは同じ KernelGatewayAppに属する。 EFS 1ユーザに1つ EFSの実態 (リソースID) は 1ドメインに 1つだが、ユーザ毎に論理的に独立している。ストレージ使用量に応じて課金される。 それでは実際に SageMaker Studioの初期設定を進める。 上の概念図において、左から順にリソースを作成していくことになる。 まずは SageMaker Studioのドメインおよびユーザを作成する。 [サービス] → [SageMaker] → [SageMaker Studio] から SageMaker Studioを作成 ユーザの実行ロール (IAMロール) には AmazonSageMakerFullAccessをアタッチ この時点で、JupyterServerAppおよび永久ストレージとして EFSが作成される。 実際に、SageMaker Studio上で Notebookを起動してみよう。 [{ユーザ名}] → [Studio を開く] から JupyterServerApp画面を開き、 下図の黄枠をクリックすると、Notebookが表示される。 ちなみに、本画面から自作のコンテナイメージを Notebookの実行環境として指定することも可能だ。 詳しい設定手順についてはこちらの記事を参照いただきたい。 Notebookを開くと、自動的に実行環境のインスタンスが裏で起動される。 下図は Notebook Kernelを3つ起動した例である。 図中①の [KERNEL SESSIONS] 部分に現在実行中の Notebookが 3つ表示されている。 一方、[RUNNING INSTANCES] 部分にはインスタンスが 2つしか表示されていないが、 これは 2つの Notebookが同じインスタンスタイプ (ml.t3.medium) を指定しており、 同一のインスタンス (KernelGatewayApp) を共有しているためだ。図中②はコードの実行場所であり、 以下ではここに処理を実装していく。なお、実行環境のスペックは図中③から変更可能だ。 学習処理 (トレーニングジョブ) の実行 Notebookの実装準備が整ったので、実際に学習処理を実行する。 学習処理は fit({'チャネル名':'S3パス'})で呼び出す。この引数指定により、 S3パス下の全ファイルがコンテナのディレクトリ /opt/ml/{チャネル名}下にコピーされる。 yamazo-sagemaker.ipynb import sagemaker from sagemaker.estimator import Estimator estimator = Estimator( image_uri="222233334444.dkr.ecr.ap-northeast-1.amazonaws.com/yamazo-qiita-ecr:latest", role=sagemaker.get_execution_role(), instance_type="ml.p3.2xlarge", instance_count=1, ) estimator.fit({'yamazo-qiita-channel':'s3://yamazo-qiita-s3/data/input/'}) fit関数を呼び出すと、SageMaker内部では学習用コンテナを動かすためのインスタンスが起動し、 docker run {コンテナイメージID} trainに相当する処理が実行される。 このコマンドに見覚えのない方は Step1の [要件1]~[要件4] をもう一度確認いただきたい。 学習処理が終了するとインスタンスは自動で削除される。 推論用エンドポイントの作成&推論処理の実行 学習の次は推論を行う。まず、deploy関数で推論用エンドポイントを作成する。 yamazo-sagemaker.ipynb my_predictor = estimator.deploy(initial_instance_count=1,instance_type='ml.t2.medium') # ---------------------------------------------!   deploy関数を実行すると、推論用コンテナを動かすためのインスタンスが起動し、 docker run {コンテナイメージID} serveに相当する処理が実行される。 エンドポイント作成後もインスタンスは削除されない。 また、このタイミングから /pingへの HTTP GETによる healthcheckが行われる。 SageMaker上の出力で---------!と「!」マークが出たら起動が成功している。 エンドポイント名は [Amazon SageMaker] → [エンドポイント] から確認可能だ。 作成したエンドポイントで推論処理を実行する場合は、predict関数を呼び出す。 もうお分かりかとは思うが、SageMaker内部では /invocationsへの HTTP POSTが実行される。 yamazo-sagemaker.ipynb my_predictor.predict(data='id,url_legal,license,excerpt\nID001, URL001, 1, I have a dream.\nID002, URL002, 2, I have a pen.') # b'0.20822687447071075\n-0.02715710550546646\n'   ちなみに、このエンドポイントは一般的な APIリクエストも受信可能である。 例えば Pythonの AWS SDKである Boto3を使用して、通常の APIと同様に推論処理を呼び出せる。 yamazo-sagemaker.ipynb import boto3 client = boto3.client('sagemaker-runtime') custom_attributes = "idxxxxx-yamazo-qiita-aaaa-1234567890ab" # トレース用ID endpoint_name = "yamazo-qiita-ecr-2021-08-26-11-34-55-453" # 推論エンドポイント名 content_type = "text/csv" # コンテンツタイプ payload = b'id,url_legal,license,excerpt\nID001, URL001, 1, I have a dream.\nID002, URL002, 2, I have a pen.' response = client.invoke_endpoint( EndpointName=endpoint_name, Body=payload ) print(response['Body'].read()) # b'0.20822687447071075\n-0.02715710550546646\n'     以上、ここまでが SageMaker Studioの基本的な使い方である。 一通りの検証が済んだら、起動したエンドポイントを削除する。 yamazo-sagemaker.ipynb sagemaker.predictor.Predictor.delete_endpoint(my_predictor, delete_endpoint_config=True) 振り返り 本記事では AWSの機械学習サービスである Amazon SageMakerについて、 筆者自身も勉強しながら基本的な構築手順を紹介した。少しでも参考になれば幸いである。 また、SageMakerには他にも様々な機能があり、例えば下記等が挙げられる。 実験管理サービス (Amazon SageMaker Experiments) ETLサービス (Amazon SageMaker Data Wrangler) CI/CDサービス (Amazon SageMaker Pipelines) これらについては【応用編】として、時間ができたタイミングで別途記事を書きたいと思う。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SSH接続でWARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!と表記されて接続できない!

エラー内容 サーバ移行後にSSH接続をしようとすると接続先や鍵ファイルが正しいのに下記メッセージが表示されて接続できない時があった。 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ こちらのメッセージが表示され接続拒否されます。 原因 fingerprint(フィンガープリント)というものが存在する。 fingerprintとは、接続したことあるサーバの情報のこと。 一度接続したサーバーの情報(fingerprint)は、known_hostsに保存されている。 二回目以降のSSH接続では、fingerprintと、接続先のサーバー情報(ホスト名)を比較し、一致した場合、接続が可能となり、不一致だとこのような警告が表示される。 対処方法 対処方法は2つあります。 ①/Users/~/.ssh/known_hostsを開き、接続するIPアドレスについて検索し情報を削除。 vi /Users/~/.ssh/known_hosts  ⇨開いたら接続するIPアドレスについて検索し削除する ②/Users/~/.ssh/known_hostsから、コマンドにて接続するIPアドレスの情報を削除。 ・ssh-keygenコマンド ssh-keygen -R 00.00.00.00 ※00.00.00.00 の部分はホスト名か接続先IPアドレスに置き換える。 ●エラー文の中に下記のような文があるのでそこからファイルのパスとIPアドレスをコピーすると楽 Offending ECDSA key in /Users/〜/.ssh/known_hosts:~~ ECDSA host key for 00.00.00.00 has changed and you have requested strict checking. 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む