1.1. Lambda関数用ソースコードファイルの作成 (config-monitor)¶
作業の目的 [why]¶
Lambda関数"config-monitor"用のソースコードファイルを作成します。
完了条件/事前条件 [設計者用情報]
完了条件 [after]
主処理は、以下を満たしたときに成功したものとします。
- 完了条件1
- Lambda関数"config-monitor"のソースコードファイル"${HOME}/conf-handson-cli/config-monitor.py"が存在する。
事前条件 [before]
主処理の実施は、以下の状態であることを前提とします。
- 事前条件1
- 関数コードファイル用ディレクトリ"${HOME}/conf-handson-cli"が存在する。
- 事前条件2
- Lambda関数"config-monitor"のソースコードファイル"${HOME}/conf-handson-cli/config-monitor.py"が存在しない。
作業対象 [what]¶
- Lambdaサービス
標準時間(合計)¶
8分
パラメータ設定¶
パラメータ設定の標準時間: | 2分 |
---|
作業に必要なモノ・情報 [resource]¶
作業開始には、以下が全て揃っていることが必要です。
リソース1: 関数コードファイル用ディレクトリ
- 今回は"${HOME}/conf-handson-cli"をLambda関数コード用ディレクトリとします。
ディレクトリが存在することを確認します。
コマンド:
ls -d ${HOME}/conf-handson-cli
結果(例:存在する場合):
${HOME}/conf-handson-cli
存在しない場合は作成します。
コマンド:
mkdir -p ${HOME}/conf-handson-cli
リソース2: Lambda関数名
- 作成するLambda関数の名称です。
- 今回は"config-monitor"とします。
リソース3: Slack Incoming Hook URL
- 通知先となるSlack Incoming HookのURLです。
- 今回は"<incoming hookのURL>"とします。
リソース4: Slackチャンネル
- 通知先となるSlackのチャンネルです。 (#で始まる文字列)
- 今回は"#handson-cli"とします。
パラメータの指定¶
作業に必要なパラメータを変数に格納をします。
0.3. Slack Incoming Hook URLの指定¶
Slack Incoming Hook URLを指定します。
変数の設定:
SLACK_URL_INCOMING_HOOK='<incoming hookのURL>'
パラメータの保存¶
設定されている変数の保存先となるファイル名を指定します。
変数の設定:
DIR_PARAMETER="${HOME}/tmp/parameter-handson-cli" FILE_PARAMETER="${DIR_PARAMETER}/$(date +%Y-%m-%d)-lambda-function_code_python-create-expand-slack-incoming.env" \ && echo ${FILE_PARAMETER}
結果(例):
${HOME}/tmp/parameter-handson-cli/2019-04-30-lambda-function_code_python-create-expand-slack-incoming.env
各変数に正しいパラメータ値が格納されていることを確認しながら保存します。
変数の確認:
cat << EOF > ${FILE_PARAMETER} # 0.1. DIR_LAMBDA_CODE:"${HOME}/conf-handson-cli" DIR_LAMBDA_CODE="${DIR_LAMBDA_CODE}" # 0.2. LAMBDA_FUNCTION_NAME:"config-monitor" LAMBDA_FUNCTION_NAME="${LAMBDA_FUNCTION_NAME}" # 0.3. SLACK_URL_INCOMING_HOOK:"<incoming hookのURL>" SLACK_URL_INCOMING_HOOK="${SLACK_URL_INCOMING_HOOK}" # 0.4. SLACK_CHANNEL:"#handson-cli" SLACK_CHANNEL="${SLACK_CHANNEL}" EOF cat ${FILE_PARAMETER}
下段の変数が入っていない、もしくは上段と同等の値が入っていない場合は、それぞれの手順番号に戻って変数の設定を行います。
タスクの実施¶
タスク標準時間: | 6分 |
---|
1. 前処理¶
1.1. 状態確認に必要な情報の取得¶
関数コードファイルの指定
変数の設定:
FILE_LAMBDA_CODE="${DIR_LAMBDA_CODE}/${LAMBDA_FUNCTION_NAME}.py" \ && echo ${FILE_LAMBDA_CODE}
結果(例):
${HOME}/conf-handson-cli/config-monitor.py
処理対象の状態確認¶
主処理の実施は、以下の状態であることを前提とします。
前提と異なることが判明した場合、直ちに処理を中止します。
事前条件1: 関数コードファイル用ディレクトリ"${HOME}/conf-handson-cli"が存在する。
「関数コードファイル用ディレクトリ"${HOME}/conf-handson-cli"が存在する。」ことを確認します。
コマンド:
ls -d ${DIR_LAMBDA_CODE}
結果(例):
${HOME}/conf-handson-cli
事前条件2: Lambda関数"config-monitor"のソースコードファイル"${HOME}/conf-handson-cli/config-monitor.py"が存在しない。
「Lambda関数"config-monitor"のソースコードファイル"${HOME}/conf-handson-cli/config-monitor.py"が存在しない。」ことを確認します。
コマンド:
! ls ${FILE_LAMBDA_CODE}
結果(例):
ls: ${HOME}/conf-handson-cli/config-monitor.py: No such file or directory
2. 主処理¶
関数コードファイルの作成¶
変数の確認:
cat << ETX # FILE_LAMBDA_CODE:"${HOME}/conf-handson-cli/config-monitor.py" FILE_LAMBDA_CODE="${FILE_LAMBDA_CODE}" # SLACK_URL_INCOMING_HOOK:"<incoming hookのURL>" SLACK_URL_INCOMING_HOOK="${SLACK_URL_INCOMING_HOOK}" # SLACK_CHANNEL:"#handson-cli" SLACK_CHANNEL="${SLACK_CHANNEL}" ETX
コマンド:
cat << EOF > ${FILE_LAMBDA_CODE} # coding: utf-8 from __future__ import print_function import json import logging from base64 import b64decode from urllib2 import Request, urlopen, URLError, HTTPError hook_url = "${SLACK_URL_INCOMING_HOOK}" channel = "${SLACK_CHANNEL}" logger = logging.getLogger() logger.setLevel(logging.INFO) def lambda_handler(event, context): logger.info("Event: " + str(event)) message = json.loads(event['Records'][0]['Sns']['Message']) logger.info("Message: " + str(message)) time_capture = message['configurationItem']['configurationItemCaptureTime'] region = message['configurationItem']['awsRegion'] resource_type = message['configurationItem']['resourceType'] resource_id = message['configurationItem']['resourceId'] configuration_item_diff = message['configurationItemDiff'] post_text = u"%s でリソースの変更を検知しました。\n\n変更されたリソース: %s ( %s )\n\n変更内容: \n\`\`\`\n%s\n\`\`\`\n\n変更を補足した時刻: %s " % (region, resource_type, resource_id, json.dumps(configuration_item_diff, indent=2), time_capture) slack_message = { 'channel': channel, 'text': post_text } req = Request(hook_url, json.dumps(slack_message)) try: response = urlopen(req) response.read() logger.info("Message posted to %s", slack_message['channel']) except HTTPError as e: logger.error("Request failed: %d %s", e.code, e.reason) except URLError as e: logger.error("Server connection failed: %s", e.reason) EOF cat ${FILE_LAMBDA_CODE}
結果(例):
# coding: utf-8 from __future__ import print_function import json import logging from base64 import b64decode from urllib2 import Request, urlopen, URLError, HTTPError hook_url = "<incoming hookのURL>" channel = "#handson-cli" logger = logging.getLogger() logger.setLevel(logging.INFO) def lambda_handler(event, context): logger.info("Event: " + str(event)) message = json.loads(event['Records'][0]['Sns']['Message']) logger.info("Message: " + str(message)) region = message['configurationItem']['awsRegion'] resource_type = message['configurationItem']['resourceType'] resource_id = message['configurationItem']['resourceId'] configuration_item_diff = message['configurationItemDiff'] post_text = u"%s でリソースの変更を検知しました。\n\n変更されたリソース: %s ( %s )\n\n変更内容: \n```\n%s\n```\n" % (region, resource_type, resource_id, json.dumps(configuration_item_diff, indent=2)) slack_message = { 'channel': channel, 'text': post_text } req = Request(hook_url, json.dumps(slack_message)) try: response = urlopen(req) response.read() logger.info("Message posted to %s", slack_message['channel']) except HTTPError as e: logger.error("Request failed: %d %s", e.code, e.reason) except URLError as e: logger.error("Server connection failed: %s", e.reason)
3. 後処理¶
完了条件の確認¶
主処理は、以下を満たしたときに成功したものとします。
完了条件1: Lambda関数"config-monitor"のソースコードファイル"${HOME}/conf-handson-cli/config-monitor.py"が存在する。
「Lambda関数"config-monitor"のソースコードファイル"${HOME}/conf-handson-cli/config-monitor.py"が存在する。」ことを確認します。
コマンド:
ls ${FILE_LAMBDA_CODE}
結果(例):
${HOME}/conf-handson-cli/config-monitor.py