일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- JPQL
- 동적sql
- shared lock
- 연관관계
- 스프링 폼
- querydsl
- 다대다
- fetch
- CHECK OPTION
- dfs
- PS
- 비관적락
- 낙관적락
- FetchType
- SQL프로그래밍
- 스토어드 프로시저
- 백트래킹
- execute
- 다대일
- 지연로딩
- BOJ
- eager
- 일대다
- 연결리스트
- 힙
- 데코레이터
- 이진탐색
- 즉시로딩
- 유니크제약조건
- exclusive lock
- Today
- Total
흰 스타렉스에서 내가 내리지
Amazon EventBridge - 이벤트 매칭 규칙 본문
> AWS의 이벤트
> Amazon EventBridge 규칙
- 발생한 이벤트를 대상 서비스가 처리할 수 있도록 전달
- 다양한 대상에 동시에 전달 가능
- API Gateway, CloudWatch Log 그룹, CodePipeline, StepFunctions, SQS, SNS등
- 두 가지 모드
- 이벤트 패턴 : AWS의 이벤트 버스에서 특정 이벤트를 패턴 매칭하여 대상에 전달
- 스케쥴 : Cron 이벤트를 활용하여 특정 시간, 혹은 주기로 대상에게 전달
> Amazon EventBridge 규칙 - 이벤트 패턴 매칭
- AWS의 이벤트에 내용 중 필요한 내용을 선별하여 패턴으로 정의
- 이후 패턴에 매칭되는 이벤트를 대상으로 보냄
- JSON 형식으로 구성
- 매칭하고 싶은 이벤트의 내용은 Array 안에 넣어 매칭
- 일반적으로 Source 필드와 detail-type 필드를 매칭하여 이벤트 종류를 분리한 후
- detail 필드 안에 있는 값으로 세부 필터링
예를 들어, EC2 인스턴스가 시작될 때의 이벤트를 잡아다가 뭔가 처리를 하고 싶다고 가정해보자.
우리가 관심있는 이벤트는 여러 이벤트 중에 "EC2 Instance State-change Notification" 이라는 이벤트이다.
이 이벤트는 EC2에 상태가 변경될 때 트리거되는 이벤트다.
우리가 이걸 찾기 위해서는 detail-type과 source 와 매칭되는 이벤트를 찾으면 된다.
그래서 패턴을 오른쪽과 같이 정의한다.
> InputTransformer
- 대상에 전달할 이벤트 내용을 편집할 수 있는 기능
- Raw 데이터 대신 의미있는 문장으로 전달 가능
- 이메일 등 사람이 보는 메시지에 주로 사용
> Demo - EC2 시작 알람 이메일로 받기
EC2 상태가 변경되면 이벤트 버스를 통해서 규칙이 트리거 된다.
규칙에서 이벤트 내용을 그대로 전달하는 것이 아니라 InputTransformer를 활용해서 SNS로 전달한다.
SNS는 Email을 보내게 된다.
"CloudFormation" → "스택 생성"
Parameters:
Email:
Type: String
Description: email addrss
Resources:
AlarmTopic:
Type: AWS::SNS::Topic
Properties:
Subscription:
- Endpoint: !Ref Email
Protocol: email
AlarmTopicpolicy:
Type: AWS::SNS::TopicPolicy
Properties:
PolicyDocument:
Id: AlarmTopicpolicy
Version: "2012-10-17"
Statement:
- Sid: state1
Effect: Allow
Principal:
Service:
- events.amazonaws.com
Action: sns:Publish
Resource: "*"
Topics:
- !Ref AlarmTopic
EC2Event:
Type: AWS::Events::Rule
Properties:
Description: EC2RunningEvent
EventPattern:
source:
- aws.ec2
detail-type:
- EC2 Instance State-change Notification
detail:
state:
- running
Targets:
- Arn:
Ref: AlarmTopic
Id: EC2-Running
InputTransformer:
InputTemplate: |
" '<InstanceId>' 가 '<State>' 상태입니다. "
InputPathsMap:
InstanceId: "$.detail.instance-id"
State: "$.detail.state"
계속해서 다음을 누르고 스택을 생성한다.
우리가 등록했던 이메일로 메일이 왔을 것이다.
메일의 링크로부터 구독을 컨펌하면, 다음과 같이 화면이 바뀐다.
CloudFront 스택이 완성되었다.
데모 확인을 위해 EC2 인스턴스를 하나 생성해보자.
지금은 인스턴스 상태가 대기 중인데, 시작 상태로 바뀌면 메일이 올 것이다.
오...
그럼 이제 EventBridge로 가서 실제로 패턴 매칭이 된 이벤트를 한 번 보자.
규칙 탭에 들어가면, 우리가 CloudFront에서 템플릿으로 만든 규칙이 보인다.
상세로 들어가보면,
이벤트 패턴을 읽어보자.
그리고 이 규칙의 편집을 한 번 눌러보자.
샘플 이벤트를 선택할 수 있는데, 여기서 여러가지 다양한 AWS의 이벤트들을 볼 수가 있다.
EC2를 검색해보면 다양한 옵션들을 볼 수 있는데, EC2 Instance State-change Notification 도 보인다.
"특정상태" 드롭다운을 통해 패턴을 수정할 수 있다.
다음 화면으로 넘어가보자
"대상 선택"을 통해 이벤트가 트리거될 때 호출할 대상을 선택한다.
이렇게 패턴 매칭을 구현해서 다양한 일을 할 수 있다.
샘플 이벤트에 "AWS Console Sign In via CloudTrail"을 통해 어떤 계정이 로그인 했는지 알림을 받아볼 수 있다.
> Demo - large 이상의 EC2 생성 시 자동 정지
CloudFormation → 스택 생성
Parameters:
Email:
Type: String
Description: email addrss
Resources:
AlarmTopic:
Type: AWS::SNS::Topic
Properties:
Subscription:
- Endpoint: !Ref Email
Protocol: email
AlarmTopicpolicy:
Type: AWS::SNS::TopicPolicy
Properties:
PolicyDocument:
Id: AlarmTopicpolicy
Version: "2012-10-17"
Statement:
- Sid: state1
Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sns:Publish
Resource: "*"
Topics:
- !Ref AlarmTopic
EC2Event:
Type: AWS::Events::Rule
Properties:
Description: EC2RunningEvent
EventPattern:
source:
- aws.ec2
detail-type:
- EC2 Instance State-change Notification
Targets:
- Arn:
Fn::GetAtt:
- "AlarmLambda"
- "Arn"
Id: EC2-Running
# InputTransformer:
# InputTemplate: |
# " '<InstanceId>' 가 '<State>' 상태입니다. "
# InputPathsMap:
# InstanceId: "$.detail.instance-id"
# State: "$.detail.state"
LambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
Policies:
- PolicyName: root
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "sns:*"
- "ec2:*"
- "cloudtrail:*"
Resource: "*"
- Effect: Allow
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "*"
AlarmLambda:
Type: "AWS::Lambda::Function"
Properties:
Handler: "index.handler"
Environment:
Variables:
alarm_topic: !Ref AlarmTopic
Role:
Fn::GetAtt:
- "LambdaRole"
- "Arn"
Runtime: nodejs14.x
# we give the function a large timeout
# so we can wait for the bucket to be empty
Timeout: 600
Code:
ZipFile: |
const AWS = require('aws-sdk');
const ec2 = new AWS.EC2();
async function getInstanceMatching(contents) {
let regexstr = `.large`;
var regex = new RegExp(regexstr, "g");
var matches = contents.match(regex)
if (matches && matches.length) {
return true;
}
return false;
}
exports.handler = async (event) => {
console.log(event);
if (event.detail.state == "running") {
var params = {
InstanceIds: [
event.detail['instance-id']
]
};
console.log(params);
//인스턴스 정보 가져오기
const result = await ec2.describeInstances(params).promise();
const instance = result.Reservations[0].Instances[0];
let name = "";
instance.Tags.forEach(element => {
if (element.Key == "Name") {
name = element.Value
}
});
let shouldTerminate = await getInstanceMatching(instance.InstanceType)
//large 이상이라면 stop
if (shouldTerminate) {
var params = {
InstanceIds: [
event.detail['instance-id']
]
};
console.log(params);
await ec2.stopInstances(params).promise();
var params = {
Message: `인스턴스가 시작되었으나, large 사이즈 이상이라 정지하였습니다. 이름:${name}, AMI:${instance.ImageId}, 타입 :${instance.InstanceType}, 시작시간:${instance.LaunchTime.toISOString()}`,
TopicArn: process.env.alarm_topic,
};
await new AWS.SNS({ apiVersion: '2010-03-31', region: 'ap-northeast-2' }).publish(params).promise();
}
else {
var params = {
Message: `인스턴스가 시작되었습니다. 이름:${name}, AMI:${instance.ImageId}, 타입 :${instance.InstanceType}, 시작시간:${instance.LaunchTime.toISOString()}`,
TopicArn: process.env.alarm_topic,
};
await new AWS.SNS({ apiVersion: '2010-03-31', region: 'ap-northeast-2' }).publish(params).promise();
}
}
};
InvokeAlarmLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
Action: "lambda:InvokeFunction"
FunctionName: !GetAtt AlarmLambda.Arn
Principal: "events.amazonaws.com"
SourceArn:
Fn::GetAtt:
- "EC2Event"
- "Arn"
위 템플릿을 업로드 하고, 스택생성
이메일 컨펌을 하면 다음과 같이 이벤트가 생성이 되어있고, 인스턴스 large을 생성해보자.
바로 중지되고 메일이 온다.
람다에 들어가면 함수도 잘 생성되어 있는 것을 볼 수 있다.,
'AWS' 카테고리의 다른 글
Amazon API Gateway 기초 (0) | 2023.09.21 |
---|---|
AWS Lambda 기초 (0) | 2023.09.21 |
Serverless 서비스 기반 지진 알람 (0) | 2023.09.20 |
Serverless Framework (0) | 2023.09.20 |
이벤트 기반 아키텍처, Lambda - S3 연결 예제 (0) | 2023.09.20 |