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

クラウドゲーミングを試そう AWS Wavelength(5G MEC)も使うよ!

概要 最近流行っているクラウドゲーミングを気軽に手元で試すことを目的にした記事です。 ゲーム開発者向けではありますが、ネットワーク関係の人も楽しく読んでもらえると思います。 複数回に分けて、概念の紹介や試せる活用例に触れていきます。 実際に構築する前に、概念や用語について解説します。 MECについて インターネットは通常、目的の宛先に届くまで様々な機器を経由して通信を行います。 あなたの家からAWSのEC2でホスティングしたサイトにアクセスしようとする場合、東京のAWSデータセンターに届くまで、様々な場所を経由します。 仮にあなたの家とサーバーが直に繋がっていたとしても、光の速さを超えてることはできず遅延が発生します。 CDNなどのキャッシュを各地に設置することで遅延削減を図るデザインはよく使われますが、 あくまでキャッシュを保存させているだけで、クラウドゲーミングのようなものには対応できません。 その問題を解決する一つの方法として、マルチアクセスエッジコンピューティング(MEC)という技術があります。 例えば5Gモバイルネットワーク網、つまり通信アンテナの近くや基地局の中に設置することで、物理的な距離を縮めます。 さらに一般的なインターネットを通過せず、通信キャリアの安定したネットワークの中で完結し、低遅延かつ安定した環境が使えます。 5Gが低遅延と謳っているのはこれが主な理由だったりします。 この環境を構築しようと通信キャリアやローカル5Gでの実験が行われています。 将来的には日本中の基地局はもちろん、通信アンテナやそれを設置している信号機や電柱などの都市インフラの中にデプロイできるVMやDockerコンテナような仮想化環境が用意されるんじゃないかなと期待しています。 街を歩けば、そこら中例のクジラに囲まれる時代が来るかもしれません。 そんな中申請すれば誰でもEC2として利用できるKDDIが提供する5G MECサービス、AWS Wavelengthがはじまりました。 Wavelengthについて Wavelengthは、MEUを通常のEC2と同じように使用できるAWSのサービスです。 日本ではKDDI(au)がサービス提供を開始しており、東京と大阪に専用のアベイラビリティゾーンが存在します。 auの4G/5G端末からのみ繋がる(ICMPプロトコルだけはどこからでも)ようになっており、ここEC2設置してキャリアのIPアドレスを紐づけられるようになってます。 安定かつ低遅延でWavelengthのEC2にアクセスできるようで、現在どのくらいの性能が出るか計測中です。 場所に依存するので、あなたの街での報告もお待ちしております。 まあぶっちゅけると、今すぐ超低遅延が体験できるというわけではなく、 実際は無線の遅延などもあるので、有線の光回線と従来のクラウドデータセンターのレスポンスに比べると見劣りします。 今後MECの設置箇所が近くなったり、SAに移行すると、もっとこの遅延が縮まるはずです。 クラウドレンダリングについて クラウド上でレンダリングされた映像をストリーミングする技術のことです。 クラウドゲーミングなど注目されており、有名どころでいくとGoogle Stadiaなどがあります。 Unreal EngineのEpic社が提供するデジタルヒューマン作成のMetaHuman Creatorもクラウドレンダリングにて提供されています。 このようにハイエンドな性能が要求されるプロ向けのツールでの活用例も出てきました。 少し変わった応用例としては、Genvidのような、インタラクティブなゲーム観戦体験を提供するプラットフォームでも使用されています。 MR機器でいくと、HololensのAzure Remote Renderingもその例です。 また、クラウドごしではありませんが、最近発表されたOculus Quest2のOculus Air LinkもLANを介したレンダリング技術です。 もし将来的にクラウドレンダリングを前提したMRグラスが発売されれば、それはハードウェアデコーダーと5Gモデムがついたとても軽量なデバイスになることでしょう。 レンダリング技術や映像配信技術の工夫で勿論遅延を減らしていくことはできますが、ユーザーの端末と物理的に近い場所にデプロイされるMECの方が都合がよいわけです。 How to UE4やGenvidのクラウドレンダリングの作例がたくさん世の中に出ているので、さっそく試したいところですが、 通常のAWSのEC2インスタンスを建てるのとは異なり、いろいろ準備が必要です。 AWSに申請しよう 申請があるの?面倒だなあ... と思われているそこのあなた、想像しているよりずっと簡単に申請されますし、許可も下ります。 英語で書く必要もありません。二日くらいで機械的な返信がきます。おそらく、研究機関や法人でなくても申請が通ります。 かんたんなかんたんな日本語申請ページ 「Wavelength Zone でアプリケーションを実行するために、どれだけのコンピューティング性能が必要ですか?」などの面倒な記入欄もありますが、 遅延計測のために軽量なインスタンス一つ、GPUインスタンスを一つ、くらいの軽い説明で大丈夫です。 EC2インスタンスやVPCを設定しよう ここに大変大変親切な記事があります。 5G MEC (KDDI / AWS Wavelength) を試す(設定編) この記事を参照して、大阪の近くに住んでいる方は「ap-northeast-1-wl1-kix-wlz-1」を、 東京の近くに住んでいる方は「ap-northeast-1-wl1-nrt-wlz-1」を選んでEC2インスタンスを作りましょう。 GPUインスタンスも1時間くらいであれば200円くらいなので、ゲームセンター感覚で遊べますが、 最小構成のt3.mediumで約5000円/月、GPUインスタンスのg4dn.2xlargeに至っては、約13万円/月です。大富豪以外は止めておきましょう。 GPUインスタンスを建てる準備ができれば、それでOKです。 コマンド一つ自動で構成される記事も準備中です... AWS Wavelengthを使ったアプリケーションを作る Unreal Engine 4のPixel Streamingを試そう。 Unreal Engineではなんとエンジンがクラウドゲーミングをサポートしています。 以下は第一弾の記事です。まずはローカル環境での動作編です。AWS編に続きます。 Genvidを使ってインタラクティブストリーミングコンテンツを作ろう。 映像配信はTwitchやYouTubeを経由してしまうので、遅延削減にどのくらい効果があるかはわからないですが、 ユーザーからの操作の遅延は縮まるはず?なので、それに期待して試験します。 Unityを使ってクラウドレンダリングできるかな? Unityを使ってクラウドレンダリングした例がいくつかあるので、頑張ってみます... でも難しいかも... 参考資料 5G MEC (KDDI / AWS Wavelength) を試す(設定編) 5G MEC (KDDI / AWS Wavelength) を試す(実測編) 5G MEC (KDDI / AWS Wavelength) を試す(比較編) 【初心者】AWS Wavelengthを使ってみる [国土IoT] 電柱・信号機等の標準化・共通化・ネットワーク化の提案 モバイル5Gって速いの??を実際に測ってみました
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[AWS Athena] 入門 ローカルのCSVをS3にアップロードしAthenaでクエリ叩くまで

本日、初めてAtehnaを使い、様々なエラーやマニュアル・他人の記事の睨めっこの格闘の末に、 ようやくローカルに保存していたCSVファイルをSQLで読み込むことができたので入門者向けにその手法を解説します。 今回はローカルにこちらのようなCSVファイルを用意しました。 スマートフォンの機種とメーカー、発売日がリストになったCSVです。 AtenaはS3に保存されているファイルをデータソースにして、SQLでデータの読込が出来るサービスなので、 まずはS3にアップロードするところから始まります。 アップロードが完了したら、Atenaのコンソール画面に遷移し、CREATE TABLE ステートメントでデータベースを作成します。 次のようなステートメントを入力し、[Run Query (クエリの実行)] を選択するか、Ctrl+ENTER を押します。 CREATE EXTERNAL TABLE IF NOT EXISTS smartphone ( id string, name string, maker string, relese_date string ) ROW FORMAT SerDe 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' WITH SerDeProperties ("field.delim" = ",", "escapeChar"="\\", "quoteChar"="\"") STORED AS TEXTFILE LOCATION 's3://aws-athena-trial/test/' TBLPROPERTIES ('has_encrypted_data'='false', 'skip.header.line.count'='1'); EXTERNALはテーブルがS3に存在するファイルをデータソースにすることを意味する IF NOT EXISTSはテーブルがすでに存在する場合にエラーを出す CSVがデータソースの場合は、ROW FORMAT SerDe org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDeを指定すると良い。データが引用符””で囲まれている場合は ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'をつかう。 LOCATION句はテーブルを作成するときに、基となるデータの Amazon S3 バケットの場所を指定する CREATE TABLE ステートメントの完了後、下記のクエリを実行すると無事結果セットが得られる。 select * from smartphone SQLさえ実行できれば、Atena上でデータ加工・変換も出来るし、加工後のデータをS3に保存することも可能。同じAWSサービスのQuick SightというBIとも連携できるので今後重宝しそう。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS EC2 Linux2 アクセスログを確認してみた

/var/log/secure を確認 $ sudo cat /var/log/secure Accepted publickey 公開鍵でログインした形跡が見つかりました。自分のグローバルIPアドレスが表示されています。 Jun 4 10:40:10 ip-172-31-46-216 sshd[3312]: Accepted publickey for ec2-user from xxx.xxx.xxx.xxx port 60615 ssh2: RSA SHA256:xxxxxxxxxxxxxxxx Invalid user 登録されていないユーザー名でログインしようとしてわざと失敗してみます。アクセスログは残るのでしょうか!?残りました!! Jun 4 11:40:04 ip-172-31-46-216 sshd[32506]: Invalid user test-user from xxx.xxx.xxx.xxx port 55569 error: AuthorizedKeysCommand インスタンス起動時に指定した公開鍵とは異なる鍵でログインを試みた結果がこちら。 Jun 4 11:53:22 ip-172-31-46-216 sshd[32599]: error: AuthorizedKeysCommand /opt/aws/bin/eic_run_authorized_keys ec2-user SHA256:yyyyyyyyyyyyyyyyyyyyy failed, status 22 /var/log/audit/audit.log を確認 $ sudo cat /var/log/audit/audit.log type=USER_LOGIN ログイン履歴が見つかりました。こちらはhostnameもしっかり記載されています。 type=USER_LOGIN msg=audit(1622803210.258:97): pid=3312 uid=0 auid=1000 ses=2 msg='op=login id=1000 exe="/usr/sbin/sshd" hostname=xxx.yyy.net addr=xxx.xxx.xxx.xxx terminal=/dev/pts/0 res=success' 登録されていないユーザー名でログインを試みました。失敗ログが残っています。 type=USER_LOGIN msg=audit(1622807835.252:451): pid=32668 uid=0 auid=4294967295 ses=4294967295 msg='op=login acct="ec2-user" exe="/usr/sbin/sshd" hostname=? addr=xxx.xxx.xxx.xxx terminal=ssh res=failed' type=USER_AUTH op=pubkey_authは鍵認証が成功したログが残っています。hostnameが記載されていませんが、グローバルIPが見えます。 type=USER_AUTH msg=audit(1622803210.014:85): pid=3312 uid=0 auid=4294967295 ses=4294967295 msg='op=pubkey_auth rport=60615 acct="ec2-user" exe="/usr/sbin/sshd" hostname=? addr=xxx.xxx.xxx.xxx terminal=? res=success' こちらは間違った公開鍵でログインを試みました。失敗ログがちゃんと残っています! type=USER_AUTH msg=audit(1622809194.934:525): pid=336 uid=0 auid=4294967295 ses=4294967295 msg='op=pubkey acct="ec2-user" exe="/usr/sbin/sshd" hostname=? addr=xxx.xxx.xxx.xxx terminal=ssh res=failed' コマンド last を実行 $ last 現在ログインしているユーザーが見えています。XXXXXXXにはホスト名が表示されています。 $ last ec2-user pts/1 XXXXXXX Fri Jun 4 11:22 still logged in ec2-user pts/0 XXXXXXX Fri Jun 4 10:40 still logged in -iでグローバルIPに変換できました。 $ last -i ec2-user pts/1 xxx.xxx.xxx.xxx Fri Jun 4 11:22 still logged in ec2-user pts/0 xxx.xxx.xxx.xxx Fri Jun 4 10:40 still logged in ログアウトした後に再度lastコマンドを実行してみます。 ログアウト時間が表示されています。このユーザーは7分ログインしていたことがわかりました! $ last ec2-user pts/1 XXXXXXX Fri Jun 4 11:22 - 11:29 (00:07) 以上です! 中二心をくすぐられますね!(≧▽≦) 参考記事
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSコンソールの画面操作を録画してCloudFormation定義を生成する(Console Recorder for AWS)

