Post

[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*)
EffectAllow(ํ—ˆ์šฉ)

โ‘ก 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์—์„œ ๋กœ๊ทธ ์ŠคํŠธ๋ฆผ๊ณผ ๊ธฐ๋ก์„ ํ™•์ธํ•œ๋‹ค.

CloudWatch ๋กœ๊ทธ


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))

์˜ˆ์•ฝ ๊ธฐ๋ฐ˜ start/stop

โš ๏ธ ์‹ค์Šต ํ›„ 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)์„ ์ฝ”๋“œ ๋ช‡ ์ค„๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.