DevOps 엔지니어로서 일을 하다 보면, 서버, 애플리케이션 메트릭 이외에도, 다양한 데이터의 추이가 필요할 때가 있습니다.
그 예시로는 클라우드 벤더 비용 증가 확인, 수집 서버에 저장되어 있는 데이터의 증가 폭을 확인 등이 있습니다. 이러한 데이터에 대한 모니터링의 필요도가 늘자 와탭 DevOps팀은 커스텀 데이터를 모니터링하고자 환경을 구축을 결심하였습니다.
와탭 DevOps팀에서 커스텀 데이터를 모니터링에 대해 논의해 본 결과 아래와 같은 요구사항이 도출되었습니다.
위의 요구사항에 맞춰서 다음과 같은 구조를 설계를 하였습니다.
• 사용하기에 간단해야 한다
• 비용이 많이 드는 인프라 구성은 피한다 → AWS Lambda를 이용해 비용 최적화
인프라 구성은 재사용성, 관리를 위해 AWS CloudFormation을 통해 진행하였습니다.
AWS CloudFormation에 대한 다양한 예시는 아래 글에서 확인이 가능합니다.
[AWS CloudFormation으로 인프라 관리/복제하기]
Parameters:
ApiGatewayName:
Type: String
Default: WhatapCustomAPI
LambdaFunctionName:
Type: String
Default: WhatapCustomLambda
LambdaMemorySize:
Type: Number
Default: 1024
MinValue: 128
MaxValue: 3000
LambdaTimeOut:
Type: Number라
Default: 30
Resources:
CustomApiGateway:
Type: AWS::ApiGateway::RestApi
Properties:
ApiKeySourceType: HEADER
Description: An API Gateway with a Lambda Integration
BinaryMediaTypes:
- application/json
EndpointConfiguration:
Types:
- EDGE
Name:
Ref : ApiGatewayName
ApiGatewayResource:
Type: AWS::ApiGateway::Resource
Properties:
ParentId: !GetAtt CustomApiGateway.RootResourceId
PathPart: 'custom'
RestApiId: !Ref CustomApiGateway
ApiGatewayMethod:
Type: AWS::ApiGateway::Method
Properties:
ApiKeyRequired: false
AuthorizationType: NONE
HttpMethod: POST
Integration:
ConnectionType: INTERNET
Credentials: !GetAtt ApiGatewayIamRole.Arn
IntegrationHttpMethod: POST
PassthroughBehavior: WHEN_NO_MATCH
TimeoutInMillis: 29000
Type: AWS_PROXY
Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${WhatapCustom.Arn}/invocations'
OperationName: 'lambda'
ResourceId: !Ref ApiGatewayResource
RestApiId: !Ref CustomApiGateway
ApiGatewayModel:
Type: AWS::ApiGateway::Model
Properties:
ContentType: 'application/json'
RestApiId: !Ref CustomApiGateway
Schema:
title: DataModel
type: object
properties:
datas:
type: array
items:
type: object
properties:
key:
type: string
value:
type: number
tags:
type: array
items:
type: object
properties:
key:
type: string
value:
type: string
whatapAccessKey:
type: string
pcode:
type: number
category:
type: string
host:
type: string
ApiGatewayStage:
Type: AWS::ApiGateway::Stage
Properties:
DeploymentId: !Ref ApiGatewayDeployment
Description: Stage for whatap-custom
RestApiId: !Ref CustomApiGateway
StageName: 'whatap'
ApiGatewayDeployment:
Type: AWS::ApiGateway::Deployment
DependsOn: ApiGatewayMethod
Properties:
Description: Lambda API Deployment
RestApiId: !Ref CustomApiGateway
ApiGatewayIamRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: ''
Effect: 'Allow'
Principal:
Service:
- 'apigateway.amazonaws.com'
Action:
- 'sts:AssumeRole'
Path: '/'
Policies:
- PolicyName: LambdaAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow'
Action: 'lambda:*'
Resource: !GetAtt WhatapCustom.Arn
ApiGatewayPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref WhatapCustom
Principal: "apigateway.amazonaws.com"
SourceArn:
!Join
- ''
- - 'arn:aws:execute-api'
- ':'
- !Ref AWS::Region
- ':'
- !Ref AWS::AccountId
- ':'
- !Ref CustomApiGateway
- '/*/POST/custom'
LambdaExecutionRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- "sts:AssumeRole"
Policies:
- PolicyDocument:
Version: "2012-10-17"
Statement:
#Lambda Basic Excution Role
- Effect: Allow
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*"
PolicyName: whatapcustompolicy
WhatapCustom:
Type: AWS::Lambda::Function
Properties:
FunctionName :
Ref : LambdaFunctionName
Handler: main
Runtime: go1.x
Code:
S3Bucket: !Sub whatapcustom
S3Key: !Sub 'whatap_custom.zip'
MemorySize:
Ref : LambdaMemorySize
Timeout:
Ref : LambdaTimeOut
Tags:
- Key: "WhaTapCustom"
Value: "Monitoring"
Role: !GetAtt LambdaExecutionRole.Arn
Outputs:
ApiEndponit:
Description: "API Endpoint"
Value: !Sub "https://${CustomApiGateway}.execute-api.${AWS::Region}.amazonaws.com/whatap/custom"
AWS CloudFormation으로 생성되는 리소스는 다음과 같습니다.
AWS APIGATEWAY
AWS LAMBDA
AWS IAM ROLE
AWS CloudFormation의 사용으로 다음과 같이 간단한 설치 페이지로 인프라 설치 가능하게 되었습니다.
설치 완료 후 출력란에서 호출에 필요한 API URL을 획득할 수 있습니다.
아래와 같은 API 호출만으로 커스텀 데이터 모니터링을 구성할 수 있게 되었습니다.
POST {APIEndpoint}
{
"datas":[
{
"key" : string
"value" : float
},
{
"key" : "data2",
"value" : 140.232323
}
],
"whatapAccessKey" : "",
"pcode" : ,
"category" : "whatap_custom"
}
또한 지표의 확인과 알림 설정 또한 가능하게 되었습니다.
와탭 DevOps팀은 이렇게 구성된 커스텀 모니터링으로 다음과 같이 이용하고 있습니다.
데이터 저장, 시각화, 알림 등을 와탭 내부 시스템을 이용하여 시스템 구축 시간을 매우 단축할 수 있었습니다. 이런 점이야말로 모니터링을 제공하는 회사에 다니는 DevOps 엔지니어의 장점 아닐까 싶습니다.