[小ネタ] AWS CLI でリソース間の設定差異を確認する

2017.02.24

こんにちは、藤本です。

小ネタです。AWS CLI の話じゃなく、diffコマンドのお話です。diffって一度ファイル出力せずともコマンド結果を比較できたんですね。知らなかった。

AWS を運用していて、既存のものと同じものを作りたい時ないでしょうか? EC2 であれば、[Launch More Like This] アクションから同じ設定ものを起動できますが、それ以外のリソースはできません。もちろん CloudFormationや、Terraform などでコード化しておけば容易でしょうが、単発作業のリソース複製となると、どうしても人の手を介し、確認を行う必要があります。マネジメントコンソールからの確認ではどうしても目grep には限界があります。見逃しが発生します。既にあるリソースとの比較をより確実に確認するにはコマンド結果の比較が分かりやすいです。今までコマンド結果をファイルに落とし込んで、diffしていたのですが、パイプを利用すると、一度ファイル出力せずに比較できました。

例えば、EC2インスタンスの比較

$ diff -u <(aws ec2 describe-instances --instance-ids i-05efff70862a4b110) <(aws ec2 describe-instances --instance-ids i-02575626c03aa30e9)
--- /dev/fd/11  2017-02-24 09:32:43.000000000 +0900
+++ /dev/fd/12  2017-02-24 09:32:43.000000000 +0900
@@ -2,29 +2,29 @@
     "Reservations": [
         {
             "OwnerId": "xxxxxxxxxx",
-            "ReservationId": "r-0368192b0b5b56d87",
+            "ReservationId": "r-0533e9a6a00b27f9a",
             "Groups": [],
             "Instances": [
                 {
                     "Monitoring": {
                         "State": "disabled"
                     },
-                    "PublicDnsName": "ec2-13-113-45-87.ap-northeast-1.compute.amazonaws.com",
+                    "PublicDnsName": "ec2-52-198-31-171.ap-northeast-1.compute.amazonaws.com",
                     "State": {
                         "Code": 16,
                         "Name": "running"
                     },
                     "EbsOptimized": false,
-                    "LaunchTime": "2017-02-24T00:15:24.000Z",
-                    "PublicIpAddress": "13.113.45.87",
-                    "PrivateIpAddress": "172.31.1.164",
+                    "LaunchTime": "2017-01-27T08:56:04.000Z",
+                    "PublicIpAddress": "52.198.31.171",
+                    "PrivateIpAddress": "172.31.23.196",
                     "ProductCodes": [],
                     "VpcId": "vpc-b8353bdd",
                     "StateTransitionReason": "",
-                    "InstanceId": "i-05efff70862a4b110",
+                    "InstanceId": "i-02575626c03aa30e9",
                     "EnaSupport": true,
-                    "ImageId": "ami-56d4ad31",
-                    "PrivateDnsName": "ip-172-31-1-164.ap-northeast-1.compute.internal",
+                    "ImageId": "ami-2443b745",
+                    "PrivateDnsName": "ip-172-31-23-196.ap-northeast-1.compute.internal",
                     "KeyName": "cm-fujimoto",
                     "SecurityGroups": [
                         {
@@ -40,41 +40,41 @@
                             "GroupId": "sg-f9c7d49d"
                         }
                     ],
-                    "ClientToken": "iSLAt1487895323396",
-                    "SubnetId": "subnet-2ebda977",
-                    "InstanceType": "t2.micro",
+                    "ClientToken": "QouYP1472477960536",
+                    "SubnetId": "subnet-617abf17",
+                    "InstanceType": "t2.nano",
                     "NetworkInterfaces": [
                         {
                             "Status": "in-use",
-                            "MacAddress": "0a:de:cd:e1:9b:23",
+                            "MacAddress": "06:38:02:25:aa:b1",
                             "SourceDestCheck": false,
                             "VpcId": "vpc-b8353bdd",
                             "Description": "Primary network interface",
                             "Association": {
-                                "PublicIp": "13.113.45.87",
-                                "PublicDnsName": "ec2-13-113-45-87.ap-northeast-1.compute.amazonaws.com",
-                                "IpOwnerId": "amazon"
+                                "PublicIp": "52.198.31.171",
+                                "PublicDnsName": "ec2-52-198-31-171.ap-northeast-1.compute.amazonaws.com",
+                                "IpOwnerId": "xxxxxxxxxxx"
                             },
-                            "NetworkInterfaceId": "eni-9e2624c1",
+                            "NetworkInterfaceId": "eni-3588157f",
                             "PrivateIpAddresses": [
                                 {
-                                    "PrivateDnsName": "ip-172-31-1-164.ap-northeast-1.compute.internal",
+                                    "PrivateDnsName": "ip-172-31-23-196.ap-northeast-1.compute.internal",
                                     "Association": {
-                                        "PublicIp": "13.113.45.87",
-                                        "PublicDnsName": "ec2-13-113-45-87.ap-northeast-1.compute.amazonaws.com",
-                                        "IpOwnerId": "amazon"
+                                        "PublicIp": "52.198.31.171",
+                                        "PublicDnsName": "ec2-52-198-31-171.ap-northeast-1.compute.amazonaws.com",
+                                        "IpOwnerId": "xxxxxxxxxxx"
: (省略)

おー、diff できてます!どうしても IPアドレスや、リソースIDなど固有のもので差分が発生しますが、インスタンスタイプの違い、サブネットの違いなどが確認できます。

、、、でもJSON だとインデントが大きくなると、差異を表す「+」、「-」がどこにかかっているのか分かりづらい。

そういえば、先日、どこかのブログで iTerm2 で特定の文字をハイライトする記事を見ました。

特定キーワードをハイライト表示してコマンド実行前に注意喚起する(iTerm2)

こんなルールを作って、、、

スクリーンショット_2017_02_24_9_38

diff すると、、、

1__fujimoto_shinji_HL00120_____zsh_

見やすい!!

ELB の比較も、、、

1__fujimoto_shinji_HL00120_____zsh_ 2

見やすい!!!

まとめ

いかがでしたでしょうか?
割と一般的な知識なのかもしれませんが、私のようにご存じない方の参考になりますと幸いです。こういう単発なテストを簡単に自動化する方法がほしい。