1. はじめに 以前書いた記事でとりあげたformer2の作者が開発した「Console Recorder for AWS」というものを試しました。 2. 「Console Recorder for AWS」とは 簡単に言うと、AWSコンソールの画面操作を記録して、画面から設定した内容をCloudFormation定義等に変換してくれるものです。 変換対象の形式は次の通りのようです。 - Boto3 - CloudFormation - Terraform - Troposphere - CDK - AWS CLI - IAM - JavaScript - Go SDK - Settings 公式サイトは以下のようです。 GitHub Page 使い方 開発者はAWSのコミュニティヒーローに認定されてるようです。 最新の AWS ヒーローの発表 – 2020 年 8 月 3. 本編(使ってみた) 3-1 「Console Recorder for AWS」の導入 WEBブラウザにプラグインを入れるだけです。対応するブラウザは次の通り。 - Firefox - Chrome 今回はChromeで試します。 (1)プラグインの導入 Chrome WEb Storeへ [Chromeに追加]を選択。 [拡張機能を追加]を選択。 (2)プラグインをツールバーに表示させる 「Console Recorder for AWS」アイコンが常に表示されたほうが便利なので「固定する」を選択。 3-2 AWSのコンソールに入る 普通にAWSコンソールに入りましょう。 今回はIAMuserの追加で試すのでIAMへ移動します。 3-3 録画を開始してIAMuserを追加する (1) 録画を開始 [Start Recording]を押しましょう。 (2) ユーザを追加 操作の途中は割愛しますが以下のようにユーザ作成が完了。 (3) 録画を停止 [Stop Recording]を押しましょう。 3-4 作成されたCloudFormation定義を見る 良い感じに定義が生成されています。 4. 最後に 生成されたCloudFormationをブラッシュアップすれば、生産性高くCloudFormationの開発が可能になります。 また、このツールはAWS用のツールを開発する人にとっても凄い役に立ちそうです。 AWSから発行されたAPIをトレースしているようなので、AWSの操作するためのAPIを確認する事もできます。 たとえばIAMの画面を操作すると以下のようなpythonコードが生成されてます。 import boto3 iam_client = boto3.client('iam', region_name='us-east-1') response = iam_client.list_policies() response = iam_client.list_groups() response = iam_client.create_user( UserName='ops-user', Path='/' ) response = iam_client.list_users() この通り、user一覧の取得方法が簡単に確認する事ができます。 [Console Recorder for AWS]の開発者は天才ですね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SSM Incident Manager の 分析テンプレートをカスタマイズしてみた。

背景 下記URLの通り、分析テンプレートのカスタマイズは普通に Documented なのですが、技術力の無い僕ははまってしまったので、はまったポイントをメモっておきます。誰かの役に立てたらいいな。 https://docs.aws.amazon.com/ja_jp/incident-manager/latest/userguide/analysis.html#analysis-templates Step1. 標準テンプレートをダウンロードする。 デフォルトが json 形式とのことなので、.json という名前で保存してみる。 aws-cli [ec2-user@ip-172-31-1-202 ~]$ aws ssm get-document --name AWSIncidents-PostIncidentAnalysisTemplate > ./AWSIncidents-PostIncidentAnalysisTemplate.json Content の中に【How could time to detection be improved? As a thought exercise, how would you cut the time in half?】とかの文字があるので、Content の中を更新した別ファイルを作ってアップロード(create-document)すればよさそう。と思われた。 出力結果 [ec2-user@ip-172-31-1-202 ~]$ cat AWSIncidents-PostIncidentAnalysisTemplate.json { "Name": "AWSIncidents-PostIncidentAnalysisTemplate", "CreatedDate": "2021-05-07T18:11:36.934000+00:00", "DocumentVersion": "1", "Status": "Active", "Content": "{\n \"sections\": [\n {\n \"id\": \"overview\",\n \"name\": \"Overview\",\n \"components\": [\n {\n \"questions\": {\n \"title\": \"Summary\",\n \"description\": \"Provide a summary of the incident, include the following; what happened, why it happened, how it was mitigated, and what is being done about it at a high level.\",\n \"questions\": [\n {\n \"id\": \"S1\",\n \"answer\": {\n \"markdown\": {\n }\n }\n }\n ]\n }\n },\n {\n \"questions\": {\n \"title\": \"Impact\",\n \"description\": \"A 1-2 paragraph summary of the customer-facing impact (or experience) during the event. Do not mention customers by name in this section. Provide explicit figures to detail the blast radius.\",\n \"questions\": [\n {\n \"id\": \"I1\",\n \"answer\": {\n \"markdown\": {\n }\n }\n }\n ]\n }\n }\n ]\n },\n {\n \"id\": \"metrics\",\n \"name\": \"Metrics\",\n \"components\": [\n {\n \"metrics\": {\n \"title\": \"Metrics\",\n \"description\": \"Metrics with detailed information about impact. When available, metrics from related incidents are imported and displayed here.\"\n }\n }\n ]\n },\n {\n \"id\": \"timeline\",\n \"name\": \"Timeline\",\n \"components\": [\n {\n \"timeline\": {\n }\n }\n ]\n },\n {\n \"id\": \"questions\",\n \"name\": \"Incident questions\",\n \"components\": [\n {\n \"questions\": {\n \"title\": \"Detection\",\n \"description\": \"The following questions help guide your team to detect incidents more effectively.\",\n \"questions\": [\n {\n \"id\": \"ID1\",\n \"title\": \"How could time to detection be improved? As a thought exercise, how would you cut the time in half?\",\n \"answer\": {\n \"text\": {\n }\n }\n },\n {\n \"id\": \"ID2\",\n \"title\": \"What adjustments could be made to the metrics used for detection?\",\n \"answer\": {\n \"pair\": {\n \"left\": {\n \"description\": \"Adjustments\",\n \"multiSelect\": {\n \"items\": [\n {\n \"value\": \"Add metric\",\n \"recommendation\": {\n \"id\": \"amzn-add-metric\",\n \"title\": \"Add detection metric\",\n \"description\": \"Create or update a CloudWatch metric\",\n \"size\": \"MEDIUM\",\n \"priority\": \"HIGH\"\n }\n },\n {\n \"value\": \"Update resolution\",\n \"recommendation\": {\n \"id\": \"amzn-update-resolution\",\n \"title\": \"Update detection metric resolution\",\n \"description\": \"Create or update a CloudWatch metric\",\n \"size\": \"SMALL\",\n \"priority\": \"HIGH\"\n }\n },\n {\n \"value\": \"Improve quality of data\",\n \"recommendation\": {\n \"id\": \"amzn-improve-quality-of-data\",\n \"title\": \"Improve the quality of detection metric data\",\n \"description\": \"Create or update a CloudWatch metric\",\n \"size\": \"SMALL\",\n \"priority\": \"HIGH\"\n }\n },\n {\n \"value\": \"Other\"\n },\n {\n \"value\": \"No actions needed\"\n }\n ]\n }\n },\n \"right\": {\n \"description\": \"Comments\",\n \"optional\": true,\n \"text\": {\n }\n }\n }\n }\n },\n {\n \"id\": \"ID3\",\n \"title\": \"What adjustments could be made to the alarms used for detection?\",\n \"answer\": {\n \"pair\": {\n \"left\": {\n \"description\": \"Adjustments\",\n \"multiSelect\": {\n \"items\": [\n {\n \"value\": \"Add alarm\",\n \"recommendation\": {\n \"id\": \"amzn-add-alarm\",\n \"title\": \"Add detection alarm\",\n \"description\": \"Create or update a CloudWatch alarm\",\n \"size\": \"SMALL\",\n \"priority\": \"HIGH\"\n }\n },\n {\n \"value\": \"Update threshold\",\n \"recommendation\": {\n \"id\": \"amzn-update-threshold\",\n \"title\": \"Update detection alarm theshold\",\n \"description\": \"Create or update a CloudWatch alarm\",\n \"size\": \"SMALL\",\n \"priority\": \"HIGH\"\n }\n },\n {\n \"value\": \"Update severity\",\n \"recommendation\": {\n \"id\": \"amzn-update-severity\",\n \"title\": \"Update detection alarm severity\",\n \"description\": \"Create or update a CloudWatch alarm\",\n \"size\": \"SMALL\",\n \"priority\": \"HIGH\"\n }\n },\n {\n \"value\": \"Other\"\n },\n {\n \"value\": \"No adjustments needed\"\n }\n ]\n }\n },\n \"right\": {\n \"description\": \"Comments\",\n \"optional\": true,\n \"text\": {\n }\n }\n }\n }\n }\n ]\n }\n },\n {\n \"questions\": {\n \"title\": \"Diagnosis\",\n \"description\": \"The following questions help guide your team to triage incidents more effectively.\",\n \"questions\": [\n {\n \"id\": \"DN1\",\n \"title\": \"How could time to diagnosis be improved? As a thought exercise, how would you cut the time in half?\",\n \"answer\": {\n \"text\": {\n }\n }\n },\n {\n \"id\": \"DN2\",\n \"title\": \"Do any of the following need to be updated to engage the correct contact faster?\",\n \"answer\": {\n \"pair\": {\n \"left\": {\n \"description\": \"Resource\",\n \"multiSelect\": {\n \"items\": [\n {\n \"value\": \"Escalation plan\",\n \"recommendation\": {\n \"id\": \"amzn-update-escalation-plan\",\n \"title\": \"Update escalation plan\",\n \"description\": \"Create or update escalation plan\",\n \"size\": \"SMALL\",\n \"priority\": \"HIGH\"\n }\n },\n {\n \"value\": \"Steps in response plan\",\n \"recommendation\": {\n \"id\": \"amzn-update-response-plan\",\n \"title\": \"Update response plan\",\n \"description\": \"Create or update response plan\",\n \"size\": \"SMALL\",\n \"priority\": \"HIGH\"\n }\n },\n {\n \"value\": \"Other\"\n },\n {\n \"value\": \"No updates needed\"\n }\n ]\n }\n },\n \"right\": {\n \"description\": \"Comments\",\n \"optional\": true,\n \"text\": {\n }\n }\n }\n }\n }\n ]\n }\n },\n {\n \"questions\": {\n \"title\": \"Mitigation\",\n \"description\": \"The following questions investigate ways to decrease MTTR.\",\n \"questions\": [\n {\n \"id\": \"MT1\",\n \"title\": \"How could time to mitigation be improved? As a thought exercise, how would you cut the time in half?\",\n \"answer\": {\n \"text\": {\n }\n }\n },\n {\n \"id\": \"MT2\",\n \"title\": \"Could the runbook for the incident be improved? Did the runbook contain unnecessary steps or lack ones that would help?\",\n \"answer\": {\n \"pair\": {\n \"left\": {\n \"singleSelect\": {\n \"items\": [\n {\n \"value\": \"N/A\"\n },\n {\n \"value\": \"No\"\n },\n {\n \"value\": \"Yes\",\n \"recommendation\": {\n \"id\": \"amzn-update-runbook\",\n \"title\": \"Update incident runbook\",\n \"description\": \"Create or update runbook\",\n \"priority\": \"HIGH\",\n \"size\": \"SMALL\"\n }\n }\n ]\n }\n },\n \"right\": {\n \"description\": \"Comments\",\n \"optional\": true,\n \"text\": {\n }\n }\n }\n }\n }\n ]\n }\n },\n {\n \"questions\": {\n \"title\": \"Prevention\",\n \"description\": \"The following questions focus on preventing future incidents from occurring.\",\n \"questions\": [\n {\n \"id\": \"IP1\",\n \"title\": \"Problem investigation - 5 Whys\",\n \"description\": \"Start with the initial problem of the incident and ask why until all root causes and contributing factors are listed. When listing root causes consider environmental and systemic factors that may have contributed prior to the incident. Consider taking action items against all contributing causes if appropriate.\",\n \"answer\": {\n \"multi\": {\n \"addButtonText\": \"Add problem\",\n \"definition\": {\n \"composite\": {\n \"definitions\": [\n {\n \"description\": \"Problem definition - define the problem\",\n \"text\": {\n }\n },\n {\n \"optional\": true,\n \"description\": \"Why did this problem occur?\",\n \"indent\": 1,\n \"multi\": {\n \"initialSize\": 5,\n \"addButtonText\": \"Add why\",\n \"definition\": {\n \"pair\": {\n \"left\": {\n \"description\": \"Why?\",\n \"text\": {\n }\n },\n \"right\": {\n \"description\": \"Lessons learned\",\n \"text\": {\n }\n }\n }\n }\n }\n }\n ]\n }\n }\n }\n }\n },\n {\n \"id\": \"IP2\",\n \"title\": \"Additional lessons learned\",\n \"description\": \"What additional lessons can be learned from this incident or analysis to prevent ore reduce impact of future incidents?\",\n \"optional\": true,\n \"answer\": {\n \"multi\": {\n \"definition\": {\n \"description\": \"Lessons learned\",\n \"text\": {\n }\n }\n }\n }\n }\n ]\n }\n }\n ]\n },\n {\n \"id\": \"related\",\n \"name\": \"Related items\",\n \"components\": [\n {\n \"relatedItems\": {\n }\n }\n ]\n },\n {\n \"id\": \"actions\",\n \"name\": \"Action items\",\n \"components\": [\n {\n \"actions\": {\n }\n }\n ]\n }\n ]\n}\n", "DocumentType": "ProblemAnalysisTemplate", "DocumentFormat": "JSON" } Step2. 更新したファイルをアップロードする Step2-1. アップロードするときの --name について。 下記のようなコマンドでアップロードしますが、--name の引数が、分析を行う際にテンプレートを呼び出すときの名前になります。 awscli aws ssm create-document --name Customized-Incidents-PostIncidentAnalysis --document-type ProblemAnalysisTemplate --content file://customized.json その名前が AWSIncidents-PostIncidentAnalysisTemplate_Customized とかだと怒られます。aws-, amazon, amzn が先頭に来るのはAWS側で予約されているから、ということらしいです。 エラー [ec2-user@ip-172-31-1-202 ~]$ aws ssm create-document --name AWSIncidents-PostIncidentAnalysis_customized --document-type ProblemAnalysisTemplate --content file://customized.json An error occurred (ValidationException) when calling the CreateDocument operation: Invalid document name AWSIncidents-PostIncidentAnalysis_customized [ec2-user@ip-172-31-1-202 ~]$ Step2-2. 更新したファイルの指定の仕方がわからなかった。 --content の引数として更新したファイルを指定するわけですが、指定方法がわかりませんでした。 ちなみに、下記状況としては、カスタマイズしたファイルが ローカルディレクトリに customized.json として保存されている想定。 --content customized.json と指定してみた。ダメだった。 うまくいかず [ec2-user@ip-172-31-1-202 ~]$ aws ssm create-document --name Customized-Incidents-PostIncidentAnalysis1 --document-type ProblemAnalysisTemplate --content customized.json An error occurred (InvalidDocumentContent) when calling the CreateDocument operation: invalid document content JSON [ec2-user@ip-172-31-1-202 ~]$ --content ./customized.json と指定してみた。ダメだった。 うまくいかず [ec2-user@ip-172-31-1-202 ~]$ aws ssm create-document --name Customized-Incidents-PostIncidentAnalysis1 --document-type ProblemAnalysisTemplate --content ./customized.json An error occurred (InvalidDocumentContent) when calling the CreateDocument operation: invalid document content JSON [ec2-user@ip-172-31-1-202 ~]$ --content file://customized.json が正解だった。 Step2-3. アップロードするファイルの中身について get-document でダウンロードしたファイルのカスタマイズしたい箇所だけ変更して create-document すればいいのかとおもったのだが、以下のエラーとなった。意味がよくわからん。 JSONで落としてきて、確かに中身はJSONで、そのまま必要なとこだけ更新してアップロードすれば、問題なさそうなのに。 エラー [ec2-user@ip-172-31-1-202 ~]$ aws ssm create-document --name Customized-Incidents-PostIncidentAnalysis7 --document-type ProblemAnalysisTemplate --content file://customized.json An error occurred (InvalidDocumentContent) when calling the CreateDocument operation: #: required key [sections] not found#: extraneous key [Status] is not permitted#: extraneous key [DocumentFormat] is not permitted#: extraneous key [Content] is not permitted#: extraneous key [CreatedDate] is not permitted#: extraneous key [DocumentType] is not permitted#: extraneous key [DocumentVersion] is not permitted#: extraneous key [Name] is not permitted#: 8 schema violations found [ec2-user@ip-172-31-1-202 ~]$ 結論から言うと、ダウンロードしたJSONファイルの中の Content の中身だけを抜きだして、アップロードしないとだめでした。 まぁ、よくよく考えると、その他の行の[Name]とか[Document type]とかは creat-document コマンドの引数としても指定してるしね。 かつ、Content の中身は、以下の様に、改行が【¥n】と表現されていたり【\】が余分についていたりだったので。 1.\n を 改行に置換。 2.\ を 削除 (\" を " に置換しました) の2つを実施し、以下のような Content の中を json 形式にしたファイルを作成しアップロードします。 ※ファイルが長いですが、最初と最後の{}あたりがわかるように全部そのまま乗っけます。 json { "sections": [ { "id": "overview", "name": "Overview", "components": [ { "questions": { "title": "Summary", "description": "日本語テスト:Provide a summary of the incident, include the following; what happened, why it happened, how it was mitigated, and what is being done about it at a high level.", "questions": [ { "id": "S1", "answer": { "markdown": { } } } ] } }, { "questions": { "title": "Impact", "description": "A 1-2 paragraph summary of the customer-facing impact (or experience) during the event. Do not mention customers by name in this section. Provide explicit figures to detail the blast radius.", "questions": [ { "id": "I1", "answer": { "markdown": { } } } ] } } ] }, { "id": "metrics", "name": "Metrics", "components": [ { "metrics": { "title": "Metrics", "description": "Metrics with detailed information about impact. When available, metrics from related incidents are imported and displayed here." } } ] }, { "id": "timeline", "name": "Timeline", "components": [ { "timeline": { } } ] }, { "id": "questions", "name": "Incident questions", "components": [ { "questions": { "title": "Detection", "description": "The following questions help guide your team to detect incidents more effectively.", "questions": [ { "id": "ID1", "title": "How could time to detection be improved? As a thought exercise, how would you cut the time in half?", "answer": { "text": { } } }, { "id": "ID2", "title": "What adjustments could be made to the metrics used for detection?", "answer": { "pair": { "left": { "description": "Adjustments", "multiSelect": { "items": [ { "value": "Add metric", "recommendation": { "id": "amzn-add-metric", "title": "Add detection metric", "description": "Create or update a CloudWatch metric", "size": "MEDIUM", "priority": "HIGH" } }, { "value": "Update resolution", "recommendation": { "id": "amzn-update-resolution", "title": "Update detection metric resolution", "description": "Create or update a CloudWatch metric", "size": "SMALL", "priority": "HIGH" } }, { "value": "Improve quality of data", "recommendation": { "id": "amzn-improve-quality-of-data", "title": "Improve the quality of detection metric data", "description": "Create or update a CloudWatch metric", "size": "SMALL", "priority": "HIGH" } }, { "value": "Other" }, { "value": "No actions needed" } ] } }, "right": { "description": "Comments", "optional": true, "text": { } } } } }, { "id": "ID3", "title": "What adjustments could be made to the alarms used for detection?", "answer": { "pair": { "left": { "description": "Adjustments", "multiSelect": { "items": [ { "value": "Add alarm", "recommendation": { "id": "amzn-add-alarm", "title": "Add detection alarm", "description": "Create or update a CloudWatch alarm", "size": "SMALL", "priority": "HIGH" } }, { "value": "Update threshold", "recommendation": { "id": "amzn-update-threshold", "title": "Update detection alarm theshold", "description": "Create or update a CloudWatch alarm", "size": "SMALL", "priority": "HIGH" } }, { "value": "Update severity", "recommendation": { "id": "amzn-update-severity", "title": "Update detection alarm severity", "description": "Create or update a CloudWatch alarm", "size": "SMALL", "priority": "HIGH" } }, { "value": "Other" }, { "value": "No adjustments needed" } ] } }, "right": { "description": "Comments", "optional": true, "text": { } } } } } ] } }, { "questions": { "title": "Diagnosis", "description": "The following questions help guide your team to triage incidents more effectively.", "questions": [ { "id": "DN1", "title": "How could time to diagnosis be improved? As a thought exercise, how would you cut the time in half?", "answer": { "text": { } } }, { "id": "DN2", "title": "Do any of the following need to be updated to engage the correct contact faster?", "answer": { "pair": { "left": { "description": "Resource", "multiSelect": { "items": [ { "value": "Escalation plan", "recommendation": { "id": "amzn-update-escalation-plan", "title": "Update escalation plan", "description": "Create or update escalation plan", "size": "SMALL", "priority": "HIGH" } }, { "value": "Steps in response plan", "recommendation": { "id": "amzn-update-response-plan", "title": "Update response plan", "description": "Create or update response plan", "size": "SMALL", "priority": "HIGH" } }, { "value": "Other" }, { "value": "No updates needed" } ] } }, "right": { "description": "Comments", "optional": true, "text": { } } } } } ] } }, { "questions": { "title": "Mitigation", "description": "The following questions investigate ways to decrease MTTR.", "questions": [ { "id": "MT1", "title": "How could time to mitigation be improved? As a thought exercise, how would you cut the time in half?", "answer": { "text": { } } }, { "id": "MT2", "title": "Could the runbook for the incident be improved? Did the runbook contain unnecessary steps or lack ones that would help?", "answer": { "pair": { "left": { "singleSelect": { "items": [ { "value": "N/A" }, { "value": "No" }, { "value": "Yes", "recommendation": { "id": "amzn-update-runbook", "title": "Update incident runbook", "description": "Create or update runbook", "priority": "HIGH", "size": "SMALL" } } ] } }, "right": { "description": "Comments", "optional": true, "text": { } } } } } ] } }, { "questions": { "title": "Prevention", "description": "The following questions focus on preventing future incidents from occurring.", "questions": [ { "id": "IP1", "title": "Problem investigation - 5 Whys", "description": "Start with the initial problem of the incident and ask why until all root causes and contributing factors are listed. When listing root causes consider environmental and systemic factors that may have contributed prior to the incident. Consider taking action items against all contributing causes if appropriate.", "answer": { "multi": { "addButtonText": "Add problem", "definition": { "composite": { "definitions": [ { "description": "Problem definition - define the problem", "text": { } }, { "optional": true, "description": "Why did this problem occur?", "indent": 1, "multi": { "initialSize": 5, "addButtonText": "Add why", "definition": { "pair": { "left": { "description": "Why?", "text": { } }, "right": { "description": "Lessons learned", "text": { } } } } } } ] } } } } }, { "id": "IP2", "title": "Additional lessons learned", "description": "What additional lessons can be learned from this incident or analysis to prevent ore reduce impact of future incidents?", "optional": true, "answer": { "multi": { "definition": { "description": "Lessons learned", "text": { } } } } } ] } } ] }, { "id": "related", "name": "Related items", "components": [ { "relatedItems": { } } ] }, { "id": "actions", "name": "Action items", "components": [ { "actions": { } } ] } ] } やっとうまくアップロード出来ました。 awscli [ec2-user@ip-172-31-1-202 ~]$ aws ssm create-document --name Customized-Incidents-PostIncidentAnalysis1 --document-type ProblemAnalysisTemplate --content file://customized.json { "DocumentDescription": { "Hash": "a9b47c3d97db941e9e21ba04a74528222fee0121346cf907", "HashType": "Sha256", "Name": "Customized-Incidents-PostIncidentAnalysis1", "Owner": "914432xxxxx", "CreatedDate": "2021-06-04T11:42:07.886000+00:00", "Status": "Creating", "DocumentVersion": "1", "PlatformTypes": [], "DocumentType": "ProblemAnalysisTemplate", "SchemaVersion": "", "LatestVersion": "1", "DefaultVersion": "1", "DocumentFormat": "JSON", "Tags": [] } } [ec2-user@ip-172-31-1-202 ~]$
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

