[Cloud] Lambda, Eventbridge์ ์ดํด
๐ ๋ค์ด๊ฐ๋ฉฐ
์ด๋ฒ ๊ธ์์๋ ์๋ฒ๋ฆฌ์ค(Serverless)์ ๋ํ ์๋น์ค AWS Lambda์, ์ด๋ฒคํธ๋ฅผ ๋ผ์ฐํ ํ๋ EventBridge๋ฅผ ์ ๋ฆฌํ๋ค. ๊ฐ๋ ์ ์ดํด๋ณธ ๋ค, EventBridge๋ก Lambda๋ฅผ ์ฃผ๊ธฐ ์คํํด EC2๋ฅผ ์๋ ์์/์ค์งํ๋ Lab์ ์งํํ๋ค.
์๋ฒ๋ฆฌ์ค๋? ์๋ฒ๋ฅผ ์ง์ ๊ด๋ฆฌยทํ๋ก๋น์ ๋ํ์ง ์๊ณ ์ฝ๋๋ฅผ ์คํํ๋ ํด๋ผ์ฐ๋ ๋ชจ๋ธ. โ์๋ฒ๊ฐ ์๋คโ๊ฐ ์๋๋ผ โ์ฐ๋ฆฌ๊ฐ ์๋ฒ๋ฅผ ๊ด๋ฆฌํ์ง ์์๋ ๋๋คโ๋ ์๋ฏธ๋ค. ์๋ฒ ๊ด๋ฆฌ ๋ถ๋ด ์ ๊ฑฐ, ์๋ ์ค์ผ์ผ๋ง, ์ฌ์ฉํ ๋งํผ๋ง ๊ณผ๊ธ์ด ํต์ฌ ์ด์ ์ด๋ค.
1. AWS Lambda
Lambda๋? ์๋ฒ๋ฅผ ๊ด๋ฆฌํ์ง ์๊ณ ์ฝ๋๋ฅผ ์คํํ๋ ์ด๋ฒคํธ ์ค์ฌ ์๋ฒ๋ฆฌ์ค ์ปดํจํ ์๋น์ค. HTTP ์์ฒญยทDB ์ ๋ฐ์ดํธยทํ์ผ ์ ๋ก๋ ๊ฐ์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ํธ๋ฆฌ๊ฑฐ๋์ด ํจ์๋ฅผ ์คํํ๋ค(PythonยทNode.jsยทJavaยทGo ๋ฑ ์ง์).
| ์ฅ์ | ์ค๋ช |
|---|---|
| ์๋ฒ ๊ด๋ฆฌ ๋ถํ์ | ์ฝ๋์ ์ด๋ฒคํธ์๋ง ์ง์ค |
| ์๋ ํ์ฅ | ์์ฒญ์ ๋ฐ๋ผ ์ธ์คํด์ค ์๋ ์ฆ๊ฐ |
| ๋น์ฉ ํจ์จ | ์คํ๋ ์๊ฐ๋ง ๊ณผ๊ธ(๋ฏธ์ฌ์ฉ ์ 0์) |
| ํตํฉ์ฑ | S3ยทDynamoDBยทAPI Gateway ๋ฑ๊ณผ ์ฐ๋ |
Lambda์ ์ ํ
| ํญ๋ชฉ | ์ ํ |
|---|---|
| ์คํ ์๊ฐ | ์ต๋ 15๋ถ |
| ์ฝ๋ ํฌ๊ธฐ | zip 50MB / unzip 250MB / ์ฝ์ 3MB |
| ๋ฉ๋ชจ๋ฆฌ | 128MB ~ 10,240MB(10GB) |
| ๊ถํ | IAM์ผ๋ก ๋ถ์ฌ |
โ ๏ธ Lambda๋ ์ต๋ 15๋ถ๋ง ์คํ๋๋ค. ์ค๋ ๊ฑธ๋ฆฌ๋ ๋ฐฐ์น ์์ ์๋ ๋ถ์ ํฉํ๋ฉฐ, ๊ทธ๋ฐ ๊ฒฝ์ฐ ์งง์ ์์ ์ผ๋ก ์ชผ๊ฐ๊ฑฐ๋ ECS/Batch ๊ฐ์ ๋ค๋ฅธ ์๋น์ค๋ฅผ ๊ณ ๋ คํด์ผ ํ๋ค.
์๊ธ: ์ 100๋ง ๊ฑด ์์ฒญ + 40๋ง GB-์ด ์คํ์ด ํ๋ฆฌ ํฐ์ด. ์ดํ ์์ฒญ ์ยท์คํ ์๊ฐ(1ms ๋จ์)ยท๋ฉ๋ชจ๋ฆฌ๋ก ๊ณผ๊ธ๋๋ค.
2. EventBridge
EventBridge๋? AWS ์๋น์คยท์ฑ์์ ๋ฐ์ํ๋ ์ด๋ฒคํธ๋ฅผ ๊ฐ์งยท๋ผ์ฐํ ํ๋ ์์ ๊ด๋ฆฌํ ์ด๋ฒคํธ ๋ฒ์ค. ๊ณผ๊ฑฐ CloudWatch Events๋ก ๋ถ๋ ธ๋ค. ์ค์๊ฐ์ผ๋ก ์ด๋ฒคํธ๋ฅผ ๋ฐ์ ๊ท์น์ ๋ง์ผ๋ฉด ํน์ ๋์(Lambda ๋ฑ)์ ํธ๋ฆฌ๊ฑฐํ๋ค.
flowchart LR
Source["๐ข ์ด๋ฒคํธ ์์ค<br/>(AWSยทSaaSยท์ฑ)"]
Bus["๐ ์ด๋ฒคํธ ๋ฒ์ค"]
Rule{"๐ ๊ท์น<br/>(์กฐ๊ฑด/์ผ์ )"}
Target["๐ฏ ํ๊ฒ<br/>(LambdaยทSQSยทSNS)"]
Source --> Bus --> Rule -->|์ผ์น| Target
| ๊ตฌ์ฑ ์์ | ์ญํ |
|---|---|
| ์ด๋ฒคํธ ์์ค | ์ด๋ฒคํธ๋ฅผ ์์ฑํ๋ ์ฃผ์ฒด |
| ์ด๋ฒคํธ ๋ฒ์ค | ์ด๋ฒคํธ ์์งยท๋ผ์ฐํ ๊ฒฝ๋ก |
| ๊ท์น(Rule) | ์กฐ๊ฑด/์ผ์ ์ ๋ง๋ ์ด๋ฒคํธ๋ง ํํฐ |
| ํ๊ฒ(Target) | ์ด๋ฒคํธ๊ฐ ์ ๋ฌ๋ ๋์ |
3. Lab โ EventBridge๋ก EC2 ์๋ ์ค์ง
โ1๋ถ๋ง๋ค EC2๋ฅผ ์ค์งโํ๋ ์๋ฒ๋ฆฌ์ค ์๋ํ๋ฅผ ๋ง๋ ๋ค. ํ๋ฆ์ ์ ์ฑ โ ์ญํ โ ํจ์ โ ํธ๋ฆฌ๊ฑฐ(๊ท์น) โ ์ฝ๋๋ค.
flowchart LR
EB["โฐ EventBridge<br/>rate(1 minute)"]
Lambda["ฮป Lambda<br/>(myStopinatorRoleFunc)"]
Role["๐ญ IAM ์ญํ <br/>(ec2:Stop* ํ์ฉ)"]
EC2["๐ป EC2"]
CW["๐ CloudWatch Logs"]
EB -- ํธ๋ฆฌ๊ฑฐ --> Lambda
Role -.๊ถํ.-> Lambda
Lambda -- stop_instances --> EC2
Lambda -- ๋ก๊ทธ --> CW
โ ์ ์ฑ
์์ฑ (AllowStopInstance)
Lambda๊ฐ CloudWatch์ ๋ก๊ทธ๋ฅผ ๋จ๊ธฐ๊ณ , EC2๋ฅผ ์ค์งํ ์ ์๋๋ก ํ์ฉํ๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"],
"Resource": "arn:aws:logs:*:*:*",
"Effect": "Allow"
},
{
"Action": ["ec2:Stop*"],
"Resource": "*",
"Effect": "Allow"
}
]
}
| ํ๋ | ์๋ฏธ |
|---|---|
Version | ์ ์ฑ
์ธ์ด ๋ฒ์ (2012-10-17 ํ์ค) |
Statement | ๊ถํ ๋ถ์ฌ ๋ช ๋ น ๋ฌถ์ |
Action | ํ์ฉํ ์์
(๋ก๊ทธ ๊ธฐ๋ก + ec2:Stop*) |
Effect | Allow(ํ์ฉ) |
โก IAM ์ญํ (myStopinatorRole)
์ ๋ขฐํ ์ํฐํฐ๋ฅผ Lambda๋ก ์ง์ ํ๊ณ , AllowStopInstance + AWSLambdaBasicExecutionRole ๋ฑ์ ๋ถ์ธ๋ค.
โข Lambda ํจ์ (myStopinatorRoleFunc)
Python 3.12๋ก ์๋ก ์์ฑํ๊ณ , ์คํ ์ญํ ์ myStopinatorRole๋ก ์ง์ ํ๋ค.
โฃ ํธ๋ฆฌ๊ฑฐ โ EventBridge ๊ท์น (everyMinute)
ํธ๋ฆฌ๊ฑฐ๋ก EventBridge๋ฅผ ์ถ๊ฐํ๊ณ , ์์ฝ ํํ์์ผ๋ก rate(1 minute)์ ๋ฃ๋๋ค.
cron vs rate ํํ์:
| ํํ์ | ์๋ฏธ |
|---|---|
rate(1 minute) | 1๋ถ๋ง๋ค |
rate(5 hours) | 5์๊ฐ๋ง๋ค |
cron(0/30 * * * ? *) | 30๋ถ๋ง๋ค |
cron(15 13 ? * MON *) | ๋งค์ฃผ ์์์ผ 13:15 |
๐ก cron์ โํน์ ์๊ฐโ(๋งค์ผ ์คํ 6์ ๋ฑ), rate๋ โ์ผ์ ๊ฐ๊ฒฉโ(N๋ถ/์๊ฐ๋ง๋ค)์ ์ด๋ค. cron ํํ์์ด ํท๊ฐ๋ฆด ๋ crontab.guru๋ก ๊ฒ์ฆํ๋ฉด ํธํ๋ค.
โค ์คํ ์ฝ๋ (boto3)
๊ธฐ๋ณธ โHello from Lambdaโ๋ฅผ ์ง์ฐ๊ณ , EC2๋ฅผ ์ค์งํ๋ ์ฝ๋๋ก ๊ต์ฒดํ ๋ค [Deploy]ํ๋ค.
1
2
3
4
5
6
7
8
import boto3
region = '<REGION>'
instances = ['<INSTANCE_ID>']
ec2 = boto3.client('ec2', region_name=region)
def lambda_handler(event, context):
ec2.stop_instances(InstanceIds=instances)
print('Stopped your instances:' + str(instances))
โฅ ๋ก๊ทธ ํ์ธ
CloudWatch โ ๋ก๊ทธ ๊ทธ๋ฃน โ /aws/lambda/myStopinatorRoleFunc์์ ๋ก๊ทธ ์คํธ๋ฆผ๊ณผ ๊ธฐ๋ก์ ํ์ธํ๋ค.
4. Lab2 โ ์ค์ ์์ (3๋ถ๋ง๋ค / start๋ก ๋ณ๊ฒฝ)
| ๋ณ๊ฒฝ | ๋ฐฉ๋ฒ |
|---|---|
| 3๋ถ๋ง๋ค ์ค์ง | EventBridge everyMinute ํธ์ง โ rate(3 minutes) |
| 1๋ถ๋ง๋ค ์์ | ์ ์ฑ
์ ec2:Start* ์ถ๊ฐ โ ์ฝ๋๋ฅผ start_instances๋ก |
| ์ค๋จ | Lambda โ ๊ตฌ์ฑ โ everyMinute ๋นํ์ฑํ |
start์ฉ ์ฝ๋:
1
2
3
4
5
6
7
8
import boto3
region = '<REGION>'
instances = ['<INSTANCE_ID>']
ec2 = boto3.client('ec2', region_name=region)
def lambda_handler(event, context):
ec2.start_instances(InstanceIds=instances)
print('Started your instances:' + str(instances))
โ ๏ธ ์ค์ต ํ EventBridge โ IAM(์ญํ ยท์ ์ฑ ) โ Lambda โ CloudWatch ๋ก๊ทธ ๊ทธ๋ฃน โ EC2 ์์ผ๋ก ์ญ์ ํ๋ค. ์ด๋ฒคํธ๋ฅผ ๋์ง ์์ผ๋ฉด ๊ณ์ ํธ๋ฆฌ๊ฑฐ๋๋ ๋ฐ๋์ ๋นํ์ฑํยท์ญ์ ํ์.
๊ณผ์ : ๋งค์ผ ์ ๋ 6์(ํ๊ตญ์๊ฐ)์ ๋ชจ๋ EC2๋ฅผ ์ค์งํ๋๋ก
cronํํ์์ผ๋ก ๊ตฌ์ฑํด๋ณด๊ธฐ.
๐ ์ ๋ฆฌ
1
2
3
4
5
Lambda & EventBridge
โโ ์๋ฒ๋ฆฌ์ค ๊ด๋ฆฌยทํ๋ก๋น์ ๋ ์์ด ์ฝ๋ ์คํ(์ฌ์ฉํ ๋งํผ ๊ณผ๊ธ)
โโ Lambda ์ด๋ฒคํธ ํธ๋ฆฌ๊ฑฐ ํจ์(์ต๋ 15๋ถ, IAM ๊ถํ)
โโ EventBridge ์ด๋ฒคํธ ๊ฐ์งยท๋ผ์ฐํ
(๊ตฌ CloudWatch Events)
โโ ์๋ํ rate/cron ๊ท์น โ Lambda โ EC2 start/stop
| ๊ฐ๋ | ํ ์ค ์ ์ |
|---|---|
| Lambda | ์ด๋ฒคํธ ๊ธฐ๋ฐ ์๋ฒ๋ฆฌ์ค ํจ์ |
| EventBridge | ์ด๋ฒคํธ ๋ฒ์ค(๊ท์นโํ๊ฒ) |
| rate/cron | ๊ฐ๊ฒฉ/ํน์ ์๊ฐ ์์ฝ ํํ์ |
์ด ์กฐํฉ์ ํต์ฌ์ EventBridge๊ฐ ์ผ์ ์ ๋ง์ถฐ Lambda๋ฅผ ํธ๋ฆฌ๊ฑฐํ๊ณ , Lambda๊ฐ IAM ์ญํ ๊ถํ์ผ๋ก EC2๋ฅผ ์ ์ดํ๋ ์๋ฒ๋ฆฌ์ค ์๋ํ๋ค. ์๋ฒ ์์ด๋ ์ ๊ธฐ ์์ (๋ฐฑ์ ยทstart/stop)์ ์ฝ๋ ๋ช ์ค๋ก ๊ตฌํํ ์ ์๋ค.





Comments powered by Disqus.