Route53のルーティング方式毎のクエリ応答切り替わりを確認する - 加重+フェイルオーバールーティング編
はじめに
前回のブログから随分と時間が経ってしまいました。
その間に、AWS Certified Developer - Associateに合格したり、転職のための準備などをやっていました。
転職のことについては、気が向いたらその内ブログにまとめようかと思います。
さて、今更ではありますが、以前Route53のシンプルルーティングの挙動を確認したので、今回はその続きとして、加重+フェイルオーバールーティングの挙動を確認したいと思います。
今回の構成
今回は、下図のように「プライマリリソース2台、セカンダリリソース2台」の構成にし、リソースのダウン状態に応じてアクセス結果がどうなるか見ていきたいと思います。
実務ではこのような構成は採用しないと思いますが、あくまで動作検証目的なのでご容赦ください。
今回はプライベートホステッドゾーンを使用し、VPC内の踏み台サーバからWEBサーバにアクセスすることにします。
NATゲートウェイは、プライベートサブネットのEC2にパッケージをインストールするために使用します。
環境構築の方法
今回は、VPC内の環境はCloudFormationで構築し、Route53の設定は手動で行います。
CloudFormationのテンプレートは以下のものを使用します。
Route53_Failover_Routing.yml
環境構築
VPC内構築(CloudFormation)
まずは上述のテンプレートを使ってVPC内の環境を構築します。
[cloudshell-user@ip-10-0-175-26 ~]$ ls -l total 3000 -rw------- 1 cloudshell-user cloudshell-user 3489792 Sep 25 08:20 core.3704 -rw-rw-r-- 1 cloudshell-user cloudshell-user 18077 Nov 6 16:31 Route53_Failover_Routing.yml [cloudshell-user@ip-10-0-175-26 ~]$ [cloudshell-user@ip-10-0-175-26 ~]$ [cloudshell-user@ip-10-0-175-26 ~]$ [cloudshell-user@ip-10-0-175-26 ~]$ aws cloudformation validate-template --template-body file:///home/cloudshell-user/Route53_Failover_Routing.yml { "Parameters": [ { "ParameterKey": "KeyName", "NoEcho": false, "Description": "Name of an existing EC2 KeyPair to enable SSH access to the instances" }, { "ParameterKey": "EnvironmentType", "DefaultValue": "test", "NoEcho": false, "Description": "The environment type" }, { "ParameterKey": "ClientIP", "DefaultValue": "0.0.0.0/0", "NoEcho": false, "Description": "Client IP Address" } ], "Description": "EC2 WEB Server Deploy for Route53 Failover Routing" } [cloudshell-user@ip-10-0-175-26 ~]$ [cloudshell-user@ip-10-0-175-26 ~]$ [cloudshell-user@ip-10-0-175-26 ~]$ [cloudshell-user@ip-10-0-175-26 ~]$ aws cloudformation create-stack \ > --stack-name EC2deploy-for-Route53Failover \ > --template-body file:///home/cloudshell-user/Route53_Failover_Routing.yml \ > --parameters \ > ParameterKey=KeyName,ParameterValue="xxx" \ > ParameterKey=ClientIP,ParameterValue="114.xxx.xxx.xxx/32" \ > ParameterKey=EnvironmentType,ParameterValue="test" { "StackId": "arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:stack/EC2deploy-for-Route53Failover/888ef8d0-3f1f-11ec-8a07-069142138e3f" } [cloudshell-user@ip-10-0-175-26 ~]$ [cloudshell-user@ip-10-0-175-26 ~]$ [cloudshell-user@ip-10-0-175-26 ~]$ aws cloudformation describe-stacks --stack-name EC2deploy-for-Route53Failover { "Stacks": [ { "StackId": "arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:stack/EC2deploy-for-Route53Failover/888ef8d0-3f1f-11ec-8a07-069142138e3f", "StackName": "EC2deploy-for-Route53Failover", "Description": "EC2 WEB Server Deploy for Route53 Failover Routing", "Parameters": [ { "ParameterKey": "KeyName", "ParameterValue": "xxx" }, { "ParameterKey": "EnvironmentType", "ParameterValue": "test" }, { "ParameterKey": "ClientIP", "ParameterValue": "114.xxx.xxx.xxx/32" } ], "CreationTime": "2021-11-06T16:35:21.031000+00:00", "RollbackConfiguration": {}, "StackStatus": "CREATE_COMPLETE", "DisableRollback": false, "NotificationARNs": [], "Outputs": [ { "OutputKey": "PublicIPaddress", "OutputValue": "18.xxx.xxx.xxx", "Description": "PublicIpaddress for Bastion" }, { "OutputKey": "InstanceSecurityGroup1", "OutputValue": "sg-xxxxxxxxxxxxxxxxx", "Description": "InstanceSecurityGroup1", "ExportName": "EC2deploy-for-Route53Failover-InstanceSecurityGroup1" }, { "OutputKey": "PublicSubnet1", "OutputValue": "subnet-xxxxxxxxxxxxxxxxx", "Description": "PublicSubnet1", "ExportName": "EC2deploy-for-Route53Failover-PublicSubnet1" } ], "Tags": [], "EnableTerminationProtection": false, "DriftInformation": { "StackDriftStatus": "NOT_CHECKED" } } ] } [cloudshell-user@ip-10-0-175-26 ~]$ [cloudshell-user@ip-10-0-175-26 ~]$
Route53設定
次はRoute53の設定です。加重+フェイルオーバールーティングの場合、先にヘルスチェックの作成をする必要があります。
ただし、今回WEBサーバにはパブリックIPを割り当てていないので、IPアドレスによるヘルスチェックは出来ません。詳細は以下のリンクを参照してください。
そのため、今回はCloudWatchアラームを使用してヘルスチェックを行います。
CloudWatchアラームの作成
というわけで、まずCloudWatchアラームを作成します。
EC2インスタンスの「StatusCheckFailed_Instance」メトリクスを使用します。
各インスタンス毎にアラームを作成します。
Route53ヘルスチェックの作成
続いて、Route53ヘルスチェックを作成します。
まずはヘルスチェック作成ボタンを押します。
続いて、諸々の情報を入力します。なお、今回はアラームが不足状態の時は異常扱いとしました。理由は、疑似障害として対象インスタンスを手動で停止した所、CloudWatchアラームが「NG」ではなく「データ不足」になってしまったためです。
Route53ヘルスチェックも、インスタンス毎に作成します。
DNSレコードの追加
続いて、DNSレコードを追加していきます。フェイルオーバーのプライマリリソース、セカンダリリソースが複数ある場合、エイリアスレコードを併用する必要があります。詳細は以下のリンクを参照してください。
まずはインスタンスのAレコードを加重ルーティングで登録します。最初はEC2Aです。
レコード名は「failover-primary」としています。先ほど作成したヘルスチェックと紐づけます。TTLは図では300秒になっていますが、後で10秒に変更しました。(TTLが長いと、短時間のアクセスでは想定通り加重されない場合がありました。)EC2Bも同様に設定します。
EC2C、EC2Dはレコード名を「failover-secondary」としました。
続いて、名前解決したいホスト名「www.example.com」のエイリアスレコードを、フェイルオーバールーティングで作成します。
「failover-primary」と紐づけ、プライマリリソースとします。
もう一つ「www.example.com」のレコードを作成します。こちらは「failover-secondary」と紐づけ、セカンダリリソースとします。
最終的にレコードは上図のようになりました。
アクセス確認
今回のアクセス確認方法
前述通り、今回は踏み台EC2からアクセス確認します。簡便なスクリプトを使い、10秒おきに「www.example.com/index.html」宛てに100回curlして、応答したインスタンスの数をカウントします。(※各WEBサーバにはCloudFormaitonでindex.htmlを配置しています。index.htmlのBodyに自身の名前が記述されているので、それを抜き出します。)
踏み台EC2で使用するスクリプトの中身は以下です。これもCloudFormationで事前に配置しています。
#!/bin/bash for ((i=1; i<=100; i++)) do curl -s http://www.example.com/index.html | grep -o "EC2." >> ./curlresult sleep 10 done cat ./curlresult | sort | uniq -c echo "curl done!!"
アクセス確認結果
全インスタンスの正常時
全インスタンスの正常時は、プライマリリソースの2台で加重ルーティングされました。
[ec2-user@ip-10-100-0-78 ~]$ [ec2-user@ip-10-100-0-78 ~]$ ./curlrepeat.sh 70 EC2A 30 EC2B curl done!! [ec2-user@ip-10-100-0-78 ~]$ [ec2-user@ip-10-100-0-78 ~]$
EC2Aの異常時
EC2Aに異常がある場合、もう1台のプライマリリソースであるEC2Bに全アクセスが集中しました。
[ec2-user@ip-10-100-0-78 ~]$ ./curlrepeat.sh 100 EC2B curl done!! [ec2-user@ip-10-100-0-78 ~]$
EC2A、EC2Bの異常時
プライマリリソースの全台に異常がある場合、セカンダリリソースの2台で加重ルーティングされました。
[ec2-user@ip-10-100-0-78 ~]$ ./curlrepeat.sh 17 EC2C 83 EC2D curl done!! [ec2-user@ip-10-100-0-78 ~]$
EC2A、EC2B、EC2Cの異常時
プライマリリソースの全台+セカンダリリソースの1台に異常がある場合、セカンダリリソースの残り1台に全アクセスが集中しました。
[ec2-user@ip-10-100-0-78 ~]$ ./curlrepeat.sh 100 EC2D curl done!! [ec2-user@ip-10-100-0-78 ~]$
結論
というわけで、以下のような結果となりました。
- プライマリリソースが全異常にならない限り、プライマリリソースの正常なレコードで加重ルーティングされる。
- プライマリリソースが全異常になっている間は、セカンダリリソースの正常なレコードで加重ルーティングされる。
ログの記載は省略しますが、EC2Bのみ異常の場合や、EC2A、EC2B、EC2Dに異常がある場合も、上記ルールに則った結果となりました。
なお、今回はプライマリ、セカンダリ両方にヘルスチェックを設定していましたが、ヘルスチェックを設定していない場合は挙動が変わるようです。詳細は以下リンクを参照ください。
Route53ヘルスチェックについての補足
もしヘルスチェックをIPで行う場合、Route53ヘルスチェッカーからのアクセスをセキュリティグループ等で許可する必要があります。Route53ヘルスチェッカーはVPC外に存在しているためです。詳細は以下のリンクを参照してください。
また、Route53ヘルスチェッカーのIPアドレスはリージョン毎に異なります。アドレス範囲については以下のリンクを参照してください。
おわりに
というわけで、前回のシンプルルーティングから2ヶ月も経ってしまいましたが、ようやく加重+フェイルオーバールーティングの設定と動作確認が出来ました。
今回もCloudFormationの設定で色々躓いたうえ、複数リソースでのフェイルオーバールーティング設定でも苦戦したため、予想以上に時間を使ってしまいました。
ただ、おかげでCloudFormationやRoute53に少しずつ慣れてきたので、今後も試行錯誤しながら色々試していきたいと思います。
CloudFormation初心者が色々ハマった話
はじめに
前回のブログで記載した通り、慣れないCloudFormationで環境構築をしようとしたところハマってしまい、解決までに結構手間取ってしまいました。今後同じようなミスをしないように、備忘としてブログに残したいと思います。
今回ハマったこと
今回、主に以下の3つのポイントでハマってしまいました。
ファイルパスの先頭にfile://をつけていなかった
CLIでCloudFormationのスタックを作成する場合、aws cloudformation create-stack
コマンドを使用し、--template-body file://<ファイルパス>
という形式でテンプレートファイルのパスを指定します。ポイントは、ファイルパスの前に「file://」をつけることなのですが、これをつけていませんでした。なぜかスッポリ意識から抜け落ちていました。「CLIで引数にファイルを指定する時はファイルパス」という思い込みがあったのかもしれません。
そうして「file://」をつけずに実行しようとすると、以下のようなエラーが表示されます。
[cloudshell-user@ip-10-0-87-215 ~]$ aws cloudformation create-stack \ > --stack-name EC2-WEB-deploy \ > --template-body /home/cloudshell-user/ec2_web.yml \ > --parameters \ > ParameterKey=KeyName,ParameterValue="XXX" \ > ParameterKey=AmiId,ParameterValue="ami-0a1c2ec61571737db" \ > ParameterKey=ClientIP,ParameterValue="114.XXX.XXX.XXX/32" \ > ParameterKey=ServerName,ParameterValue="www.XXXXXXXXXX.com:80" An error occurred (ValidationError) when calling the CreateStack operation: Template format error: unsupported structure. [cloudshell-user@ip-10-0-87-215 ~]$
aws cloudformation validate-template
コマンドでも同様のエラーが表示されます。
[cloudshell-user@ip-10-0-87-215 ~]$ aws cloudformation validate-template --template-body /home/cloudshell-user/ec2_web.yml An error occurred (ValidationError) when calling the ValidateTemplate operation: Template format error: unsupported structure. [cloudshell-user@ip-10-0-87-215 ~]$
「テンプレートフォーマットエラー:サポートされていない構造」という表記だったので、まさかコマンドの書式が間違っているとは思いもしませんでした。特に今回は初めてヘルパースクリプトやユーザーデータを使っていて、テンプレートの記載が正しいか自信がなかったので、真っ先にテンプレートの中身を疑ってしまいました。
そうして暫くテンプレートと格闘していたのですが、エラーメッセージでググったら、そのものズバリな回答が記載されているサイトがすぐ出てきました。。
大文字小文字の記述ミス
こうしてテンプレートフォーマットエラーを解消して、aws cloudformation create-stack
コマンドは通るようになったのですが、スタック作成が途中で失敗してロールバックしてしまいました。そこで、aws cloudformation describe-stack-events
コマンドで、スタックのイベントをチェックしてみました。
[cloudshell-user@ip-10-0-87-215 ~]$ aws cloudformation create-stack \ > --stack-name EC2-WEB-deploy \ > --template-body file:///home/cloudshell-user/ec2_web.yml \ > --parameters \ > ParameterKey=KeyName,ParameterValue="XXX" \ > ParameterKey=AmiId,ParameterValue="ami-0a1c2ec61571737db" \ > ParameterKey=ClientIP,ParameterValue="114.XXX.XXX.XXX/32" \ > ParameterKey=ServerName,ParameterValue="www.XXXXXXXXXX.com:80" { "StackId": "arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/EC2-WEB-deploy/8af162a0-0fe7-11ec-a7df-0a0e301349e7" } [cloudshell-user@ip-10-0-87-215 ~]$ [cloudshell-user@ip-10-0-87-215 ~]$ [cloudshell-user@ip-10-0-87-215 ~]$ [cloudshell-user@ip-10-0-87-215 ~]$ aws cloudformation describe-stack-events --stack-name EC2-WEB-deploy { "StackEvents": [ { ----- 中略 ----- }, { "StackId": "arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/EC2-WEB-deploy/8af162a0-0fe7-11ec-a7df-0a0e301349e7", "EventId": "EC2A-CREATE_FAILED-2021-09-07T14:51:54.021Z", "StackName": "EC2-WEB-deploy", "LogicalResourceId": "EC2A", "PhysicalResourceId": "", "ResourceType": "AWS::EC2::Instance", "Timestamp": "2021-09-07T14:51:54.021000+00:00", "ResourceStatus": "CREATE_FAILED", "ResourceStatusReason": "Encountered unsupported property Userdata" }, {
最後の行に、何やら「Userdataというサポートしていないpropertyに遭遇した」という表記が出てきました。「EC2はユーザーデータをサポートしていない?いや、そんなはずない。。」と悩みつつ、ユーザーデータの中身をチェックし直してみますが、おかしそうな所は見当たりません。
困惑しつつ、見本にしたテンプレートを自分のテンプレートを何度も見比べて、ようやく気付きました。「Userdata」ではなく「UserData」が正しいことに。。
日本語の文字化け
propertyの表記も修正して、ようやく環境構築が完了したので、早速WEBページにブラウザでアクセスしてみたところ、今度はWEBページが文字化けしていました。。
「文字コードはUTF-8にしてテンプレートにしたのに何故。。」と思ってググったところ、以下のページに詳しい解説がありました。
CloudFormationの組み込み関数Fn::Base64
で日本語を一度ASCII文字に変換してから、ユーザーデータ上のスクリプトでデコードする必要があるようです。
ただ、環境構築を開始したのが深夜で、これに気付いた時点ですでに夜が明けかかっており、文字変換まで実装する気力がなかったので、今回はWEBページを英語表記にして逃げました。。
今回の一番の反省点
以上、つらつらとハマったポイントをまとめてみました。最初の二つは「不注意」と言われればそれまでなんですが、今回四苦八苦したおかげで、金輪際「file://」と「UserData」を忘れることはないでしょう。
日本語WEBページの表示は、また今度、機会を作って挑戦したいと思います。
そして何より、今回の一番の反省ポイントは「寝不足状態で作業しない」ですw
寝不足だと本当にしょうもないミスが多くて、以前にも、しっかり寝た後で見直して「なんでこんなミスを」と呆れた事がありました。
手を動かしての検証は楽しいのでつい時間を忘れて取り組んでしまいますが、要反省ですね。
(オマケ)今回のCloudFormationの環境構築について
最後に、あまり本題とは関係ないのですが、今回CloudFormationで構築した構成や、テンプレートの中身などについてまとめました。
今回構築した構成
今回は、下図の赤点線部分をCloudFormationで構築しました。
Route53のパブリックホストゾーンは既に存在していたものを使用しました。
cfn-init、ユーザーデータによる設定
cfn-init、ユーザーデータを使い、EC2に対して以下の設定も実施してみました。
- httpdのインストール
- /var/www/html/index.htmlへのコンテンツ格納
- /etc/httpd/conf/httpd.confのServerNameの値を変更
- SSHのListenポートを22から51512に変更
/etc/httpd/conf/httpd.confの変更は、CloudFormationのParameterで入力した値を、ユーザーデータでシェル変数として使うために参照させました。
Parameterの値をユーザーデータで変数として利用できるのは便利ですね。
最後のSSHのポート変更は今回の趣旨と関係ありませんが、以前のブログでユーザーデータを扱った際にやった事があったので、今回CloudFormationでもやってみました。
今回使用したCloudFormationテンプレート
上記の構築・設定のために使用したCloudFormationテンプレートはこちらです。
CloudFormationテンプレートの作成にあたっては、以下のページを大いに参考にさせていただきました。
CloudFormationの実行方法
冒頭でも記載した通り、今回、CloudFormationのスタック作成はマネコンではなくCLIで実施しました。
Route53のルーティング方式毎のクエリ応答切り替わりを確認する - シンプルルーティング編
はじめに
前回のブログで記載した通り、AWS Certified Advanced Networking - Specialtyに合格することが出来ました。
試験対策中は座学が中心だったのですが、一区切りついたので、勉強した内容について実際に挙動を確認してみたいと思います。
とはいえDirectConnectなどは構築のハードルが高いので、Route53の各ルーティング方式毎の挙動(クエリ応答の切り替わり)を見ていくことにしました。その中で今回は、最も基本的なシンプルルーティングの挙動を見ていきたいと思います。
Route53シンプルルーティングについて
シンプルルーティングについては以下の公式ページに説明があります。
「複数の値を 1 つのレコードに指定すると、Route 53 はすべての値をランダムな順序で再帰的リゾルバーに返し」と記載があるので、ラウンドロビンではないようです。
今回の構成
今回は図のような構成を作りました。
通常であれば、WEBサーバはプライベートサブネットに置いて、ELBをパブリックサブネットに置くのがベタな構成ですが、今回は検証目的なので直接パブリックサブネットに置いてしまいます。
2台のWEBサーバに同じホスト名を割り当て、そのホスト名に対するAレコードを、Route53パブリックホストゾーンに登録します。シンプルルーティングによって、2つのWEBページがランダムに表示されることを確認します。
WEBページについて
2つのWEBページがランダムに表示されていることを確認するために、ページの内容は若干変えました。「Hello」とだけ表示されるページとかでも良かったのですが、それだと少し寂しいので、無駄にリンクなどをつけて、以下のような感じにしました。
この時点ではIPアドレスを直接叩いてアクセスしています。
Route53作業
それでは、Route53のパブリックホストゾーンにAレコードを登録します。
まずは目的のゾーンに移動して、「レコードを作成」を選択
ルーティングポリシーで「シンプルルーティング」を選択
ホスト名を入力し、レコードタイプでAレコードを選択。値/トラフィックのルーティング先には「レコードタイプに応じたIPアドレスまたは別の値」を選択し、二つのWEBサーバのIPアドレスを登録。TTLを適当に短い時間(今回は10秒)に変更し、「シンプルなレコードの定義」を選択。
内容に問題がないことを確認して、「レコードを作成」を選択。
シンプルルーティングのAレコードが登録されたことを確認。
ページ閲覧・クエリ応答確認
ホスト名でのページ閲覧
それでは、ホスト名でWEBページにアクセスし、適当にブラウザを更新してみます。
同じホスト名で、ランダムで二つのWEBページが表示されました。
クエリ応答確認
続いて、クライアントPCからnslookupでクエリを飛ばし、応答を確認してみます。
C:\Users>echo %date% %time% 2021/09/05 16:18:12.85 C:\Users>nslookup www.XXXXX.com サーバー: UnKnown Address: 2404:1a8:7f01:b::3 権限のない回答: DNS request timed out. timeout was 2 seconds. 名前: www.XXXXX.com Addresses: 18.XXX.XXX.XXX 54.XXX.XXX.XXX C:\Users>echo %date% %time% 2021/09/05 16:19:02.34 C:\Users>nslookup www.XXXXX.com サーバー: UnKnown Address: 2404:1a8:7f01:b::3 権限のない回答: 名前: www.XXXXX.com Addresses: 18.XXX.XXX.XXX 54.XXX.XXX.XXX C:\Users>echo %date% %time% 2021/09/05 16:19:11.60 C:\Users>nslookup www.XXXXX.com サーバー: UnKnown Address: 2404:1a8:7f01:b::3 権限のない回答: 名前: www.XXXXX.com Addresses: 54.XXX.XXX.XXX 18.XXX.XXX.XXX C:\Users>echo %date% %time% 2021/09/05 16:19:19.88 C:\Users>nslookup www.XXXXX.com サーバー: UnKnown Address: 2404:1a8:7f01:b::3 権限のない回答: 名前: www.XXXXX.com Addresses: 54.XXX.XXX.XXX 18.XXX.XXX.XXX C:\Users>echo %date% %time% 2021/09/05 16:19:25.38 C:\Users>nslookup www.XXXXX.com サーバー: UnKnown Address: 2404:1a8:7f01:b::3 権限のない回答: 名前: www.XXXXX.com Addresses: 54.XXX.XXX.XXX 18.XXX.XXX.XXX C:\Users>echo %date% %time% 2021/09/05 16:19:32.73 C:\Users>nslookup www.XXXXX.com サーバー: UnKnown Address: 2404:1a8:7f01:b::3 権限のない回答: 名前: www.XXXXX.com Addresses: 18.XXX.XXX.XXX 54.XXX.XXX.XXX C:\Users>echo %date% %time% 2021/09/05 16:19:39.71 C:\Users>nslookup www.XXXXX.com サーバー: UnKnown Address: 2404:1a8:7f01:b::3 権限のない回答: 名前: www.XXXXX.com Addresses: 54.XXX.XXX.XXX 18.XXX.XXX.XXX C:\Users>echo %date% %time% 2021/09/05 16:19:47.60 C:\Users>nslookup www.XXXXX.com サーバー: UnKnown Address: 2404:1a8:7f01:b::3 権限のない回答: 名前: www.XXXXX.com Addresses: 18.XXX.XXX.XXX 54.XXX.XXX.XXX C:\Users>echo %date% %time% 2021/09/05 16:19:53.42 C:\Users>nslookup www.XXXXX.com サーバー: UnKnown Address: 2404:1a8:7f01:b::3 権限のない回答: 名前: www.XXXXX.com Addresses: 18.XXX.XXX.XXX 54.XXX.XXX.XXX C:\Users>echo %date% %time% 2021/09/05 16:20:04.39 C:\Users>nslookup www.XXXXX.com サーバー: UnKnown Address: 2404:1a8:7f01:b::3 権限のない回答: 名前: www.XXXXX.com Addresses: 18.XXX.XXX.XXX 54.XXX.XXX.XXX C:\Users>echo %date% %time% 2021/09/05 16:20:10.62 C:\Users>nslookup www.XXXXX.com サーバー: UnKnown Address: 2404:1a8:7f01:b::3 権限のない回答: 名前: www.XXXXX.com Addresses: 18.XXX.XXX.XXX 54.XXX.XXX.XXX C:\Users>echo %date% %time% 2021/09/05 16:20:17.89 C:\Users>nslookup www.XXXXX.com サーバー: UnKnown Address: 2404:1a8:7f01:b::3 権限のない回答: 名前: www.XXXXX.com Addresses: 18.XXX.XXX.XXX 54.XXX.XXX.XXX C:\Users>echo %date% %time% 2021/09/05 16:20:23.82 C:\Users>nslookup www.XXXXX.com サーバー: UnKnown Address: 2404:1a8:7f01:b::3 権限のない回答: 名前: www.XXXXX.com Addresses: 54.XXX.XXX.XXX 18.XXX.XXX.XXX C:\Users>
ラウンドロビンではなく、ランダムで応答が返ってきていることが確認できました。
おわりに
というわけで、Route53のシンプルルーティングの挙動確認でした。こんな感じで、次はフェイルオーバールーティング、加重ルーティングあたりの確認をしようかと思います。位置情報ルーティングや地理的近接性ルーティングも気になりますが、その辺はうまい確認方法があれば試してみたいと思います。
実は今回、Route53の設定と挙動確認は一瞬で終わったのですが、Route53以外の部分を慣れないCloudFormationで構築してみたところ、色々失敗してかなり手間取り、ほとんどの時間をそこに費やしました。ただ、おかげでCloudFormationの扱いには多少慣れました。
せっかくなので、CloudFormationで躓いた箇所についても、備忘として別途ブログに残したいと思います。
AWS Certified Advanced Networking - Specialty試験の振り返り
はじめに
先日、AWS Certified Advanced Networking - Specialty(以下、ANS)に合格しました。(スコアはギリギリでしたが。。)
試験対策として何をやったか、受けてみてどうだったか等を振り返り、備忘録として残したいと思います。「これさえやれば合格間違いない!」というものではありませんが、誰かにとって何らか参考になる事があれば幸いです。
なお、試験内容について記載することは規約違反のため、「具体的にこういう問題が出た」みたいな事はここでは記載しません。
(前提)私のスキル・知識
AWSを業務で使ったことはありません。2021年3月くらいからAWSの勉強を開始し、以下の資格を取得しました。
- Solutions Architect - Associate(以下、SAA)
- SysOps Administrator - Associate(以下、SOA)
ネットワークに関しては、6,7年くらい業務で関わっていました。(最近は自分で手を動かす機会がめっきり減っていましたが。。)資格はネットワークスペシャリスト、CCNPを取得していました(CCNPはすでに失効)。そのため、ネットワークに関する基本的な知識はある状態でした。
試験対策期間
SOA合格後の2021年7月中旬から勉強を開始し、2021/9/2に受けたので、期間としては大体1.5ヵ月くらいです。
平日は仕事終わりに勉強していたため、仕事の繁忙によって1日の勉強時間は異なりますが、平均1~1.5時間くらいかなーと思います。
休日も予定の有無や体調、やる気で大分差がありますが、対策期間の前半は1日2~3時間、終盤は1日5~6時間くらいだったかと思います。
試験対策としてやったこと
試験対策としては主に以下を実施しました。
- 「AWS WEB問題集で学習しよう」で問題を解く。
- ネットワーク関連のBlackBelt資料を読む。
UdemyやAWS公式模擬試験は利用しませんでした。
「AWS WEB問題集で学習しよう」
「AWS WEB問題集で学習しよう」は、SAA、SOAの試験勉強でも利用しました。問題を解いて解説を読み、解説を読んでもよく分からない所はググったりBlackBert資料を読んだりして理解を深めました。
間違えた問題や、ちゃんと理解できていなかった問題は番号をメモしておき、2周目はメモした問題だけ解きました。さらに復習した方が良さそうな問題をメモして、合計3周しました。
これまでいくつかの資格試験を受けてきましたが、問題を繰り返し解くと記憶に定着しやすいと感じています。有料ですが、個人的には使って損はありませんでした。
BlacBelt資料
「AWS WEB問題集で学習しよう」はANSの問題がそこまで多くはないので、(全部で150問程度で、SAAやSOAと比べると大分少ない)BlackBelt資料も読むようにしました。
BlackBelt資料では、Networking & Content Deliveryカテゴリの内、以下の資料を読みました。
- Elastic Load Balancing (ELB)
- Amazon CloudFront deep dive
- Amazon CloudFrontの概要
- Amazon Route 53 Resolver
- Amazon Route 53 Hosted Zone
- AWS Direct Connect
- オンプレミスと AWS 間の冗長化接続
上記のサービスを選んだ理由は、カテゴリの中でも特にメジャーなサービスなので、出題頻度も多いかな、と思ったためです。
BlackBeltの内容はYouTubeで解説が聴けるものもありますが、私は自分のペースで読み進めたかったのでPDFを読んでいました。
また、読むだけだとなかなか頭に入らないので、自分でBlackBeltの内容から選択問題を作成し、それを解いたりしました。
こういったアウトプットは多少時間がかかりますが、記憶の定着が良いので、出来るだけインプットだけではなくアウトプットしながら学習したいと思ってはいます。
試験当日
試験は自宅で受験しました。SAA、SOAも自宅受験で今回3回目だったので、さすがに慣れてきていて、セッティングで焦ることはありませんでした。
ただ、試験時間をちゃんと確認しておらず、120分の試験だと思い込んでいたら実際には180分の試験で、これにはちょっと焦りました。。
というのも、その日は平日で仕事を抜けられる時間に限りがあり、試験開始の120分後には上司との1on1ミーティングが設定されていました。しかも試験を開始してしまっているので上司に連絡も出来ないので、もうとにかく120分以内に終わらせることにしました。
結果的には見直しも含めてギリギリ120分で終わりましたが、前半で結構時間を使ったため、途中はかなり焦りました。時間はちゃんと確認しとけって話ですね。。
終わった時は正直あまり自信はありませんでした。択一式なら大体2択には絞れるのですが、最後どっちだっけ?と悩む問題が結構あったような気がします。「合格」の2文字を見た時は思わず安堵のため息が出ました。
今回の反省点と良かった点
反省点
反省点は主に2点です。
- 試験時間を事前に把握しておくべきだった
- 試験ガイドの出題内容をもっとちゃんと確認しておきべきだった
1は当たり前の話ですね。。
2は、WEB問題集とBlackBeltを見れば何とかなるだろうと高を括ってあまりちゃんと確認しなかったのですが、自分があまり知らないサービスが出題内容になっていないか、くらいはもっとちゃんと見るべきだったなと思います。
良かった点
これは受かったから言えることかもしれませんが、「まだ準備が万全ではないかも」と思いつつ、思い切って受験してしまったのは良かったと思っています。
1.5ヵ月ANSの勉強をして、正直ちょっと飽きてきていたので、思い切って3日後くらいに試験をセッティングしてしまいました。
そこから当日までは気合を入れて勉強できたので、ダレないように締切を自分でセッティングするのも大事かな、と思いました。
今後の勉強について
今回の試験でスコアが悪かった分野
スコアレポートでは出題分野毎のスコアパフォーマンスが出ますが、今回は以下の2分野について「改善が必要」の判定でした。
- 分野4:アプリケーションサービスとネットワークの連携を構成する
- 分野5:ネットワークの管理、最適化、トラブルシューティングを行う
各分野の詳細な内容は以下ページの「試験ガイドのダウンロード」から確認できますので、そちらを参照してください。
私は上記分野の中では、以下の内容についてあまり勉強してこなかったので、実際に使ったり調べたりして知見を増やしたいと思います。
- VPCフローログ
- CloudTrail
- CloudWatch
- 各種ヘルスチェック
比較的新しいネットワークサービス
ネットワークに関しては、比較的最近に以下のようなサービスが登場していますが、試験範囲には含まれていなそうだったので勉強していませんでした。
とはいえ、今後業務でAWSに携わるようになれば使う必要も出てくるかもしれないので、別途勉強したいと思います。
次に狙う資格
次はDVAを取って、アソシエイト3冠を達成したいと思います。
(オマケ)自宅受験について
自宅受験の際は、事前のシステムテストをちゃんとやった方が良い、と今回改めて思いました。
私は今回3回目の自宅受験で、過去2回も大きなトラブルはありませんでしたが、念のため、今回も事前にシステムテストを実施しました。
すると、「mDNSResponder
というバックグラウンドプロセスが動いている」とのことでシステムエラーが出ました。(知らない人のために説明しておくと、自宅受験の際には余計なバックグラウンドプロセスを停止させる必要があるのです。)
しかし、タスクマネージャーをいくら確認しても、mDNSResponder
というプロセスが見つからないのです。
そこでググってみると、mDNSResponder
はWindows10のタスクマネージャーではBonjour
という名前で表示されていることが分かりました。
もし事前にシステムテストをやっていなかったら、当日にこのエラーが出てきてもっとバタバタしていたに違いないし、最悪、試験が受けられなかったかもしれ
ないと思うとゾッとしました。。
おわりに
やや取り留めのない振り返りになってしまいましたが、以上です。またDVAに受かったら振り返りを行いたいと思います。
iptablesでインスタンスメタデータへのアクセスをブロックしてIAMロールの権限を無効化してみた
はじめに
今回は、EC2インスタンスのiptablesでインスタンスメタデータへのアクセスをブロックして、IAMロールの権限を無効化してみました。
試してみようと思ったきっかけは、AWSでのプロキシ利用について勉強していた時に、以下の記事を見つけたことです。
169.254.169.254はインスタンスメタデータへのアクセスに使われること、IAMロールの権限の利用にメタデータへのアクセスが必要であることが記載されています。
また、以下の記事にも同様の記載がありました。
これらを見て、「iptablesで169.254.169.254へのアクセスを制限すれば、IAMロールの権限が無効化されるのか?」を試してみたくなったので、やってみました。
今回の環境について
今回は、AmazonS3ReadOnlyAccessの権限をIAMロールで付与したEC2インスタンスを用意しました。
[cloudshell-user@ip-10-0-104-65 ~]$ aws ec2 describe-instances --region ap-northeast-1 --instance-ids i-xxxxxxxxxxxxxxxxx \ > --query Reservations[].Instances[].IamInstanceProfile.Arn \ > --output text arn:aws:iam::xxxxxxxxxxxxx:instance-profile/ec2-sample-s3readonly [cloudshell-user@ip-10-0-104-65 ~]$ [cloudshell-user@ip-10-0-104-65 ~]$ [cloudshell-user@ip-10-0-104-65 ~]$ [cloudshell-user@ip-10-0-104-65 ~]$ aws iam list-attached-role-policies --role-name ec2-sample-s3readonly { "AttachedPolicies": [ { "PolicyName": "AmazonS3ReadOnlyAccess", "PolicyArn": "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess" } ] } [cloudshell-user@ip-10-0-104-65 ~]$
また、対象のEC2インスタンスのバージョンは以下です。
[ec2-user@ip-10-0-11-11 ~]$ asw --version aws-cli/1.18.147 Python/2.7.18 Linux/4.14.225-168.357.amzn2.x86_64 botocore/1.18.6 [ec2-user@ip-10-0-11-11 ~]$
事前アクセス確認
まずはiptablesを設定する前に、インスタンスメタデータへのアクセスが可能であること、S3のリストが表示可能であることを確認してみます。
インスタンスメタデータへのアクセス
インスタンスメタデータへのアクセスは、curl http://169.254.169.254/latest/meta-data/
で実施します。また、IAMロールから提供されたセキュリティ認証情報は、メタデータの中のiam/security-credentials/<ロール名>
でアクセス可能です。
[ec2-user@ip-10-0-11-11 ~]$ curl http://169.254.169.254/latest/meta-data/ ami-id ami-launch-index ami-manifest-path block-device-mapping/ events/ hibernation/ hostname iam/ identity-credentials/ instance-action instance-id instance-life-cycle instance-type local-hostname local-ipv4 mac metrics/ network/ placement/ profile public-hostname public-ipv4 public-keys/ reservation-id security-groups services/[ec2-user@ip-10-0-11-11 ~] [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2-sample-s3readonly { "Code" : "Success", "LastUpdated" : "2021-08-22T06:40:36Z", "Type" : "AWS-HMAC", "AccessKeyId" : "ASIATxxxxxxxxxx73ZJD", "SecretAccessKey" : "/7ri3Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxo8Rn", "Token" : "~省略~", "Expiration" : "2021-08-22T13:15:46Z"
メタデータへのアクセスは問題ありませんでした。
S3へのアクセス
続いて、S3へのアクセスが問題ないか確認します。
[ec2-user@ip-10-0-11-11 ~]$ aws s3 ls 2021-05-16 09:21:40 cf-templates-xxxxxxxxxxxx-ap-northeast-1 [ec2-user@ip-10-0-11-11 ~]$
こちらも問題なく表示されました。
iptablesの設定
それではiptablesの設定をしていきます。
とはいったものの、そもそもiptablesはインストールされているのでしょうか?分からなかったので確認してみます。
iptablesの確認
[ec2-user@ip-10-0-11-11 ~]$ sudo which iptables /sbin/iptables [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ sudo iptables -nL Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination [ec2-user@ip-10-0-11-11 ~]$
コマンドはありますし、設定も一見すると存在するように見えますね。設定ファイルやサービスの有無はどうでしょうか。
[ec2-user@ip-10-0-11-11 ~]$ sudo systemctl list-unit-files --type=service | grep iptables [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ sudo cat /etc/sysconfig/iptables cat: /etc/sysconfig/iptables: No such file or directory [ec2-user@ip-10-0-11-11 ~]$
見つかりませんでした。どうも、「iptablesコマンドはあるけどiptablesサービスはない」状態みたいですね。。
iptablesサービスのインストール
このままだとコマンドが通ってもiptablesが効かないので、サービスをインストールします。
[ec2-user@ip-10-0-11-11 ~]$ sudo yum -y install iptables-services Loaded plugins: extras_suggestions, langpacks, priorities, update-motd amzn2-core | 3.7 kB 00:00 Resolving Dependencies --> Running transaction check ---> Package iptables-services.x86_64 0:1.8.4-10.amzn2.1.2 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: iptables-services x86_64 1.8.4-10.amzn2.1.2 amzn2-core 58 k Transaction Summary ================================================================================ Install 1 Package Total download size: 58 k Installed size: 24 k Downloading packages: iptables-services-1.8.4-10.amzn2.1.2.x86_64.rpm | 58 kB 00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : iptables-services-1.8.4-10.a [ ] 1/1 Installing : iptables-services-1.8.4-10.a [### ] 1/1 Installing : iptables-services-1.8.4-10.a [###### ] 1/1 Installing : iptables-services-1.8.4-10.a [####### ] 1/1 Installing : iptables-services-1.8.4-10.a [######## ] 1/1 Installing : iptables-services-1.8.4-10.a [################## ] 1/1 Installing : iptables-services-1.8.4-10.a [############################ ] 1/1 Installing : iptables-services-1.8.4-10.amzn2.1.2.x86_64 1/1 Verifying : iptables-services-1.8.4-10.amzn2.1.2.x86_64 1/1 Installed: iptables-services.x86_64 0:1.8.4-10.amzn2.1.2 Complete! [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$
インストールが出来たので、改めて設定ファイルやサービスの有無を確認してみます。
[ec2-user@ip-10-0-11-11 ~]$ sudo cat /etc/sysconfig/iptables # sample configuration for iptables service # you can edit this manually or use system-config-firewall # please do not ask us to add additional ports/services to this default configuration *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ sudo systemctl list-unit-files --type=service | grep iptables iptables.service disabled
問題ないようです。
iptablesの設定投入
それではiptablesの設定を入れていきます。メタデータへのアクセスはHTTPで行うので80番ポートだけ閉じれば大丈夫そうですが、今回は面倒なので169.254.169.254へのアクセスを全てDROPしてしまいます。
[ec2-user@ip-10-0-11-11 ~]$ sudo iptables -I OUTPUT 1 -p tcp -d 169.254.169.254 -j DROP [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ sudo iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination DROP tcp -- anywhere instance-data.ap-northeast-1.compute.internal [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ sudo service iptables save iptables: Saving firewall rules to /etc/sysconfig/iptables: [ OK ] [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ sudo service iptables restart Redirecting to /bin/systemctl restart iptables.service [ec2-user@ip-10-0-11-11 ~]$
" instance-data.ap-northeast-1.compute.internal "へのDROP設定が入りました。
事後アクセス確認
それでは再度メタデータとS3へのアクセスを確認してみます。
[ec2-user@ip-10-0-11-11 ~]$ curl http://169.254.169.254/latest/meta-data/ ^C [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2-sample-s3readonly ^C [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ aws s3 ls Unable to locate credentials. You can configure credentials by running "aws configure". [ec2-user@ip-10-0-11-11 ~]$
想定通り、メタデータとS3へのアクセスが出来なくなりました。
おわりに
というわけで、想定通りにiptablesでメタデータへのアクセスをブロックすることで、IAMロールの権限を無効化することができました。
実際にEC2インスタンスでiptablesを使う機会はあまり無いとは思いますが、メタデータが認証に使われていることが確認できて良かったです。
「AWSの基礎を学ぼう 特別編 最新サービスをみんなで触ってみる - Amazon Route 53 Resolver DNS Firewall」をJAWS-UG CLI支部チックにやってみた
はじめに
先日の7/31(土)に以下のハンズオンに参加しました。
今回は、ハンズオン当日にGUIで実施したDNS Firewallの設定を、CLIで実施してみたいと思います。
また、最近JAWS-UG CLI支部のハンズオンにちょくちょく参加するようになったので、折角なのでそちらで学習したお作法やコマンドを意識しながらやってみたいと思います。
JAWS-UG CLI支部についてはこちらをご参照ください。CLI手順だけでなく、サービスの特徴や運用の勘所なども学べて、とても勉強になります。
今回のハンズオンの内容と手順
今回のハンズオンの内容や手順については、以下にまとめられているのでこちらを参照ください。
今回は、上記手順の「3. DNS Firewall 設定」と「4. 動作確認」をCLIで実施していきます。
CLIでの手順
それでは、CLIでの手順を実際に見ていきます。CLIで実施する場合、マネジメントコンソールでの手順と一部順番が変わるので、その辺も確認しながらやっていきます。
0.動作環境と使用コマンド
今回は、以下の動作環境で作業を実施しました。
YuY:~/environment $ aws --version aws-cli/1.19.112 Python/2.7.18 Linux/4.14.238-182.422.amzn2.x86_64 botocore/1.20.112 YuY:~/environment $
DNS Firewallの設定は、route53resolver
コマンドで実施します。コマンドの詳細は以下を参照してください。
route53resolver — AWS CLI 1.20.11 Command Reference
なお、CLIバージョン2では、バージョン1で使用可能だったサブコマンドがいくつか無くなっているようで、以下の手順は実行できませんでした。詳細は後述します。
1.事前のDNSクエリ確認
まずは事前のDNSクエリ確認を実施します。ハンズオン手順の「Step 2-3」に該当する箇所です。
YuY:~/environment $ dig example.com ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> example.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35625 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;example.com. IN A ;; ANSWER SECTION: example.com. 300 IN A 93.184.216.34 ;; Query time: 2 msec ;; SERVER: 10.1.0.2#53(10.1.0.2) ;; WHEN: Sun Aug 01 08:13:09 UTC 2021 ;; MSG SIZE rcvd: 56 YuY:~/environment $
example.comのAレコードが返ってきていることが確認できます。
2.DNS Firewall ルールグループ作成
さて、いよいよここから本題のDNS Firewall設定です。まずはDNS Firewallのルールグループを作成します。
# ルールグループ名を定義 YuY:~/environment $ FW_RULE_GR_NAME='handson0731-gr' YuY:~/environment $ # ルールグループを作成 YuY:~/environment $ aws route53resolver create-firewall-rule-group \ > --name ${FW_RULE_GR_NAME} { "FirewallRuleGroup": { "Status": "COMPLETE", "Name": "handson0731-gr", "CreationTime": "2021-08-01T08:44:58.245974Z", "CreatorRequestId": "988bb4be-db45-419a-869e-e8624732a249", "ModificationTime": "2021-08-01T08:44:58.245974Z", "ShareStatus": "NOT_SHARED", "Arn": "arn:aws:route53resolver:ap-northeast-1:XXXXXXXXXXXX:firewall-rule-group/rslvr-frg-3f7127xxxxxxxxxx", "RuleCount": 0, "OwnerId": "XXXXXXXXXXXX", "Id": "rslvr-frg-3f7127xxxxxxxxxx", "StatusMessage": "Created Firewall Rule Group" } } YuY:~/environment $ # ルールグループIDの取得 YuY:~/environment $ FW_RULE_GR_ID=$( \ > aws route53resolver list-firewall-rule-groups \ > --query FirewallRuleGroups[?Name==\`${FW_RULE_GR_NAME}\`].Id \ > --output text \ > ) \ > && echo ${FW_RULE_GR_ID} rslvr-frg-3f7127xxxxxxxxxx YuY:~/environment $
ルールグループIDを取得する理由は、この後のコマンドで引数として必要になるためです。
3.ドメインリスト作成
続いて、フィルタリングルールを作る前に、先にドメインリストの作成を実施します。CLIの場合、フィルタリングルールの作成時にドメインリストIDを指定する必要があるためです。
# ドメインリスト名を定義 YuY:~/environment $ DOMAIN_LIST_NAME='example-list' YuY:~/environment $ # ドメインリストを作成 YuY:~/environment $ aws route53resolver create-firewall-domain-list \ > --name ${DOMAIN_LIST_NAME} { "FirewallDomainList": { "Status": "COMPLETE", "Name": "example-list", "CreationTime": "2021-08-01T09:21:15.074053Z", "CreatorRequestId": "4698e450-6c16-4115-8e38-eed0efb99e78", "ModificationTime": "2021-08-01T09:21:15.074053Z", "Arn": "arn:aws:route53resolver:ap-northeast-1:XXXXXXXXXXXX:firewall-domain-list/rslvr-fdl-7a6d3xxxxxxxxxx", "DomainCount": 0, "Id": "rslvr-fdl-7a6d3xxxxxxxxxx", "StatusMessage": "Created Firewall Domain List" } } YuY:~/environment $ # ドメインリストIDの取得 YuY:~/environment $ FW_DOMAIN_LIST_ID=$( \ > aws route53resolver list-firewall-domain-lists \ > --query "FirewallDomainLists[?Name==\`${DOMAIN_LIST_NAME}\`].Id" \ > --output text \ > ) \ > && echo ${FW_DOMAIN_LIST_ID} rslvr-fdl-7a6d3xxxxxxxxxx YuY:~/environment $
ドメインリストIDも、ルールグループID同様、この後のコマンドで引数として必要となります。
4.ドメインリストへのドメインの追加
続いて、ドメインリストにドメイン「example.com」を追加します。
# ドメインの定義 YuY:~/environment $ FW_DOMAIN='example.com' YuY:~/environment $ # ドメインリストへのドメインの追加 YuY:~/environment $ aws route53resolver update-firewall-domains \ > --firewall-domain-list-id ${FW_DOMAIN_LIST_ID} \ > --operation ADD \ > --domains ${FW_DOMAIN} { "Status": "COMPLETE", "Id": "rslvr-fdl-7a6d3d4778xxxxx", "StatusMessage": "Created Firewall Domain List", "Name": "example-list" } YuY:~/environment $ # ドメインの追加の確認 YuY:~/environment $ aws route53resolver list-firewall-domains \ > --firewall-domain-list-id ${FW_DOMAIN_LIST_ID} \ > --query "Domains[]" \ > --output text example.com. YuY:~/environment $
5.フィルタリングルール作成
続いて、フィルタリングルールを作成します。
# フィルタリングルール名を定義 YuY:~/environment $ FW_RULE_NAME='handson0731-rule' YuY:~/environment $ # フィルタリングルールを設定 YuY:~/environment $ aws route53resolver create-firewall-rule \ > --name ${FW_RULE_NAME} \ > --firewall-rule-group-id ${FW_RULE_GR_ID} \ > --firewall-domain-list-id ${FW_DOMAIN_LIST_ID} \ > --action BLOCK \ > --block-response NODATA \ > --priority 1 { "FirewallRule": { "Name": "handson0731-rule", "CreationTime": "2021-08-01T11:52:21.983902Z", "CreatorRequestId": "7dfbada3-455a-420b-975a-5a4c489761a1", "ModificationTime": "2021-08-01T11:52:21.983902Z", "Priority": 1, "BlockResponse": "NODATA", "FirewallDomainListId": "rslvr-fdl-7a6d3xxxxxxxxxx", "Action": "BLOCK", "FirewallRuleGroupId": "rslvr-frg-3f7127xxxxxxxxxx" } } YuY:~/environment $
6.ルールグループにVPCを関連付け
続いて、ルールグループにVPCを関連付けます。関連付けにはVPC IDが必要なので、まずはVPC IDを取得します。
# VPC名の定義 YuY:~/environment $ FW_VPC_NAME='handson-dns-firewall-20210731-VPC' YuY:~/environment $ # VPC IDの取得 YuY:~/environment $ FW_VPC_ID=$( \ > aws ec2 describe-tags --filter "Name=tag-value,Values=${FW_VPC_NAME}" \ > --query "Tags[].ResourceId" \ > --output text \ > ) \ > && echo ${FW_VPC_ID} vpc-0808ed7xxxxxxxxxx YuY:~/environment $
VPC名は、「{ハンズオン手順のStep1-2で入力したスタック名}-VPC」になっているかと思います。(ハンズオン手順では「handson0731」になっていますが、私は「handson-dns-firewall-20210731」と入力していたため、そちらを指定しています。)
VPC IDが取得できたら、ルールグループにVPCを関連付けます。
# 関連付け名の定義 YuY:~/environment $ FW_ASSOCIATE_NAME='handson-dns-firewall-20210731' YuY:~/environment $ # 関連付け YuY:~/environment $ aws route53resolver associate-firewall-rule-group \ > --firewall-rule-group-id ${FW_RULE_GR_ID} \ > --vpc-id ${FW_VPC_ID} \ > --priority 101 \ > --name ${FW_ASSOCIATE_NAME} { "FirewallRuleGroupAssociation": { "Status": "UPDATING", "VpcId": "vpc-0808ed7xxxxxxxxxx", "Name": "handson-dns-firewall-20210731", "CreationTime": "2021-08-01T12:10:42.351432Z", "MutationProtection": "DISABLED", "CreatorRequestId": "3c68e290-da71-476e-bb26-7f108683b938", "ModificationTime": "2021-08-01T12:10:42.351432Z", "Priority": 101, "StatusMessage": "Creating Firewall Rule Group Association", "Id": "rslvr-frgassoc-7a0ba2xxxxxxxxxx", "Arn": "arn:aws:route53resolver:ap-northeast-1:XXXXXXXXXXXX:firewall-rule-group-association/rslvr-frgassoc-7a0ba2xxxxxxxxxx", "FirewallRuleGroupId": "rslvr-frg-3f7127xxxxxxxxxx" } } YuY:~/environment $
上記を見ると、Statusが"UPDATING"、StatusMessageが"Creating Firewall Rule Group Association"となっており、まだ関連付けが完了していないことが分かります。そのため、少し時間を置いてから、次の手順で再度StatusとStatusMessageを取得します。
7.ルールグループへのVPC関連付けの完了確認
再度StatusとStatusMessageを取得、関連付けが完了したことを確認します。
# 関連付けIDの取得 YuY:~/environment $ FW_ASSOCIATION_ID=$( \ > aws route53resolver list-firewall-rule-group-associations \ > --firewall-rule-group-id ${FW_RULE_GR_ID} \ > --query "FirewallRuleGroupAssociations[].Id" \ > --output text \ > ) \ > && echo ${FW_ASSOCIATION_ID} rslvr-frgassoc-7a0ba2xxxxxxxxxx YuY:~/environment $ # Status、StatusMessageの取得 YuY:~/environment $ aws route53resolver get-firewall-rule-group-association \ > --firewall-rule-group-association-id ${FW_ASSOCIATION_ID} \ > --query "FirewallRuleGroupAssociation.[Status, StatusMessage]" \ > --output text COMPLETE Finished rule group association update YuY:~/environment $
Statusが「COMPLETE」、StatusMessageが「Finished rule group association update」に変わりました。
8.動作確認
DNS Firewallの設定が一通り終わったので、改めて動作確認します。ハンズオン手順の「4.動作確認」の部分です。
YuY:~/environment $ dig example.com ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> example.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1611 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;example.com. IN A ;; Query time: 3 msec ;; SERVER: 10.1.0.2#53(10.1.0.2) ;; WHEN: Sun Aug 01 12:26:30 UTC 2021 ;; MSG SIZE rcvd: 40 YuY:~/environment $ YuY:~/environment $ YuY:~/environment $ YuY:~/environment $ dig example.com @8.8.8.8 ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.amzn2.5.2 <<>> example.com @8.8.8.8 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14379 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;example.com. IN A ;; ANSWER SECTION: example.com. 20694 IN A 93.184.216.34 ;; Query time: 3 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Sun Aug 01 12:27:02 UTC 2021 ;; MSG SIZE rcvd: 56 YuY:~/environment $
ハンズオン手順と同じ結果になりました。どうやら問題なくDNS Firewallの設定が出来たようです。
補足:CLIバージョン1とバージョン2の差異について
冒頭にも記載した通り、今回のCLI手順はCLIバージョン1での手順となります。CLIバージョン2では「create-firewall-rule-group」等のサブコマンドが使えないらしく、同じ手順を実行することが出来ませんでした。
以下に、バージョン1とバージョン2で使用できるサブコマンドの差分を記載します。※マイナーバージョンの違いでも差分が出るかもしれないので、一例として見てください。
# aws cliバージョン1の場合 YuY:~/environment $ aws --version aws-cli/1.19.112 Python/2.7.18 Linux/4.14.238-182.422.amzn2.x86_64 botocore/1.20.112 YuY:~/environment $ YuY:~/environment $ YuY:~/environment $ aws route53resolver associate-firewall-rule-group get-resolver-rule associate-resolver-endpoint-ip-address get-resolver-rule-association associate-resolver-query-log-config get-resolver-rule-policy associate-resolver-rule import-firewall-domains create-firewall-domain-list list-firewall-configs create-firewall-rule list-firewall-domain-lists create-firewall-rule-group list-firewall-domains create-resolver-endpoint list-firewall-rule-group-associations create-resolver-query-log-config list-firewall-rule-groups create-resolver-rule list-firewall-rules delete-firewall-domain-list list-resolver-dnssec-configs delete-firewall-rule list-resolver-endpoint-ip-addresses delete-firewall-rule-group list-resolver-endpoints delete-resolver-endpoint list-resolver-query-log-config-associations delete-resolver-query-log-config list-resolver-query-log-configs delete-resolver-rule list-resolver-rule-associations disassociate-firewall-rule-group list-resolver-rules disassociate-resolver-endpoint-ip-address list-tags-for-resource disassociate-resolver-query-log-config put-firewall-rule-group-policy disassociate-resolver-rule put-resolver-query-log-config-policy get-firewall-config put-resolver-rule-policy get-firewall-domain-list tag-resource get-firewall-rule-group untag-resource get-firewall-rule-group-association update-firewall-config get-firewall-rule-group-policy update-firewall-domains get-resolver-dnssec-config update-firewall-rule get-resolver-endpoint update-firewall-rule-group-association get-resolver-query-log-config update-resolver-dnssec-config get-resolver-query-log-config-association update-resolver-endpoint get-resolver-query-log-config-policy update-resolver-rule YuY:~/environment $ # aws cliバージョン2の場合 [cloudshell-user@ip-10-0-141-253 ~]$ aws --version aws-cli/2.1.28 Python/3.8.8 Linux/4.14.225-168.357.amzn2.x86_64 exec-env/CloudShell exe/x86_64.amzn.2 prompt/off [cloudshell-user@ip-10-0-141-253 ~]$ [cloudshell-user@ip-10-0-141-253 ~]$ aws route53resolver associate-resolver-endpoint-ip-address delete-resolver-query-log-config get-resolver-query-log-config list-resolver-endpoint-ip-addresses put-resolver-query-log-config-policy associate-resolver-query-log-config delete-resolver-rule get-resolver-query-log-config-association list-resolver-endpoints put-resolver-rule-policy associate-resolver-rule disassociate-resolver-endpoint-ip-address get-resolver-query-log-config-policy list-resolver-query-log-config-associations tag-resource create-resolver-endpoint disassociate-resolver-query-log-config get-resolver-rule list-resolver-query-log-configs untag-resource create-resolver-query-log-config disassociate-resolver-rule get-resolver-rule-association list-resolver-rule-associations update-resolver-dnssec-config create-resolver-rule get-resolver-dnssec-config get-resolver-rule-policy list-resolver-rules update-resolver-endpoint delete-resolver-endpoint get-resolver-endpoint list-resolver-dnssec-configs list-tags-for-resource update-resolver-rule [cloudshell-user@ip-10-0-141-253 ~]$
aws-cliバージョン2の場合に、DNS Firewallの設定をCLIでどのように実施すればよいのかは、少し調べてみただけではよく分かりませんでした。また機会がある時に調査したいと思います。
おわりに
というわけで、CLIでDNS Firewallの設定をすることが出来ました。
手順書の内容をコピペするだけではなく、これまで勉強した事を活かしながら手探りでやって、結果的に上手くいったので良かったです。
ただ、ハンズオン手順の「5.DNSクエリログの記録」と「6.片付け」がまだ残っているため、今度はそちらもCLIで実施したいと思います。
追伸:今回、「JAWS-UG CLI支部チックにやる」と冒頭で記載しましたが、CLI支部では変数を定義した時には必ずヒアドキュメントで中身の確認をしているのに、今回は省略しちゃいました。この辺、まだまだ徹底が足りないですね。
CloudFormationでVPCピアリングを設定し通信確認してみた
はじめに
これまで、本ブログでの「やってみた」系の記事は全て、JAWS-UGハンズオンの復習だけでしたが、そろそろ自分でテーマを決めて構築や検証をしてみようと思います。
その際、今後の業務利用も見据え、構築は出来るだけCloudFormation等のIaCツールを使用して実施してみます。それと、折角JAWS-UG CLI専門支部でCLIを扱っているので、リソースの確認はCLIで確認したいと思います。
というわけで、今回はタイトル通り、CloudFormationでVPCピアリングを設定し、通信確認を行ってみます。非常にシンプルな構成なので、入り口としては丁度良さそうです。
VPCピアリングを試そうと思った理由は、ちょうど今「AWS 認定 高度なネットワーキング – 専門知識」の学習中で、「インプットした記憶をアウトプットによって定着させたい」と思ったためです。そのため、今後も資格取得まではネットワーク系の構築と検証が中心になる予定です。(DirectConnectは個人環境で試すのがちょっと難しいですが。。)
今回の構成と試すこと
今回は、3つのVPCを作成し、下図のようにVPCピアリング接続を行い、ルーティング設定を行います。クライアントPCから各EC2にSSH接続するため、インターネット接続設定もしておきます。
また、各EC2のセキュリティグループでは、他のVPCのCIDRからのインバウンド通信は全て許可する設定を入れておきます。
VPCピアリングではトランジット接続は出来ないため、たとえルーティング設定と通信許可設定を行っていても、VPC1とVPC3は通信が出来ないことを確認します。
今回構築に使用するCloudFormationテンプレ
今回構築に使用するCloudFormationテンプレートですが、このブログに直接貼り付けると結構な行数になってしまうので、こちらに格納しました。
CloudFormationをちゃんと使うのは初めてなので、CIDRブロックやAMI IDがベタ書きだったりして色々と粗がありますが、徐々にマシなものが書けるようになりたいと思います。
あと、実はGitHubを使うのも初めてだったりします。一応IT業界には7~8年くらいいるのですが、今まで全く触れる機会がありませんでした。使わない所は使わないものですね。
とはいえ今後いつ必要になるか分からないし、折角なのでこの機会に使い始めて、慣れておきたいと思います。
CLIによるリソースの確認
上記テンプレートによる環境構築が完了したので、CLIでリソースの確認をしてみます。今回はCloudShellを使用します。
CLIコマンドについては、こちらのブログをかなり参考にさせていただきました。
# VPCの確認(VPCID、CIDRブロック、状態、テナンシー) [cloudshell-user@ip-10-0-131-98 ~]$ aws ec2 describe-vpcs \ > --filters "Name=tag-value,Values=handson-vpc*" \ > --output text \ > --query "Vpcs[].[Tags[?Key=='Name'] > | [0].Value,VpcId,CidrBlock,State,InstanceTenancy]" \ > | sort handson-vpc-peering1 vpc-0932bf14cf664577f 10.100.0.0/16 available default handson-vpc-peering2 vpc-0f5af64c8262401f0 10.200.0.0/16 available default handson-vpc-peering3 vpc-0150bd49c56f4f085 10.50.0.0/16 available default [cloudshell-user@ip-10-0-131-98 ~]$ [cloudshell-user@ip-10-0-131-98 ~]$ #サブネットの確認(VPCID、CIDRブロック、利用可能アドレス数、サブネットID、AZ、状態) [cloudshell-user@ip-10-0-131-98 ~]$ aws ec2 describe-subnets \ > --filters "Name=tag-value,Values=handson-vpc*" \ > --query "Subnets[].[Tags[?Key=='Name'] \ > | [0].Value,VpcId,CidrBlock,AvailableIpAddressCount,SubnetId,AvailabilityZone,MapPublicIpOnLaunch,State]" \ > --output text \ > | sort handson-vpc-peering1 vpc-0932bf14cf664577f 10.100.0.0/24 250 subnet-05283462e7cd5044d ap-northeast-1a True available handson-vpc-peering2 vpc-0f5af64c8262401f0 10.200.0.0/24 250 subnet-082fe1abac42bd13c ap-northeast-1c True available handson-vpc-peering3 vpc-0150bd49c56f4f085 10.50.0.0/24 250 subnet-02bf2ccee82e23c16 ap-northeast-1c True available [cloudshell-user@ip-10-0-131-98 ~]$ [cloudshell-user@ip-10-0-131-98 ~]$ #ルートテーブルの確認1(サブネットID、ルートテーブルID、メインルートかどうか、関連付けられたサブネットがあるか) [cloudshell-user@ip-10-0-131-98 ~]$ aws ec2 describe-route-tables \ > --filters "Name=tag-value,Values=handson-vpc*" \ > --query "RouteTables[].Associations[].[SubnetId,RouteTableId,Main,AssociationState.State]" \ > --output text \ > | sort | column -t subnet-02bf2ccee82e23c16 rtb-09af531f07f2cd06f False associated subnet-05283462e7cd5044d rtb-09abdfe97a306a035 False associated subnet-082fe1abac42bd13c rtb-0e3a628ee0d845da7 False associated [cloudshell-user@ip-10-0-131-98 ~]$ [cloudshell-user@ip-10-0-131-98 ~]$ #ルートテーブルの確認2(ルートテーブルID、経路) [cloudshell-user@ip-10-0-131-98 ~]$ aws ec2 describe-route-tables \ > --filters "Name=tag-value,Values=handson-vpc*" \ > --query "RouteTables[].[Associations[].[RouteTableId],Routes]" \ > --output text rtb-09af531f07f2cd06f 10.100.0.0/24 CreateRoute active pcx-0dbfc21a4ec1e1609 10.200.0.0/24 CreateRoute active pcx-0dbfc21a4ec1e1609 10.50.0.0/16 local CreateRouteTable active 0.0.0.0/0 igw-0a6cbcd0152530b46 CreateRoute active rtb-0e3a628ee0d845da7 10.50.0.0/24 CreateRoute active pcx-0dbfc21a4ec1e1609 10.100.0.0/24 CreateRoute active pcx-0b9cd821777935106 10.200.0.0/16 local CreateRouteTable active 0.0.0.0/0 igw-0628af6c9db7c71d6 CreateRoute active rtb-09abdfe97a306a035 10.50.0.0/24 CreateRoute active pcx-0b9cd821777935106 10.200.0.0/24 CreateRoute active pcx-0b9cd821777935106 10.100.0.0/16 local CreateRouteTable active 0.0.0.0/0 igw-0bada0d7405535216 CreateRoute active [cloudshell-user@ip-10-0-131-98 ~]$ [cloudshell-user@ip-10-0-131-98 ~]$ #インターネットゲートウェイの確認 [cloudshell-user@ip-10-0-131-98 ~]$ aws ec2 describe-internet-gateways \ > --filters "Name=tag-value,Values=handson-vpc*" \ > --query "InternetGateways[].{InternetGatewayId:InternetGatewayId,VpcId:Attachments[0].VpcId}" \ > --output table ---------------------------------------------------- | DescribeInternetGateways | +------------------------+-------------------------+ | InternetGatewayId | VpcId | +------------------------+-------------------------+ | igw-0628af6c9db7c71d6 | vpc-0f5af64c8262401f0 | | igw-0a6cbcd0152530b46 | vpc-0150bd49c56f4f085 | | igw-0bada0d7405535216 | vpc-0932bf14cf664577f | +------------------------+-------------------------+ [cloudshell-user@ip-10-0-131-98 ~]$ [cloudshell-user@ip-10-0-131-98 ~]$ #VPCピアリングの確認(VPCピアリングコネクションID、CIDRブロック) [cloudshell-user@ip-10-0-131-98 ~]$ aws ec2 describe-vpc-peering-connections \ > --filters "Name=status-code,Values=active" \ > --query "VpcPeeringConnections[].[VpcPeeringConnectionId,AccepterVpcInfo.CidrBlock,RequesterVpcInfo.CidrBlock]" \ > --output text pcx-0dbfc21a4ec1e1609 10.50.0.0/16 10.200.0.0/16 pcx-0b9cd821777935106 10.200.0.0/16 10.100.0.0/16 [cloudshell-user@ip-10-0-131-98 ~]$ [cloudshell-user@ip-10-0-131-98 ~]$ #EC2インスタンス(プライベートIP、グローバルIP、タグ名、CloudFormationロジカルID) [cloudshell-user@ip-10-0-131-98 ~]$ aws ec2 describe-instances \ > --filters "Name=tag-value,Values=handson-vpc*" \ > --query "Reservations[].Instances[].[PrivateIpAddress,PublicIpAddress,Tags[?Key=='Name'].[Value],Tags[?Key=='aws:cloudformation:logical-id'].[Value]]" \ > --output text 10.50.0.215 13.112.80.211 handson-vpc-peering3 EC2C 10.200.0.230 3.112.25.175 handson-vpc-peering2 EC2B 10.100.0.199 18.176.59.141 handson-vpc-peering1 EC2A [cloudshell-user@ip-10-0-131-98 ~]$ #セキュリティグループの確認(Description、プロトコル、CIDRブロック) [cloudshell-user@ip-10-0-131-98 ~]$ aws ec2 describe-security-groups \ > --filters "Name=tag-value,Values=handson-vpc*" \ > --query "SecurityGroups[].[Description,IpPermissions]" \ > --output text Security Group for VPC2 -1 #すべてのプロトコル IPRANGES 10.100.0.0/16 IPRANGES 10.50.0.0/16 22 tcp 22 IPRANGES XXX.XXX.XXX.XXX/32 #クライアントPCのグローバルIP Security Group for VPC1 -1 #すべてのプロトコル IPRANGES 10.50.0.0/16 IPRANGES 10.200.0.0/16 22 tcp 22 IPRANGES XXX.XXX.XXX.XXX/32 #クライアントPCのグローバルIP Security Group for VPC3 -1 #すべてのプロトコル IPRANGES 10.200.0.0/16 IPRANGES 10.100.0.0/16 22 tcp 22 IPRANGES XXX.XXX.XXX.XXX/32 #クライアントPCのグローバルIP [cloudshell-user@ip-10-0-131-98 ~]$
どうやらリソースは問題なく作成されていそうですので、クライアントPCから各EC2へSSH接続して、他のEC2への通信確認をしてみたいと思います。
通信確認
それでは、各EC2インスタンスにSSHログインして、他のVPCのEC2インスタンスにPingを打ってみます。
#EC2AからEC2BへのPing [ec2-user@ip-10-100-0-199 ~]$ [ec2-user@ip-10-100-0-199 ~]$ ping 10.200.0.230 PING 10.200.0.230 (10.200.0.230) 56(84) bytes of data. 64 bytes from 10.200.0.230: icmp_seq=1 ttl=255 time=1.63 ms 64 bytes from 10.200.0.230: icmp_seq=2 ttl=255 time=1.60 ms 64 bytes from 10.200.0.230: icmp_seq=3 ttl=255 time=1.59 ms 64 bytes from 10.200.0.230: icmp_seq=4 ttl=255 time=1.61 ms 64 bytes from 10.200.0.230: icmp_seq=5 ttl=255 time=1.58 ms ^C --- 10.200.0.230 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4006ms rtt min/avg/max/mdev = 1.587/1.608/1.631/0.015 ms [ec2-user@ip-10-100-0-199 ~]$ #EC2AからEC2CへのPing [ec2-user@ip-10-100-0-199 ~]$ ping 10.50.0.215 PING 10.50.0.215 (10.50.0.215) 56(84) bytes of data. ^C --- 10.50.0.215 ping statistics --- 10 packets transmitted, 0 received, 100% packet loss, time 9198ms [ec2-user@ip-10-100-0-199 ~]$ [ec2-user@ip-10-100-0-199 ~]$ #EC2BからEC2AへPing [ec2-user@ip-10-200-0-230 ~]$ [ec2-user@ip-10-200-0-230 ~]$ ping 10.100.0.199 PING 10.100.0.199 (10.100.0.199) 56(84) bytes of data. 64 bytes from 10.100.0.199: icmp_seq=1 ttl=255 time=1.88 ms 64 bytes from 10.100.0.199: icmp_seq=2 ttl=255 time=1.66 ms 64 bytes from 10.100.0.199: icmp_seq=3 ttl=255 time=1.67 ms 64 bytes from 10.100.0.199: icmp_seq=4 ttl=255 time=1.59 ms 64 bytes from 10.100.0.199: icmp_seq=5 ttl=255 time=1.59 ms ^C --- 10.100.0.199 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4006ms rtt min/avg/max/mdev = 1.593/1.682/1.880/0.108 ms [ec2-user@ip-10-200-0-230 ~]$ [ec2-user@ip-10-200-0-230 ~]$ #EC2BからEC2CへPing [ec2-user@ip-10-200-0-230 ~]$ [ec2-user@ip-10-200-0-230 ~]$ ping 10.50.0.215 PING 10.50.0.215 (10.50.0.215) 56(84) bytes of data. 64 bytes from 10.50.0.215: icmp_seq=1 ttl=255 time=0.572 ms 64 bytes from 10.50.0.215: icmp_seq=2 ttl=255 time=0.390 ms 64 bytes from 10.50.0.215: icmp_seq=3 ttl=255 time=0.178 ms 64 bytes from 10.50.0.215: icmp_seq=4 ttl=255 time=0.181 ms 64 bytes from 10.50.0.215: icmp_seq=5 ttl=255 time=0.218 ms ^C --- 10.50.0.215 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4093ms rtt min/avg/max/mdev = 0.178/0.307/0.572/0.154 ms [ec2-user@ip-10-200-0-230 ~]$ [ec2-user@ip-10-200-0-230 ~]$ #EC2CからEC2AへPing [ec2-user@ip-10-50-0-215 ~]$ [ec2-user@ip-10-50-0-215 ~]$ ping 10.100.0.199 PING 10.100.0.199 (10.100.0.199) 56(84) bytes of data. ^C --- 10.100.0.199 ping statistics --- 9 packets transmitted, 0 received, 100% packet loss, time 8176ms [ec2-user@ip-10-50-0-215 ~]$ [ec2-user@ip-10-50-0-215 ~]$ #EC2CからEC2BへPing [ec2-user@ip-10-50-0-215 ~]$ [ec2-user@ip-10-50-0-215 ~]$ ping 10.200.0.230 PING 10.200.0.230 (10.200.0.230) 56(84) bytes of data. 64 bytes from 10.200.0.230: icmp_seq=1 ttl=255 time=0.214 ms 64 bytes from 10.200.0.230: icmp_seq=2 ttl=255 time=0.178 ms 64 bytes from 10.200.0.230: icmp_seq=3 ttl=255 time=0.230 ms 64 bytes from 10.200.0.230: icmp_seq=4 ttl=255 time=0.202 ms 64 bytes from 10.200.0.230: icmp_seq=5 ttl=255 time=0.225 ms ^C --- 10.200.0.230 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4094ms rtt min/avg/max/mdev = 0.178/0.209/0.230/0.026 ms [ec2-user@ip-10-50-0-215 ~]$
想定通り、VPCピアリングをトランジットした通信は(ルーティング設定を行ってセキュリティグループで許可設定しても)出来ませんでした。
おわりに
今回はVPCピアリングの基本的な確認でした。非常に簡便な構成でしたが、CloudFormationでの環境構築やCLIでのリソース確認、GitHubの使用など、本題以外の不慣れな部分で結構時間がかかってしまいました。。もっと数をこなして、検証やアウトプットをスピーディに出来るようになりたいですね。
あと、今回はCloudFormationのスタック作成・削除をマネジメントコンソールで実施しましたが、次回以降はこれもCLIで実施してみようと思います。