dynamodb のアイテムを CSV にして S3 に吐き出してみた。Lambda で。

ssm.describe_instance_information() で取得したインスタンスID、プラットフォーム名、プラットフォームバージョンが格納されている DynamoDB のテーブルをCSVに吐き出す。 lambda-python3.8 import json import csv import boto3 def export_s3(): # lambda 上に展開する一次ファイルの定義。 /tmp/配下が使えるよ。 local_path = "/tmp/platform.csv" # s3 に保存するファイルの定義。/xxx/plaform.csv のような感じでディレクトリ指定可能 s3_path = "platform.csv" # 吐き出す先の S3 バケットの指定 bucket_name = "jiro-platform" # DynamoDB のテーブル名。今回は事前に作ってある想定。 table_name = 'platform-information' # DynamoDB のクライアントを定義 ddb_client = boto3.client('dynamodb') # scan にて DynamoDB テーブルの中身(Item)を get_data に一旦投入 get_data = ddb_client.scan( TableName=table_name ) # CSV における列を定義。ここでは3列。インスタンスID、プラットフォーム名、プラットフォームバージョン fieldnames = ['instanceid', "platform_name", "platform_version"] # lambda の /tmp 領域に 一時的な csvファイルを作成・オープンし、get_data から1行ずつ読み出しては csvファイルに書き出し。をfor 文で回す。 with open(local_path, 'w') as f: writer = csv.DictWriter(f, fieldnames = fieldnames) writer.writeheader() for data in get_data['Items']: instanceid = data['instanceid']['S'] platform_name = data['platform_name']['S'] platform_version = data['platform_version']['S'] writer.writerow({"instanceid":instanceid, "platform_name":platform_name, "platform_version": platform_version}) # s3 クライアント、s3バケット定義 s3 = boto3.resource('s3') bucket = s3.Bucket(bucket_name) # /tmp内のローカルファイルを s3 にアップロード bucket.upload_file(local_path, s3_path)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

エンド企業とSlerの関わり方:システム開発の内製化のポイント@ANGEL Dojo

