- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2019-08-17T20:14:52+00:00","","")
#author("2019-08-18T00:38:28+00:00","","")
#mynavi(AWSメモ)
#setlinebreak(on)
* 目次 [#l73ce603]
#contents
- 関連
-- [[AWSメモ]]
-- [[AWS CloudFormationメモ]]
* 概要 [#i870a94c]
#html(<div style="padding-left:10px;">)
オンプレミスで稼働しているサーバのログをS3に収集して、解析を行う環境を構築する。
** 簡単な処理の流れ [#n5fc8eb4]
- 収集は各サーバの日次バッチで署名付きURLを取得する
- バッチ処理で署名付きURLに対して対象のログをアップロードする
- S3のPUT通知からLambdaを起動してログデータをCSVに変換する
- 変換したログをS3バケットにアップロードする
** イメージ [#ja87db22]
#todo(TODO)
#html(</div>) // 概要
* AWS側の処理作成 [#ib79308c]
#html(<div style="padding-left:10px;">)
** ファイル/フォルダ構成 [#fb34f269]
#html(<div style="padding-left:10px; display:inline-block; border: 1px solid #999; border-radius: 5px;">)
#html(<div style="display:inline-block;">)
/collectlog2aws
/template.yml
/src
/index.py
/collectlog2aws
/__init__.py
/analyze.py
/genurl.py
#html(</div>)
#html(<div style="display:inline-block; padding: 0 30px; vertical-align: top;">)
・・・ cloudformationテンプレート
・・・ Lambdaソース格納用
・・・ Lambda本体(メインハンドラ)
・・・ 一応パッケージ化しておく
・・・ CSV変換 及び ログ解析処理
・・・ 署名付きURL生成処理
#html(</div>)
#html(</div>) // ファイル/フォルダ構成
** 署名付きURLの生成のLambda作成 [#g95392ad]
#html(<div style="padding-left:10px;">)
#html(</div>) // 署名付きURLの生成のLambda
** CSVに変換するLambda作成 [#g9c4bf3e]
#html(<div style="padding-left:10px;">)
#html(</div>) // CSVに変換するLambda
** CloudFormationテンプレートの作成 [#u3baacec]
#html(<div style="padding-left:10px;">)
S3バケット 及び Lambdaを作成/デプロイする為の CloudFormationテンプレートを作成する
※生ログ格納用S3バケットは、ログがPUTされたらCSV変換Lambdaが起動するように設定しておく
※署名付きURL生成用の処理はオンプレミス側のサーバから要求があった時に起動できるようにAPI Gateway 経由で起動する
*** template.yml [#gf618b7d]
#html(<div style="padding-left:10px;">)
#mycode2(){{
WSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: "Stack for generate pre signed url and analyze log when put to s3."
Resources:
# ログファイルアップロード用の署名付きURL生成するLambda
GenerateSignedUrlFunc:
Type: "AWS::Serverless::Function"
Properties:
FunctionName: GenerateSignedUrl
Description: "サーバログ用のs3バケットの署名付きURLを生成する"
Handler: index.generate_url
Runtime: python3.6
CodeUri: ./src
MemorySize: 128
Timeout: 60
Events:
GenUrlApi:
Type: Api
Properties:
Path: /
Method: get
Role: !GetAtt GenerateSignedUrlFuncRole.Arn
# ログファイルアップロード用の署名付きURLを生成するLambda用のロール
GenerateSignedUrlFuncRole:
Type: "AWS::IAM::Role"
Properties:
RoleName: GenerateSignedUrlFuncRole
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service: "lambda.amazonaws.com"
Action: "sts:AssumeRole"
Policies:
- PolicyName: "GenerateSignedUrlPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- s3:PutObject # 生ログ格納用のs3バケットにログをputする為の権限を付与しておく
Resource: "*" # TODO: 対象のバケットを絞る(循環参照への対応が必要)
# アップロードされた生ログを解析するLambda
AnalyzeLogFunc:
Type: "AWS::Serverless::Function"
Properties:
FunctionName: AnalyzeLog
Description: "アップロードされたログをフォーマット 及び 解析する"
Runtime: python3.6
Handler: index.analyze_log
CodeUri: ./src
MemorySize: 128
Timeout: 60
Role: !GetAtt AnalyzeLogFuncRole.Arn
# アップロードされた生ログを解析するLambda用のロール
AnalyzeLogFuncRole:
Type: "AWS::IAM::Role"
Properties:
RoleName: AnalyzeLogFuncRole
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service: "lambda.amazonaws.com"
Action: "sts:AssumeRole"
Policies:
- PolicyName: "AnalyzeLogFuncPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- s3:GetObject # 生ログ格納用のs3バケットからログをgetする為の権限を付与しておく
- s3:PutObject # 解析済ログ格納用のs3バケットにログをputする為の権限を付与しておく
Resource: "*" # TODO: 対象のバケットを絞る(循環参照への対応が必要)
# サーバログ解析用Lambdaへのアクセス許可
AnalyzeLogFuncPermission:
Type: "AWS::Lambda::Permission"
Properties:
Action: "lambda:InvokeFunction"
FunctionName: !GetAtt AnalyzeLogFunc.Arn
Principal: "s3.amazonaws.com"
SourceArn: !Join
- ""
- - "arn:aws:s3:::"
- !Sub 'serverlogs-${AWS::AccountId}'
# サーバ生ログ格納用バケット
ServerlogBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain # スタック削除時にバケットを削除しない
DependsOn:
- AnalyzeLogFuncPermission
Properties:
BucketName: !Sub 'serverlogs-${AWS::AccountId}'
# 生ログがputされた時に自動的にログ解析用Lambdaを実行する
NotificationConfiguration:
LambdaConfigurations:
- Event: "s3:ObjectCreated:Put"
Function: !GetAtt AnalyzeLogFunc.Arn
Filter:
S3Key:
Rules:
- Name: suffix
Value: log
# 解析済みログ格納用バケット
AnalyzedlogBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain # スタック削除時にバケットを削除しない
Properties:
BucketName: !Sub 'analyzedlogs-${AWS::AccountId}'
Outputs:
# 署名付きURL生成用のAPIエンドポイントをエクスポートしておく
GenerateSignedUrl:
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
Export:
Name: GenerateSignedUrl
}}
#html(</div>)
*** awsbuild.sh [#mc96d937]
#include(CloudFormation実行用のシェル,notitle,notitle)
#html(</div>) // CloudFormationテンプレートの作成
** デプロイ [#x24c0c20]
#html(<div style="padding-left:10px;">)
#myterm2(){{
./awsbuild.sh deploy
}}
#html(</div>) // デプロイ
#html(</div>) // AWS側の処理作成
* オンプレミスのサーバ側のバッチ処理 [#we900a8a]
#html(<div style="padding-left:10px;">)
** log2aws.sh [#u29a07b3]
#mycode2(){{
xxxxx
#!/bin/bash
gen_url=上記のデプロイ時に表示された GenerateSignedUrlの値
server=`hostname`
log_dir=ログディレクトリのPATH
date=`date --date '+1day ago' +%Y-%m-%d`
# 署名付きURL取得
signed_url=`curl -s -L ${gen_url}?server=${server}\&date=${date}`
# アップロード
curl -s -L -D - -X PUT --upload-file ${log_dir}/${date}.log $signed_url >/dev/null 2>&1
}}
#html(</div>) // オンプレミスのサーバ側のバッチ処理
* 動作確認 [#q0b4ad4c]
#html(<div style="padding-left:10px;">)
#html(</div>)