GASを使ってALBのIPアドレス変更を検知しSlackへ通知する
世の中の数多くのサービスがAWSやAzure,GCPなどのクラウドにホストされることが普通になり,オンプレの時に比べてサーバや各種リソースのIPアドレスが動的に変わることが増えてきた.そんななか,業務でどうしてもクラウドで動作中のリソースに紐づいているIPアドレスの変更を検知して通知する仕組みが必要だったので,今日はその方法を紹介しようと思う.
前提
今回はAWSのロードバランサの1つであるApplication Load Balancer(以降ALB)を検知対象とする.ALBを立てると多くの場合,1つのDNS名に対して複数のIPアドレスを持つ状態となる,ここでは2つIPアドレスを持つ場合を考える.
やりたいこと
ALBが持つ2つのIPアドレスのうち,片方を事前に記録しておく.ALBのIPアドレスの変更により,その記録したIPアドレスがALBのIPアドレスと異なる状態になったとき通知を行う.
検知と通知方法
スプレッドシートでGoogle Apps Script(以降GAS)を使い,Slackへ通知する方法で実現する. まずはシートに初期値として現状のALBのIPアドレスをメモしておく.また検知した日と新しいIPアドレスを記録するように列を用意しておく.
GASで実装する内容は主に以下の2つ.
まずはDNS over HTTPSを使って名前解決する.DNS over HTTPSとは,文字通りHTTPSを用いてDNSの通信を行う技術である.今回はGoogleが提供してくれているGoogle Public DNS over HTTPS
という全世界の人が無料で使えるフルリゾルバを使用する.どんなものかというのは,以下のURLを叩くと雰囲気がわかると思う.
https://dns.google.com/resolve?type=A&name=example.com
次に,Slack通知を行う部分を書く.以下のブログが参考になった.
Incoming Webhook
をSlackのチャンネルに設定して,hookするURLさえ分かれば通知できる.完成版のGASは以下のようになる.
function resolveName() { var ss = SpreadsheetApp.getActiveSheet(); var apiUrl = 'https://dns.google.com/resolve'; // Google Pubic DNS API URL var type = 'A'; // Aレコードを指定 var name = 'hogehoge.com'; // 検知するドメイン名 // 名前解決 var requestUrl = apiUrl + '?name=' + name + '&type=' + type; var response = UrlFetchApp.fetch(requestUrl); var responseText = response.getContentText(); // レスポンスをパース var json = JSON.parse(responseText); var newIpList = json.Answer.map(function(ans) { return ans.data }); // 登録IPアドレス取得 var oldIp = ss.getRange(2,1).getValue(); // IPが変更したか確認 if (newIpList.indexOf(oldIp) !== -1) { return; } // 文字列としてパース newIpList.sort(); var ipAddr = newIpList.join('\n'); // 変更日時とIPアドレスを記録 var date = new Date(); Utilities.formatDate( date, 'Asia/Tokyo', 'yyyyMMdd: hhmm'); var lastRow = ss.getLastRow(); ss.getRange(lastRow + 1, 3).setValue(date); ss.getRange(lastRow + 1, 4).setValue(ipAddr); // Slackへ通知 notifySlack(name,ipAddr); } function notifySlack(name,ip_addr) { var postUrl = 'https://hooks.slack.com/services/hoge/fuga/moge'; var username = 'IP報告する男'; var message = name + 'のIPアドレスが変わりました\n' + ip_addr; var jsonData = { "username" : username, "text" : message }; var payload = JSON.stringify(jsonData); var options = { "method" : "post", "contentType" : "application/json", "payload" : payload }; UrlFetchApp.fetch(postUrl, options); }
テストとしてGAS上のタブから「実行」を選んでresolveName
関数を実行する.IPアドレスが変わっていればスプレッドシートに検知した日と新しいIPアドレスが記録され,Slackへ通知が届く.
あとは,GAS上のタブから「編集」->「現在のプロジェクトのトリガー」をクリックし,このスクリプトを時間ベースで定期実行するようにしておけば,IPアドレスが変わったタイミングでSlackに通知が届く.Slackに気づいたら,シートの初期値として設定したIPアドレスを通知された新しいIPアドレスに手動で書き換える運用をしている.もちろんGASで自動的に書き換えてもらってもよい.
まとめ
- GASを使ってALBのIPアドレス変更を検知してSlackへ通知した
- GASからSlack通知も便利だが,
Google Public DNS over HTTPS
も便利だった - 今回の対象はALBだったが,他の対象にも使えそうな手段だと思う