目次 1.はじめに 2.全体スケジュール 3.ワークショップの内容-エンドユーザーとSIの関わり方- 4.キックオフを終えてみて 1-はじめに ANGEL Dojoって何? ANGEL Dojoでは次世代を担うAPNの若手のエンジニアの方々に、擬似プロジェクトを通じてアジャイル、DevOps、モダンなアプリケーション開発などのクラウドネイティブな手法と、様々なInnovationを作ってきたAmazonの文化と考え方を体験いただくことで、お客様にクラウドの価値を100%届けるための基礎的なスキルを実践を通して身につけていただきます。参加者の皆様はここで培ったスキルと、各パートナーの皆様がお持ちのそれぞれの強みを活かすことでお客様のビジネスを成功に導き、日本のITや経済をさらに成長させる主役、すなわち「APN Next Generation Engineer Leader」になっていただきます。 ( 「日本を元気にする」APN Next Generation Engineer Leaders(ANGEL) Dojo のご紹介 )より 簡潔に言うと「AWSを使い、3か月間、少人数のチームで企画から実装までを体験する疑似プロジェクト」になります。 同じ企業内の5名が1チームとなり、様々な講義やトレーニングを受け、企画開発、実装へと進んでいきます。 参加条件については、IT経験が1~3年目であることなど、幾つかあるので、気になる方は上記リンクで確認してみて下さい。 余談ですが、キックオフの説明で「ANGEL Dojo」はいろんなチャレンジができる場です。」というのがとても印象に残っていて、 私自身、インフラメインの業務に携わっていたので、フロント側など、普段業務では経験できないことをやってみようと思いました。 2-全体スケジュール ANGEL Dojoの全体スケジュールとしては以下の2つに分かれています  1 : 企画フェーズ     6/3~6/25  2 : 設計・開発フェーズ    7/1~7/30(中間発表) 8/5~9/3(最終発表) それぞれ詳細に説明すると、 1:企画フェーズ  ゴール:企画書の作成  期間:6/3~6/25  ここでは、Amazonの文化の1つでもある「Working Backwards(お客様から考える)」の手法をもとに、  疑似プロジェクトで開発するサービスコンセプトを決定します。 「Working Backwards」の考え方  1. お客様は誰ですか ?  2. お客様が抱える課題や改善点は明確ですか ?  3. お客様が受けるメリットは明確ですか ?  4. お客様のニーズやウォンツをどのように知りましたか ?  5. お客様の体験が描けていますか ? 2:設計・開発フェーズ  ゴール:設計及び開発の完了  期間:7/1~9/3  プレスリリース及び、FAQから実際に設計及び開発を行っていきます。 1週間のスケジュール  毎週金曜日を1日ワークDayとし、プロジェクトを進めていきます。  その他月曜日から水曜日までは通常業務を行っています。   → 講義やワークショップもある為、毎週1日~2日がプロジェクトに充てる時間になります   → 場合によってはその他の時間でタスク管理や進捗確認を行います  また、週に2回程度、講義やワークショップが実施されます。(必須参加or任意参加)   例)エンドユーザーとSIの関わり方、Working BackWordsの考え方 など ※上記はある週のスケジュール メンバー体制 <AWSからの支援体制>  ・各チームにPSA1名がメンターとしてサポート  ・AWSの様々なトレーニングを提供(講義やワークショップ)  ・疑似プロジェクトで用いるAWSリソースに対する$500のAWSクレジット  → 技術的な不安や、プロジェクトを進めるにあたって、AWSの方々に相談しやすい環境になっています <参加企業のメンバー体制>  ・1年目から3年目の若手社員5名 + 社内メンター(サポート役)1人 の計6名で参加  → 各メンバーのバックグラウンドは自動化やフロントメインに携わってきた方、インフラに関わってきた方などそれぞれです。 若手が集まったチームということもあり、MTGでも気兼ねなくそれぞれが発言できていました 3-ワークショップの内容 今回は、初回ワークショップで行われた「エンドユーザーとSIの関わり方」について簡単に紹介できればと思います。 このワークショップでは「内製化」をキーワードにユーザー企業の抱える課題、パートナー企業が可能な支援方法をディスカッションしました。 1.内製化の背景 説明する前に、内製化がなぜ求められているのか、簡単に説明したいと思います。 昨今、コロナ禍で様々な環境が変化していく中で、ぽっと出のビジネスモデルが急激に求められたり、従来のビズネスモデルが急激に衰退したりと、良くも悪くもビジネススピードの高速化が顕著に表れています。 そこで企業に求められるのが、「素早いシステム開発」です。 従来、多くのユーザー企業はシステム開発をする際、開発のほとんどをSIに委託するシステムでした。 しかし、このようなスタイルでは、企業間の距離や、SIのビジネスとの距離が遠い、などシステム開発までの時間がかかります。そこで注目されたのが「内製化」です。 そもそも「内製化」とは... ITシステムの内製化とは「ITシステムの根幹の開発を自社内で行う」ことを指します。 ITシステムの内製化とは「ITシステムの根幹の開発を自社内で行う」ことを指します。 ?ITがビジネスの場に登場してから四半世紀ほどの間、日本企業の多くは自社システムの開発をSIer(システムインテグレーター)に外注していまし>た。資金的余裕もなく、IT人材を自社内で育成することもできない日本企業は、人材外注先の企業とのやり取りを繰り返しながら、自社システム>の改善を続けてきたのです。 しかし、それではデータ活用などを見越して社内にIT人材を囲い込んでいる海外企業との競争には勝つことが出来ない、イノベーションが生まれ>ないなどの弊害が出てきたため、そのデメリットに気が付いた日本企業が、少しずつITシステムを内製化する動きに転換し始めているのです。 (ITシステムの内製(インハウス)化とは)より 2.現在のユーザー企業の内製化状況 参考資料2018年:(https://www.i-learning.jp/service/dbiz/topics/dbiz_itt10.html) ユーザー企業の内製化状況としては、全体の50%が内製化を進めているという状況  → 上流工程から下流工程の内、企画・設計などの上流の内製化を進めている企業が多い 参考資料:(https://mynavi-agent.jp/it/geekroid/2021/03/post-330.html) ユーザー企業のIT人材の”質”に関する調査では、上流、下流含め大幅に不足しているといった状況 3.内製化のポイント ここでは、内製化が上手くいった事例について、大切なポイントを3つほど、紹介します。 1.壁のないコミュニケーション(相互理解)  内製化が行われていない場合、システムを開発する上では様々な壁があります   例えばユーザー企業とSIの壁、開発と運用の壁、営業側とIT部門の壁など  スムーズに内製化が進んだ事例では、ユーザー企業、Slが同一の場所で開発、運用を行っていました  その為、スピーディに意志決定、情報の連携が行えることが、内製化では大切です 2.教育コストを加味した計画  ユーザー企業側は上流工程に対し強みがあるが、下流工程に関して深く理解していないことがあります   例えば、開発やテストにかかる工数など  この課題を解決するためには、ユーザー企業側はSIに対し、SIはユーザー企業側に対し、相互理解を深めることが大切です  お互いの文化等を理解した上で計画することが、内製化を上手く進めるためのポイントになります 3.進め方に対する意思決定権を持つ人の理解  意思決定権を持つ人が内製化に対し、柔軟に理解していること  ユーザー企業側の意思決定者が現場(ユーザー企業、SI)に対し、理解が深められていないと、ここにも壁が生じます  その為、意思決定者が柔軟に判断し、理解することがスムーズに内製化を進めるうえでの鍵になります   4-キックオフを終えてみて ここからは私がキックオフ、初回ワークショップを終えてみての感想です。 参加する前は「3か月で企画から開発、、大変そう」というのが率直な意見でした。 初日を終えてみて、1つ貴重な経験をしたなと思ったのが、普段はあまり聞くことが出来ない「ユーザー企業」の生の声が聞けた事です。 普段はシステムの開発に注力している為、ユーザーの声というものはあまり実感する機会がありませんでした。 ただ、今回のワークショップで実際にどのような部分にユーザー企業は不安を感じるのか、ユーザー企業側の課題を知ることで、 今後のシステム開発へのアプローチの方法も考える余地があるなと感じました。 それと単純に面白く、楽しかったです。(まだ初日ですが...) これから企画、開発と進んでいきますが、"Learn and Be Curious"をスローガンに挑戦をしてこれからも頑張っていきます。    
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

閉じたサブネット内のESドメインとEC2踏み台で手動スナップショットを登録する

やりたいこと 外部ネットワークへのルートがなく、従ってAWSのAPIエンドポイントへの疎通ができないサブネット(以降、Secured Subnet)に存在する踏み台EC2がある。 ここから、同じくSecured Subnet内にVPCアクセスとして構成したAmazon ESドメインに対し、手動スナップショットレポジトリの登録を行いたい。 ここに手順が書いてあるが、SigV4認証が必要とあり、インスタンスプロファイルから認証情報取ってくるから大丈夫だろうとは思いつつも一抹の不安がある。 環境 Amazon ES 7.10 VPCアクセス(Secured Subnetに配置) VPC外とは疎通できない IAM認証なし、Fine Grained Access Control(FGAC)なし Secured Subnet内の通信のみ許可 踏み台EC2 Amazon Linux 2 あらかじめpip3で以下をインストール済み boto3 requests requests_aws4auth Secured Subnetに配置 VPC外とは疎通できない 手順 1. S3バケットを作成する 今回はmy-bucket-4-esとして作成。 % aws s3 mb s3://my-bucket-4-es --region ap-northeast-1 2. S3バケットに読み書きできるポリシーを作成する いくつかポリシーを作成していくのだが、これはESが使う用のポリシー。 手動スナップショットのデータをS3にPutするのに使用する。 { "Version": "2012-10-17", "Statement": [{ "Action": [ "s3:ListBucket" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::my-bucket-4-es" ] }, { "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::my-bucket-4-es/*" ] } ] } 3. ESに渡すロールを作成し、上記ポリシーをアタッチする ポリシーをESに渡すために、es.amazonaws.comをプリンシパルに指定したロールを作る。 ここではTestRoleForESManualSnapshotとして作成する。 ちなみに、マネジメントコンソールのIAMポリシージェネレーターから作るとESを指定できないので、EC2とかで適当に作成して後で修正する。もちろんCLIで作ってもよい。 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "es.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } なおこのロールは、マネジメントコンソールやCLIからはESには渡せない。 後続のPythonスクリプトでESドメインに手動スナップショットレポジトリを登録する際に、一緒に渡す建て付けとなっている。 4. iam:passRoleとes:ESHttpPut権限を付与したポリシーを作成する 上記で作成したロールをESに渡すには、iam:passRoleという「ロールを渡すための権限」が必要になる。 今回、渡す側はEC2上のPythonスクリプトで、PythonスクリプトはEC2インスタンスプロファイルから一時認証情報を取ってくるので、iam:passRoleを持たせる相手はこのインスタンスプロファイルに指定するロール、ということになる。 また、ESドメインに手動スナップショットレポジトリを登録するためにPUTを使うので、es:ESHttpPutも併せて付与する。 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iam:PassRole", "Resource": "arn:aws:iam::123456789012:role/TestRoleForESManualSnapshot" }, { "Effect": "Allow", "Action": "es:ESHttpPut", "Resource": "arn:aws:es:ap-northeast-1:123456789012:domain/<ESドメイン名>/*" } ] } 5. EC2インスタンスプロファイルとして使うロールを作成し、上記ポリシーをアタッチする 上記ポリシーをEC2インスタンスプロファイルで使えるようにするために、プリンシパルをec2.amazonaws.comとしたロールを作成する。 ここではEC2RoleForESSnapshotとして作成し、マネジメントコンソールで踏み台EC2にアタッチする。 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } 6. 踏み台に接続 準備が整ったので、手動スナップショットレポジトリの作成に入る。 目指す踏み台には直接入れないので、IGWのいるサブネット(Public Subnet)上の踏み台を経由して入る。他にも手段はあるが今回はそこ主眼でないので、古の方法で。 % ssh -A ec2-user@"<Public Subnet上のEC2 FQDN>".ap-northeast-1.compute.amazonaws.com Last login: Fri Jun 4 07:17:53 2021 from 27.0.3.146 __| __|_ ) _| ( / Amazon Linux 2 AMI ___|\___|___| https://aws.amazon.com/amazon-linux-2/ [ec2-user@ip-XXX-XXX-XXX-XXX ~]$ ssh "<Secure Subnet上のEC2 FQDN>".ap-northeast-1.compute.internal Last login: Fri Jun 4 07:22:30 2021 from ip-XXX-XXX-XXX-XXX.ap-northeast-1.compute.internal __| __|_ ) _| ( / Amazon Linux 2 AMI ___|\___|___| https://aws.amazon.com/amazon-linux-2/ [ec2-user@ip-YYY-YYY-YYY-YYY ~]$ 7. 手動スナップショットレポジトリ登録用のPythonスクリプトを用意する 公式ドキュメントのサンプルを改修して作成。 import boto3 import requests from requests_aws4auth import AWS4Auth host = 'https://<ESエンドポイント>.ap-northeast-1.es.amazonaws.com/' region = 'ap-northeast-1' s3bucket = 'my-bucket-4-es' snapshotrole = 'arn:aws:iam::123456789012:role/TestRoleForESManualSnapshot' service = 'es' credentials = boto3.Session().get_credentials() awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token) # Register repository path = '_snapshot/my-snapshot-repo' # the Elasticsearch API endpoint url = host + path payload = { "type": "s3", "settings": { "bucket": s3bucket, "region": region, "role_arn": snapshotrole } } headers = {"Content-Type": "application/json"} r = requests.put(url, auth=awsauth, json=payload, headers=headers) print(r.status_code) print(r.text) 8. レポジトリの登録を実行 [ec2-user@ip-YYY-YYY-YYY-YYY ~]$ python3 ./manual-ss.py 200 {"acknowledged":true} 問題なく実行できた。 AWSのAPIエンドポイントへのアクセスは不要であるようだ。 9. レポジトリの確認 [ec2-user@ip-YYY-YYY-YYY-YYY ~]$ curl -XGET https://"<ESエンドポイント>".ap-northeast-1.es.amazonaws.com/_snapshot/my-snapshot-repo-name/my-first-snapshot?pretty { "snapshots" : [ { "snapshot" : "my-first-snapshot", "uuid" : "lw31y3buT1iJyV-09Gy85Q", "version_id" : 7090199, "version" : "7.9.1", "indices" : [ "movies", ".kibana_1" ], "data_streams" : [ ], "include_global_state" : true, "state" : "SUCCESS", "start_time" : "2021-06-04T07:43:34.170Z", "start_time_in_millis" : 1622792614170, "end_time" : "2021-06-04T07:43:34.770Z", "end_time_in_millis" : 1622792614770, "duration_in_millis" : 600, "failures" : [ ], "shards" : { "total" : 6, "failed" : 0, "successful" : 6 } } ] } 10. 手動スナップショットの作成 % curl -XPUT https://<ESエンドポイント>.ap-northeast-1.es.amazonaws.com/_snapshot/my-snapshot-repo/my-first-snapshot {"accepted":true} 11. 手動スナップショットの確認 % curl -XGET https://<ESエンドポイント>.ap-northeast-1.es.amazonaws.com/_snapshot/my-snapshot-repo/my-first-snapshot S3上ではこんな感じで作られる。 通常の自動スナップショットはユーザーのS3側には現れないが、こちらはユーザー所有の(1.で作成した)バケット上に格納され、自由に扱える。 まとめ AWSのAPIエンドポイントへのアクセスが一切ない環境でも、手動スナップショットレポジトリの登録とスナップショットの作成ができることが確認できた。 リストアについてはまたいずれ。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Raspberry Pi 3 と AWS でインターネット速度を計測・記録する

はじめに _s__o_ です。 私事ですが、昨年マンションを引っ越しました。インターネット接続は、マンションの各戸に RJ-45 の口が付いているような、いわゆる「マンション共有型」タイプです (こちら の分類でいうところの「インターネット完備マンション」にあたります)。 メリットは利用料が安いことです。一方、マンションに引き込んだ光回線を共有設備の SW で各戸に分配しているため、回線速度が他戸の利用状況にかなり左右されます。 ※ちなみに、マンションに引き込む光回線も、大本を (最大で) 32 分岐しているそうです (参考 )。今回の引っ越しを機に知りました。恐ろしい。。。 その「左右され具合」がなかなかに大きいので、いっそのこと「見える化」(not 可視化 but 数値化) してやろうと思いました。というわけで、Raspberry Pi 3 と AWS を使って、ちょろっと環境を作っていきます。 構成イメージ 下記のイメージです。 それぞれの役割は下記のとおりです。 - Raspberry Pi 3   - Raspberry Pi 3 Model B で、中身は個人的な趣味で CentOS にしています。   - Python 2.7 で「(1) インターネット速度計測」、「(2) AWS IoT へのデータ配信」を実現します。 - AWS IoT Core   - Raspberry Pi 3 の配信データを Subscribe しています。 - DynamoDB   - AWS IoT Core のルールにもとづき、IoT が受信したデータを保管します。 準備 Dynamo DB 下記のようなテーブルを作成しておきます。 特記事項はありませんが、基本的なパラメータは下記としています。 テーブル名 : internet_speed プライマリパーティションキー : client_id → クライアント名を格納します。クライアント名はこの後に登場する Python コードの中で定義しています。 プライマリソートキー : timestamp_aws → 格納時のタイムスタンプ (unixtime) を格納します。タイムスタンプは後述の AWS IoT のルールの関数で出力します。 AWS IoT こちら の記事を参照にしながら、エンドポイントを作成します。過程で証明書 & 秘密鍵が生成されるので、ダウンロードして Raspberry Pi 3 上に配置しておきます。 また、CA 証明書も必要になるので、こちら からダウンロードし、上記と同様に Raspberry Pi 3 上に配置しておきます。 上記を実施後、DynamoDB に連携するため、下記のようにルールを設定します。 SQL 部分をピックアップします。ポイントは下記の通りです。 - トピック名「internet_speed」から情報を取り出す。 - 「client_id」と「timestamp_aws」を関数で取得する。 - それ以外は微妙に名前を変えたりしながら取得する。 SELECT clientid() AS client_id, timestamp() AS timestamp_aws, unixtime As timestamp_device1, datetime AS timestamp_device2, down, up FROM 'internet_speed' Raspberry Pi 3 (Python 2.7) 「速度計測用」と「AWS IoT へのデータ配信」に 2 つのコードを準備します。また、それらのコードを呼び出すラッパースクリプトを準備します。 速度計測用コード (speed_test.py) 処理として、主に下記を行います。 1. Down 速度と Up 速度を計測する。 1. タイムスタンプを取得する。 1. 上記をまとめて json で出力する。 なお、「speedtest」というモジュールを使うため、事前に pip や easy_install でインストールする必要があります。インストール方法は こちら などを参照してください。 # -*- coding:utf8 -*- # https://qiita.com/yokobonbon/items/67deb3fab84b0c0954e0 # https://qiita.com/hiroyuki827/items/3488a2b578de6777d2fc import speedtest import time import datetime import json json_name = 'tmp.json' def get_speed_test():     servers = []     stest = speedtest.Speedtest()     stest.get_servers(servers)     stest.get_best_server()     return stest def get_now():     time_now = time.time()     return time_now def test_speed(stest):     down_result = int(stest.download())     up_result = int(stest.upload())     return down_result, up_result def command_line_runner():     stest = get_speed_test()     now_unixtime = get_now()     now_datetime = datetime.datetime.fromtimestamp(now_unixtime)     now_datetime_str = str(now_datetime.strftime('%Y/%m/%d %H:%M:%S'))     down_result, up_result = test_speed(stest)     f = open(json_name, 'w')     result = {'unixtime': (now_unixtime * 1000), 'datetime': now_datetime_str, 'down': down_result, 'up': up_result}     json.dump(result, f)     f.close() if __name__ == '__main__':     command_line_runner() データ配信用コード (publish_aws.py) 処理として、主に下記を行います。 1. json ファイル (tmp.json) を AWS IoT に配信する。 なお、「AWS IoT Device SDK for Python」を使うため、事前に pip でインストールする必要があります。インストール方法は こちら などを参照してください。 また、コード中の ca_cert_path・key_path・cert_path の部分は、(上述の手順で配置した) CA 証明書・サーバ証明書・サーバ秘密鍵のパスを指定してください。 # -*- coding:utf8 -*- # https://symfoware.blog.fc2.com/blog-entry-2224.html from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient import time import json json_name = 'tmp.json' # AWS IoT Info clientName = 'lcrpi01' # クライアント名。AWS IoT の ルールの SQL で参照する endpoint = '*****' ca_cert_path = '*****' key_path = '*****' cert_path = '*****' topic_name = 'internet_speed' # トピック名。AWS IoT の ルールの SQL で参照する def command_line_runner():     # json load     f = open(json_name, 'r')     json_load = json.load(f)     f.close()     # For certificate based connection     myMQTTClient = AWSIoTMQTTClient(clientName)     myMQTTClient.configureEndpoint(endpoint, 8883)     myMQTTClient.configureCredentials(ca_cert_path, key_path, cert_path)     # Set MQTT Parameter     myMQTTClient.configureOfflinePublishQueueing(-1) # Infinite offline Publish queueing     myMQTTClient.configureDrainingFrequency(2) # Draining: 2 Hz     myMQTTClient.configureConnectDisconnectTimeout(10) # 10 sec     myMQTTClient.configureMQTTOperationTimeout(5) # 5 sec     # Publish to AWS IoT     myMQTTClient.connect()     myMQTTClient.publish(topic_name, json.dumps(json_load), 1) if __name__ == '__main__':     command_line_runner() ラッパースクリプト (internet_speed.sh) 上記の Python コードを呼び出すだけの単純なスクリプトです。これを cron で定期的に回します (30 分に 1 回など)。 #!/usr/bin/bash cd /home/snishiyama/aws_iot # 1. Speed Test python ./speed_test.py sleep 1 # 2. Publish to AWS IoT python ./publish_aws.py sleep 1 取得結果 こんな感じで取得できます。今後の展開を考えて、できるだけ生データで取得しているので、視認性が低いのはご容赦を。 おまけ 数値化とくれば次は可視化だと思います。AWS であれば、Elasticsearch Service & Kibana などが有名です……が、個人で利用するには些か高い (コストが)。 というわけで、簡単に可視化するため、Ambient というサービスとも組み合わせました (既に AWS は関係なくなってますが。。。)。 Ambient と連携するために、Raspberry Pi 3 に下記のコードを追加しています (publish_ambient.py)。例によって、事前に「ambient」モジュールを入れる必要があるため、こちら を参考にしながら導入しました。 # -*- coding:utf8 -*- # https://ambidata.io/samples/temphumid/python/ import ambient import json json_name = 'tmp.json' # Ambient Info ambi_Channel_id = ***** ambi_write_key = '*****' def convert_to_mbps(bps):     mbps = float(bps)/1000/1000     return mbps def command_line_runner():     # json load     f = open(json_name, 'r')     json_load = json.load(f)     f.close()     # Adjust the value     down_mbps = convert_to_mbps(json_load['down'])     up_mbps = convert_to_mbps(json_load['up'])     # Publish to Ambient     msg = {'d1' : down_mbps, 'd2' : up_mbps}     ambi = ambient.Ambient(ambi_Channel_id, ambi_write_key)     r = ambi.send(msg)     return r if __name__ == '__main__':     command_line_runner() Ambient で描画したのが下記グラフです。期待したイメージ通りです。 ……激しい荒ぶり方ですね。。。 まとめ 以上、Raspberry Pi 3 と AWS (IoT と DynamoDB) を使ってインターネットの回線速度を収集する方法でした。今まで IoT に触れたことがなかったため、こういった機会に経験できて良かったです。今後は他の項目を収集したり (せっかく Raspberry Pi を使っているので)、AWS の機能で何とか (低コストで) 可視化していきたいなあと思っています。 追記 その後、FTTH 開通しました。ちょうどタイミングが良く、ひいきにしているプロバイダが「IPoE 標準提供」を始めたため、期せずして IPoE デビューもできました。 肝心の Raspberry Pi 3 で計測したインターネット速度ですが……なぜか 100 Mbps で頭打ちです。他の端末 (PC やスマホ) で計測した場合は 300 Mbps を越えるのですが、なぜか Raspberry Pi 3 で計測した場合はそれが出てこない。明らかに原因は  Raspberry Pi 3 なので色々調べてみたところ……  Raspberry Pi 3 の NIC は 100 Mbps までにしか対応していないという、哀しいオチが判明しました。 仕方がないのでギガイーサの USB NIC を Raspberry Pi 3 につないで、それで計測するようにしました。結果は下記の通りです。 ※ちなみに、Raspberry Pi 3 の USB は USB 2.0 なので、USB NIC がギガでも、理論上の MAX は 480 Mbps となります。 まあ、300 Mbps は出ませんが、少なくとも以前に比べて改善は見られますので、とりあえず OK ということで。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CloudFormationでCloudFront Functionsデプロイ時にInternalFailureが発生する

発生事象 CloudFormation で CloudFront Functions をデプロイする際に InternalFailure が発生してしまう。 Resource handler returned message: "null" (RequestToken: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, HandlerErrorCode: InternalFailure) 使用したテンプレート 上記を参考にこんな感じのテンプレートを使いました。 template.yaml AWSTemplateFormatVersion: '2010-09-09' Description: add-security-headers-cloudfront-function Resources: AddSecurityHeaderFunction: Type: AWS::CloudFront::Function Properties: AutoPublish: false FunctionCode: | function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"}; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; return response; } Name: add-security-headers-cff 回避策 FunctionConfig プロパティを追加すると回避できます。 FunctionConfig: Comment: add-security-headers-cff Runtime: cloudfront-js-1.0 Comment は任意のコメントを記載。Runtime は CloudFront Functions のランタイム環境を指定するが、今のところ cloudfront-js-1.0 のみ有効。 原因 2021/6/4 現在で CloudFormation のユーザーガイドには FunctionConfig プロパティは Required: No と記載されていますが、プロパティを省略すると InternalFailure でデプロイが失敗してしまいます。 CloudFormation の不具合なのかドキュメントの記載ミスなのかは判断できませんので、事象が解消されたことを確認したら追記したいと思います。 対応後 デプロイ成功!! template.yaml AWSTemplateFormatVersion: '2010-09-09' Description: add-security-headers-cloudfront-function Resources: AddSecurityHeaderFunction: Type: AWS::CloudFront::Function Properties: AutoPublish: false FunctionConfig: Comment: add-security-headers-cff Runtime: cloudfront-js-1.0 FunctionCode: | function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"}; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; return response; } Name: add-security-headers-cff
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSとMicrosoft Azureにおける機械学習モデルのサービング技術の概要

