やりたいこと
AWSのリソースが使うIPアドレスレンジは、以下に公開されています。
https://ip-ranges.amazonaws.com/ip-ranges.json
ちょくちょく更新されますが、FireWallやWAFの設定に反映させる必要があるシステムをお持ちのプロジェクト担当者へ、正確かつ迅速に通知することを目標に自動化システムを構築しました。
実現
AWSのリソースが使うIPアドレスレンジの変更は、SNSで受信することができるようです。 また、担当者への連絡はBacklogを使うこととします。
以下のような構成で実現します。
S3
S3に通知を受ける直前のIPアドレスレンジを保管しておきます。 バケット名は適当に。
Lambdaファンクション
IAMロールには、S3の読み書き権限を付けておきます。
#!/usr/bin/python # -*- coding: utf-8 -*- import httplib import json import difflib import boto3 s3 = boto3.resource('s3') import pprint pp = pprint.PrettyPrinter(indent=4) API_KEY = "<Backlogより発行>" BACKLOG_HOST = "<Backlogスペース + ドメイン>" S3_BACKET_NAME = "<バケット名>" S3_LAST_IP_RANGE_OBJ = "last-ip-range.json" def get_project_id(project_code): uri = "/api/v2/projects/%s?apiKey=%s" % (project_code, API_KEY) connect = httplib.HTTPSConnection(host = BACKLOG_HOST, port = 443) connect.request("GET", uri) response = connect.getresponse() body = response.read() connect.close() data = json.loads(body) project_id = data['id'] return project_id def post_issue(project_id, summary, issue_type_id, priority_id, description): data = { "projectId" : project_id, "summary" : summary, "issueTypeId" : issue_type_id, "priorityId" : priority_id, "description" : description } params = json.dumps(data) headers = { "Accept":"application/json", "Content-Type":"application/json", } uri = "/api/v2/issues?apiKey=%s" % (API_KEY) connect = httplib.HTTPSConnection(host = BACKLOG_HOST, port=443) connect.request("POST", uri , params, headers) response = connect.getresponse() connect.close() def download_ip_range(file): uri = "/ip-ranges.json" connect = httplib.HTTPSConnection(host = "ip-ranges.amazonaws.com", port = 443) connect.request("GET", uri) response = connect.getresponse() body = response.read() f = open(file, "w") f.write(body) f.close() connect.close() return def construct_description(diff): description = u"AWSの使用するIPアドレスレンジに更新がありました。" description += u"変更内容は以下です。" description += 'n' description += "{code}n" for buf in diff: description += buf description += "{/code}n" print(description) return description def lambda_handler(event, context): last_ip_range_file = '/tmp/' + S3_LAST_IP_RANGE_OBJ + '_last' current_ip_range_file = '/tmp/' + S3_LAST_IP_RANGE_OBJ + '_current' download_ip_range(current_ip_range_file) s3.meta.client.download_file(S3_BACKET_NAME, S3_LAST_IP_RANGE_OBJ, last_ip_range_file) last_ip_range = open(last_ip_range_file, "r") current_ip_range = open(current_ip_range_file, "r") diff = difflib.context_diff(last_ip_range.readlines(), current_ip_range.readlines(), fromfile='before', tofile='after') description = construct_description(diff) summary = "[連絡] AWSリソースのIPアドレスレンジに更新がありました" issue_type_id = 3 priority_id = 3 # 通知したいプロジェクトを追加 project_ids = [] project_ids.append(get_project_id("HOGE")) project_ids.append(get_project_id("FUGA")) for project_id in project_ids: post_issue(project_id, summary, issue_type_id, priority_id, description) response = s3.meta.client.upload_file(current_ip_range_file, S3_BACKET_NAME, S3_LAST_IP_RANGE_OBJ)
SNS
こちらのサイトを参考にTopic ARNを設定します。 ProtocolはLambda、Endpointは先ほど作ったファンクションを選択します。
Lambdaのイベントソースに反映されます。
結果
ちゃんとBacklogに投稿されました! Lambdaの恩恵、デカすぎです!!
元記事はこちら
「AWSのIPアドレスレンジ変更をBacklogに通知する(SNS + Lambda + S3)【cloudpack大阪BLOG】」