- 投稿日:2020-09-22T22:43:40+09:00
Amazon Forecastで(自分の)電気代を予測してみる
はじめに
4月ごろから個人的な興味で機械学習の勉強をはじめました。
普段は本やオンライン教材に出てくるサンプルコードを写経しながら理解を深めつつ、たまにKaggleに挑戦し挫折したりしています。この記事では、とりあえず何か成果を出してモチベーションを上げたい私が、マネージドの機械学習サービス(Amazon Forecast)にデータの前処理やモデル設計などをお任せして、電気料金の予測モデルを構築、簡単な評価までを記載します。
※1 本文内に記載する学習データ内の数値はサンプルです
※2 初学者のため関連用語の用法が誤っている可能性があります、ご容赦くださいAmazon Forecastとは
AWS公式ウェブサイト1より抜粋
Amazon Forecast は、機械学習を使用して精度の高い予測を行うフルマネージドサービスです。
Amazon.com と同じテクノロジーをベースとし、機械学習を使って時系列データを付加的な変数に結びつけて予測を立てます。
必要なのは過去のデータと、予測に影響を与える可能性があるその他の追加データだけです。
ユーザーがデータを提供すると、それを自動的に精査し、何が重要かを識別して、予測を立てるための予測モデルを作成します。目標
2020年9月の1日ごとの電気料金を予測する
精度が高いともちろん嬉しいですが最低限それっぽい予測ができること学習に使用するデータ
今回は予測したい電気料金の情報に加えて、追加データとして同期間の天候に関する情報を与えます。
- 過去の電気料金
- 2019年1月1日〜2020年8月31日の電気料金 - elec_data.csv
elec_data.csv# CSVサンプル id,ymd,cost 0,2019-01-01,11 0,2019-01-02,22 0,2019-01-03,33 ︙ 0,2020-08-29,44 0,2020-08-30,55 0,2020-08-31,66
- 自宅付近の過去の天候データ(気象庁公開のデータ2を使用) - weather_data.csv
- 最高気温、平均気温、最低気温 [℃]
- 降水量 [mm]
- 日照時間 [時間]
weather_data.csv# CSVサンプル id,ymd,max_temp,avg_temp,min_temp,precip,day_length 0,2019-01-01,10.0,4.0,-4.0,0.0,7.0 0,2019-01-02,10.5,4.5,-3.0,5.0,7.5 0,2019-01-03,11.0,5.0,-2.0,10.0,7.2 ︙ 0,2020-08-29,34.0,30.0,25.0,5.0,10.0 0,2020-08-30,34.5,30.5,25.5,10.0,7.3 0,2020-08-31,35.0,31.0,26.0,15.0,8.5学習
ここから上記データを使用して実際にモデル構築のための学習に入ります。
インポートの際はS3上のパスで指定するため、事前にCSVファイルをアップロードしておきます。データセットグループの作成
データをインポートする際、データセットグループに対して使用データを指定する形となります。
電気料金の予測モデル構築がゴールのため、Forecasting domain
はCustom
としました。
(上記設定についての詳細は こちら をご覧ください)データセットのインポート
予測対象データのインポート画面に移るので、一部設定を更新します
Frequency of your data
- 1 dayData schema
- CSVのスキーマに合わせて修正Timestamp format
- yyyy-MM-ddData location
- S3上のelec_data.csv
のパスを入力続けて、Related time series data > Import から天候データのインポートをします
Data location
にS3上のweather_data.csv
のパスを入力以上でデータセットのインポートが完了します。
学習の開始
両方のデータセットの状態が Active になったのを確認し、Predictor training > Start から学習を開始します。
要件が2020年9月の1日ごとの電気料金を予測する
であることを考慮し、30日分のデータ返却する予測器を作成します。
-Forecast horizon
- 30
-Forecast frequency
- 1 day
-Algorithm selection
- AutoML
-Country for holidays
- Japan各項目の詳細は、これまたAWSの公式サイト1を参照ください
(なおAutoMLについては 数種類のアルゴリズムの中から最適なものを選定してモデル構築してくれる くらいの理解しかありません)予測の作成と取得
予測の作成
少し待つと学習が完了し、Predictor trainingの状態が Active となります
AutoMLによって作成されたモデルを使用し、予測結果を取得します。Forecast generation > Start
Predictor
- 前のステップで作成した予測器を選択上記設定後 Create Forecast を選択し、予測結果を出力できるようになるまで待ちます
(Lookup forecast
とCreate a forecast
が選択できるようになっていればOK)
予測の取得
実際に予測結果を見てみます
Lookup forecast
から必要な情報を入力し、1ヶ月分の予測結果を表示します(Get Forecast
)
Forecast
- 前のステップで作成した予測Start date
- 2020/08/31 00:00:00End date
- 2020/09/30 00:00:00Forecast key
- item_id:0評価
最後、上記の予測と実際の電気料金(~9/15)を比較してみたいと思います
Oh... 軸名を書くのすら面倒になるほど外れてました…一旦まとめ
- 管理画面上でポチポチするだけ、(とりあえず)ノンコーディングで回帰モデルが作れました
反省
前提条件の異なるデータが訓練データに含まれていた
3月以降、在宅勤務がメインとなり、その分自宅にいる時間が大幅に増えました
それ以前は平日には出社していたので、データを準備しながらうすうす 去年のデータ全然参考にならないんじゃ… と思ってましたが、少なくとも曜日による重みはほぼ無意味になっているはず…予測対象とは別に与えた関連データ(天候データ)が不足していた
こちらの記事にありますが、予測する期間も含めたデータが必要だったようです、ウワー
上のよりこちらのほうが影響大きそう
- 投稿日:2020-09-22T22:43:40+09:00
Amazon Forecastで自分の電気代を予測してみる
はじめに
4月ごろから個人的な興味で機械学習の勉強をはじめました。
普段は本やオンライン教材に出てくるサンプルコードを写経しながら理解を深めつつ、たまにKaggleに挑戦し挫折したりしています。この記事では、とりあえず何か成果を出してモチベーションを上げたい私が、マネージドの機械学習サービス(Amazon Forecast)にデータの前処理やモデル設計などをお任せして、電気料金の予測モデルを構築、簡単な評価までを記載します。
※1 本文内に記載する学習データ内の数値はサンプルです
※2 初学者のため関連用語の用法が誤っている可能性があります、ご容赦くださいAmazon Forecastとは
AWS公式ウェブサイト1より抜粋
Amazon Forecast は、機械学習を使用して精度の高い予測を行うフルマネージドサービスです。
Amazon.com と同じテクノロジーをベースとし、機械学習を使って時系列データを付加的な変数に結びつけて予測を立てます。
必要なのは過去のデータと、予測に影響を与える可能性があるその他の追加データだけです。
ユーザーがデータを提供すると、それを自動的に精査し、何が重要かを識別して、予測を立てるための予測モデルを作成します。目標
2020年9月の1日ごとの電気料金を予測する
精度が高いともちろん嬉しいですが最低限それっぽい予測ができること学習に使用するデータ
今回は予測したい電気料金の情報に加えて、追加データとして同期間の天候に関する情報を与えます。
- 過去の電気料金
- 2019年1月1日〜2020年8月31日の電気料金 - elec_data.csv
elec_data.csv# CSVサンプル id,ymd,cost 0,2019-01-01,11 0,2019-01-02,22 0,2019-01-03,33 ︙ 0,2020-08-29,44 0,2020-08-30,55 0,2020-08-31,66
- 自宅付近の過去の天候データ(気象庁公開のデータ2を使用) - weather_data.csv
- 最高気温、平均気温、最低気温 [℃]
- 降水量 [mm]
- 日照時間 [時間]
weather_data.csv# CSVサンプル id,ymd,max_temp,avg_temp,min_temp,precip,day_length 0,2019-01-01,10.0,4.0,-4.0,0.0,7.0 0,2019-01-02,10.5,4.5,-3.0,5.0,7.5 0,2019-01-03,11.0,5.0,-2.0,10.0,7.2 ︙ 0,2020-08-29,34.0,30.0,25.0,5.0,10.0 0,2020-08-30,34.5,30.5,25.5,10.0,7.3 0,2020-08-31,35.0,31.0,26.0,15.0,8.5学習
ここから上記データを使用して実際にモデル構築のための学習に入ります。
インポートの際はS3上のパスで指定するため、事前にCSVファイルをアップロードしておきます。データセットグループの作成
データをインポートする際、データセットグループに対して使用データを指定する形となります。
電気料金の予測モデル構築がゴールのため、Forecasting domain
はCustom
としました。
(上記設定についての詳細は こちら をご覧ください)データセットのインポート
予測対象データのインポート画面に移るので、一部設定を更新します
Frequency of your data
- 1 dayData schema
- CSVのスキーマに合わせて修正Timestamp format
- yyyy-MM-ddData location
- S3上のelec_data.csv
のパスを入力続けて、Related time series data > Import から天候データのインポートをします
Data location
にS3上のweather_data.csv
のパスを入力以上でデータセットのインポートが完了します。
学習の開始
両方のデータセットの状態が Active になったのを確認し、Predictor training > Start から学習を開始します。
要件が2020年9月の1日ごとの電気料金を予測する
であることを考慮し、30日分のデータ返却する予測器を作成します。
-Forecast horizon
- 30
-Forecast frequency
- 1 day
-Algorithm selection
- AutoML
-Country for holidays
- Japan各項目の詳細は、これまたAWSの公式サイト1を参照ください
(なおAutoMLについては 数種類のアルゴリズムの中から最適なものを選定してモデル構築してくれる くらいの理解しかありません)予測の作成と取得
予測の作成
少し待つと学習が完了し、Predictor trainingの状態が Active となります
AutoMLによって作成されたモデルを使用し、予測結果を取得します。Forecast generation > Start
Predictor
- 前のステップで作成した予測器を選択上記設定後 Create Forecast を選択し、予測結果を出力できるようになるまで待ちます
(Lookup forecast
とCreate a forecast
が選択できるようになっていればOK)
予測の取得
実際に予測結果を見てみます
Lookup forecast
から必要な情報を入力し、1ヶ月分の予測結果を表示します(Get Forecast
)
Forecast
- 前のステップで作成した予測Start date
- 2020/08/31 00:00:00End date
- 2020/09/30 00:00:00Forecast key
- item_id:0評価
最後、上記の予測と実際の電気料金(~9/15)を比較してみたいと思います
Oh... 軸名を書くのすら面倒になるほど外れてました…一旦まとめ
- 管理画面上でポチポチするだけ、(とりあえず)ノンコーディングで回帰モデルが作れました
反省
前提条件の異なるデータが訓練データに含まれていた
3月以降、在宅勤務がメインとなり、その分自宅にいる時間が大幅に増えました
それ以前は平日には出社していたので、データを準備しながらうすうす 去年のデータ全然参考にならないんじゃ… と思ってましたが、少なくとも曜日による重みはほぼ無意味になっているはず…予測対象とは別に与えた関連データ(天候データ)が不足していた
こちらの記事にありますが、予測する期間も含めたデータが必要だったようです、ウワー
上のよりこちらのほうが影響大きそう
- 投稿日:2020-09-22T22:09:01+09:00
【試験合格記】AWS 認定 データベース – 専門知識(DBS-C01)
お疲れさまです。
表題の試験に合格したため記録として残したいと思います。結果
合格(816点)
AWS-Certified-Database-Specialty_Exam-Guide.pdf
分野 名称 割合 1 ワークロード固有のデータベース設計 26% 2 展開および移行 20% 3 管理および運用 18% 4 監視およびトラブルシューティング 18% 5 データベースセキュリティ 18% 所有資格
資格名 取得年月日 AWS Certified Solutions Architect - Associate (SAA) 2018-06-14 AWS Certified SysOps Administrator - Associate (SOA) 2018-06-22 AWS Certified Developer - Associate (DVA) 2018-06-25 AWS Certified Solutions Architect - Professional (SAP) 2018-07-19 AWS Certified DevOps Engineer - Professional (DOP) 2020-02-19 AWS Certified Big Data - Speciality (BDS) 2020-03-23 AWS Certified Security - Speciality (SCS) 2020-04-01 AWS Certified Machine Learning - Speciality (MLS) 2020-04-13 AWS Certified Advanced Networking - Speciality (ANS) 2020-04-27 AWS Certified Cloud Practitioner (CLF) 2020-04-27 AWS Certified Database - Specialty (DBS) 2020-09-22 事前知識
AuroraやElastiCacheを業務で建てることはよくあるので、そのへんのパラメータ周りは知ってます。
あとは過去に「エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド」という書籍を読破したり、レンサバ運用で泣き叫んでるMySQLサーバのスロークエリを抽出したりパフォーマンスチューニングをしたり・・・といった程度で正直ひよっこレベルでした。所感
学習期間は1ヶ月半くらいだったと思います。
難易度としては普段からDBサーバを触っているかいないかで大きく変動するのではないでしょうか。また、この試験に限らず、DBリソース選定や面接などで「RDSとAuroraはどう違うのか」といった話はよく出るので体系的に理解しておくのがオススメです。
試験内容についてはどなたかのブログで書いてましたが、「セキュリティ専門」と「ネットワーク専門」の知識が正しく頭にあればそれだけで30%くらいのスコアを稼げると思います。
あとはRDSとAuroraの違いやディザスタリカバリ要件に対するアプローチ、それにDMSを使ったマイグレーションなどの最適解を導き出せると60%が見えてくるはずです。
残りの40%はNeptune、DynamoDB、Aurora Serverless、ElastiCacheといった雑多な周辺知識の特徴を抑えておけば合格ラインを超えられる可能性が出てくると思います。学習範囲
- サンプル問題
- 模擬試験
- Exam Readiness: AWS Certified Database - Specialty
- 各種ブラックベルト
受験者に向けたアドバイス
- セキュリティとネットワークのAWS認定で学んだ内容をしっかり振り返る
- RDS(MySQL, PostgreSQL, SQL Server, Oracle)それぞれができること、できないことを理解する
- Auroraも同じ
- DMSを使ったマイグレーションの手順やそれに頼らない別のアプローチを把握しておく
- DynamoDBはそれなりに出題された記憶があるので要復習
- IAMを使った権限管理やDBをふっ飛ばしたので巻き戻したい系のトラブルシューティングも重要
まとめ
Kubernetesの資格を取ったあたりで試験勉強に飽きてしまいました。
データベース資格に関しては試験勉強をすることで身近な運用時のミスをカバーできる知識を得ることができるので、DBを触ったことがないという方も学んでみると色々と役に立つことがあるかもしれません。
特にインフラ屋にとってはDBが安定していないと睡眠時間が減ってしまうという問題もあるので是非取得を目指すとよいと思います。年内に最後の資格であるAlexaを取得できるよう引き続き頑張ります。
- 投稿日:2020-09-22T19:45:56+09:00
【AWS】Amazon SESを用いてRuby on Railsのdeviseでメールを送信する
目次
・経緯
・今回の前提条件
・注意事項
・AWS SES(Simple Email Service)とは
・料金
・大体の流れ(イメージ)
・1. AWS SESの設定
・2. AWSのCSに制限解除のメールを送る
・3. IAMユーザーの設定
・4. railsに設定
・用語解説
・最後に経緯
私がPortfolioを作成している段階でして、divise上のメールが飛んでいないことに気づきました。
改善策を模索している中、AWSSES(有料)なるものを見つけGmail(無料?)でも実装できることが分かったが、AWSでEC2なども利用していたので
・AWSでまとめて管理ができるのですっきりしそう
・いい経験になるかも
上記の理由で実装してみた。私自身も初学者なので、完全に鵜呑みにせずイメージをつかむ感覚で読んでいただければと!
今回の前提条件
- Ruby on railsでappがありdeviseを導入している
- AWSのアカウントを所持している
- Route53の設定が完了していて、ドメインでのアクセス可能なサイトがある。
くらいですかね、、
注意事項
私がだいぶ躓いたところなので、、
2020/09/22現在AWSSESを東京リージョン(ap-northeast-1)で本番環境で実装するとメールが飛びません!!!!!
最近のリリースなのでまだバグが多いから?!
解決方法わかる方教えていただきたいです
祝!Amazon SESが東京リージョンにやってきた!
私はアイルランドリージョン(eu-west-1)で実装しました。
AWS SES以外の設定は東京リージョンで済ませております。(EC2,Route53など)あとサンドボックスの制限解除に1日かかります!
ご利用は計画的に!AWS SES(Simple Email Service)とは
AWSで提供されているクラウドベースの電子メール送信サービスです。
料金
AWS SESは有料で、一定量送信毎での従量課金制ぽいです。
SES の料金は、送信する各 1,000 通の E メールにつき、0.10USD であり、非常に低コストです。
上記の通り、高額な金額が発生するわけではなさそうなので試しに利用してみるのもありでしょう!
大体の流れ(イメージ)
- AWS SESの設定
- AWSのCSに制限解除のメールを送る
- IAMユーザーの設定
- railsに設定
1. AWS SESの設定
1-1. AWSにログイン
1-2. ヘッダーのサービスをクリック
1-3. SESと検索してエンター
1-4. IdentityManagement>Domainをクリック
1-5. Varufy a NeW Domianをクリック
※この段階で東京リージョン以外のリージョンを選択しておいたほうが良いです
1-6. Domainに接続したいドメイン名を入れる
1-7. Generate DKIM Settingsにチェック入れる
1-8. Varufy This Domianをクリック
1-9. User Route53をクリック
Route53を登録している場合上記表示になる。
登録している場合レコードの設定までを自動でやってくれるぽい
1-10. Create Record Setsをクリック
AWS SWSのsettingは一旦こちらで終了です!2. AWSのCSに制限解除のメールを送る
AWS SESをsettingをしただけではメールは送信されません。
設定初期ProductionAcsessがSandboxになっており、これを解除する必要があります。
2-1. Email Sending > Sending Statistics をクリック
2-2. ProductionAcsessがSandboxになっていることを確認する。
2-3. 右上のサポートをクリック
2-4. サポートセンターをクリック以降メールの送信手順に関しては下記記事でご丁寧にまとめられておりましたので
メールを送るまでは参考にしてみてください。
2-6.メール送信の手順
※2.解除申請を送るフォームに入力から行ってみてください。
メール送信して一日後、上記のような解除しましたとメールが来れば
下記がProductionAcsessがSandbox⇒Enabledに代わります。
2-7.IdentityManagement>Domain>SendaTestEmailをクリック
2-8.メールを送ってみる
最後にテストです。
メールを送り受信ボックスに届くか確認します。3. IAMユーザーの設定
AWS SESのsettingと制限解除だけではrailsにつなぎこめません。
最後にIAMユーザーを新規登録しなくてはいけません。
※筆者はrootアカウントでキーとIDを参照する方法を探してみましたがありませんでした。
※本来rootアカウントでは接続管理は好ましくなく、各アクションごとにIAMユーザー(権限の範囲)を指定して接続したほうがいいと参考書に書いてありました。
のであるかはわかりませんがとりあえずIAMユーザーで作成しておけってことですね。
3-1. ヘッダーのサービスをクリック
3-2. IAMと検索してエンター
3-3. ユーザーをクリック
3-4. ユーザーを追加をクリック
3-5. ユーザー名を入れる(※ここはわかりやすければなんでもOKです)
3-6. プログラムによるアクセスにチェック
3-7. 次のステップ:アクセス権限をクリック
3-8. 既存ポリシーを直接アタッチをクリック
3-9. ポリシーのフィルタにSESと入れる
3-10. AmazonSESFullAccessにチェックを入れる
3-11. 次ぐのステップ:タグをクリック
3-12. 次ぐのステップ:確認をクリック
キーと値は何も入れなくてOKです。
こちらでIAMユーザーの作成が完了です。
※アクセスキーIDとシークレットアクセスキーは必ず控えておきましょう。
※アクセスキーIDは後程確認できますが、シークレットアクセスキーはこのページでしか確認ができず消したらもう見れません。
こちらでAWS上での設定は完了です。4. railsに設定
お疲れ様です。
最後はrailsに設定して終わりです。
大体の作業は下記の流れです。
1. gemのインストール
2. ActionMailerの設定
3. 本番環境、開発環境の設定
4. deviseの設定変更
5. Mailerクラスのfromの設定
6. .envをアップロードする(本番環境用)4-1. gemのインストール
gem 'aws-ses'Gemfileにて上記を記載してbundle install
4-2. ActionMailerの設定
ActionMailer::Base.add_delivery_method :ses, AWS::SES::Base, access_key_id: ENV['AWS_ACCESS_KEY_ID'], secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'], server: 'email.リージョンID.amazonaws.com'config/initializers/aws.rbを新規で作成
リージョンIDと記載されているところはSESを作成したリージョンIDを入れてください。
※分からない場合はAWSにログインをするとURLの末尾にリージョンIDが記載されてます。例
東京:ap-northeast-1
アイルランド:eu-west-1IDとKEYはpushしてしまうとまずいので.envに新規で追加します。
AWS_ACCESS_KEY_ID = IDを入力 AWS_SECRET_ACCESS_KEY = KEYを入力4-3 開発環境(のみ)の設定
config.action_mailer.default_url_options = { host: 'ドメイン名' } config.action_mailer.delivery_method = :sesconfig/environments/development.rbに上記を追加
ドメイン名と書いてあるところは接続しようとしているドメイン名に変えてください。4-3 本番環境(のみ)の設定
config.action_mailer.default_url_options = { host: 'ドメイン名' } config.action_mailer.delivery_method = :sesconfig/environments/production.rbに上記を追加
ドメイン名と書いてあるところは接続しようとしているドメイン名に変えてください。4-4. deviseの設定変更
# config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com' config.mailer_sender = 'Testrooper <noreply@ドメイン名>'config/initializers/devise.rbを変更します
ドメイン名と書いてあるところは接続しようとしているドメイン名に変えてください。4-5. Mailerクラスのfromの設定
class ApplicationMailer < ActionMailer::Base default from: 'MyDomain <noreply@ドメイン名>' layout 'mailer' endMailerクラスのfromの設定をします。
mailers/application_mailer.rbに上記を追加します。
ドメイン名と書いてあるところは接続しようとしているドメイン名に変えてください。
開発環境であればこちらで終了となります^^4-6. .envをアップロードする(本番環境のみの設定)
開発環境では正常に動き、本番環境で動かなかった際、こちら完全に忘れておりました、、
.envはpushされないのでEC2上にアップロードします
でないと本番環境ではSESの参照ができません!
流れは下記のとおりです。
1.EC2にログイン
2.アプリケーションのディレクトリに移動
3.viで.envにアクセスキーIDとシークレットアクセスキーの上書き保存
4.PUMAの再起動用語解説
後程追加いたします。
最後に
現在ポートフォリオを作成しておりますので
ご意見などいただければうれしいです!
NotePro
- 投稿日:2020-09-22T19:45:56+09:00
【AWS】AWS SESを用いてRuby on Railsのdeviseでメールを送信する
目次
・経緯
・今回の前提条件
・注意事項
・AWS SES(Simple Email Service)とは
・料金
・大体の流れ(イメージ)
・1. AWS SESの設定
・2. AWSのCSに制限解除のメールを送る
・3. IAMユーザーの設定
・4. railsに設定
・用語解説
・最後に経緯
私がPortfolioを作成している段階でして、divise上のメールが飛んでいないことに気づきました。
改善策を模索している中、AWSSES(有料)なるものを見つけGmail(無料?)でも実装できることが分かったが、AWSでEC2なども利用していたので
・AWSでまとめて管理ができるのですっきりしそう
・いい経験になるかも
上記の理由で実装してみた。私自身も初学者なので、完全に鵜呑みにせずイメージをつかむ感覚で読んでいただければと!
今回の前提条件
- Ruby on railsでappがありdeviseを導入している
- AWSのアカウントを所持している
- Route53の設定が完了していて、ドメインでのアクセス可能なサイトがある。
くらいですかね、、
注意事項
私がだいぶ躓いたところなので、、
2020/09/22現在AWSSESを東京リージョン(ap-northeast-1)で本番環境で実装するとメールが飛びません!!!!!
最近のリリースなのでまだバグが多いから?!
解決方法わかる方教えていただきたいです
祝!Amazon SESが東京リージョンにやってきた!
私はアイルランドリージョン(eu-west-1)で実装しました。
AWS SES以外の設定は東京リージョンで済ませております。(EC2,Route53など)あとサンドボックスの制限解除に1日かかります!
ご利用は計画的に!AWS SES(Simple Email Service)とは
AWSで提供されているクラウドベースの電子メール送信サービスです。
料金
AWS SESは有料で、一定量送信毎での従量課金制ぽいです。
SES の料金は、送信する各 1,000 通の E メールにつき、0.10USD であり、非常に低コストです。
上記の通り、高額な金額が発生するわけではなさそうなので試しに利用してみるのもありでしょう!
大体の流れ(イメージ)
- AWS SESの設定
- AWSのCSに制限解除のメールを送る
- IAMユーザーの設定
- railsに設定
1. AWS SESの設定
1-1. AWSにログイン
1-2. ヘッダーのサービスをクリック
1-3. SESと検索してエンター
1-4. IdentityManagement>Domainをクリック
1-5. Varufy a NeW Domianをクリック
※この段階で東京リージョン以外のリージョンを選択しておいたほうが良いです
1-6. Domainに接続したいドメイン名を入れる
1-7. Generate DKIM Settingsにチェック入れる
1-8. Varufy This Domianをクリック
1-9. User Route53をクリック
Route53を登録している場合上記表示になる。
登録している場合レコードの設定までを自動でやってくれるぽい
1-10. Create Record Setsをクリック
AWS SWSのsettingは一旦こちらで終了です!2. AWSのCSに制限解除のメールを送る
AWS SESをsettingをしただけではメールは送信されません。
設定初期ProductionAcsessがSandboxになっており、これを解除する必要があります。
2-1. Email Sending > Sending Statistics をクリック
2-2. ProductionAcsessがSandboxになっていることを確認する。
2-3. 右上のサポートをクリック
2-4. サポートセンターをクリック以降メールの送信手順に関しては下記記事でご丁寧にまとめられておりましたので
メールを送るまでは参考にしてみてください。
2-6.メール送信の手順
※2.解除申請を送るフォームに入力から行ってみてください。
メール送信して一日後、上記のような解除しましたとメールが来れば
下記がProductionAcsessがSandbox⇒Enabledに代わります。
2-7.IdentityManagement>Domain>SendaTestEmailをクリック
2-8.メールを送ってみる
最後にテストです。
メールを送り受信ボックスに届くか確認します。3. IAMユーザーの設定
AWS SESのsettingと制限解除だけではrailsにつなぎこめません。
最後にIAMユーザーを新規登録しなくてはいけません。
※筆者はrootアカウントでキーとIDを参照する方法を探してみましたがありませんでした。
※本来rootアカウントでは接続管理は好ましくなく、各アクションごとにIAMユーザー(権限の範囲)を指定して接続したほうがいいと参考書に書いてありました。
のであるかはわかりませんがとりあえずIAMユーザーで作成しておけってことですね。
3-1. ヘッダーのサービスをクリック
3-2. IAMと検索してエンター
3-3. ユーザーをクリック
3-4. ユーザーを追加をクリック
3-5. ユーザー名を入れる(※ここはわかりやすければなんでもOKです)
3-6. プログラムによるアクセスにチェック
3-7. 次のステップ:アクセス権限をクリック
3-8. 既存ポリシーを直接アタッチをクリック
3-9. ポリシーのフィルタにSESと入れる
3-10. AmazonSESFullAccessにチェックを入れる
3-11. 次ぐのステップ:タグをクリック
3-12. 次ぐのステップ:確認をクリック
キーと値は何も入れなくてOKです。
こちらでIAMユーザーの作成が完了です。
※アクセスキーIDとシークレットアクセスキーは必ず控えておきましょう。
※アクセスキーIDは後程確認できますが、シークレットアクセスキーはこのページでしか確認ができず消したらもう見れません。
こちらでAWS上での設定は完了です。4. railsに設定
お疲れ様です。
最後はrailsに設定して終わりです。
大体の作業は下記の流れです。
1. gemのインストール
2. ActionMailerの設定
3. 本番環境、開発環境の設定
4. deviseの設定変更
5. Mailerクラスのfromの設定
6. .envをアップロードする(本番環境用)4-1. gemのインストール
gem 'aws-ses'Gemfileにて上記を記載してbundle install
4-2. ActionMailerの設定
ActionMailer::Base.add_delivery_method :ses, AWS::SES::Base, access_key_id: ENV['AWS_ACCESS_KEY_ID'], secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'], server: 'email.リージョンID.amazonaws.com'config/initializers/aws.rbを新規で作成
リージョンIDと記載されているところはSESを作成したリージョンIDを入れてください。
※分からない場合はAWSにログインをするとURLの末尾にリージョンIDが記載されてます。例
東京:ap-northeast-1
アイルランド:eu-west-1IDとKEYはpushしてしまうとまずいので.envに新規で追加します。
AWS_ACCESS_KEY_ID = IDを入力 AWS_SECRET_ACCESS_KEY = KEYを入力4-3 開発環境(のみ)の設定
config.action_mailer.default_url_options = { host: 'ドメイン名' } config.action_mailer.delivery_method = :sesconfig/environments/development.rbに上記を追加
ドメイン名と書いてあるところは接続しようとしているドメイン名に変えてください。4-3 本番環境(のみ)の設定
config.action_mailer.default_url_options = { host: 'ドメイン名' } config.action_mailer.delivery_method = :sesconfig/environments/production.rbに上記を追加
ドメイン名と書いてあるところは接続しようとしているドメイン名に変えてください。4-4. deviseの設定変更
# config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com' config.mailer_sender = 'Testrooper <noreply@ドメイン名>'config/initializers/devise.rbを変更します
ドメイン名と書いてあるところは接続しようとしているドメイン名に変えてください。4-5. Mailerクラスのfromの設定
class ApplicationMailer < ActionMailer::Base default from: 'MyDomain <noreply@ドメイン名>' layout 'mailer' endMailerクラスのfromの設定をします。
mailers/application_mailer.rbに上記を追加します。
ドメイン名と書いてあるところは接続しようとしているドメイン名に変えてください。
開発環境であればこちらで終了となります^^4-6. .envをアップロードする(本番環境のみの設定)
開発環境では正常に動き、本番環境で動かなかった際、こちら完全に忘れておりました、、
.envはpushされないのでEC2上にアップロードします
でないと本番環境ではSESの参照ができません!
流れは下記のとおりです。
1.EC2にログイン
2.アプリケーションのディレクトリに移動
3.viで.envにアクセスキーIDとシークレットアクセスキーの上書き保存
4.PUMAの再起動用語解説
後程追加いたします。
最後に
現在ポートフォリオを作成しておりますので
ご意見などいただければうれしいです!
NotePro
- 投稿日:2020-09-22T18:28:13+09:00
マネジメントコンソールの呼び方は?
呼び方は?
みなさん、AWS(アマゾン ウェブ サービス)使ってますか?
使っている方はおなじみの マネジメントコンソール ですが、何と呼んでいるでしょうか。略さず、 マネジメントコンソール
略して、 マネコン
のどちらかが多いのではないでしょうか。私の職場では
私の職場では、前者の「マネジメントコンソール」と呼ぶメンバーばかりです。
実は、私もずっと「マネジメントコンソール」と略さずに呼んでいたのですが、
半年(?)ほど前に「マネコン」と略すのをネットで見かけて、
これは言いやすいと「マネコン」に鞍替えしたのですが、なかなか浸透せず。。。
誰も「マネコン」と言わないので、ちょっと恥ずかしくもあり。。。Windowsの「コントロールパネル」を「コンパネ」と呼ぶのと同じ感じなんですけどね。
- 投稿日:2020-09-22T17:44:32+09:00
【合格体験記】半年かけて確実に合格! AWSソリューションアーキテクト合格までの道のり 〜アプリケーションエンジニアがSAAを取得した話〜
はじめに
2020年9月21日、AWSソリューションアーキテクトアソシエイト(以下SAA)に合格しました。自分自身の勉強の方法やスケジュールに関してシェアする記事です。
ネットには「3週間で合格しました!」などと短期間の学習での合格体験記もありますが、
「一回の受験でで確実に合格する」
「知識だけでは意味がないので、ハンズオンもちゃんと行う」
という方針の下、じっくり6ヶ月の時間をかけて勉強しました。筆者のバックグラウンド
基本的にはフロントエンド(React)とバックエンド(Java,Go)ができるアプリケーションエンジニアです。AWSの経験としては、EC2、RDS、S3、Lambdaなどを少しだけ仕事で触ったことがある程度でした。その他のサービスに関しては、実務経験がゼロの状況で学習を開始しました。
受験の動機
IT系の資格としては応用情報技術者の資格を既に持っていました。
「何かIT系の資格もう1つくらいほしいなー」と思い、
情報処理安全確保支援士かSAAかで迷った結果、SAA取得を決意しました。SAAを選んだ理由としては、
・ AWSの資格はグローバルに通用する資格だから。
・ インフラ系やアーキテクチャの設計とかにも仕事を広げられるかもしれないと思ったから。
・ なんかのランキングでAWSの資格が最近人気と聞いたから。
・ 「AWSの資格持ってます!」と周りの人に自慢してみたかったから。下位の資格であるクラウドプラクティショナーを受ける選択肢もあったのですが、
頑張ればいけそうだったので、いきなりSAAの学習を開始しました。学習教材
①【書籍】Amazon Web Services 基礎からのネットワーク&サーバー構築
SAAに特化した書籍というわけではないです。VPC,EC2の一般的なサーバー構成に関して実際に手を動かして学習できる教材です。資格学習の導入として、書籍の内容を一通りハンズオンしてみました。②【書籍】AWS認定アソシエイト3資格対策
SAAの範囲を一通り学習できる書籍です。インプット用の書籍とした何周か読みました。また、試験直前の問題演習期間に、練習問題の復習をする際にリファレンス的な使い方ができたので、非常に役に立ちました。
同書籍には練習問題が掲載されているのですが、その量は少ないのでこの書籍だけで合格は難しいと思いますが、情報のインプットとしては最適な書籍だと感じました。③【Udemy】これだけでOK! AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座
SAAの対策教材として有名な動画教材です。
サービス概要・ハンズオン・練習問題とバランス良く掲載されているので、時間のある人は一通りこなすのが良いと思います。
私は知識の取得だけでは意味がないと思い、こちらのハンズオンパートを一通りこなしました。実際にハンズオンをこなした方が、問題を解く際にもイメージしやすかったです。④【Udemy】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集(6回分390問)
一番頼りにした教材です。かなり難易度が高く、かつ分量も多いです。ですが、こちらの問題をマスターすればほぼ合格は確実、だと感じました。
一度間違えた問題をチェックしつつ何度も何度も解き直しました。⑤【Web問題集】AWS WEB問題集で学習しよう
問題集に関しては④でも十分なのですが、ダメ押しでこちらのサイトも有料プランを契約して利用しました。
SAAに関しては問題が1000問近くも掲載されています。細かすぎるような知識を問う問題もいくつか掲載されているのですが、よくできた問題も多数掲載されています。実際に試験を受けた際に出題された問題とほぼ同様の問題がこちらのサイトにも掲載されており、非常に感謝しているサービスの1つです。スケジュール
段階 時期 学習方法 導入 2020年3月上旬 ・学習教材①を使ってハンズオン インプット 2020年3月中旬〜5月末 ・学習教材②を使って知識のインプット
→iPadで学習ノートを作成しつつ3週程度読む
・学習教材③を使ってハンズオン問題演習① 2020年6月〜8月 ・学習教材④を使って問題演習
→間違えた問題を中心に復習し、繰り返し演習
・オリジナルの一問一答集を作成・暗記問題演習② 2020年9月 ・学習教材⑤を使って問題演習
→時間がなくて一周しかこなせなかった。。。本番 2020年9月21日 ・テストセンターにて受験
→ 合格!学習ペース
試験直前の9月はほぼ毎日勉強していました(平日1〜2時間、休日1〜4時間程度)が、
それ以外時期に関しては勉強したり、勉強しなかったりという感じでした^^;3月~8月は一週間の内、半数程度の日は勉強していたかと思います。
(これも半年くらい時間がかかった理由の1つです。。。。)もうちょっと集中して勉強すれば短期間で合格できたのかな、、、とも思います。
AWSの資格はテストセンターの予約する形式なので、直前まで日程を決めずダラダラ勉強してしまったように思います。学習に活用したツール
iPad
Apple PencilとGoodNoteというアプリを使って学習ノートを作成していました。何か勉強する際にはノートをとらないと気がすまない性格なので、この組み合わせは個人的には最強でした。SmaTan
単語帳を自作できるアプリです。こちらのアプリで一問一答集を作成して暗記をしていました。Qiita
Qiitaの記事に暗記事項とかをまとめていました。こちらのページなどに自分なりの視点で試験に出そうな部分をまとめました。試験直前になってからやりはじめたので、もうちょっと早めにやっておけば良かったなー、と思いました。合格の目安
学習教材④ または 学習教材⑤ にて8~9割程度の正答率が安定する、ことだと思います。
8割9割という数字は完全に私の主観的な意見ですが、演習問題を解くことは非常に重要です。
紛らわしい選択肢が非常に多いので、問題を解きまくって正解を探す訓練をするのは大事だと感じています。試験を終えての感想
実務経験なくても(実際にAWS触ってなくても)試験には合格できる
知識だけでも合格はできます、、、が実際に触ったことがあると試験勉強はかどります。なので、主要なサービスだけでも良いのでハンズオンをこなしておくのがおすすめです。EC2,RDS,ELB(AutoScaling),S3くらいはやっておいて損はないかと思います。最新の情報を取得するように心がけるべき
AWSのサービスは日々更新しているので、古い情報で覚えてしまうと、間違った選択肢を選んでしまいがちです。Qiitaやブログで調べ物をすることも良いですが、なるべくAWS公式のドキュメントを読むようにすると良いです。試験の日程は最初に決める
自分で試験の日程を決めるスタイルなので、日程を決めずに学習をはじめてしまうとダラダラ勉強しがちです。
最悪、日程は後で変更も可能なので、一度日程を決めて、スケジュールドリブンで学習をする、というのが効果的だと思いました。
- 投稿日:2020-09-22T17:43:56+09:00
【axios+SAM+API Gateway】localhostからapiを叩けるようになるために苦労した話 (3/3)ローカルから先程作成した`API Gateway`の`POST`メソッドを叩く
はじめに
本稿は下記流れに沿って、axios+SAM+API Gatewayを利用して、GET及びPOSTメソッドのAPIを叩けるところまでを目標としています。
- SAMを利用して、API Gateway及びlambdaを構築
- ローカルから先程作成したAPI GatewayのGETメソッドを叩く
- ローカルから先程作成したAPI GatewayのPOSTメソッドを叩く
前回「ローカルから先程作成したAPI GatewayのGETメソッドを叩く」ということを試しました。その際に、「ドメインが異なる場合はCORSを意識する必要がある」ということを学びました。具体的には、API側でドメイン間でのリソースを共有を許可するような内容を
header
に含んで返却する必要がある、ということでした。今回は、「ローカルから先程作成したAPI GatewayのPOSTメソッドを叩く」ということを試していきたいと思います。
3. ローカルから先程作成した
API Gateway
のPOST
メソッドを叩くでは
POST
メソッドを叩けるようにしていきたいと思います。まずはAPI側の実装をしていきます。
POST
のAPIとして以下のlambda
を作成します。// post_item.py import json # import requests def lambda_handler(event, context): print(event) msg = json.loads(event['body'])['message'] return { "statusCode": 200, 'headers': { 'Access-Control-Allow-Headers': 'Content-Type', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'OPTIONS,POST,GET' }, "body": json.dumps({ "message": "you posted this message: " + msg }), }またこの
lambda
をSAM
で管理できるよう、template.yaml
を修正します。Resources: PostItemFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: post_item/ Handler: post_item.lambda_handler Runtime: python3.7 Events: HelloWorld: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: Path: /post_items Method: postそしてこれらをビルド・デプロイしてAPI側の準備は完了です。
続いてアプリ側の修正を行います。今回はPOST
メソッドに対応した処理を追加します。// App.js import React, {Component} from 'react'; import axios from 'axios'; class App extends Component { constructor(props){ super(props); this.state = { 'appMessage': 'hello,app', postApiMessage: 'before post' }; this.doChange = this.doChange.bind(this); this.getApi = this.getApi.bind(this); this.postApiMessage = this.postApiMessage.bind(this); } instance = axios.create({ baseURL: 'https://flz1roclul.execute-api.ap-northeast-1.amazonaws.com/Prod' }); doChange(e){ this.setState({ message: e.target.value }) } getApi(){ this.instance.get('/hello') .then((response) => { this.setState({ 'appMessage': response.data['message'] }) }) .catch(() => { this.setState({ 'appMessage': 'faild get message from button' }) }) } postApiMessage(){ this.instance.post('/post_items', {'message': this.state.message}) .then((results)=>{ //console.log(results.json()) console.log(results) this.setState({ 'postApiMessage': 'postApiSuccess! ' + results.data['message'] }) }) .catch((results) => { console.log(results) this.setState({ 'postApiMessage': 'postApiFailed' + results }) }) } render(){ return( <div> <p>{this.state.postApiMessage}</p> <form> <input type="text" value={this.state.message} onChange={this.doChange}/> <input type="button" value="post api" onClick={this.postApiMessage} /> </form> <div>{this.state.appMessage}</div> <input type='button' onClick={this.getApi} value="button" /> </div> ) } } export default App;今回の処理は、アプリ側でポストした内容をAPI側でくっつけて返却するという単純なものです。
前回の反省を活かし、今回はAPI側に必要なheaderを予め追加しておいたので、大丈夫だと思います!何がだめったのか?
今回のエラーメッセージは以下のとおりです。
Access to XMLHttpRequest at 'https://{APIのURL}/Prod/post_items' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
'Access-Control-Allow-Origin'
はつけたはずなのになんで?と思っていたのですが、今回重要なのは次の箇所でしたResponse to preflight request doesn't pass access control check調べてみると、特定の条件を満たすと、実際のメソッドが実行される前に
OPTIONS
メソッドが実行される(だからpreflight
)ようです。で今回はそれに対応するメソッドが用意されてなかったので、エラーとなったと。
というわけで対策をしようと思います。メソッド部分は必要なheaderを返すだけでよいので以下のようにしました。// post_item_options.py import json # import requests def lambda_handler(event, context): return { "statusCode": 200, 'headers': { 'Access-Control-Allow-Headers': 'Content-Type', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'OPTIONS,POST,GET' }, "body": json.dumps({ "message": "this is the method to avoid cors for post method" # "location": ip.text.replace("\n", "") }), }そしてこれを
template.yaml
に追加します。Resources: PostItemOptionsFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: post_item_options/ Handler: post_item_options.lambda_handler Runtime: python3.7 Events: HelloWorld: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: Path: /post_items Method: options大事なのは、
POST
メソッドとPathは同じにすることです。これは、preflight
メソッドは送信しようとしたメソッドに対して飛ぶためです。もう一度やってみた
API側の修正を行ったので、もう一度チャレンジしてみました。
無事postが成功して、メッセージが返却されました!終わりに
無事API環境を構築し、アプリから
GET
及びPOST
APIを叩けるようになりました。「ただURLとメソッドを指定して叩けばいい」と思っていたので、まさかheader云々でこんなにハマるとは思わなかったです。もし本稿が同じような悩みに直面している人の助けになれば幸いです。
- 投稿日:2020-09-22T17:40:34+09:00
インフラ未経験エンジニアのソリューションアーキテクトアソシエイト (SAA-C002) 合格体験記
はじめに
- 標記の通り、インフラ未経験エンジニアによる AWS ソリューションアーキテクトアソシエイトの試験対策をまとめた記事です。1
- インフラ構築についてはオンプレミスを含めても未経験のため、ハンズオンの経験が大事だと思いました。
- 2回目の受験でギリギリで合格できました。
受験動機
- クラウドの強みとの一つに、スピーディーかつスケーラブルに、開発環境の構築からサービスの展開ができることだと思います。世の中のスピード感に対応するための一つの手段としてクラウドがあるのかなと思い勉強し始めました。2
- その勉強の中で知識・技術のレベルを客観的に把握できるのがAWS認定の資格試験と思い受験しました。
あとは、ソリューションアーキテクトアソシエイトに合格すると会社から奨励金がもらえるからです。勉強方法
本
ご多分にもれず、下の2冊の本を読んで対策しました。
自分でインフラに関するAWSのサービスを使わないとな・・・と思っていたら下記の本が見つかりました。
- Amazon Web Servicesインフラサービス活用大全
- ソリューションアーキテクトアソシエイト試験に頻出されるサービスを扱った実践的な内容で、結果的には自分にとって最も有効な試験対策となりました。
- 特にインフラ未経験エンジニアは実際に手を動かして見ないと、試験対策本を読んでも理解が進みませんでしたが、この本の内容を一通りこなした後で、対策本の解説の内容がより理解できるようになりました。
その他資料
- AWS 認定セッション
- AWS Summit 2020 の認定試験に関する資料集です。ソリューションアーキテクトアソシエイトに関する資料があります。
- Get Certified 2020
- AWS提供の無料の認定試験に関するワークショップです。定期的に開催している様子で、2020/09/25に開催予定。
模擬試験
公式
- AWS training and certification
- AWSが提供する公式の模試です。あくまで基礎的な内容で、本番の試験はもっと難易度が上がります。
Udemy
- 【SAA-C02版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集(6回分390問) | Udemy
- 6回分全て行いました。特に、基本問題とSAA-C02版向けを重点的に行いました。
- 本番と同じ65問で、解答後に分野ごとのスコアを教えてくれます。
結果
- 753点 / 1000点 (合格ラインは720点)
- ちなみに1回目は689点でした。2回目の受験は、1回目の受験の2ヶ月後です。
- ギリギリなので偉そうなことは言えないですね。精進します。
- 出題範囲の分野ごとの理解の度合い(再学習の必要あり or 十分な知識を有する)も教えてくれます。
- 分野1:レジリエントアーキテクチャ ・・・ 十分な知識を有する
- 分野2:高パフォーマンスアーキテクチャの設計 ・・・ 十分な知識を有する
- 分野3:セキュアなアプリケーションとアーキテクチャの設計 ・・・ 再学習の必要あり
- 分野4:コスト最適化アーキテクチャの設計 ・・・ 十分な知識を有する
おわりに
- 理論と実践のバランスが必要な資格試験だと思いました。
- オンプレミスで経験がある人はさておき、未経験者は実際に手を動かして、簡単な内容でも一通り自分の手で動かすことが大事だと思いました。
- インフラ未経験だけど、クラウド (AWS) の活用に興味があって、資格取得をしたい方、スキルアップしたい方への一助となれば幸いです。
- 次はデベロッパーアソシエイトの認定を目指します。
- 投稿日:2020-09-22T17:39:25+09:00
AWS SAA(C02)に1か月で合格するはずが3回受験してしまった話
コロナで在宅ワークに励んでいたころふと気づいた...。「このままだと今年の実績で大したものがない!」かねてより資格を取ろうと勉強していた某試験が、コロナ禍で無期限延期になってしまったのです。(余談ですが、自分は1年に一つ人生初をやっていこうというのをここ数年のタスクにしています。)
さて、それに気づいたのが6月頭だったので、何とかその資格とレベル感のあった別の資格無いもんかな、ということで自分が目を付けたのが表題にある通りAWSのSAAです。実は以前からQiitaの合格体験記を読んで人知れず狙ってはいたのですが、前述の資格のこともあり後回しにしていたのです。本当は自分はGoogle推し(特に何の根拠もなし。ロゴがカラフルだから?)なのでGCPも考えたのですが、やはりAWSがシェアNo.1ということもあり、体験談や教材が豊富ということがAWSを選択した一つの理由でした。それに皆さんご存じの通りクラウドは3強(AWS、GCP、Azure)に加え、競合他社が多いので、本当に必要な機能であれば競合他社がどんどんキャッチアップしていくので、よほど強い拘りがないのであればNo.1を選択するのが無難だと思いますし、1社をしっかり勉強・経験すれば応用効くような気がしています。
記事の前提となる知識・経験
インフラ業務 → 0
クラウド業務 → 0
クラウド経験 → GCPの無料枠を使い切ったくらいでヘタレて解約。
趣味的な経験 → サクラVPSに自分のブログを立てて2年くらい運用していた。こんな感じなのでおそらく「あんまり経験はないけど受けてみよう」という人たちのレベル感に近いのではないかと思います。
AWS試験で越えなければならないハードル
これについてはおおむね以下の2つに絞られると思います。
①AWSで提供するサービスの数がメチャクチャ多いので単語を覚えること自体が疲れる。
②試験問題を読むのに疲れるし、問題数も結構あるので疲れる。このあたりについては大体どの体験談でも触れられています。ただ、単語から類推される機能イメージとかが英語ネイティブの人であれば多少違ってくるのかもしれず、この記事読んでる人は関係ないかもしれませんが日本のエンジニアにとってハードルを少し上げているのかもしれません。
試験にあたって利用した有料の試験対策
経験談によれば、メジャーなものはUdemyのハンズオン講座、黒本、AWS WEB問題集の3つです。今回はUdemyのハンズオン講座を購入して取り組んでみました。この時点でテスト代も含めて20000円ほど。まあこんなもんかなと。
勉強の進めかた(序盤)
AWSはとにかくサービスの数が多いので、全部について覚えるのは無理なわけですが、試験に出るのはあくまでも主要な機能とセキュリティ・コスト的に正しい使い方(ベストプラクティス)なわけです。素人はまずそのあたりが絞りこめず黒本を片手に途方に暮れるのですが、Udemyのハンズオンはそのあたりをちゃんと順序立てて重要な機能に絞って説明してくれるのです...。と言いたかったけど、長いよ!!1.5倍で聞いてもメチャクチャ時間かかるぞ!20時間って書いてあるけどハンズオンってそのままの時間では進まないし、1.5倍だけに資料進むのが早くてメモが追い付かない(等速で見ればいいじゃんとは言わないでください)ただ、講習で話していることはタメになることが多かったし、もともとある動画に手を加えて日々情報を最新化してくれているので、書籍の参考書にはないメリットを感じることができました。(後述の模擬試験も誤字が結構あったのですが、評価コメントで指摘したらちゃんと対応してくれました。)
直前の試験対策
ハンズオンに関してはおよそ6割くらいやった状態で、試験日が迫ってきたので、あとはハンズオン講座におまけでついているテストをスマホで何回も繰り返して覚えました。見直しした際に解説がついているので親切ですが、たまたま正解したやつだと解説読めないのがちょっと不満かなと。問題数はそれほど多くないので正直何回か繰り返すうちに答えを暗記してしまいます。それでも極力問題を読むようには心掛けました。初回は65問の試験やるのに1時間以上はかかるので、結構疲れます。
試験(1回目) 2020/6/28
というわけで第一回目の試験です。正直あんまり受かる気はしなかったのですが、まぐれで1発合格もあるんじゃないの?って気持ちは多少ありました。
結果は「不合格」(まあ3回受けたってタイトルに書いてますし...)
問題は勉強したところ以外で多く出てきました。ロードバランサとか暗号化、パフォーマンスの最適化について正しいものはどれか、とか聞かれましたが、そもそもそんなのどうすればいいのかなんて聞いてないよ!(逆ギレ)この辺は暗中模索で自信ないまま選択しています。
翌日来た得点を見ると、1000点満点の660点(5問不足)でした。まあまあなのか....?反省と対策
試験受けた感想ですが、やはり問題文に対する慣れが圧倒的に足りないなというのは実感としてありました。もう一つ、ロードバランサとかネットワークセキュリティに関しては業務経験もないし、Udemyの試験対策でもそれほどカバーしていないのでわからないところが多かったです。この辺については公式資料であるホワイトペーパーやブラックベルトを見た方がいいのかもしれません。あと、試験対策をする公式動画もあったのですが、すべて英語だったので挫折しました。(これについては合格後に活用方法見つけたので時間あれば記事にしてみます)勉強に関してお手軽にできる追加の試験対策が思い浮かばなかったのでUdemyの模擬試験問題集を追加でポチリました。(3600円)
試験(2回目) 2020/7/12
あまり長々と勉強したくなかったので記憶がフレッシュなうちにと臨んだ2回目の試験ですが、試験3日前に恐ろしいことに気づきました。前回受けたのがC01だったのですが、今回受験したのがC02だったのです。自分の不注意ですが...。まあUdemyでも大筋は変わってないというし、C01もうすぐ終わるからこっちでもいいか、と思って受験しました。まあ当然不合格だったわけですが。ただ、試験問題にそこまでの違いは感じませんでした。要は実力で落ちたと。
翌日来た得点を見ると、700/1000(2問不足)でした。採点の大きい問題が通ってればあと一問くらいで合格していたようなレベル。結構残念な感じですが、直前の勉強状況に関しては1回目の方が時間取れていたので、少ないなりに知識は少しずつついてきているのかなと思いました。今回の試験で16500円+3600円、AWS2か月の使用料が6000円で、総額46000円くらい、馬鹿にならない出費になってきました....。ちなみにAWSの使用料に関してはEC2の落とし忘れ等、テキトーにやっていたからです。マメにシャットダウンすれば100円くらいに抑えることも可能なはず。ただ、Udemyのハンズオン再開するときに前回やめたときと同じ環境をセットアップするのがめんどくさいんですよね。クラウドフォーメーション(※)とかうまく使えればいいのかもしれませんが。まとまった勉強時間取れる人なら一気にやってしまうことをお勧めします。
反省と対策(その2)
正直なところ、勉強以外のことが忙しすぎてあまり勉強時間が取れなかったこともありますが、そろそろ追い詰められてきたことで真面目に勉強することにしました。とはいってもモロモロの事情からあまりまとまった勉強時間取れないので、上述のUdemyの模擬試験問題集をスマホでポチポチ解いていくのがメインでした。全部合わせて390問(65問×6種類)もあるので答えを暗記するには自分の脳が少々キャパオーバーだったこともあり、間違えるところが都度違ったり苦労しました。間違えた問題に関しては都度ノートに取ったりした方が記憶が整理されていいかもしれませんね。それでも、試験直前にはだいたい6種類の模試で、どれも90%くらいは安定して取れるようになっていました。
試験(3回目)2020/8/23
今回に関しては万全とはいえないもののそれなりに勉強して、体調に関してもベストコンディションだったため、自信はそれなりにありました。ただ、問題を解いていて確信して答えを選択したものはそれほどなかったです。試験問題を読むストレスも3回目ということもあってほとんどかんじず。しっかりと読みつつ、問題で問われていることを理解できたと思います。
結果は....合格!!(タイトルに書いてあるので溜める必要はないですが)
正直ホッとはしましたが、自信もあったので、これで落ちたら次の勉強どうやろうかな~って思いながら試験やってたので左程感動はありませんでした。850くらい取れただろうという手ごたえを感じていました。ちなみにテストと勉強にかかったコストの総額は65000円くらいです。会社の補助もあるので8割くらいは返ってきますが、コスト以上に得たものは大きいのかなと思います。勉強したという証明にもなるし、最新の開発トレンドについて得られた知見も多かったですし。衝撃の採点結果と3回受験して分かったこと
しかし、翌日の採点結果を見たところ...732/1000!! ギリギリでした(笑)
分野ごとの評価を見る限り、やはりネットワークとか安全性のところに関してイマイチだったのは最後まで改善していませんでした。今更ですが、500点~600点とるのは固有名詞さえ知っていればそれほど難しくないですが、そこから点を上げていくにはしっかり知識を積み重ねていく必要があると思いました。試験の感想にも書いていますが、確信して答えを選べるものがあまりない状態だとせいぜい7割くらいしか取れなさそです。体験談によく出てる800点とか行くには45問くらいは確信して答えを選択できていないと届かないんじゃないかと思いますが、みんなかなりしっかり勉強していたのではないでしょうか。自分の場合は時間の制約もあって結局Udemyの講座一本でやりましたが、それだけで一発合格するには結構AWS触ってるかインフラのバックボーンがある人でないと厳しい気がします。ただ、何回かチャレンジする気があるのであればUdemyの試験対策2本プラス以下の2点やっておけば3回以内に受かる可能性は結構あるのではないかと思いました。
①試験問題をよく読む。特に但し書きに注目。(コストが何とか、とか顧客の要望が何とか)
②苦手箇所は公式資料で補足する。(インフラ未経験の人は、ロードバランサ、ネットワークACL、セキュリティグループ、各サービスの暗号化、クラウド移行に関する資料だけでも最低限読み込む)資格を取って思うこと
試験勉強は想像以上に大変でしたし、AWS自身が猛烈なスピードで進化しているので、資格更新するころには今持ってる知識はかなりの部分が不要になってきそうではあります。ただ、クラウドは官公庁でも導入事例出てきていますし、これからさらに伸びる業界であるのは間違いないので、技術者がどんどん増えて日本のクラウド業界が発展することを夙に期待していますし、自分の投稿が微力ながらも資格試験にチャレンジしようとしているけど、その一歩が踏み出せない方の背中を一押しすることができればと思っています。
自分は当面仕事でAWSに触る機会がなさそうなので、このまま座学でAWS SAPに挑戦してみようと思います。最後まで読んでいただき本当にありがとうございました。
- 投稿日:2020-09-22T17:33:04+09:00
【axios+SAM+API Gateway】localhostからapiを叩けるようになるために苦労した話 (2/3)ローカルから先程作成した`API Gateway`の`GET`メソッドを叩く
はじめに
本稿は下記流れに沿って、axios+SAM+API Gatewayを利用して、
GET
及びPOST
メソッドのAPIを叩けるところまでを目標としています。
SAM
を利用して、API Gateway
及びlambda
を構築- ローカルから先程作成した
API Gateway
のGET
メソッドを叩く- ローカルから先程作成した
API Gateway
のPOST
メソッドを叩く前回は
SAM
を利用して、API Gateway
及びlambda
を構築し、作成したAPIに対してcurl
コマンドを利用し叩けるところまでを検証しました。
今回は、「ローカルから先程作成したAPI Gateway
のGET
メソッドを叩く」ということを試していきたいと思います。2. ローカルから先程作成した
API Gateway
のGET
メソッドを叩くlocalhostを起動し、先程のURLを叩いてみます。
デモ用のソースは以下としました(実処理部分のみ)。import React, {Component} from 'react'; // import ReactDOM from 'react-dom'; import axios from 'axios'; class App extends Component { constructor(props){ super(props); this.state = { 'appMessage': 'hello,app' }; this.getApi = this.getApi.bind(this); } instance = axios.create({ baseURL: 'https://{メソッドのURL}//Prod' }); getApi(){ this.instance.get('/hello') .then((response) => { this.setState({ 'appMessage': response.data['message'] }) }) .catch(() => { this.setState({ 'appMessage': 'faild get message from button' }) }) } render(){ return( <div> <div>{this.state.appMessage}</div> <input type='button' onClick={this.getApi} value="button" /> </div> ) } } export default App;Access to XMLHttpRequest at 'https://{メソッドのURL}//Prod/hello' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.どうやらCORSに関する実装がちゃんとされてないことが原因で怒られたようです(参考にしたAWS公式ドキュメントはこちら)。
なのでresponseに以下のheaderを含むようにします。// app.py return { "statusCode": 200, 'headers': { 'Access-Control-Allow-Headers': 'Content-Type', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'OPTIONS,POST,GET' }, "body": json.dumps({ "message": "hello world", # "location": ip.text.replace("\n", "") }), }試しにresponse部分を確認すると、先程追加したheaderが含まれているのを確認できます。
原因部分をもう少し詳しく
(※こちらの記事が大変参考になりました!なんとなく CORS がわかる...はもう終わりにする。)
先述したとおり、今回の原因はCORSに関する実装がちゃんとされてなかったことです。
CORSとは、「Cross-Origin Resource Sharing」の略で、別のオリジン間でリソースを共有するためには、ちゃんと許可してあげようねというものだそうです。今回私は、
- 叩き元:localhost
- 叩き先:API Gateway
としたので、これらは当然ドメインが異なります。なのでAPIからのresponseにリソースの共有を許可する
'Access-Control-Allow-Origin': '*'
をheaderに追加する必要があったということですね。終わりに
今回は自分で作成したAPIに対し、アプリを介して叩いてみるということを検証しました。これまでCORSは言葉を知っている程度だったので今回みたいなことは考えたことがなかったです。そのため、「なんで
curl
で叩けたのに、アプリ経由だと叩けないの…?」とだいぶハマりました。
今回の経験を経て、「じゃあPOST
も同様のことを気をつける必要があるんだな!」と気をつけてたら、また別のところでハマりました…
それは次回で説明できればと思います。
- 投稿日:2020-09-22T17:08:59+09:00
クラウドの概念
【クラウドの概念】
ポートフォリオにAWSを本格的に組み込んでいこうと思っているので、
その予備知識としてクラウドについて簡単にまとめました。クラウドコンピューティング
インターネット上にアクセスして、物理的に見えないコンピュータを利用すること。
ユーザーがインフラやソフトウェアを持たなくても、インターネットを通じて、サービスを必要な時に必要な分だけ利用できる特徴がもつ。
○○aaS(as a Service) と呼ばれるようなクラウドコンピューティングサービスがいくつかある。
仮想化技術
仮想化技術とは、物理的なコンポーネントを、複数の論理的コンポーネントに分割して使用する技術である。
クラウドコンピューティングは、インターネット技術や仮想化技術が基本になっている。1台の物理的コンピュータを、あたかも何十台といったコンピュータがあるかのように、論理的に分割して、何十台といったコンピュータを共有する。
これによって、提供者と利用者のwin-win関係ができる。○○aaS(as a Service)の主要例
・IaaS(Infrastructure as a Service)
サーバー(インフラ)を提供するクラウドサービス・PaaS(Platform as a Service)
開発環境を提供するクラウドサービス・SaaS(Software as a Service)
ソフトウェアを提供するクラウドサービス余談
Git,GitHubを使用せずにSVNを使用しているようなレガシーSIerでもAWSは使用されています。(私個人の範囲でのお話です。)
クラウドの知識、主にAWSの知識はITの世界では既に常識になっていると思います。
今後も引き続き、業務内外でしっかりAWSを学んでいきます。
- 投稿日:2020-09-22T16:46:16+09:00
terraformでEKS上にオンラインシステムを構築してみた
はじめに
最近マルチクラウドへの需要が増えている気がします。
パブリッククラウド毎のサービス特性やビジネス判断によって、その時々での最適解を選ぶ必要性に迫られている今日この頃。。今の現場ではAWS ECS上でコンテナオーケストレーションを行っていますが、既存システムを他クラウドへ移行する際のポータビリティを考えると、ECSは完全にAWSロックインだし、Kubernetes Cluster管理だけ任せることができればEKS、GKE、AKSのように他クラウドへの移行も簡単になるのかなと漠然と考えていました。
個人的にもKubernetes Service系のマネージドサービスを使ってみたいということもあり、今回はEKSを使って簡単なオンラインシステムを構築してみたので、手順と所感を残していきます。アーキテクチャ
- インターネットからの通信をALBで受けて、バックエンドのnginxに接続する。
- 名前解決にはexternal-dnsコンテナを利用する。
フォルダ構成
terraform │ eks.tf │ helm_external_dns.tf │ helm_nginx.tf │ iam_service_account.tf │ └─charts ├─external_dns │ │ Chart.yml │ │ values.yml │ │ │ └─templates │ external-dns.yml │ └─online_app │ Chart.yml │ values.yml │ └─templates nginx-deployment.yml nginx-service.yml構築手順
EKS ClusterとWorker Nodeのデプロイ
terraform公式の eksモジュールを利用。公式なだけあってよく作りこまれています。
work_groupsの設定だけカスタマイズするくらいで、あとは特に変更せずに使えました。eks.tfmodule "online_app" { source = "terraform-aws-modules/eks/aws" version = "v12.2.0" cluster_name = "online-app" cluster_version = "1.17" // publicサブネットを含めないとexternal ALBが作成されないので注意 subnets = concat(data.aws_subnet.private_subnets.*.id, data.aws_subnet.public_subnets.*.id) vpc_id = data.aws_vpc.vpc.id worker_groups = [ { instance_type = "t3.medium" asg_max_size = 1 // worker nodeにssh接続したい場合に指定 key_name = "dummy" // ssh接続元IPを絞りたいなど、特殊な通信要件がある場合に指定 additional_security_group_ids = [sg-xxxx] subnets = data.aws_subnet.private_subnets.*.id } ] }terraform applyを実行すればEKSクラスタ構築は完了です。構築に15分ほどかかるので気長に待ちます。
k8nのコード準備
ECSではterraformコードとして表現していたコンテナオーケストレーションのコードを、EKSではKubernetesのyamlファイルに記述する必要があります。
LoadBalancerのクラウド毎の個別設定はmetadata->annotationsで設定していきます。
LoadBalancer servicecharts/templates/nginx-deployment.ymlapiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabels: app: nginx replicas: 2 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80kubernetes単独だと変数化ができないので、helmを利用して変数化しています。
charts/templates/nginx-service.ymlapiVersion: apps/v1 kind: Service metadata: name: nginx-service labels: app: nginx annotations: service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http service.beta.kubernetes.io/aws-load-balancer-ssl-cert: {{ .Values.loadBalancer.sslCert }} service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" external-dns.alpha.kubernetes.io/hostname: {{ .Values.loadBalancer.hostname }} spec: selector: app: nginx ports: - name: https port: 443 targetPort: 80 protocol: TCP type: LoadBalancer作成されたLoad Balancerの名前解決はどうすればいいのか悩んでいたところ、externalDNSというAuto Discovery用のサービスがあるとのこと。metadata->annotationsに
external-dns.alpha.kubernetes.io/hostname
を指定することで、Serviceに到達するためのRoute 53 recordを自動で作成してくれます。Kubernetes yamlはexternalDNSのサイトに記載されているテンプレートを元に、変数化しました。external-dns.ymlapiVersion: v1 kind: ServiceAccount metadata: name: external-dns annotations: eks.amazonaws.com/role-arn: {{ .Values.eks.serviceAccountRoleArn }} --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata: name: external-dns rules: - apiGroups: [""] resources: ["services","endpoints","pods"] verbs: ["get","watch","list"] - apiGroups: ["extensions","networking.k8s.io"] resources: ["ingresses"] verbs: ["get","watch","list"] - apiGroups: [""] resources: ["nodes"] verbs: ["list","watch"] --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: external-dns-viewer roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: external-dns subjects: - kind: ServiceAccount name: external-dns namespace: default --- apiVersion: apps/v1 kind: Deployment metadata: name: external-dns spec: strategy: type: Recreate selector: matchLabels: app: external-dns template: metadata: labels: app: external-dns spec: serviceAccountName: external-dns containers: - name: external-dns image: k8s.gcr.io/external-dns/external-dns:v0.7.3 args: - --source=service - --source=ingress - --domain-filter={{ .Values.externalDns.domainFilter }} - --provider=aws - --aws-zone-type={{ .Values.externalDns.zoneType }} - --registry=txt - --txt-owner-id=my-hostedzone-identifier securityContext: fsGroup: {{ .Values.externalDns.securityContext.fsGroup }}externalDNSコンテナにRoute53の操作を許可するために、Service Accountとして利用するIAM Roleを作成して、EKSのOpenID Connect Providerと連携させます。
こちらのページを参考に、terraformコードを作成しました。iam_service_account.tfdata "aws_iam_policy_document" "eks_assume_role_policy" { statement { effect = "Allow" principals { type = "Federated" identifiers = [aws_iam_openid_connect_provider.eks.arn] } actions = ["sts:AssumeRoleWithWebIdentity"] condition { test = "StringEquals" variable = "${aws_iam_openid_connect_provider.eks.url}:aud" values = ["sts.amazonaws.com"] } } } data aws_iam_policy_document AllowExternalDNSUpdates { statement { effect = "Allow" actions = [ "route53:ChangeResourceRecordSets", ] resources = [ "arn:aws:route53:::hostedzone/*", ] } statement { effect = "Allow" actions = [ "route53:ListHostedZones", "route53:ListResourceRecordSets" ] resources = [ "*", ] } } resource aws_iam_role_policy cluster_AllowExternalDNSUpdates { name = "AllowExternalDNSUpdates" role = aws_iam_role.external_dns_cluster_AllowExternalDNSUpdates.id policy = data.aws_iam_policy_document.AllowExternalDNSUpdates.json } resource aws_iam_role external_dns_cluster_AllowExternalDNSUpdates { name = "${local.name}-external-dns" assume_role_policy = data.aws_iam_policy_document.eks_assume_role_policy.json } resource aws_iam_openid_connect_provider eks { url = module.online_app.cluster_oidc_issuer_url client_id_list = [ "sts.amazonaws.com" ] thumbprint_list = ["9e99a48a9960b14926bb7f3b02e22da2b0ab7280"] }helmコードの準備
AWSリソースとKubernetesコンテナの準備が整ったので、コンテナをデプロイするためのコードを作ります。helmをそのまま使ってもデプロイできますが、今回はterraform Helm providerを利用しました。
terraform Helm providerを使ってみて、下記の点で素晴らしいと感じました。
1. terraformで構築したAWSの情報を共有できるため、helm実行時に渡す変数をaws-cliなどを使って取得する必要がない。
2. helm chartsのデプロイ状態がterraform stateとして管理できる。Helmのコードとterraform Helm Providerのコードは以下の通りです。
charts/nginx/Charts.ymlapiVersion: v1 appVersion: "1.0" description: nginx helm chart for Kubernetes name: nginx version: 1.0.0charts/nginx/values.ymlloadBalancer: sslCert: hostname:helm_nginx.tfprovider "helm" { version = "~> 1.3.0" kubernetes { config_path = module.online_app.kubeconfig_filename } } resource "helm_release" "nginx" { name = "nginx-chart" chart = "./charts/nginx" // force_updateをtrueにすることで、helm chartに差分があったら更新する。 force_update = true set { name = "loadBalancer.sslCert" value = data.aws_acm_certificate.this.arn } set { name = "loadBalancer.hostname" value = "nginx.${data.aws_route53_zone.this.name}" } }同様にexternalDNSのデプロイコードも作成していきます。
charts/external_dns/Charts.ymlapiVersion: v1 appVersion: "1.0" description: external-dns chart for Kubernetes name: external-dns version: 1.0.0charts/external_dns/values.ymleks: serviceAccountRoleArn: externalDns: domainFilter: zoneType: public securityContext: fsGroup: 65534helm_external_dns.tfresource "helm_release" "external_dns" { name = "external-dns-chart" chart = "./charts/external_dns" force_update = true set { name = "eks.serviceAccountRoleArn" value = aws_iam_role.external_dns_cluster_AllowExternalDNSUpdates.arn } set { name = "externalDns.domainFilter" value = data.aws_route53_zone.this.name } }動作確認
コードの準備ができたら再度terraform applyを実行します。
うまく動いているようならexternal-dns.alpha.kubernetes.io/hostname
で指定したホストに接続することで、nginxの画面が表示されます。
また、externalDNS podのログを見るとちゃんとRoute 53へのUPSERTに成功していることが確認できました。
kubectl logs external-dns-xxx # please use your pod id
EKSを使ってみて所感
EKSクラスタ作成に時間がかかる。
コスト節約のために毎回terraformでVPC周りから検証環境を作り直しているが、ECSと比べてEKSはクラスタ作成に時間がかかる。検証するたびに毎回15分以上待つのはツライ。。ECSよりもポータビリティが上がった (気がする…)
Kubernetes yamlに付与するmetadataの種類によってマルチクラウドに対応可能。
ECSでは必要なAWSリソースを自分で構築しなければいけなかったが、EKSではmetadataを付与することでALBが自動で作成されたり、DNS recordが作られたりと、特定クラウドを意識させない点はよい。リソースの統合管理
ECSはAWS管理コンソール上で、コンテナインスタンスのリソース使用状況、各タスクの実行状態やサービスタスク起動数など確認できる統合管理画面が提供されているが、それに比べるとEKSの管理画面は情報が不足していると感じた。Kubernetesの統合管理を実現するための仕組みを検討する必要がある。
- 投稿日:2020-09-22T16:14:41+09:00
AWS Route 53 Resolver & Transit Gateway ~ demo
AWS Route 53 Resolver と Transit Gateway を利用して、複数の AWS VPC が異なる AWS アカウントで管理されている場合、VPC 間の名前解決には Amazon Route 53 Resolver が便利です。
1.CloudFormationによるVPC,Transit Gatewayの作成
リージョン vpc リージョン1 vpc-A リージョン2 vpc-BC vpc-A{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Hands-On AWS Transit Gateway with Amazon Route 53 Resolver: Creates a Virginia VPC-A and Transit Gateway then check your TGW id for the other TGW Attachements.", "Outputs": { "VirginiaTGWId": { "Value": { "Ref": "VirginiaTGW" } }, "vpcAId": { "Value": { "Ref": "VPCA" } }, "vpcACIDRRange": { "Value": { "Ref": "vpcACIDRRange" } }, "vpcAInstanceId": { "Value": { "Ref": "vpcAInstance" } } }, "Parameters": { "Ec2ImageId": { "Type": "AWS::SSM::Parameter::Value<String>", "Default": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2" }, "vpcACIDRRange": { "Description": "The IP address range for your new VPC-A.", "Type": "String", "MinLength": "9", "MaxLength": "18", "Default": "192.168.0.0/16", "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." }, "vpcAEC2PublicSubnetCIDRRange": { "Description": "The IP address range for a subnet in VPC-A.", "Type": "String", "MinLength": "9", "MaxLength": "18", "Default": "192.168.1.0/24", "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." }, "vpcAEC2PrivateSubnetCIDRRange": { "Description": "The IP address range for a subnet in VPC-A.", "Type": "String", "MinLength": "9", "MaxLength": "18", "Default": "192.168.0.0/24", "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." } }, "Resources": { "AttachGateway": { "Type": "AWS::EC2::VPCGatewayAttachment", "Properties": { "VpcId": { "Ref": "VPCA" }, "InternetGatewayId": { "Ref": "myInternetGateway" } } }, "EIP": { "Type": "AWS::EC2::EIP", "Properties": { "Domain": "VPCA" } }, "IAMIP3UK0E": { "Type": "AWS::IAM::InstanceProfile", "Properties": { "Path": "/", "Roles": [ { "Ref": "IAMR3XJT6" } ] } }, "IAMR3XJT6": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "ec2.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] }, "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" ], "Path": "/" } }, "myInternetGateway": { "Type": "AWS::EC2::InternetGateway" }, "NAT": { "Type": "AWS::EC2::NatGateway", "Properties": { "AllocationId": { "Fn::GetAtt": [ "EIP", "AllocationId" ] }, "SubnetId": { "Ref": "vpcAPublicSubnet" }, "Tags": [ { "Key": "Name", "Value": "VPCA-NatGw" } ] } }, "PrivateRoute": { "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { "Ref": "vpcAPrivateRouteTable" }, "DestinationCidrBlock": "0.0.0.0/0", "NatGatewayId": { "Ref": "NAT" } } }, "PrivateRoute10": { "Type": "AWS::EC2::Route", "DependsOn": "VirginiaTGWvpcAattach", "Properties": { "RouteTableId": { "Ref": "vpcAPrivateRouteTable" }, "DestinationCidrBlock": "10.0.0.0/16", "TransitGatewayId": { "Ref": "VirginiaTGW" } } }, "PrivateRoute172": { "Type": "AWS::EC2::Route", "DependsOn": "VirginiaTGWvpcAattach", "Properties": { "RouteTableId": { "Ref": "vpcAPrivateRouteTable" }, "DestinationCidrBlock": "172.16.0.0/16", "TransitGatewayId": { "Ref": "VirginiaTGW" } } }, "PrivateSubnetRouteTableAssociation": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "SubnetId": { "Ref": "vpcAPrivateSubnet" }, "RouteTableId": { "Ref": "vpcAPrivateRouteTable" } } }, "PublicSubnetRouteTableAssociation": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "SubnetId": { "Ref": "vpcAPublicSubnet" }, "RouteTableId": { "Ref": "vpcAPublicRouteTable" } } }, "Route": { "Type": "AWS::EC2::Route", "DependsOn": "AttachGateway", "Properties": { "RouteTableId": { "Ref": "vpcAPublicRouteTable" }, "DestinationCidrBlock": "0.0.0.0/0", "GatewayId": { "Ref": "myInternetGateway" } } }, "VirginiaTGW": { "Type": "AWS::EC2::TransitGateway", "Properties": { "AmazonSideAsn": "64512", "AutoAcceptSharedAttachments": "enable", "DefaultRouteTableAssociation": "enable", "DefaultRouteTablePropagation": "enable", "Description": "Virginia-TGW-ASN-64512", "DnsSupport": "enable", "Tags": [ { "Key": "Name", "Value": "VirginiaTGW" } ], "VpnEcmpSupport": "disable" } }, "VirginiaTGWvpcAattach": { "Type": "AWS::EC2::TransitGatewayAttachment", "Properties": { "SubnetIds": [ { "Ref": "vpcAPrivateSubnet" } ], "Tags": [ { "Key": "Name", "Value": "Virginia-TGW-VPC-A-Attachement" } ], "TransitGatewayId": { "Ref": "VirginiaTGW" }, "VpcId": { "Ref": "VPCA" } } }, "VPCA": { "Type": "AWS::EC2::VPC", "Properties": { "CidrBlock": { "Ref": "vpcACIDRRange" }, "EnableDnsSupport": true, "EnableDnsHostnames": true, "InstanceTenancy": "default", "Tags": [ { "Key": "Name", "Value": "VPCA" } ] } }, "vpcAEC2SecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Public instance security group", "VpcId": { "Ref": "VPCA" }, "SecurityGroupIngress": [ { "IpProtocol": "icmp", "FromPort": 8, "ToPort": -1, "CidrIp": "0.0.0.0/0" }, { "IpProtocol": "udp", "FromPort": "33434", "ToPort": "33523", "CidrIp": "0.0.0.0/0" } ] } }, "vpcAInstance": { "Type": "AWS::EC2::Instance", "Properties": { "IamInstanceProfile": { "Ref": "IAMIP3UK0E" }, "ImageId": { "Ref": "Ec2ImageId" }, "InstanceType": "t2.micro", "PrivateIpAddress": "192.168.0.10", "SecurityGroupIds": [ { "Ref": "vpcAEC2SecurityGroup" } ], "SubnetId": { "Ref": "vpcAPrivateSubnet" }, "Tags": [ { "Key": "Name", "Value": "vpcAInstance" } ] } }, "vpcAPrivateRouteTable": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { "Ref": "VPCA" }, "Tags": [ { "Key": "Name", "Value": "vpcAPrivateRouteTable" } ] } }, "vpcAPrivateSubnet": { "Type": "AWS::EC2::Subnet", "Properties": { "CidrBlock": { "Ref": "vpcAEC2PrivateSubnetCIDRRange" }, "VpcId": { "Ref": "VPCA" }, "AvailabilityZone": "us-east-1a", "Tags": [ { "Key": "Name", "Value": "vpcAPrivateSubnet" } ] } }, "vpcAPublicRouteTable": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { "Ref": "VPCA" }, "Tags": [ { "Key": "Name", "Value": "vpcAPublicRouteTable" } ] } }, "vpcAPublicSubnet": { "Type": "AWS::EC2::Subnet", "Properties": { "CidrBlock": { "Ref": "vpcAEC2PublicSubnetCIDRRange" }, "VpcId": { "Ref": "VPCA" }, "AvailabilityZone": "us-east-1a", "Tags": [ { "Key": "Name", "Value": "vpcAPublicSubnet" } ] } } } }VPC-BC{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Hands-On AWS Transit Gateway with Amazon Route 53 Resolver: Creates Oregon VPC-B/C and then creates a Transit Gateway, Attache with an existing VPC that you specify.", "Outputs": { "vpcBInstanceId": { "Value": { "Ref": "vpcBInstance" } }, "vpcCInstanceId": { "Value": { "Ref": "vpcCInstance" } }, "vpcCId": { "Value": { "Ref": "VPCC" } } }, "Parameters": { "Ec2ImageId": { "Type": "AWS::SSM::Parameter::Value<String>", "Default": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2" }, "vpcBCIDRRange": { "Description": "The IP address range for your new VPC-B.", "Type": "String", "MinLength": "9", "MaxLength": "18", "Default": "10.0.0.0/16", "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." }, "vpcBEC2PublicSubnetCIDRRange": { "Description": "The IP address range for a subnet in VPC-B.", "Type": "String", "MinLength": "9", "MaxLength": "18", "Default": "10.0.1.0/24", "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." }, "vpcBEC2PrivateSubnetCIDRRange": { "Description": "The IP address range for a subnet in VPC-B.", "Type": "String", "MinLength": "9", "MaxLength": "18", "Default": "10.0.0.0/24", "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." }, "vpcCCIDRRange": { "Description": "The IP address range for your new VPC-C.", "Type": "String", "MinLength": "9", "MaxLength": "18", "Default": "172.16.0.0/16", "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." }, "vpcCEC2PublicSubnetCIDRRange": { "Description": "The IP address range for a subnet in VPC-C.", "Type": "String", "MinLength": "9", "MaxLength": "18", "Default": "172.16.1.0/24", "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." }, "vpcCEC2PrivateSubnetCIDRRange": { "Description": "The IP address range for a subnet in VPC-C.", "Type": "String", "MinLength": "9", "MaxLength": "18", "Default": "172.16.0.0/24", "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." } }, "Resources": { "EIPtoVpcBNat": { "Type": "AWS::EC2::EIP", "Properties": { "Domain": "VPCB" } }, "EIPtoVpcCNat": { "Type": "AWS::EC2::EIP", "Properties": { "Domain": "VPCB" } }, "IAMIP3UK0F": { "Type": "AWS::IAM::InstanceProfile", "Properties": { "Path": "/", "Roles": [ { "Ref": "IAMR3XJT7" } ] } }, "IAMR3XJT7": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "ec2.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] }, "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" ], "Path": "/" } }, "OregonTGW": { "Type": "AWS::EC2::TransitGateway", "Properties": { "AmazonSideAsn": "64513", "AutoAcceptSharedAttachments": "enable", "DefaultRouteTableAssociation": "enable", "DefaultRouteTablePropagation": "enable", "Description": "Oregon-TGW-ASN-64513", "DnsSupport": "enable", "Tags": [ { "Key": "Name", "Value": "OregonTGW" } ], "VpnEcmpSupport": "disable" } }, "OregonTGWvpcBattach": { "Type": "AWS::EC2::TransitGatewayAttachment", "Properties": { "SubnetIds": [ { "Ref": "vpcBPrivateSubnet" } ], "Tags": [ { "Key": "Name", "Value": "Oregon-TGW-VPC-B-Attachement" } ], "TransitGatewayId": { "Ref": "OregonTGW" }, "VpcId": { "Ref": "VPCB" } } }, "OregonTGWvpcCattach": { "Type": "AWS::EC2::TransitGatewayAttachment", "Properties": { "SubnetIds": [ { "Ref": "vpcCPrivateSubnet" } ], "Tags": [ { "Key": "Name", "Value": "Oregon-TGW-VPC-C-Attachement" } ], "TransitGatewayId": { "Ref": "OregonTGW" }, "VpcId": { "Ref": "VPCC" } } }, "PrivateSubnetBRouteTableAssociation": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "SubnetId": { "Ref": "vpcBPrivateSubnet" }, "RouteTableId": { "Ref": "vpcBPrivateRouteTable" } } }, "PrivateSubnetCRouteTableAssociation": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "SubnetId": { "Ref": "vpcCPrivateSubnet" }, "RouteTableId": { "Ref": "vpcCPrivateRouteTable" } } }, "PublicRouteVPCB": { "Type": "AWS::EC2::Route", "DependsOn": "vpcBAttachGateway", "Properties": { "RouteTableId": { "Ref": "vpcBPublicRouteTable" }, "DestinationCidrBlock": "0.0.0.0/0", "GatewayId": { "Ref": "vpcBInternetGateway" } } }, "PublicRouteVPCC": { "Type": "AWS::EC2::Route", "DependsOn": "vpcCAttachGateway", "Properties": { "RouteTableId": { "Ref": "vpcCPublicRouteTable" }, "DestinationCidrBlock": "0.0.0.0/0", "GatewayId": { "Ref": "vpcCInternetGateway" } } }, "PublicSubnetBRouteTableAssociation": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "SubnetId": { "Ref": "vpcBPublicSubnet" }, "RouteTableId": { "Ref": "vpcBPublicRouteTable" } } }, "PublicSubnetCRouteTableAssociation": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "SubnetId": { "Ref": "vpcCPublicSubnet" }, "RouteTableId": { "Ref": "vpcCPublicRouteTable" } } }, "VPCB": { "Type": "AWS::EC2::VPC", "Properties": { "CidrBlock": { "Ref": "vpcBCIDRRange" }, "EnableDnsSupport": true, "EnableDnsHostnames": true, "InstanceTenancy": "default", "Tags": [ { "Key": "Name", "Value": "VPCB" } ] } }, "vpcBAttachGateway": { "Type": "AWS::EC2::VPCGatewayAttachment", "Properties": { "VpcId": { "Ref": "VPCB" }, "InternetGatewayId": { "Ref": "vpcBInternetGateway" } } }, "vpcBEC2SecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Public instance security group", "VpcId": { "Ref": "VPCB" }, "SecurityGroupIngress": [ { "IpProtocol": "icmp", "FromPort": 8, "ToPort": -1, "CidrIp": "0.0.0.0/0" }, { "IpProtocol": "udp", "FromPort": "33434", "ToPort": "33523", "CidrIp": "0.0.0.0/0" }, { "IpProtocol": "udp", "FromPort": "53", "ToPort": "53", "CidrIp": "0.0.0.0/0" }, { "IpProtocol": "tcp", "FromPort": "53", "ToPort": "53", "CidrIp": "0.0.0.0/0" } ] } }, "vpcBInstance": { "Type": "AWS::EC2::Instance", "Properties": { "IamInstanceProfile": { "Ref": "IAMIP3UK0F" }, "ImageId": { "Ref": "Ec2ImageId" }, "InstanceType": "t2.micro", "PrivateIpAddress": "10.0.0.10", "SecurityGroupIds": [ { "Ref": "vpcBEC2SecurityGroup" } ], "SubnetId": { "Ref": "vpcBPrivateSubnet" }, "Tags": [ { "Key": "Name", "Value": "vpcBInstance" } ] } }, "vpcBInternetGateway": { "Type": "AWS::EC2::InternetGateway" }, "vpcBNAT": { "Type": "AWS::EC2::NatGateway", "Properties": { "AllocationId": { "Fn::GetAtt": [ "EIPtoVpcBNat", "AllocationId" ] }, "SubnetId": { "Ref": "vpcBPublicSubnet" }, "Tags": [ { "Key": "Name", "Value": "VPCB-NatGw" } ] } }, "vpcBPrivateRoute": { "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { "Ref": "vpcBPrivateRouteTable" }, "DestinationCidrBlock": "0.0.0.0/0", "NatGatewayId": { "Ref": "vpcBNAT" } } }, "vpcBPrivateRoute172": { "Type": "AWS::EC2::Route", "DependsOn": "OregonTGWvpcBattach", "Properties": { "RouteTableId": { "Ref": "vpcBPrivateRouteTable" }, "DestinationCidrBlock": "172.16.0.0/16", "TransitGatewayId": { "Ref": "OregonTGW" } } }, "vpcBPrivateRoute192": { "Type": "AWS::EC2::Route", "DependsOn": "OregonTGWvpcBattach", "Properties": { "RouteTableId": { "Ref": "vpcBPrivateRouteTable" }, "DestinationCidrBlock": "192.168.0.0/16", "TransitGatewayId": { "Ref": "OregonTGW" } } }, "vpcBPrivateRouteTable": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { "Ref": "VPCB" }, "Tags": [ { "Key": "Name", "Value": "vpcBPrivateRouteTable" } ] } }, "vpcBPrivateSubnet": { "Type": "AWS::EC2::Subnet", "Properties": { "VpcId": { "Ref": "VPCB" }, "CidrBlock": { "Ref": "vpcBEC2PrivateSubnetCIDRRange" }, "AvailabilityZone": "us-west-2a", "Tags": [ { "Key": "Name", "Value": "vpcBPrivateSubnet" } ] } }, "vpcBPublicRouteTable": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { "Ref": "VPCB" }, "Tags": [ { "Key": "Name", "Value": "vpcBPublicRouteTable" } ] } }, "vpcBPublicSubnet": { "Type": "AWS::EC2::Subnet", "Properties": { "VpcId": { "Ref": "VPCB" }, "CidrBlock": { "Ref": "vpcBEC2PublicSubnetCIDRRange" }, "AvailabilityZone": "us-west-2a", "Tags": [ { "Key": "Name", "Value": "vpcBPublicSubnet" } ] } }, "VPCC": { "Type": "AWS::EC2::VPC", "Properties": { "CidrBlock": { "Ref": "vpcCCIDRRange" }, "EnableDnsSupport": true, "EnableDnsHostnames": true, "InstanceTenancy": "default", "Tags": [ { "Key": "Name", "Value": "VPCC" } ] } }, "vpcCAttachGateway": { "Type": "AWS::EC2::VPCGatewayAttachment", "Properties": { "VpcId": { "Ref": "VPCC" }, "InternetGatewayId": { "Ref": "vpcCInternetGateway" } } }, "vpcCEC2SecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Public instance security group", "VpcId": { "Ref": "VPCC" }, "SecurityGroupIngress": [ { "IpProtocol": "icmp", "FromPort": 8, "ToPort": -1, "CidrIp": "0.0.0.0/0" }, { "IpProtocol": "udp", "FromPort": "33434", "ToPort": "33523", "CidrIp": "0.0.0.0/0" }, { "IpProtocol": "udp", "FromPort": "53", "ToPort": "53", "CidrIp": "0.0.0.0/0" }, { "IpProtocol": "tcp", "FromPort": "53", "ToPort": "53", "CidrIp": "0.0.0.0/0" } ] } }, "vpcCInstance": { "Type": "AWS::EC2::Instance", "Properties": { "IamInstanceProfile": { "Ref": "IAMIP3UK0F" }, "ImageId": { "Ref": "Ec2ImageId" }, "InstanceType": "t2.micro", "PrivateIpAddress": "172.16.0.10", "SecurityGroupIds": [ { "Ref": "vpcCEC2SecurityGroup" } ], "SubnetId": { "Ref": "vpcCPrivateSubnet" }, "Tags": [ { "Key": "Name", "Value": "vpcCInstance" } ] } }, "vpcCInternetGateway": { "Type": "AWS::EC2::InternetGateway" }, "vpcCNAT": { "Type": "AWS::EC2::NatGateway", "Properties": { "AllocationId": { "Fn::GetAtt": [ "EIPtoVpcCNat", "AllocationId" ] }, "SubnetId": { "Ref": "vpcCPublicSubnet" }, "Tags": [ { "Key": "Name", "Value": "VPCC-NatGw" } ] } }, "vpcCPrivateRoute": { "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { "Ref": "vpcCPrivateRouteTable" }, "DestinationCidrBlock": "0.0.0.0/0", "NatGatewayId": { "Ref": "vpcCNAT" } } }, "vpcCPrivateRoute10": { "Type": "AWS::EC2::Route", "DependsOn": "OregonTGWvpcCattach", "Properties": { "RouteTableId": { "Ref": "vpcCPrivateRouteTable" }, "DestinationCidrBlock": "10.0.0.0/16", "TransitGatewayId": { "Ref": "OregonTGW" } } }, "vpcCPrivateRoute192": { "Type": "AWS::EC2::Route", "DependsOn": "OregonTGWvpcCattach", "Properties": { "RouteTableId": { "Ref": "vpcCPrivateRouteTable" }, "DestinationCidrBlock": "192.168.0.0/16", "TransitGatewayId": { "Ref": "OregonTGW" } } }, "vpcCPrivateRouteTable": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { "Ref": "VPCC" }, "Tags": [ { "Key": "Name", "Value": "vpcCPrivateRouteTable" } ] } }, "vpcCPrivateSubnet": { "Type": "AWS::EC2::Subnet", "Properties": { "VpcId": { "Ref": "VPCC" }, "CidrBlock": { "Ref": "vpcCEC2PrivateSubnetCIDRRange" }, "AvailabilityZone": "us-west-2a", "Tags": [ { "Key": "Name", "Value": "vpcCPrivateSubnet" } ] } }, "vpcCPublicRouteTable": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { "Ref": "VPCC" }, "Tags": [ { "Key": "Name", "Value": "vpcCPublicRouteTable" } ] } }, "vpcCPublicSubnet": { "Type": "AWS::EC2::Subnet", "Properties": { "VpcId": { "Ref": "VPCC" }, "CidrBlock": { "Ref": "vpcCEC2PublicSubnetCIDRRange" }, "AvailabilityZone": "us-west-2a", "Tags": [ { "Key": "Name", "Value": "vpcCPublicSubnet" } ] } } } }2.2つ Transit Gatewayに対 し、リージョン間ピアリングを行う
「Create Transit Gateway 接続」から「Create Transit Gateway Attachment」
「Transit Gateway ID」を選択して、「Attachment type」には、「Peering Connection」を指定。
「Region」にvpcーAのもの、「Transit gateway (accepter)*」にvpc-AのTransit Gateway IDを入力。
vpcーAのリージョンに移動し、承認作業「Accept」を行う。(数分間要します。)
承認されたら、peer-attachmentのアタッチメントが表示された状態で 、右のAssociated route tableに表示されたTransit Gateway Route TableのIDを開き、VPC-B(10.0.0.0/16)とVPC-C(172.16.0.0/16)への静的経路を追加する。
※もう片方のリージョンでも同様にVPC-A(192.168.0.0/16)への静的経路を追加する。EC2にコンソール接続し、pingで疎通確認をしておく。
3.Route 53 プライベートホストゾーンとRoute 53 インバウンド Resolverの設定をする
ドメイン名:example.jp プライベートゾーンでホストを作成する。
次にレコードを「シンプルルーティング」で作成する。今回でいうとvpc-cのホストに作成することとなる。
vpc-cのEC2にログインし、名前解決できているか確認する。
sh-4.2$ dig test.example.jp. +short 172.16.0.10Route53でインバウンドエンドポイントを開き、エンドポイントを作成していく。
ステップ 1 エンドポイントの設定
インバウンドのみ:お使いのネットワークまたは別のVPCからVPCへのDNSクエリを許可するエンドポイントの設定。
ステップ 2 インバウンドエンドポイントの設定
ここでは、「vpc-c」がエンドポイントとなるため、vpc-cの情報を入力する。
IPアドレス#1
サブネット:vpcCPrivateSubnet
IPアドレス:自分で指定 172.16.0.5
IPアドレス#2
サブネット:vpcCPublicSubnet
IPアドレス:自分で指定 172.16.1.5
他の情報はデフォルトで作成を完了させる。
4.VPCで参照用DNSを変更する
最後にVPC-AとVPC-BにDHCPオプションセットを関連づけし、名前解決要求をVPC-CのRoute 53 Resolver Inbound Endpointへ振り向ける。
VPC-AとVPC-BにDHCPオプションセットをアタッチする。
各VPCから名前解決ができる事を確認します。
sh-4.2$ sudo service network restart Restarting network (via systemctl): [ OK ] sh-4.2$ cat /etc/resolv.conf options timeout:2 attempts:5 ; generated by /usr/sbin/dhclient-script nameserver 172.16.0.5 nameserver 172.16.1.5 sh-4.2$ test.example.co.jp +short 172.16.0.10
- 投稿日:2020-09-22T16:10:08+09:00
藤井聡太二冠のPCをAWSと価格比較してみた
はじめに
先日このような記事を見かけました。
50万のCPUを搭載してるそうです。
普通に使うには高い!となりますが、用途がはっきりしてますからね。安い投資じゃないでしょうか。でも、この記事見てすぐ思ってしまいました。
「ずっと使ってるわけじゃないだろうし、AWSで建てたら安くならんかな?」比べてみた
CPU以外は分からないので、CPUにフォーカスしてざっくり比較してみます。
藤井聡太二冠のPC
記事を見るとこちらのCPUを搭載してるようですね。
Ryzen Threadripper 3990X価格.comで調べたところ、サーバ用途を除くと最高値のCPUのようです。
https://kakaku.com/pc/cpu/itemlist.aspx?pdf_so=p2Ryzen 5/7などとはソケット形状が異なるので、取付ける事もできません。
マザボだけでも結構する…
Socket sTRX4 マザーボードAWSのインスタンス
単純にEC2インスタンスと比較する事にします。
CPUバウンドな処理でしょうから「コンピューティング最適化」インスタンスを
その中でもAMDのプロセッサを搭載している「C5a」ファミリーと比較します。
C5 インスタンス先ほどの「Ryzen Threadripper 3990X」のCPU数は64なので、「c5a.16xlarge」相当…
というわけではありません。vCPU数は(一部のインスタンスを除き)スレッド数なので、スレッド数と比較しなければなりません。
正確にはこちらのドキュメントの表に記載されていました。
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/instance-optimize-cpu.html「c5a.16xlarge」も32コア64スレッドですね。
「Ryzen Threadripper 3990X」は64コア128スレッドなので、128vCPUのインスタンスと比較しなければなりません。…なかった
仕方がないので「c5a.16xlarge」×2台と比較します。
リージョンは「ムンバイ」(ap-south-1)が安かったのでそちらにしてみます。
※バージニアやオレゴンが最安だと思ってましたが、c5aは違いました。全リージョン簡単に比較できるサイトとか無いかな…価格算出
料金計算には、AWS Pricing Calculatorを使用します。
どのような使い方をされるか不明ですが、一旦12時間/日使う前提で試算してみます。
朝の10時から夜の10時まで使用するイメージですね。ムンバイを選んで「Advanced estimate」を使う事にして
12時間/日をどう入力するかですが
Workloadの欄でDaily spike trafficを選択し、以下のように入力すればOKです。
※毎日使う、普段は落としてるので0台、使ってる12時間の間はずっと2台起動しているという事です。
※念のためWorkloadがConstant usageで2台の場合と比較してみると、1/2の料金になります。EBSの欄がデフォルトで入っています。
純粋にインスタンスで比較したいのですがツールの仕様上、0にはできないのでテキトウに減らします。
算出結果
年間 13,188.72 USD となりました!(2020/9/22現在)
リンク現在1ドル105円程度なので、約138万円ですね。
※ちなみに東京リージョンに変えてみると倍ぐらいになりました。こんなに変わるんだ。。t3.microだと20%増しくらいなんですけどね毎日12時間使うというのが妥当か分かりませんが、仮にその1/3の4時間だとしても46万円くらいですね。
EC2に含まれてるマザボやメモリ、電気代をPC側に加算したとしても50万円のざっくり2割増として60万円程度でしょうか。
1年分でこれですからね。買ったほうが良さそうです。コストを下げられないか
なんかちょっと悔しいですね(謎)
AWSのコストを下げられないか調べてみます。リザーブドインスタンス
「c5a.16xlarge」の場合、一番割引率の高い「スタンダード 3 年間 全額前払い」でも62%引きです。
EC2 リザーブドインスタンス料金表なので、24時間×(100%-62%)=約9時間/日以上使用する場合はリザーブドが安いですが、そうでない場合はオンデマンドの方が安いです。
これでは勝てませんね…Savings Plans
これならどうでしょう。利用料をコミットする事で安くできます。
分かりやすくするために3年間の前払い無し、で入力してみましたが大して安くなりません。
リンクなんでだろと思ったら「1時間毎」の一定費用の契約なんですね。(1ヵ月ではない)
Qiita - Saving Plansの特徴それもそうか。ユーザは一定時間しか使わなくても、AWSとしてはリソースを用意しとかないといけないですもんね。(実際使った事なかったから勉強になった)
なので使わない時間に落としても意味が無くて、リザーブドと同じように使わない時間の割合より割引率の方が高ければ若干安くはなるくらいです。
スポットインスタンス
じゃぁこれしかないかな。中断対策を考えないといけないので、単純には移行できませんが。
こちらを見ると、オンデマンドの半額近くになるようです。
EC2 スポットインスタンスの料金4時間/日で年間46万円だったのが26万円くらいになりますね。
この料金ならAWSもアリではないでしょうか。Graviton2 のインスタンスを使う
最近出てきたこれもありました。
確認してみたら「最大40%高いコストパフォーマンス」と書かれていますので、大分コストを抑えられる可能性があります。
実際ベンチマークでもマルチコアの性能は結構高いようです。
https://gigazine.net/news/20200616-intel-vs-graviton2/スポットインスタンスでコストを抑えるのとは違って、インスタンスの中断対策を考えなくて良いですしね。
また、併用することでさらに安くもできそうです。
※c6g.16xlargeのスポットは余ってるインスタンスが少ないのか割引率は落ちますまとめ
単純比較すると、藤井聡太二冠のPCの勝ちではないでしょうか。
やりようによってはAWSもアリかもしれません。
- 投稿日:2020-09-22T15:25:35+09:00
Ruby on Railsにて、Blocked Host:"ホスト名"が出てしまう時の対処法
背景
Ruby on Railsチュートリアルの1章の演習で、ずっと「Blocked Host:自分のホスト名」というエラーが出てしまい、長時間色々なことを試した結果、ある根本的なことをしていなかったことに気づき解決できたため、この投稿をさせてもらいました。
試したこと
Web上でよく書かれていることとしては、
1.environment/development.rbにて、「config.hosts.clear」を入れることです。
しかし、これを試しても、エラーが発生したままでした。
2.environment/development.rbにて「config.hosts<<"自分のホスト名"」を入れることです。
しかし、これを試しても、またしてもエラーが発生したままでした。原因
(Ⅰ).違うアプリケーションの中の、development.rbに1と2のプログラムを追加していた。
例えば、自分が作っているアプリケーションがhello_appだとすると、違うアプリケーション(例えば、a_app)の中のdevelopment.rbに1と2のプログラムを追加していたということです。
これでは、a_appのホストが許可されただけで、hello_appのホストは許可されません。
これを間違えた理由としましては、階層構造がenvironment/hello_app/config/environment/development.rb、とenvironmentが2つあることにより、同じ環境内であれば、一つのdevelopment.rbを書き直せば、全てに反映されると勘違いしたことによるものでした。
development.rbの階層は上の通りであり、1つのアプリケーションにつき一つのファイルとなります。
決して、共通ではありません。
自分が作成しているアプリケーション内の、config/environment内のdevelopment.rbを1と2のように書き直すようにしましょう。(Ⅱ).development.rbを書き直した後に、「rails server」を実行しなかった。
順序としては、「development.rb内のプログラムを書き直す→rails serverを実行する」という手順を踏まないと、いくら(Ⅰ)の手順を踏んだとしましても、エラーが発生したままとなります。
- 投稿日:2020-09-22T14:56:39+09:00
CloudWatchメトリクス
CloudWatchメトリクス「期間の5分」について
1. はじめに
- CloudWatchメトリクスのCPU使用率について「期間の5分」は5分毎にデータを取得しているのかな?
- 次に取得するまで4分59秒の間はデータを取得しないのかな?と思い、実際にデータ取得の様子を確認してみました。
2. 実験
- EC2(RHEL8.2)インスタンスにsshログインしてyesコマンドを実行し、CPU使用率を上げます。
- 下図の様にEC2のCPU使用率のメトリクスをグラフにします。SampleCount「5」に注目すると、5分毎にメトリクスが生成される時に「5」個のデータポイントを使っていることが分かります。
- 次にBlackBeltをよく読むと・・・。
- 結論としては「1分間隔でデータポイントを取得し、5分毎にメトリクスを生成」している動きに観えます。
- 投稿日:2020-09-22T03:23:29+09:00
【AWS】WorkSpacesを利用したテレワーク環境にHA構成のプロキシ(Squid)を構築する
はじめに
前回の記事でWorkSpacesを使ったテレワーク環境の構築方法を紹介しました。
今回は、WorkSpacesから安全なインターネットアクセスを行うため、前回構築した環境に
SquidでHA構成のプロキシを導入したいと思います。プロキシについて
WorkSpacesのWebブラウザでインターネットにアクセスする際、プロキシを経由することで、プロキシがクライアントの代理でリクエスト先のWebサーバと通信を行ってくれます。
リクエストを受けるWebサーバからすると、接続元がプロキシとなるため、クライアントのIPアドレスを隠蔽することができます。
また、プロキシではアクセス制御やユーザ認証、URLフィルタリングなどを利用することで、よりセキュアなインターネット利用環境を実現できます。
クライアントからのアクセスログを取得できる点もメリットです。
対象者
- WorkSpacesでプロキシを使いたい方
- AWSの環境にSquidを導入したい方
- Auto Scalingの使い方を知りたい方
実現したいこと
前回の記事で作成した環境をベースとし、Auto Scalingを活用したHA構成のプロキシを構築します。
運用の手間がかからないよう、Squidの設定ファイル(squid.conf)はS3バケットに格納します。
そうすることで、設定ファイルを後で変更した時に、その都度AMIの登録や起動テンプレートの作成を行わずにすみます。プロキシを構築したら、WorkSpaces上でプロキシの設定(※)を行い、プロキシ経由でインターネットに接続できることを確認します。
※ADのグループポリシーでも設定できますが、今回はWorkSpacesでの設定の仕方を説明したいので手動で行います
構成
注意点
- 2020年9月時点の情報です。
- AWSマネジメントコンソールを使用します。ルートユーザもしくは権限を満たすIAMユーザを利用できる前提で進めます。
- AWS利用料にご注意ください。利用料については、AWSの公式ページをご参照ください。
環境構築
1.ネットワーク設定(サブネット作成、ルーティング設定)
2.S3バケット作成、Squid.conf配置
3.Network Load Balancer作成
4.セキュリティグループ作成
5.Auto Scaling設定
6.WorkSpacesプロキシ設定、動作確認1.ネットワーク設定(サブネット作成、ルーティング設定)
前回作成したVPCに、プロキシを配置するためのパブリックサブネットを作成します。
サブネットはAZ-aとAZ-cにそれぞれ作成し、パブリックサブネット用のルートテーブルを割り当てます。以下は上記の作業を行った後のサブネットの一覧を表示した状態です。
(わかりやすくするため、WorkSpacesの作成先サブネットのNameを「telework-workspaces-subnet-x」に変更しています)2.S3バケット作成、squid.conf格納
まず、squid.confを格納するためのS3バケットを作成します。
このバケットはAuto Scalingで起動するEC2インスタンスからのアクセスしか発生しないため、パブリックアクセスは「すべてブロック」とします。その他の設定はデフォルトのままで問題ありません。
以下は作成時の確認画面です。
次に、ローカルでsquidの設定ファイル(squid.conf)を作成します。
テキストエディタを開き、以下を貼り付けて「squid.conf」として保存してください。
※以下は最小限のコンフィグです。80、443以外の検証で不要なポートは閉じていますので、必要に応じて編集してください。
(参考リンク:https://qiita.com/tosier/items/30297afb6ffbd4567eb5)squid.conf# # Recommended minimum configuration: # Example rule allowing access from your local networks. # Adapt to list your (internal) IP networks from where browsing # should be allowed acl localnet src 10.0.0.0/8 # RFC1918 possible internal network acl localnet src 172.16.0.0/12 # RFC1918 possible internal network acl localnet src 192.168.0.0/16 # RFC1918 possible internal network acl localnet src fc00::/7 # RFC 4193 local private network range acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines acl SSL_ports port 443 acl Safe_ports port 80 # http acl Safe_ports port 443 # https acl CONNECT method CONNECT # # Recommended minimum Access Permission configuration: # # Deny requests to certain unsafe ports http_access deny !Safe_ports # Deny CONNECT to other than secure SSL ports http_access deny CONNECT !SSL_ports # Only allow cachemgr access from localhost http_access allow localhost manager http_access deny manager # We strongly recommend the following be uncommented to protect innocent # web applications running on the proxy server who think the only # one who can access services on "localhost" is a local user #http_access deny to_localhost # # INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS # # Example rule allowing access from your local networks. # Adapt localnet in the ACL section to list your (internal) IP networks # from where browsing should be allowed http_access allow localnet http_access allow localhost # And finally deny all other access to this proxy http_access deny all # Squid normally listens to port 3128 http_port 3128 # Uncomment and adjust the following to add a disk cache directory. #cache_dir ufs /var/spool/squid 100 16 256 # Leave coredumps in the first cache dir coredump_dir /var/spool/squid # # Add any of your own refresh_pattern entries above these. # refresh_pattern ^ftp: 1440 20% 10080 refresh_pattern ^gopher: 1440 0% 1440 refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 refresh_pattern . 0 20% 4320squid.confを作成したら、ファイルをバケットに保存します。
AWSのマネジメントコンソールでバケットを開き、ファイルをドラッグ&ドロップして[アップロード]をクリックしてください。
3.Network Load Balancer作成
AWSのマネジメントコンソールでEC2の画面を開き、左のメニューから[ロードバランサー]を選択し、[ロードバランサーの作成]をクリックします。
作成画面が開いたら、中央のNetwork Load Balancerの[作成]をクリックします。
任意の名前を設定し、スキームは「内部」を選択します。
リスナーに設定するポートには、squid.confで設定したhttp_portを設定してください。
デフォルトのままであれば「3128」です。
アベイラビリティーゾーンでは、使用しているVPCと「1.ネットワーク設定」で作成したパブリックサブネットを選択します。
手順2は何もせずにそのまま次に進んでください。
手順3でターゲットグループを作成します。
こちらもポートには、squid.confで設定したhttp_portを設定してください。
手順4ではターゲットの登録ができますが、まだターゲットがないため、この時点では何も設定せずに次に進んでください。
手順5で設定内容を確認し、問題なければ[作成]をクリックします。4.セキュリティグループ作成
プロキシに設定するセキュリティグループを作成します。
インバウンドルールでSSHとプロキシの設定ポートを許可してください。
セキュリティの面から、SSHは現在自分が使用しているグローバルIPのみを許可します(グローバルIPの確認)
以下は作成後の画面です。
5.Auto Scaling設定
プロキシ用の起動テンプレートとAuto Scalingグループを作成します。
マネジメントコンソールでEC2の画面を開き、左のメニューから[Auto Scaling グループ]を選択し、[Auto Scaling グループを作成する]をクリックします。
作成画面が開くので、任意の名前を選択し、[起動テンプレートを作成する]をクリックします。
起動テンプレートの設定については、以下の画面を参考にしてください。
AMIはAmazon Linuxを使用していますが、別のものでも大丈夫です。
その場合はOSに合わせてユーザーデータを変更してください。
インスタンスタイプはお好みのものを設定してください。
キーペアの設定は必須ではありませんが、後ほどSSH接続してアクセスログを確認したいため、設定しておきました。
サブネットは冒頭で作成したパブリックサブネットを選択します。
パブリックIPの自動割り当ては有効化し、先ほど作成したセキュリティグループを設定してください。
IAMインスタンスプロフィールには、EC2用のIAMロールを作成して割り当ててください。
ロールには以下のIAMポリシーを作成してアタッチしています。
AMIがAmazon Linuxの場合、ユーザーデータには以下を設定します。#!/bin/bash sudo yum update -y sudo yum -y install squid chkconfig squid on aws s3 cp s3://<バケット名>/squid.conf /etc/squid/squid.conf sudo service squid restartAuto Scalingグループの作成画面に戻り、作成した起動テンプレートをセットします。
次の画面に進み、設定の構成を行います。
ステップ3、5、6については、特になにも設定せずにそのままでも問題ありません。
ステップ4でグループサイズを決められるので以下を設定します。
・希望する容量…2
・最小キャパシティ…2
・最大キャパシティ…2これで常時2台プロキシが稼働します。
※後でプロキシの台数を調整したい時は、この値を変更してください。上から全部0にするとプロキシは停止状態となります。6.WorkSpacesプロキシ設定、動作確認
WorkSpaces上でプロキシ設定を行います。
左下のWindowsアイコンをクリックして[設定]を開き、[ネットワークとインターネット]をクリックします。
左のメニューから[プロキシ]をクリックし、手動プロキシ セットアップでプロキシの設定を行います。
・プロキシ サーバーを使う:オン
・アドレス:NLBのパブリックDNS
・ポート: プロキシの設定ポート
設定後、Webブラウザを開き、インターネットにアクセスできることを確認します。
Auto Scalingによって起動したEC2インスタンスにログインし、Squidのアクセスログ(/var/log/squid/access.log)を確認すると、WorkSpacesからのWebアクセスのログを確認できます。
構築手順は以上です。
参考元
Forward Proxy と Reverse Proxy の決定的な違い
Squidでホワイトリストプロキシを作成する
HA構成プロキシ環境をNLBを使って構築してみるさいごに
Auto Scalingを使ったHA構成のプロキシの構築方法を紹介しました。
プロキシはWorkSpacesに限らず、インターネットアクセスが必要なインスタンスやコンテナを
運用するシーンでも役立ちますので、上手く活用していただければと思います。今回はプロキシとしてSquidを使いましたが、BIG-IPやFortigateなどのネットワーク仮想アプライアンスを利用することも可能です。このあたりについては、次回以降の記事で取り上げたいと思います。
- 投稿日:2020-09-22T02:25:14+09:00
AWS Copilot でnginxを動かしてみる。
前提
- 環境
- Mac OS
- AWS CLIを使うことができる
- Dockerがインストールされている。
Copilot のインストール
curl -Lo /usr/local/bin/copilot https://github.com/aws/copilot-cli/releases/download/v0.1.0/copilot-darwin-v0.1.0 && \ chmod +x /usr/local/bin/copilot && \ copilot --helpDockerfileを用意
mkdir copilot cd copilot
copilot
ディレクトリの中に下記のDockerfileを作成します。FROM nginx:alpine EXPOSE 80 COPY . /usr/share/nginx/htmlcopilot init
copilot initCLI上でいくつか質問されるので下記を入力・選択しました。
Application name: nginx-test Service type: Load Balanced Web Service Service name: nginx Dockerfile: ./Dockerfile確認
ブラウザ
先ほどの
copilot init
の実行結果、最終行にURLが記載されています。
ここにアクセスします。✔ Deployed nginx, you can access it at http://nginx-Publi-64I230BK4R******5852852.ap-northeast-1.elb.amazonaws.com.AWS ECS
FARGATEで先ほどのnginxが実行されています。
参考
公式:
https://aws.amazon.com/jp/blogs/news/introducing-aws-copilot/
- 投稿日:2020-09-22T00:05:48+09:00
EC2インスタンス作成~ログインまで(画像つき)
今回は
EC2インスタンスをweb上から作成し、ログインまでの箇所を画像つきで進めていきます。EC2インスタンスの作成
ログイン
>EC2インスタンス
以下の画面になると思います。
そこで、インスタンスの作成
を行います。
- OS を選択。
検索窓で、
CensOS7
を検索(今回はCentOS7を作成します。)
AWS Marketplace
に移動すると、CentOS7があるので、選択します。
- 料金の表示
このOSはこれだけの料金かかりますよ
と言ってくれます。
ですので、次へ。
- インスタンスタイプの選択
次はCPUとかメモリとか決めていきます。
特に負荷がかかることをしないのであれば、一旦t2.nano
やt2.micro
でやってみることをおすすめします(費用的に)
- インスタンスの詳細設定
このインスタンスはどこで立てますか?
やIPアドレスつける?
など設定していきます。
今回は、自動割当パブリックIP
のみ変更し、有効にします。
これはIPアドレスを自動で割り当てるというものです。
- ストレージの追加
次はストレージの容量、要するに
HDDの容量どれくらいにする?
やSSD?HDD?
など決めていきます。
特に指定がないので、サイズはデフォルトの8GBにしておきます。
また、終了時に削除
にチェックを入れておくと、EC2インスタンスを削除した際に一緒に消えてくれるので手間が減って便利です!
- タグの追加
いっぱいサーバがあって料金の計算をしたい...など様々なことが出来ますが、最初は一旦
name
だけでOK
- セキュリティグループをの設定
セキュリティグループの設定を行います。
どこからのアクセス(ここでいうソース)
を許可するか。
どういうプロトコル
を許可するか。
など設定できます。今回は、webサーバを作る予定なので
ログインするためのSSH
とアクセスするためのHTTP
を開けておきます。
ソースは自分のIPアドレスを記載。
- 確認
今まで設定してきたものが表示されるので、OKだったら
起動
を行います。
- キーペアの作成
キーペアの選択を行います。
キーペア
とはインスタンスへの接続時に使用される認証情報。
イメージ、SSHの鍵のようなものです。
既存のものを使わない場合は、新しいキーペアの作成
からキーペア名
を入れて、キーペアのダウンロード
をする必要があります。
完了したら、インスタンスの作成
に進みます。
- EC2のページへ戻る
EC2インスタンスの作成が完了したら、EC2の画面へ戻ります。
すると、新しいインスタンスが表示されました!ログイン
用意するもの
- キーペア
- パブリックIPアドレス(
EC2のページへ戻る
の画像の下の方にIPv4パブリックIP
が書かれている)キーペアの権限を変更します。
$ chmod 600 test-server.pem $ ls -al .ssh | grep test-server.pem -rw-------. 1 root vboxsf 1704 9月 15 20:28 test-server.pem
- ログイン
CentOSでEC2インスタンスを作成した際のデフォルトユーザが
centos
Amazonlinuxではec2-user
になり、OSごとにデフォルトユーザが違うので、注意してくださいssh -i .ssh/test-server.pem centos@XX.XX.XX.XX [centos@ip-XX-XX-XX-XX ~]$ログイン出来ました
注意
- EC2インスタンスは使ったら落としましょう
EC2インスタンスは、起動時間がそのまま費用になってきます。
ですので、必要ないときはEC2インスタンスを落としておきましょう。以下でインスタンスを落とすことが出来ます。
1. 落とすEC2インスタンスにチェックを入れる
2.右クリック(アクション)
→インスタンスの状態
→停止