初版: 2021年6月4日 著者: 橋本恭佑、柿田将幸, 株式会社 日立製作所 はじめに 近年、機械学習をはじめとするAI技術を活用したデータ分析が注目を集めており、AIを活用する案件が増加しています。 機械学習モデルを活用したシステムを構築する案件では、まずPoC(Proof of Concept)で機械学習モデルの有用性を確認し、その成果をもとに本番用のシステムを開発するケースが多いです。機械学習モデルをシステムに組み込み、サービスとして公開する一連の技術はサービング技術と呼ばれており、システム構築と運用を担う技術者にとって重要な技術です。 特に、機械学習サービスの負荷が大きく変動する場合は、負荷に合わせて柔軟にリソースを増減可能なパブリッククラウド上でのサービングが有効といえます。 本連載では、オンプレミス環境で作成した機械学習モデルをパブリッククラウド(AWSおよびMicrosoft Azure)でサービングする技術について、実際に検証した手順を交えながら解説します。 投稿一覧 AWSとMicrosoft Azureにおける機械学習モデルのサービング技術の概要・・・本投稿 Amazon SageMakerとAzure MLにおける機械学習モデルのサービング技術比較: AWS/Azureが提供するコンテナイメージを利用する場合・・・近日公開 Amazon SageMakerとAzure MLにおける機械学習モデルのサービング技術比較: 自作コンテナイメージを利用する場合・・・近日公開 AWS FargateとAzure Container Instanceにおける機械学習モデルのサービング技術比較・・・近日公開 パブリッククラウドにおける機械学習モデルのサービングパターン パブリッククラウドにおける機械学習モデルのサービング パブリッククラウドにおける機械学習モデルのサービングに必要なコンポーネントとサービングの手順の概要を図1に示します。 パブリッククラウド上で機械学習モデルをサービングする際は、前処理、モデル、後処理、およびそれらの実行に必要なライブラリ群を、 パブリッククラウドのコンテナ基盤上にまとめてコンテナとしてデプロイします。 AWSやMicrosoft Azureが提供する機械学習プラットフォームであるAmazon SageMakerやAzure Machine Learning(以下、Azure ML)では、 各々の機械学習プラットフォーム上で機械学習モデルを学習させて、同じパブリッククラウドのコンテナ基盤上へサービングする機能を提供しています1。 図1 パブリッククラウドにおける機械学習モデルのサービングに必要なコンポーネントとサービングの手順の概要 オンプレミス環境で作成した機械学習モデルのサービングパターン Amazon SageMakerやAzure MLを利用してサービングする場合は、SageMakerやAzure ML上で利用可能なコンテナイメージを用意します。 AWSやMicrosoft Azureは、SageMakerやAzure MLで利用可能な、機械学習の用途ごとに必要なライブラリが含まれるコンテナイメージを提供しています。 機械学習モデルの用途に沿ったコンテナイメージを選択し、モデルや前処理・モデル・後処理を呼び出す推論コードを追加することで、オンプレミス環境で作成した機械学習モデルをコンテナ基盤上にデプロイできます。 一方で、AWSやMicrosoft Azureが提供するコンテナイメージに、必要なライブラリが不足している場合や、オンプレミス環境で利用したライブラリとバージョンが異なる場合もあります。 これらの場合、次の2つのパターンのいずれかを行う必要があります。 パターン1: パブリッククラウドが提供するコンテナイメージをコンテナ基盤にデプロイするときに、ライブラリの追加またはバージョン変更して、前処理・モデル・後処理を追加する パターン2: パブリッククラウドが提供するコンテナイメージを利用せず、オンプレミス環境で必要なライブラリを含んだコンテナイメージを作成して、コンテナ基盤へデプロイするときに、前処理・モデル・後処理を追加する 一方で、Amazon SageMakerやAzure MLを利用しない場合は、AWS FargateやAzure Container Instance (Azure CI)といったコンテナ実行サービスを利用して、次のパターン3を行うことも考えられます。 パターン3: オンプレミス環境でライブラリ・前処理・モデル・後処理を含んだコンテナイメージを作成し、コンテナ基盤へデプロイする パターン1、パターン2、パターン3の比較を表1に示します。パターン毎に、オンプレミス環境で用意するものの多さと、パブリッククラウド環境で必要な手順の多さが異なります。 本連載では、パターン1からパターン3を実際にパブリッククラウドで試し、パブリッククラウド毎にどのパターンが可能であるかを確認します。さらに、複数のパブリッククラウドで可能なパターンについては、実際に試した結果を踏まえて、どのパブリッククラウドのサービスを使うべきか、指針を示します。 表1 サービングパターンの比較 パターン サービングに利用するクラウドサービス ベースとなるコンテナイメージ 必要ライブラリの追加方法 前処理・モデル・後処理の追加方法 1 機械学習プラットフォーム(Amazon SageMaker/Azure ML) パブリッククラウドが提供 コンテナイメージのデプロイ後に追加 コンテナイメージをデプロイするときに追加 2 機械学習プラットフォーム(Amazon SageMaker/Azure ML) オンプレミス環境で作成 コンテナイメージの作成時に追加 コンテナイメージをデプロイするときに追加 3 コンテナ実行基盤(Amazon Fargate/Azure CI) オンプレミス環境で作成 コンテナイメージの作成時に追加 コンテナイメージの作成時に追加 サービング検証のシナリオ パターン1からパターン3の実現可能性と各パターンの選定の指針を検討するために、今回設定した検証シナリオを説明します。 今回の投稿では機械学習モデルの学習に用いたソースコードと、前処理、推論、後処理を行うソースコードを紹介し、次回以降の投稿で実際にパブリッククラウドでサービングした結果を紹介します。 検証シナリオ: MNISTデータセットを用いた手書き文字画像の認識 本連載における検証シナリオでは、オンプレミス環境で学習させた手書き文字認識(MNIST)の機械学習モデルをパブリッククラウドでサービングします。 MNISTは28×28ピクセルの手書き画像で、ピクセル値は0から255までの整数です。MNISTのデータセットを学習用データセットと推論用データセットに分割し、学習用データセットを用いて作成した機械学習モデル(joblibファイル)に、JPEGファイルの手書き画像データを入力させて推論結果を出力します。 まず、機械学習モデルの前処理、学習、後処理、推論を実行する環境を用意します。表2に本検証シナリオに用いたpythonライブラリのバージョンを示します。 表2: 今回の検証シナリオに用いたpythonライブラリのバージョン ソフトウェア バージョン python 3.7.6 numpy 1.18.1 scikit-learn 0.22.1 pillow 7.0.0 joblib 1.0.0 flask 1.1.2 手書き文字認識モデルの学習 下記に学習用のソースコード(train.py)を示します。 train.py import numpy as np from sklearn import model_selection, svm, metrics from sklearn.neural_network import MLPClassifier import joblib # MNISTデータセット(mnist.npz)を学習用データセットと推論用データセットに分割する # X_train is 60000 rows of 28x28 values --> reshaped in 60000 x 784 RESHAPED = 784 NB_CLASSES = 10 x_train = x_train.reshape(60000, RESHAPED) x_test = x_test.reshape(10000, RESHAPED) x_train = x_train.astype('float32') x_test = x_test.astype('float32') # 学習 clf = MLPClassifier(hidden_layer_sizes=(128,), solver='adam', max_iter=20, verbose=10, random_state=0) clf.fit(x_train, y_train) # 推論用データセットを利用して精度を検証 print('accuracy_score: %.3f' % clf.score(x_test, y_test)) # joblibファイルとして機械学習モデルをエクスポート joblib.dump(clf, "./model.joblib") 手書き文字認識モデルによる推論 次に、推論用のソースコード(api_server.py)を示します。 api_server.py import argparse import os import sys import numpy as np from PIL import Image import joblib import flask app = flask.Flask(__name__) @app.route("/") def hello_world(): return 'Flask Hello world' @app.route("/predict", methods=["POST"]) def predict(): model = joblib.load(os.path.join(“/root/serving/”, "model.joblib")) response = {"Content-Type": "application/json", "number": None} RESHAPED = 784 if flask.request.method == "POST": if flask.request.files["file"]: image_number = np.array( Image.open(flask.request.files["file"]).convert('L')) array = [image_number.reshape(RESHAPED)] print('type(array): {0}, array: {1}'.format(type(array), array)) prediction = model.predict(array) response["number"] = str(prediction[0]) return flask.jsonify(response) if __name__ == '__main__': app.run(debug=True, host='0.0.0.0') 上記のソースコード(api_server.py)を実行すると、前処理、推論、後処理を行うサーバプログラムが起動します。 $ python api_server.py * Serving Flask app "api_server" (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: on * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger PIN: 180-690-578 手書き文字認識サービスの利用 上記のソースコード(api_server.py)を実行して、手書き数字のJPEGファイルを送信します。今回利用した手書き数字のJPEGファイルを図2に示します。 図2 今回利用した手書き数字の画像ファイル(左がx_test_30.jpeg, 右がx_test_60.jpeg) 図2に示した画像ファイルをサーバへ入力した場合の出力を下記に示します。 $ curl -F file=@x_test_30.jpeg localhost:5000/predict { "Content-Type": "application/json", "number": "3" } $ curl -F file=@x_test_60.jpeg localhost:5000/predict { "Content-Type": "application/json", "number": "6" } 実行環境の選定 パターン1からパターン3をAWSおよびMicrosoft Azureで実現する際のサービス一覧を表3に示します。パターン1とパターン2については、Amazon SageMakerと Azure Machine Learningで対応します。また、パターン3についてはAWSではAWS Fargate、Microsoft AzureではAzure Container Instanceが対応します。 表3 オンプレミス環境で学習させた機械学習モデルをAWSおよびMicrosoft Azure上でサービングする際のサービス一覧(2021年2月現在) パターン 概要 AWS Microsoft Azure 1 AWS/Azureが提供するコンテナイメージを利用(デプロイ時にライブラリと前処理・モデル・後処理を追加) Amazon SageMaker Azure Machine Learning 2 自作コンテナイメージを利用(コンテナイメージ作成時にライブラリを追加し、デプロイ時に前処理・モデル・後処理を追加) Amazon SageMaker Azure Machine Learning 3 自作コンテナイメージを利用(コンテナイメージ作成時にライブラリと前処理・モデル・後処理を追加) AWS Fargate Azure Container Instance おわりに 次回以降の投稿で、表3に示した各パターンをAWSおよびMicrosoft Azureで実現する技術を紹介します。また実際にサービングしてわかった注意点や使いどころを紹介します。 Amazon SageMakerまたはAzure ML上で作成した機械学習モデルをサービングする技術については、AWSやMicrosoft Azureが提供するドキュメントや、こちらの投稿をご覧ください。 ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS S3にテストウイルスのファイルをLambdaでアップする

