Amazon Connect 실시간 모니터링: 삽질에서 완성까지 실전 구축기
Amazon Connect 실시간 통계(메트릭)를 Grafana로 시각화하는 프로젝트에서 보안, 실시간성, 비용, AWS 특유의 삽질(!)까지 모두 경험하며 완성한 구축 과정을 기록한다.
1. Lambda → S3 → Grafana: 흔한 구조, 그리고 한계
- Amazon Connect의 실시간 메트릭을 Lambda에서 주기적으로 수집해서 S3에 저장
- Grafana에서 Infinity 플러그인으로 S3의 latest.json을 폴링
-
문제: S3를 퍼블릭으로 열어야만 Grafana가 접근 가능
→ 데이터 노출 위험, 보안 취약!
Presigned URL로 우회도 시도했으나, Grafana에서 동적 URL 처리 불가로 실시간 연동이 막힘
2. API Gateway & Lambda 구조로 보안 추가… 그러나
- Lambda에서 S3를 읽어서 API Gateway로 반환하는 구조
- API Gateway에 API Key 인증까지 붙여서 보안 강화
-
문제: Grafana가 1초마다 Lambda 호출 → 비용↑, 호출량 제한(429 에러), 실시간성도 떨어짐
Presigned URL 활용 불가, 여전히 데이터 노출 우려 존재
3. S3 비공개 & IAM Role → Grafana 직접 연동도 불가
- S3를 비공개로 바꾸고 IAM Role로 Grafana에서 바로 읽으려 했으나
- Grafana 공식 플러그인에 S3 데이터 소스가 없음 (삽질 끝에 알게 됨)
4. 최종 구조: Lambda → Flask(EC2) → Grafana
-
Lambda가 Amazon Connect 실시간 메트릭을 3초마다 조회
→ Flask(EC2)로 HTTP POST(/upload)로 전송, 파일로 저장 - Flask는 latest.json 파일을 GET(/latest)으로 반환 (실시간 최신 데이터)
- Grafana Infinity 플러그인이 Flask의 /latest를 1초마다 폴링하여 대시보드에 실시간 반영
- 비용↓, 실시간성↑, 보안: EC2 보안그룹으로 접근 제한 가능
5. 삽질과 문제해결 노트 (실전 경험!)
- S3 퍼블릭/Presigned URL 한계: 실시간/보안 동시 만족 불가
- API Gateway-Lambda 구조: 실시간에 비용폭탄, 호출제한
- S3 비공개 IAM Role 연동 불가: Grafana 플러그인 미지원
- Lambda-EC2 네트워크: 퍼블릭IP, 보안그룹, OS 방화벽 등 네트워크 삽질
- Grafana 세팅: JSON Root, 컬럼, 쿼리 경로 등 세팅 반복
- Connect 메트릭이 빈 배열([]): 실시간 상담/대기자 없으면 빈값 나옴 (이것도 정상)
6. 코드/구성도 (실전 예시)
# Lambda 주요로직 (Connect → Flask) response = connect.get_current_metric_data(...) data = { "timestamp": int(time.time()), "metrics": response.get("MetricResults", []) } requests.post("http://EC2_IP:5000/upload", data=json.dumps(data))
# Flask 주요로직 (파일 저장 & 제공) @app.route('/upload', methods=['POST']) def upload(): with open('/tmp/latest.json', 'wb') as f: f.write(request.data) return 'ok', 200 @app.route('/latest', methods=['GET']) def latest(): with open('/tmp/latest.json', 'r') as f: return f.read(), 200, {'Content-Type': 'application/json'}
# Grafana Infinity 플러그인 설정 Type: JSON URL: http://EC2_IP:5000/latest
최종 아키텍처
Lambda → Flask(EC2) → Grafana (Infinity 플러그인)
비용, 보안, 실시간성 모두 챙긴 구성!
Lambda → Flask(EC2) → Grafana (Infinity 플러그인)
비용, 보안, 실시간성 모두 챙긴 구성!
7. 운영시 참고 및 팁
- Flask(EC2) 포트는 반드시 운영시 보안그룹으로 제한
- 추가로 HTTPS, 인증, 파일 장애 대비 예외처리 등 확장 가능
- 삽질과정에서 얻은 실전 경험이 바로 DevOps 성장 포인트!
실시간 AWS Connect 모니터링을 꿈꾸는 DevOps라면 삽질의 길이 성공의 지름길!
EC2에서 AWS 서비스(Connect 등) 안전하게 접근하는 법 (IAM Role 방식)
EC2에서 boto3 등으로 AWS 서비스에 접근하려면, Access Key를 직접 넣지 않고 IAM Role을 EC2에 연결해서 사용하는 게 가장 보안에 강력한 방법입니다.
-
IAM 역할(Role) 생성
- AWS 콘솔에서 IAM → 역할(Roles)에서 역할 만들기(Create role)
- 신뢰할 수 있는 엔터티 유형은
EC2
선택 - 권한 정책에
AmazonConnectReadOnlyAccess
붙이기 (Amazon Connect API Read 전용) - Role 이름 예시:
EC2-connect-grafana
-
EC2 인스턴스에 IAM Role 연결
- EC2 콘솔 → 해당 인스턴스 선택 → “작업” > “보안” > IAM 역할 수정(Attach/Replace IAM role)
- 방금 만든 역할(
EC2-connect-grafana
) 선택하고 저장 - 별도 재부팅 없이 바로 반영
-
Python 코드에서 boto3로 Connect 데이터 호출
- Access Key/Secret Key 필요 없음!
- IAM Role 권한만 있으면 바로 boto3가 Credential을 EC2에서 알아서 가져감
- 예시:
import boto3 connect = boto3.client('connect', region_name='ap-northeast-2') response = connect.get_current_metric_data( InstanceId='YOUR_INSTANCE_ID', Filters={ 'Queues': ['YOUR_QUEUE_ID'], 'Channels': ['VOICE'] }, CurrentMetrics=[ {'Name': 'AGENTS_AVAILABLE', 'Unit': 'COUNT'}, {'Name': 'CONTACTS_IN_QUEUE', 'Unit': 'COUNT'}, {'Name': 'AGENTS_ON_CALL', 'Unit': 'COUNT'}, ] ) print(response)
Tip:
boto3에서
추가적으로 S3, DynamoDB 등도 같은 방식으로 활용 가능.
boto3에서
NoCredentialsError: Unable to locate credentials
가 안 뜨고, 바로 잘 조회되면 세팅 성공!추가적으로 S3, DynamoDB 등도 같은 방식으로 활용 가능.