Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 체코
- react.js
- pyenv
- PostgreSQL
- Python
- codebuild
- 방콕
- local
- PayPay
- javascript
- duckdb
- Selenium
- node.js
- documentdb
- 태국
- 페이페이
- 三井住友カード
- typescript
- 뮌헨
- 메르페이
- JenkinsFile
- 熱海
- 미츠이 스미토모
- 프라하
- terraform
- 카마츠루
- vba
- 아타미
- CSV
- 釜つる
Archives
- Today
- Total
도쿄사는 외노자
Eventbridge Scheduler를 이용한 Teams 자동 통지 본문
개요
Eventbridge Scheduler를 이용해 Lambda를 정기적으로 기동, Teams에 Adaptive Card 형식으로 자동 통지를 구현
상세
폴더 구조
python과 terraform으로 폴더를 나눔.
.
├── README.md
├── python
│ ├── layer
│ │ └── python
│ └── main.py
└── terraform
└── main.tf
혹시 관리하는 aws 환경이 여러개라면, terraform 폴더 아래에 dev, prod 등의 폴더를 나누고 그 안에서 terraform init
을 할 것.
Lambda
pymsteams 에서 adaptive card 를 이용하여, Teams 에 byname 으로 멘션 통지.
import pymsteams
from typing import Dict
TEAMS_WEB_HOOK = "https://company.webhook.office.com/webhook/12345678..."
# 담당자
handlers: Dict[str, str] = {
"Kim": "kim@company.com",
"Lee": "lee@company.com",
"Ryu": "ryu@company.com",
}
# 메시지 작성
def create_message():
mentions = ", ".join(["<at>" + name + "</at> 님" for name in handlers.keys()])
entities = [
{
"type": "mention",
"text": f"<at>{name}</at>",
"mentioned": {"id": email, "name": name},
}
for name, email in handlers.items()
]
# 텍스트
text = ""
text += f"{mentions} \n"
text += "각 담당자는 XXX 정기 운용 보고서를 제출할 필요가 있습니다.\n"
text += "이하 페이지를 참조하여 운용 보고서를 제출해 주세요.\n"
text += "[운용 보고서 제출 양식](https://company.atlassian.net/wiki/spaces/123456/report)"
text = text.replace("\n", "\n \n")
# payload 작성 및 멘션 연계
payload = {
"type": "message",
"attachments": [
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"isMultiline": "true",
"size": "small",
"text": text,
},
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0",
"msteams": {
"width": "Full",
"entities": entities,
},
},
}
],
}
return payload
def send_notice(title, payload):
myTeamsMessage = pymsteams.connectorcard(TEAMS_WEB_HOOK)
myTeamsMessage.title(title)
myTeamsMessage.payload = payload
myTeamsMessage.send()
def lambda_handler(event, content):
TITLE = "정기 운용 보고서 제출 의뢰"
payload = create_message()
send_notice(TITLE, payload)
# For local test
# lambda_handler(event="", content="")
Terraform
기본적으로는 아래와 같은 느낌.
Terraform의 Eventbridge Module 을 사용.
terraform {
required_version = "~> 1.3.0"
backend "s3" {
bucket = "terraform-tfstate-bucket"
region = "ap-northeast-1"
key = "project_name/terraform.tfstate"
encrypt = true
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
default_tags {
tags = {
Owner = "Dept"
Environment = "dev"
Terraform = "true"
Project = "PJT-123"
}
}
}
data "aws_caller_identity" "current" {}
# IAM
resource "aws_iam_role" "report_alert" {
name = "eventbridge-scheduler-role"
assume_role_policy = data.aws_iam_policy_document.report_alert_assume_policy.json
inline_policy {
name = "eventbridge-scheduler-role-inline-policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"lambda:InvokeFunction",
]
Effect = "Allow"
Resource = "*"
},
]
})
}
}
data "aws_iam_policy_document" "report_alert_assume_policy" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["scheduler.amazonaws.com"]
}
}
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}
# Lambda
module "lambda_function" {
source = "terraform-aws-modules/lambda/aws"
version = "4.12.1"
function_name = "report_alert"
description = "Report Alert for each dept"
handler = "main.lambda_handler"
runtime = "python3.11"
create_role = false
lambda_role = report_alert.arn
source_path = "../../python/main.py"
layers = [
module.lambda_layer_local.lambda_layer_arn,
]
timeout = 100
}
module "lambda_layer_local" {
source = "terraform-aws-modules/lambda/aws"
create_layer = true
layer_name = "lambda-layer-pymsteams"
description = "Layer for pymsteams"
compatible_runtimes = ["python3.11"]
source_path = "../../python/layer"
}
# Eventbridge Scheduler
resource "aws_scheduler_schedule" "report-alert" {
name = "report-alert"
group_name = "default"
flexible_time_window {
mode = "OFF"
}
# 매주 월요일 10시
schedule_expression = "cron(0 10 ? * MON *)"
schedule_expression_timezone = "Asia/Tokyo"
target {
arn = module.lambda_function.lambda_function_arn
role_arn = aws_iam_role.report_alert.arn
}
}
for_each 를 사용하는 방법
일정이 비정기적이어서 cron식만으로는 해결하기 힘든 경우에는 for_each 를 사용한다.
위의 테라폼 코드에 필요한 일시를 map으로 추가하고, Eventbridge Scheduler
에서 for_each 를 사용하면 됨.
아래의 예시는 2026년 연말까지의 매 분기 첫번째 영업일에 통지를 하는 경우.
variable "alert_datetime" {
type = map(string)
default = {
"2024_1" = "0 9 5 1 ? 2024" // 2024.01.05 09:00
"2024_2" = "0 9 1 4 ? 2024" // 2024.04.01 09:00
"2024_3" = "0 9 1 7 ? 2024" // 2024.07.01 09:00
"2025_4" = "0 9 1 10 ? 2024" // 2024.10.01 09:00
"2025_1" = "0 9 6 1 ? 2025" // 2025.01.06 09:00
"2025_2" = "0 9 1 4 ? 2025" // 2025.04.01 09:00
"2025_3" = "0 9 1 7 ? 2025" // 2025.07.01 09:00
"2025_4" = "0 9 1 10 ? 2025" // 2025.10.01 09:00
"2026_1" = "0 9 5 1 ? 2026" // 2026.01.05 09:00
"2026_2" = "0 9 1 4 ? 2026" // 2026.04.01 09:00
"2026_3" = "0 9 1 7 ? 2026" // 2026.07.01 09:00
"2026_4" = "0 9 1 10 ? 2026" // 2026.10.01 09:00
}
}
# Eventbridge Scheduler
resource "aws_scheduler_schedule" "report-alert" {
name = "report-alert-${each.key}"
group_name = "default"
flexible_time_window {
mode = "OFF"
}
// 매 분기 첫번째 영업일
for_each = var.alert_datetime
schedule_expression = "cron(${each.value})"
schedule_expression_timezone = "Asia/Tokyo"
target {
arn = module.lambda_function.lambda_function_arn
role_arn = aws_iam_role.report_alert.arn
}
}
그외 준비할 것
Lambda Module 추가
레이어를 사용하므로, 추가 모듈이 있는 경우엔 아래와 같이 ./python/layer/python
폴더에 추가 필요.
pip install [모듈명] -t ./python/layer/python
tfstate 저장용 S3 Bucket
본 샘플의 경우, terraform-tfstate-bucket
에 tfstate 를 저장하므로, 해당 환경에 이 버켓을 만들어 두어야 함.
'Tech > AWS for Data Engineering' 카테고리의 다른 글
dbt with AWS Codebuild (1) | 2024.12.18 |
---|---|
DynamoDB Local (0) | 2024.07.06 |
AWS Glue Job에서 Tableau에 Hyper파일 Publish하기 (1) | 2023.04.20 |
Glue Crawler로 쌍따옴표가 포함된 CSV파일 읽기 (2) | 2023.02.14 |
Terraform으로 CloudTraild의 Cloudwatch 만들 때 조심할 것 (0) | 2022.12.14 |