はじめに EICAR のテストウイルスが HTTP でダウンロードできなくなってしまったので、Amazon S3 の静的ウェブサイトを使ってテストウイルスのダウンロード環境を作ってみました。 ※HTTPS ではダウンロードできるんですが、HTTP でテストしたい時があるんです! Amazon S3 の設定 バケットを作成して静的ウェブサイトの設定を行います。 詳細は下記チュートリアルや他サイトを参照ください。 Lambda の設定 言語は Python 3.8 で作成。 下記コードを保存 → Deploy → Test 実行 で S3 にファイルがアップされます。 トリガなど特に設定する必要はありません。 lambda_function.py import json import boto3 import os def lambda_handler(event, context): # ローカルにテストファイル作成 fp = open('/tmp/eicar.com', 'w') # EICARテストファイルのアスキー文字列を書き込みます fp.write('X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*') # ファイルのクローズ。 fp.close() # S3アップロード s3 = boto3.resource('s3') s3.meta.client.upload_file('/tmp/eicar.com', '[S3バケット名]', 'eicar.com') # ローカルファイル削除 os.remove('/tmp/eicar.com') 動作確認 ブラウザ等から以下のURLにアクセスしてファイルがダウンロードできることを確認します。 http://[S3バケット名].s3-website-ap-northeast-1.amazonaws.com/eicar.com ※上記リージョンは東京ですので環境に合わせてURLを調整ください うまくいかない場合は、S3のバケット内にファイルがアップされているか確認してください。 最後に 今回 Lambda を使いましたが、一度きりの作業で他システムからの連携もありませんので、あえて Lambda でやるメリットはあまりなかったかもしれません。 まあ環境を作って壊してを繰り返すときは Lambda にコードが残っていれば、再作成は容易いかなと思います。 参考サイト https://rioner2525.hatenablog.com/entry/2019/07/25/185907 https://www.eicar.org/?page_id=3950
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSにてyumのインストールができない時

EC2サーバーにyumをインストールしようとした際に、以下エラーが発生してインストールできなかったのでその備忘録を残しておきます。 [ec2-user@ip-10-0-0-110 ~]$ sudo yum install httpd -y [sudo] ~ のパスワード: Loaded plugins: extras_suggestions, langpacks, priorities, update-motd  〜省略~ Cannot find a valid baseurl for repo: amzn2-core/2/x86_64 結論 EC2のセキュリティグループのアウトバウンド設定が正しく設定されていなかった。 対処策 EC2のセキュリティグループのアウトバウンド設定にhttpとhttpsを追加する。 以下手順となります。 まず、AWSのEC2インスタンスの画面に移行します。 そしてネットワーク&セキュリティ→セキュリティグループを選択します。 次にアウトバウンドルールを編集します。 ここでHTTPとHTTPSを追加して、外部接続を許可します。 これで再度yumのインストールの実行を行ってみてください。 もし、またインストールできないようであればAmazon Linuxのyumリポジトリにアクセスできていない可能性がありますので、その場合は以下記事が参考になりました。 https://go-journey.club/archives/14364
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

fishでもaws-cliのprofileを簡単に切り替えたい!!

fishでもawsのprofileを簡単に切り替えたい!! これ使ったら、fishでもaws-cliのprofileを簡単に切り替えられます! TL;DR 仕事でAWSを使うことになりました。 AWS CLIのプロファイル切り替えをいい感じにするでも紹介されいてるawspというコマンドでaws-cliのprofileを簡単に切り替えられるらしい! しかし、インストールしても、fishは使えない様でした?。(zshとbashでは使えるらしい。) ソースコードを読み込んだら、fishでも手軽に実装できそうだったので、実装しちゃいました。 共有します。 インストール とりあえず、下記コマンドを実行すると_awspコマンドが使える様になります。 fish npm install -g awsp # インストール完了後下記ファイルを作成。中身は次のブロックに記載。 nano ~/.config/fish/functions/awsp.fish # 終わったら、再読み込みすると、使える様になります。 exit 下記のように編集 ~/.config/fish/functions/awsp.fish function awsp AWS_PROFILE="$AWS_PROFILE" _awsp_prompt set selected_profile (cat ~/.awsp) set -xU AWS_PROFILE $selected_profile end 参考文献 AWS CLIのプロファイル切り替えをいい感じにする
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amazon Lightsailを触ってみた

はじめに AWS認定試験などでたまに見かける「Amazon Lightsail」。 概要は知っていたものの、そういえば触ったことないなぁと思ったので、触ってみました。 Amazon Lightsailとは 公式の説明を引用すると、以下のようです。 Lightsail は使いやすい仮想プライベートサーバー (VPS) であり、アプリケーションやウェブサイトの構築に必要なすべてのものに加えて、コスト効率が良い月額プランを提供します。クラウドに慣れていないお客様でも、信頼している AWS インフラストラクチャを使用してすぐにクラウドにアクセスしようとしている場合も、対応できます。 要するに、「安く、必要なものがすでにそろっているサーバ」という印象でしょうか。 高負荷なワークロード向けというわけではなく、個人でサーバを建てたいときや、小規模なサービスで使用できるようです。 Try せっかくなので、最も一般的なユースケースと思われる、WordPressを実行してみました。 前提として、AWSアカウントは作成済みとします。 Amazon Lightsailコンソールにアクセス。 コンソールから「lightsail」と検索。 画面が切り替わります。ライトな感じがして良いですね。 中央のインスタンスの作成を押下します。 インスタンスの作成 インスタンスの作製を行います。 インスタンスロケーションは以下にしました。それぞれに適したロケーションを選択してください。 リージョン:東京 アベイラビリティゾーン:1a イメージの選択は以下の通りです。 プラットフォーム:Linux/Unix ブループリント:WordPress 起動スクリプト/SSHキーの作成/自動スナップショットの有効化 適宜カスタマイズしてください。今回は変更を加えません。 自動スナップショットに関しては、すぐ消すのであれば有効化しないほうが良いです。 インスタンスプランの選択 無料枠を使用する為、一番左のプランを選択してください。 インスタンス名を入力 インスタンス名は他のインスタンスと重複できません。 初めてLightsailを利用する場合はデフォルトで問題ないです。 「インスタンスの作成」を押下する。 数分待つとインスタンスが作成されます。 WordPress管理ダッシュボードにサインイン 立ち上げたインスタンスにSSHする。 SSHクライアントがあるので、そちらで繋げます。以下のアイコンをクリックしてください。 尚、立ち上げてすぐであると接続できません。数分待ってから接続してください。 パスワードを取得する。 cat $HOME/bitnami_application_password を入力し、WordPressの管理ダッシュボードにサインインするパスワードを入手します。 exitで接続を切断します。 WordPress管理ダッシュボードにサインイン http://<PublicIPAdress>/wp-login.phpにアクセスします。 <PublicIPAdress>は以下に記載があります。確認して置き換えてください。 id:user,password:先ほど入手したもの を入力すると、サインインできます。 インスタンスの削除 インスタンス詳細画面から「削除」タブを選択し、「インスタンスの削除」ボタンを押下すると削除できます。 Option パブリックIPはインスタンスの停止などで変更される可能性があります。そのため、静的なIPアドレスを付与する必要があります。 静的 IP を作成し、 のインスタンスにアタッチするAmazon Lightsail データベースを作成することもできます。 Amazon Lightsail でデータベースを作成する 独自ドメインを使用することもできます。 でドメインの DNS レコードを管理する DNS ゾーンを作成するAmazon Lightsail まとめ 特に躓くこともなく、環境構築ができました。 やはり、ネットワークなどを意識せずに構築できるのは非常に楽でいいですね。 インフラ等よくわからないけどワードプレスやってみたいという人に勧められるサービスです。UIもそういった方向けのライトな感じでわかりやすさを重視しているように感じました。 ただ、インスタンスを建てただけではやることは終わっておらず、運用負荷は多少あるなというのが感想でした。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

作りながら覚えるTerraform入門(2) - 基本編

作りながら覚えるTerraform入門シリーズの第2回です。 第1回の インストールと初期設定 でTerraformを使う準備ができたので、とりあえず動かしてみましょう。 最初はVPCの操作を通じてTerraformの基本的なコマンドを覚えるのが良いと思います。 作りながら覚えるTerraform入門シリーズ インストールと初期設定 基本編 => 今回はコチラ VPC編(準備中) EC2編(準備中) Route53 + ACM編(準備中) ELB編(準備中) RDS編(準備中) VPCの作成 まず、作業用のフォルダを作成しておきます。 mkdir terraform cd terraform/ provider.tfというファイルを作成して、以下のコードを貼り付けます。 拡張子が.tfであればファイル名は任意で大丈夫です。 provider.tf terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 3.0" } } } provider "aws" { region = "ap-northeast-1" } provider.tfにはAWSにリソースを作成するための宣言を記述します。 デフォルトリージョンもここで指定しておきます。このあたりはお決まりの構文ですね。 公式ドキュメントのAWS Providerを参考にしています。 続いて、network.tfというファイルを作成して、以下のコードを貼り付けます。 ファイルを分ける必要はありませんが、リソースごとに分けたほうが管理がしやすくなります。 network.tf # Resourceブロックで「aws_vpc」を指定してVPCを作成 resource "aws_vpc" "vpc" { cidr_block = "10.0.0.0/16" instance_tenancy = "default" tags = { Name = "my-vpc" } } resourceから始まる箇所をResourceブロックと呼びます。 resourceに続けて以下の引数を与えて、波括弧{}で囲った中にパラメータを記述します。 ①第1引数:リソースタイプ ②第2引数:任意の識別名 ①はAWSのリソースタイプで、aws_*の形になっています。Azureであればazurerm_*といった形。 基本的には*の箇所にサービス名が入るので連想しやすいですが、公式リファレンスを参照しながら記述します。 aws_vpcであれば、Resource: aws_vpc です。 ②は識別名なので自由に命名できますが、他のリソースと重複はできません。 ここの命名に意外と悩んだりしますが、最初はとりあえず動かすことを目的としてexampleやmainとしておくのも一つの手です。 作成したコードを元にリソースを作成してみましょう。 リソースを作成するには、terraform applyを実行します。 terraform apply ╷ │ Error: Could not load plugin │ │ │ Plugin reinitialization required. Please run "terraform init". : そうすると、プラグインが読み込めないのでterraform initを実行するようエラーが表示されます。Terraformのインストールによってコマンド自体は利用できるようになりますが、AWSやAzureなど各サービス(プロバイダー)を利用するためのプラグインは分離されているため、まず最初にterraform initを実行してダウンロード(初期化)する必要があります。 terraform init Initializing the backend... Initializing provider plugins... - Finding latest version of hashicorp/aws... - Installing hashicorp/aws v3.44.0... - Installed hashicorp/aws v3.44.0 (signed by HashiCorp) Terraform has created a lock file .terraform.lock.hcl to record the provider selections it made above. Include this file in your version control repository so that Terraform can guarantee to make the same selections by default when you run "terraform init" in the future. Terraform has been successfully initialized! : terraform initを実行すると、.terraformディレクトリと.terraform.lock.hclファイルが作成されます。.terraformディレクトリが「AWS」というプロバイダーを利用するためのもの、.terraform.lock.hclは依存関係をコントロールするためのロックファイル、くらいに考えておきましょう。 tree -a . ├── .terraform │ └── providers │ └── registry.terraform.io │ └── hashicorp │ └── aws │ └── 3.44.0 │ └── darwin_amd64 │ └── terraform-provider-aws_v3.44.0_x5 ├── .terraform.lock.hcl ├── network.tf └── provider.tf それでは、改めてterraform applyを実行してみます。 「Do you want to perform these actions?」と確認を求められるので「yes」と入力して進めます。 terraform apply Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_vpc.vpc will be created + resource "aws_vpc" "vpc" { + arn = (known after apply) + assign_generated_ipv6_cidr_block = false + cidr_block = "10.0.0.0/16" + default_network_acl_id = (known after apply) + default_route_table_id = (known after apply) + default_security_group_id = (known after apply) + dhcp_options_id = (known after apply) + enable_classiclink = (known after apply) + enable_classiclink_dns_support = (known after apply) + enable_dns_hostnames = (known after apply) + enable_dns_support = true + id = (known after apply) + instance_tenancy = "default" + ipv6_association_id = (known after apply) + ipv6_cidr_block = (known after apply) + main_route_table_id = (known after apply) + owner_id = (known after apply) + tags = { + "Name" = "my-vpc" } + tags_all = { + "Name" = "my-vpc" } } Plan: 1 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes aws_vpc.vpc: Creating... aws_vpc.vpc: Creation complete after 2s [id=vpc-0e32cf9d1213b770d] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. 最後の「Apply complete!」の行を見ると1 addedとなっていて、1つのリソースが追加されたことがわかります。コンソール画面を確認してみると、「my-vpc」のNameタグが付いたVPCが作成できていることがわかります。 VPCの更新 続いて、更新の動きを見ていきましょう。 試しにnetwork.tfのNameタグを「my-first-vpc」に変更してみます。 network.tf resource "aws_vpc" "vpc" { cidr_block = "10.0.0.0/16" instance_tenancy = "default" tags = { Name = "my-first-vpc" } } もう一度terraform applyを実行して適用してみましょう。 terraform apply aws_vpc.vpc: Refreshing state... [id=vpc-0e32cf9d1213b770d] Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: ~ update in-place Terraform will perform the following actions: # aws_vpc.vpc will be updated in-place ~ resource "aws_vpc" "vpc" { id = "vpc-0e32cf9d1213b770d" ~ tags = { ~ "Name" = "my-vpc" -> "my-first-vpc" } ~ tags_all = { ~ "Name" = "my-vpc" -> "my-first-vpc" } # (14 unchanged attributes hidden) } Plan: 0 to add, 1 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes aws_vpc.vpc: Modifying... [id=vpc-0e32cf9d1213b770d] aws_vpc.vpc: Modifications complete after 2s [id=vpc-0e32cf9d1213b770d] Apply complete! Resources: 0 added, 1 changed, 0 destroyed. 1 changedと表示されて更新されたことがわかります。 コンソール画面からもNameタグが変更できていることを確認しておきましょう。 次はcidr_blockを「192.168.0.0/16」に変更してみます。 network.tf resource "aws_vpc" "vpc" { cidr_block = "192.168.0.0/16" instance_tenancy = "default" tags = { Name = "my-first-vpc" } } terraform applyを実行して適用してみましょう。 terraform apply aws_vpc.vpc: Refreshing state... [id=vpc-0e32cf9d1213b770d] Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: -/+ destroy and then create replacement Terraform will perform the following actions: # aws_vpc.vpc must be replaced -/+ resource "aws_vpc" "vpc" { ~ arn = "arn:aws:ec2:ap-northeast-1:123456789012:vpc/vpc-0e32cf9d1213b770d" -> (known after apply) ~ cidr_block = "10.0.0.0/16" -> "192.168.0.0/16" # forces replacement ~ default_network_acl_id = "acl-009e09c086ff9c692" -> (known after apply) ~ default_route_table_id = "rtb-0b555443103cfbe0b" -> (known after apply) ~ default_security_group_id = "sg-0af32faf28e1dfa87" -> (known after apply) ~ dhcp_options_id = "dopt-2489e243" -> (known after apply) ~ enable_classiclink = false -> (known after apply) ~ enable_classiclink_dns_support = false -> (known after apply) ~ enable_dns_hostnames = false -> (known after apply) ~ id = "vpc-0e32cf9d1213b770d" -> (known after apply) + ipv6_association_id = (known after apply) + ipv6_cidr_block = (known after apply) ~ main_route_table_id = "rtb-0b555443103cfbe0b" -> (known after apply) ~ owner_id = "123456789012" -> (known after apply) tags = { "Name" = "my-first-vpc" } # (4 unchanged attributes hidden) } Plan: 1 to add, 0 to change, 1 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes aws_vpc.vpc: Destroying... [id=vpc-0e32cf9d1213b770d] aws_vpc.vpc: Destruction complete after 0s aws_vpc.vpc: Creating... aws_vpc.vpc: Creation complete after 3s [id=vpc-05c92959157ff59d0] Apply complete! Resources: 1 added, 0 changed, 1 destroyed. 今回のcidr_blockの変更のように既存リソースの変更では対応できないケースは削除→作成の置き換えの動作になります。 後述しますが、実行計画の中に「replaced」や「forces replacement」という文字が含まれている場合は、それが意図したものなのか十分に確認してから実行する必要があります。 VPCの削除 最後に、作成したVPCを削除してみましょう。 リソースを削除するには、terraform destroyを実行します。 applyの時と同じように「yes」を入力して実行してみましょう。 terraform destroy aws_vpc.vpc: Refreshing state... [id=vpc-05c92959157ff59d0] Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: - destroy Terraform will perform the following actions: # aws_vpc.vpc will be destroyed - resource "aws_vpc" "vpc" { - arn = "arn:aws:ec2:ap-northeast-1:123456789012:vpc/vpc-05c92959157ff59d0" -> null - assign_generated_ipv6_cidr_block = false -> null - cidr_block = "192.168.0.0/16" -> null - default_network_acl_id = "acl-0896f7ab7cd8e3bbd" -> null - default_route_table_id = "rtb-0ba11eb799c733669" -> null - default_security_group_id = "sg-0ddd72a743034c145" -> null - dhcp_options_id = "dopt-2489e243" -> null - enable_classiclink = false -> null - enable_classiclink_dns_support = false -> null - enable_dns_hostnames = false -> null - enable_dns_support = true -> null - id = "vpc-05c92959157ff59d0" -> null - instance_tenancy = "default" -> null - main_route_table_id = "rtb-0ba11eb799c733669" -> null - owner_id = "123456789012" -> null - tags = { - "Name" = "my-first-vpc" } -> null - tags_all = { - "Name" = "my-first-vpc" } -> null } Plan: 0 to add, 0 to change, 1 to destroy. Do you really want to destroy all resources? Terraform will destroy all your managed infrastructure, as shown above. There is no undo. Only 'yes' will be accepted to confirm. Enter a value: yes aws_vpc.vpc: Destroying... [id=vpc-05c92959157ff59d0] aws_vpc.vpc: Destruction complete after 0s Destroy complete! Resources: 1 destroyed. 1 destroyedと表示されて削除されたことがわかりますね。 Terraformの実行計画 これまで見てきたように、terraform applyやterraform destroyを実行すると、これから起こる変更差分を「実行計画」として表示してくれます。 実行したコマンドの中にあるTerraform will perform the following actionsの箇所を振り返ってみてください。それぞれこれから行われる処理を示してくれています。 aws_vpc.vpc will be created aws_vpc.vpc will be updated in-place aws_vpc.vpc must be replaced aws_vpc.vpc will be destroyed リソースやパラメータの頭にある記号からも判別できます。 なお、何も変更がない場合はNo changes.と表示されます。 作成: + 更新: ~ 削除: - 置き換え: -/+ 繰り返しになりますが、単なる更新で済む場合と、作り直しになる場合があります。このあたりの挙動はコンソール画面から実施する場合と同じですが、実行計画はよく確認するように心がけましょう。 Terraformの基本コマンド この記事ではVPCの作成と削除を通じて、init → apply → destroyを実行して、初期化 → 適用 → 削除を行いましたが、その他のよく使うコマンドも確認しておきましょう。 validate terraform validateを実行すると、構文に誤りがないか、パラメータが適切かチェックすることができます。 # valid terraform validate Success! The configuration is valid. # invalid (cidr_blockの範囲が誤っている例) terraform validate Error: expected cidr_block to contain a valid network Value, expected 10.0.0.0/16, got 10.0.1.0/16 │ │ with aws_vpc.vpc, │ on network.tf line 2, in resource "aws_vpc" "vpc": │ 2: cidr_block = "10.0.1.0/16" plan 先に実践した例ではterraform applyをいきなり実行しましたが、terraform planを実行すると実行計画の確認のみ行うことができます。applyやdestroyはせずに実行計画だけ確認したい場合に利用します。 fmt terraform fmtを実行するとインデントを整えて見た目をキレイにしてくれます。-recursiveのオプションを付け加えるとサブディレクトリ含めて再帰的にフォーマットしてくれます。(付けない場合はカレントディレクトリの.tfファイルのみ) が、インストールと初期設定でご紹介したように、VSCode拡張機能を利用して自動フォーマットを有効にすることをオススメします。 console terraform consoleを実行すると対話型のコンソールを起動することができます。変数の値や関数の評価結果を確認したい場合に便利です。コンソールを終了するにはexitを入力します。 terraform console > max(5, 12, 9) 12 他にもありますが、とりあえずこのあたりの基本コマンドを覚えておけば困らないと思います。 コマンド実行の流れ 私の場合は、initのあとはvalidate → plan → applyを繰り返して、いらなくなったらdestoryするって形で学習を進めました。学習環境は作って壊すの繰り返しなので、インストールと初期設定でご紹介したように、applyとdestoryの時に「yes」を入力しなくて済むように-auto-approveを付け加えたエイリアス設定を利用してtf init → tfv → tfp → tfa → tfdの流れで実行しています。エイリアス設定を再掲しておきます。 ~/.zshrc alias tf="terraform" alias tfp="terraform plan" alias tfv="terraform validate" alias tff="terraform fmt -recursive" alias tfa="terraform apply -auto-approve" alias tfd="terraform destroy -auto-approve" 今回は以上です。最後に作業用フォルダを削除しておきましょう。 cd .. rm -rf terraform/ 次回はVPC編ということで、サブネットやルートテーブルなど含め、改めてVPC関連のリソースを作成する方法について書いてみたいと思います! 参考リンク AWS Provider Resource: aws_vpc Terraform CLI Documentation
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EC2へドメインでアクセスする方法

AWSのRoute53を利用しても同様のことができますが、こちらだと利用料金がかからないのと、複数のサービスを利用するの仕組みを理解しつつできるのでこちらの方法でアドレス解決しています。 必要なプロセス ドメインを取得 動的に割り当てられるEC2のIPアドレスを、DDNSサービスに通知するようにsystemdを利用して設定 DDNSサービスを利用して、動的に割り当てられるIPとドメイン名を紐づける。 インターネットからドメイン名でアクセスしようとする際に、アドレス解決(ドメイン名とIPアドレスの紐づけ)ができていないと、どこにアクセスしたらいいのか分かりません。 特に動的にIPを割り当てられるEC2では、自動でアドレス解決をしてくれる手段がないと面倒です。 ドメインにアクセスしようとする際の流れは、 1. ドメイン名でアクセス。 2. Freenomでアドレス解決のできるサーバー(ネームサーバー)を探します。(あらかじめ設定する必要あり) 3. ネームサーバーからアクセス元へIPアドレスを返す。(Aレコード) 4. アクセスできるようになる。 ドメインを取得 Freenomでドメインを取得。 動的に割り当てられるEC2のIPアドレスを、DDNSサービスに通知するようにsystemdを利用して設定 以下のスクリプトを実行することでMyDNSへ自分のIPアドレスを通知することができる。 (/etc/rc.d/配下に置いておいてね。) /etc/rc.d/MyDNSNotification.sh #!/bin/bash #ID="mydnsのMasterID" #PASS="mydnsのPassword" #wget -o - 'https://$ID:$PASS@www.mydns.jp/login.html' wget -o - 'https://{mydnsのMaterID}:{mydnsのPASS}@www.mydns.jp/login.html' (3行コメントアウトにしているのは、なぜかうまくいかない為です。IDとPASSをベタ打ちにすればうまくいきます。) しかし、起動の度にこれを実行させるのはさすがに手間がかかる。 その為、こちらのスクリプトを起動後に自動で実行してくれるように設定する。 ただ起動後に実行すればいいというわけではなく、インターネットに接続の確認後に上記スクリプトを実行しなければならないので/etc/rc.localや~/.bashrcに書いたり、crontab -eに追記すればいいわけではない。 これの実現方法として、daemon化したプロセスとして実行させる。具体的には、.serviceファイルを作り、適切に配置する。 .serviceファイルの書き方は以下。 MyDNSNotification.service [Unit] Description=Initialize environment variables. After=network.target [Service] Type=oneshot User=root Group=root ExecStart=/etc/rc.d/MyDNSNotification.sh [Install] WantedBy=default.target こちらの.servieファイルを/etc/systemd/system/配下に置く。 そして、chmod ugo+xで実行権限を付与しておきます。 ここで、sudo systemctl enable MyDNSNotificationで有効化し、sudo systemctl start MyDNSNotificationでサービススタートすると、MyDNSに通知ができるようになっているはずです。 DDNSサービスを利用して、動的に割り当てられるIPとドメイン名を紐づける。 DDNSサービスは、MyDNSを利用する。 取得したら、MyDNSのネームサーバーをドメイン取得したFreenomにて設定する。 Freenomにて、ServiceからMyDomainsを開く 紐づけたいドメイン名の欄の右にあるManage Domainを開く。 Management Toolsの中のNameserversを開く。 Use Custom Nameserversを選択し、Nameserver名を記入。(画像では、MyDNSのNameserver記入済み) MyDNSのNameserverの情報は、MyDNSのDOMAIN INFO内のある。 以上の設定全て終了したら、EC2を再起動してMyDNSにログインし、IPアドレスが更新されていることを確認する。 それ以後、ドメイン名でEC2にアクセスできるようになる。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS CloudWatchイベントのルールにおけるインスタンスIDの設定フォーマット

要約 CloudWatchルールにインスタンスIDを設定する時のフォーマットの備忘 ["i-999999","i-888888"] 動機 設定後の値を見ると、JSONフォーマットになっているが、それで入力するとエラーになる。 入力画面を見ると、ただのカンマ区切りで良さそうなのに、それで入力するとエラーになる。 以上
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

EC2サーバーの立て方

皆さん、特に初学者の方はサーバー、サーバーってよく聞くかと思います。 サーバーは一体どんなものなのか。一旦は「画面がないコンピュータ」だと思ってもらえればいいです。 今日は実際にAWSのEC2を使ってサーバーをたて(構築する)て見ましょう。 それではコンソールにログインします。 ここでEC2を選択してください。 ここにInstancesとありますね。これがサーバーです。 クリックしてください。 ここに今存在してるインスタンスの一覧が表示されます。 新しいインスタンスを起動するには右上のオレンジのボタンをクリックしてください。 今回は無料枠の対象であるAmazon Linux 2 AMI を利用しましょう。 さてここでインスタンスを配置するVPCとサブネットを選択します。 VPCとサブネットの設定の仕方はこちらの記事 https://qiita.com/Hibiki24/items/fe39d2a951ac81a8bb58 を参照してください。 さて、こちらのパブリックIPアドレスを有効にするかしないかと言う項目ですが、今回はどっちらでも大丈夫です。一応Enable(有効にする)にしておきましょう。 これは、VPC内(仮想ネットワーク内)でのIPアドレスと別にインターネット上の(パブリックな)IPアドレスをインスタンスに割り振るか否かを決める項目です。 これはセキュリティグループです。このインスタンスに対してどんな方式の通信を許可するか、どこからの通信を許可するかと言うのを決める項目です。 今回は特に大事なものも入っていないのでall trafics(すべての通信)にしておきましょう。 普段はこの設定は絶対ダメですからね!!! さて、最後にkey-pairをダウンロードします。これは何かというとサーバーにログインする際に必要になってくる鍵です。 このタイミングでしかダウンロードできないので大切に保管してください。 鍵は新しいものをこの時作ることもできれば以前使った他のインスタンスと共通のものをダウンロードすることもできます。完了したら右下のLaunch Instancesをクリックしましょう。 無事インスタンスが立ち上がりました。 右にスクロールしていくとパブリックIPアドレスも割り振られていますね。 今回はここまでです。お疲れ様でした。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CodeCommit導入手順

CodeCommit導入手順 CodeCommitを新規プロジェクトで使うことになったので導入手順を備忘録メモ AWSコンソールからCodeCommitを検索 目的 新規リポジトリ作成 認証設定 新規リポジトリ作成 名前・説明を入力して、作成をクリック 作成後、リポジトリ一覧表示 認証設定 SSH用のキー生成 入力内容は各々入力、passphraseは今回省略 $ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/Users/takashimorita/.ssh/id_rsa): xxx_id_rsa Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in xxx_id_rsa. Your public key has been saved in xxx_id_rsa.pub. The key fingerprint is: ユーザー設定 IAMよりユーザーを選択 認証情報タブを選択、SSHパブリックキーのアップロード アクセスキーが発行される MacにSSHの設定を追加 $ vi ~/.ssh/config Host git-codecommit.*.amazonaws.com User XXXXXX # SSHキーID IdentityFile /Users/takashimorita/.ssh/xxx_id_rsa # 作成したプライベートキーパス Git Clone $ git clone ssh://git-codecommit.ap-southeast-1.amazonaws.com/v1/repos/[リポジトリ名] Cloning into '[リポジトリ名]'... The authenticity of host 'git-codecommit.ap-southeast-1.amazonaws.com (54.240.226.221)' can't be established. RSA key fingerprint is SHA256:ZIsVa7OVzxrTIf+Rk4UbhPv6Es22mSB3uTBojfPXIno. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'git-codecommit.ap-southeast-1.amazonaws.com,54.240.226.221' (RSA) to the list of known hosts. Counting objects: 3, done. Receiving objects: 100% (3/3), done. いいね!と思ったら LGTM お願いします 【PR】週末ハッカソンというイベントやってます! → https://weekend-hackathon.toyscreation.jp/about/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSの無料枠で課金発生した話。

どうでもいい備忘録。 初学者さんでAWS利用する方もいると思うので。 無料枠の利用期間にもかかわらず、 Elastic IP address で料金が発生しました。 削除というネーミングではなく、 オプションからElastic IP の解放を選択。 どうやら課金は止まったようです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む