♨ EventBridge 규칙에서 Lambda함수 호출에 실패할때 조치 방법
- EventBridge 규칙(Rule) 설정 확인:
- 이벤트 패턴(Event Pattern): CodeDeploy 배포 성공 이벤트(CodeDeploy Deployment State Change, detail.state가 SUCCESS인 경우)를 정확히 필터링하도록 이벤트 패턴이 올바르게 정의되었는지 확인합니다. 실제 CodeDeploy 성공 시 발생하는 이벤트 구조와 비교해보세요. AWS 콘솔의 CloudWatch Logs Insights나 EventBridge의 이벤트 버스 모니터링 기능을 통해 실제 전달된 이벤트 내용을 확인하면 패턴 작성에 도움이 됩니다.
- 대상(Target) 설정: 규칙의 대상으로 설정된 Lambda 함수가 올바른지, 그리고 대상 설정이 **활성화(Enabled)**되어 있는지 확인합니다. 실수로 비활성화되어 있을 수 있습니다.
- 규칙 상태(Rule Status): EventBridge 규칙 자체가 활성화(Enabled) 상태인지 확인합니다.
- IAM 권한 확인 (가장 흔한 원인 중 하나): ☜ 나는 이게 문제였더라고!
- EventBridge가 Lambda 함수를 호출하려면 적절한 권한이 필요합니다. 일반적으로 EventBridge가 Lambda 함수를 대상으로 지정할 때 AWS 콘솔에서 자동으로 **리소스 기반 정책(Resource-based Policy)**을 Lambda 함수에 추가해줍니다.
- Lambda 함수 권한 확인:
- AWS Lambda 콘솔에서 해당 함수로 이동합니다.
- '구성(Configuration)' 탭 아래의 '권한(Permissions)' 섹션으로 이동합니다.
- '리소스 기반 정책' 섹션을 확인합니다.
- eventbridge.amazonaws.com 서비스 주체(principal) 또는 해당 EventBridge 규칙의 ARN이 lambda:InvokeFunction 작업을 수행할 수 있도록 허용하는 정책문(statement)이 있는지 확인합니다. 예를 들어 다음과 유사한 정책이 있어야 합니다:
-
JSON
{ "Sid": "AllowEventBridgeInvoke", "Effect": "Allow", "Principal": { "Service": "events.amazonaws.com" }, "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:YOUR_FUNCTION_NAME", "Condition": { "ArnLike": { "AWS:SourceArn": "arn:aws:events:REGION:ACCOUNT_ID:rule/YOUR_RULE_NAME" } } }
- 만약 이 정책이 없거나 잘못 설정되었다면, EventBridge는 Lambda 함수를 호출할 권한이 없어 실패하게 됩니다. EventBridge 규칙의 대상을 제거했다가 다시 추가하면 콘솔이 이 정책 생성을 시도할 수 있습니다. 또는 AWS CLI나 SDK를 사용하여 직접 추가할 수도 있습니다 (aws lambda add-permission 명령어 사용).
- Lambda 함수 실행 로그 및 오류 확인:
- EventBridge가 Lambda를 호출했더라도, Lambda 함수 자체에서 초기화 오류나 실행 중 오류가 발생하여 즉시 실패했을 수 있습니다. 이 경우 호출되지 않은 것처럼 보일 수 있습니다.
- CloudWatch Logs 확인:
- 해당 Lambda 함수와 연결된 CloudWatch Log Group으로 이동합니다.
- CodeDeploy 성공 이벤트가 발생한 시점 근처에 새로운 로그 스트림이나 로그 항목이 있는지 확인합니다.
- START, END, REPORT 로그 외에 에러 메시지나 스택 트레이스가 있는지 확인합니다. 특히 함수 핸들러 설정 오류, 코드 내 오류, 타임아웃 등을 확인하세요.
- EventBridge 규칙 모니터링 확인:
- CloudWatch Metrics에서 EventBridge 관련 지표를 확인합니다.
- 해당 EventBridge 규칙(Rule)의 이름으로 필터링하여 다음 지표를 확인합니다:
- TriggeredRules: 규칙의 이벤트 패턴과 일치하는 이벤트가 발생하여 규칙이 트리거되었는지 횟수를 보여줍니다. 이 값이 증가한다면 이벤트 패턴 매칭은 성공한 것입니다.
- InvocationAttempts: EventBridge가 Lambda 함수 호출을 시도한 횟수입니다.
- FailedInvocations: Lambda 함수 호출 시도가 실패한 횟수입니다. 이 값이 증가한다면 권한 문제나 Lambda 함수 자체의 문제(예: 함수가 존재하지 않음, 리소스 기반 정책 누락 등)일 가능성이 높습니다.
- Lambda 함수 구성 확인:
- Lambda 함수의 핸들러 설정이 올바른지, 런타임은 적절한지 등 기본적인 구성 사항을 다시 한번 확인합니다.
- Lambda 함수의 제한 시간(Timeout) 설정이 너무 짧게 되어 있어 이벤트 처리 중 타임아웃되는 것은 아닌지 확인합니다.
요약 및 추천 접근법:
- EventBridge 규칙 설정 (패턴, 대상, 활성화 상태) 재확인.
- Lambda 함수 권한 탭에서 리소스 기반 정책 확인 (가장 중요!). eventbridge.amazonaws.com 또는 규칙 ARN에 대한 lambda:InvokeFunction 권한이 있는지 확인합니다.
- CloudWatch에서 EventBridge 규칙의 FailedInvocations 지표 확인.
- CloudWatch에서 Lambda 함수의 로그 확인. (오류가 있는지, 아예 로그 자체가 없는지)
이 단계들을 차례대로 점검해보시면 문제의 원인을 파악하고 해결하는 데 도움이 될 것입니다. 만약 위의 방법으로도 해결되지 않는다면, 사용하신 이벤트 패턴이나 Lambda 리소스 기반 정책의 구체적인 내용을 공유해주시면 좀 더 자세히 살펴볼 수 있습니다.
♨ Lambda 함수가 호출되었는데, Lambda 함수 실행 중 타임아웃이 발생할 경우 조치 방법
Lambda 함수 실행 중 타임아웃은 codedeploy.list_deployment_instances API 호출 부분에서도 충분히 발생할 수 있습니다. 특히 "Target instance IDs:", instance_ids 로그가 출력되기 전에 타임아웃이 발생했다면, 해당 API 호출 또는 관련 로직(페이지네이션 루프 포함) 수행 중에 설정된 제한 시간을 초과했을 가능성이 매우 높습니다.
타임아웃이 발생하는 주요 원인들은 다음과 같습니다.
- 네트워크 연결 문제 (가장 흔한 원인 중 하나): ☜ 나는 이게 문제였더라고!
- Lambda 함수가 VPC 내부에 있는 경우:
- Private Subnet: Lambda 함수가 인터넷 아웃바운드 액세스가 없는 Private Subnet에 있고, NAT Gateway나 CodeDeploy용 VPC 엔드포인트(Interface Endpoint)가 설정되어 있지 않으면 AWS API(CodeDeploy 엔드포인트)에 연결할 수 없습니다. 이 경우 boto3 클라이언트는 응답을 기다리다가 결국 Lambda 함수의 타임아웃 시간에 도달하게 됩니다.
- Security Group / NACL: Lambda 함수에 연결된 보안 그룹의 아웃바운드 규칙이나 서브넷의 네트워크 ACL이 HTTPS (포트 443) 트래픽을 차단하고 있을 수 있습니다. CodeDeploy API 엔드포인트로의 통신이 막히면 타임아웃이 발생합니다.
- VPC 엔드포인트 설정 오류: CodeDeploy용 VPC 엔드포인트를 사용 중이라면, 라우팅, 보안 그룹, 엔드포인트 정책 등이 올바르게 설정되었는지 확인해야 합니다.
- 해결 방안:
- Lambda 함수가 VPC 내에 있다면, 네트워크 구성을 점검하세요 (NAT Gateway, Internet Gateway, 라우팅 테이블, 보안 그룹, NACL).
- CodeDeploy용 VPC 엔드포인트 설정을 확인하거나, 없다면 생성을 고려해 보세요. (VPC 엔드포인트 사용 시 NAT Gateway 불필요)
- 보안 그룹 아웃바운드 규칙에서 포트 443이 열려 있는지 확인하세요.
- Lambda 함수가 VPC 내부에 있는 경우:
- 매우 많은 수의 인스턴스 및 페이지네이션:
- CodeDeploy 배포 대상 인스턴스가 수백, 수천 대로 매우 많을 경우, list_deployment_instances API는 여러 페이지의 결과를 반환합니다. 코드의 while 루프는 모든 페이지를 다 가져올 때까지 반복해서 API를 호출합니다.
- 각 API 호출마다 약간의 시간이 소요되는데, 페이지 수가 너무 많으면 이 시간들이 누적되어 Lambda 함수의 전체 타임아웃 시간을 초과할 수 있습니다. 특히 Lambda 함수의 타임아웃 설정이 짧을 경우(예: 기본값 3초 또는 수십 초) 발생 가능성이 높습니다.
- 해결 방안:
- Lambda 함수의 타임아웃 설정을 늘려보세요. (예: 1분, 5분 등). 임시로 늘려서 코드가 완료되는지 확인하면, 단순히 시간이 부족했던 것인지 다른 문제인지 판단하는 데 도움이 됩니다.
- 정말로 많은 인스턴스를 처리해야 하고 시간이 오래 걸린다면, Step Functions 등을 사용하여 작업을 분할하거나 다른 아키텍처를 고려해야 할 수도 있습니다.
- CodeDeploy API 응답 지연 또는 일시적 문제:
- 드물지만 AWS CodeDeploy 서비스 자체의 일시적인 성능 저하나 문제로 인해 API 응답이 느려져 타임아웃이 발생할 수도 있습니다.
문제 해결 방법 상세(Lambda 함수가 VPC 내부에 있는 경우):
Lambda 함수가 VPC 내부에 있을 때 타임아웃이 발생한다면 네트워크 연결 문제일 가능성이 높습니다. 다음 단계를 순서대로 점검해 보세요.
1단계: Lambda 함수 VPC 구성 확인
- 어떤 VPC, 서브넷, 보안 그룹에 연결되어 있는지 확인합니다.
- 작업: AWS Lambda 콘솔 > 해당 함수 선택 > '구성(Configuration)' 탭 > 'VPC' 메뉴로 이동합니다.
- 여기에 명시된 **VPC ID, 서브넷 ID(들), 보안 그룹 ID(들)**을 메모해 둡니다.
2단계: 서브넷 유형 확인 (Public vs Private)
- Lambda 함수가 연결된 서브넷들이 인터넷에 직접 연결될 수 있는 Public Subnet인지, 아니면 인터넷 연결을 위해 다른 경로(NAT 게이트웨이 등)가 필요한 Private Subnet인지 확인합니다.
- 작업:
- AWS VPC 콘솔 > '서브넷(Subnets)' 메뉴로 이동합니다.
- 1단계에서 확인한 서브넷 ID 각각을 선택합니다.
- '라우팅 테이블(Route table)' 탭을 확인하여 연결된 라우팅 테이블 ID를 확인합니다.
3단계: 라우팅 테이블 확인
- Lambda 함수 서브넷에 연결된 라우팅 테이블이 인터넷 또는 CodeDeploy 서비스 엔드포인트로 트래픽을 보낼 경로를 가지고 있는지 확인합니다.
- 작업:
- AWS VPC 콘솔 > '라우팅 테이블(Route tables)' 메뉴로 이동합니다.
- 2단계에서 확인한 라우팅 테이블 ID를 선택합니다.
- '라우팅(Routes)' 탭 내용을 확인합니다.
- 시나리오 A: NAT 게이트웨이 사용 예상 시 (가장 일반적) ☜ 난 이방법을 사용함.
- 대상(Destination) 0.0.0.0/0 (모든 IPv4 트래픽)에 대한 경로가 있습니까?
- 해당 경로의 대상(Target)이 **NAT 게이트웨이 ID (nat-xxxxxxxx)**로 지정되어 있습니까?
- 만약 그렇다면: 4단계 (NAT 게이트웨이 확인)로 진행합니다.
- 만약 경로가 없거나 대상이 잘못되었다면: 이것이 문제의 원인일 가능성이 높습니다. Private Subnet에서 외부 API를 호출하려면 0.0.0.0/0 트래픽을 NAT 게이트웨이로 보내는 경로가 필요합니다.
- 시나리오 B: VPC 엔드포인트 사용 예상 시
- CodeDeploy 서비스용 VPC 인터페이스 엔드포인트(com.amazonaws.<region>.codedeploy)를 사용하도록 의도했습니까?
- 이 경우 0.0.0.0/0 경로는 필요 없거나 다른 용도로 사용될 수 있습니다. CodeDeploy로 가는 트래픽은 엔드포인트를 통해 라우팅됩니다.
- 만약 그렇다면: 5단계 (VPC 엔드포인트 확인)로 진행합니다.
- 시나리오 C: 퍼블릭 서브넷 사용 시 (Lambda에는 일반적이지 않음)
- 대상 0.0.0.0/0의 대상(Target)이 **인터넷 게이트웨이 ID (igw-xxxxxxxx)**로 지정되어 있습니까?
- 만약 그렇다면: 해당 서브넷은 퍼블릭 서브넷입니다. 이 경우 Lambda 함수 자체에 퍼블릭 IP가 할당되어야 외부 통신이 가능합니다 (기본 설정 아님). 일반적으로 Lambda는 Private Subnet + NAT/엔드포인트 조합을 사용합니다. 이 구성이 의도된 것이 아니라면 Private Subnet으로 변경하는 것을 고려하세요. 의도된 것이라면 6단계 (보안 그룹 확인)로 진행합니다.
4단계: NAT 게이트웨이 상태 및 구성 확인 (3단계 A 시나리오 해당 시) ☜ 상세한 해결방법 (주의 : NAT게이트웨이는 퍼블릿 서브넷, lambda 함수는 프라이빗 서브넷에 있어야함. 프라이빗 서브넷에서의 라우트에는 NAT 게이트웨이가 설정되어 있어야 하며, 퍼블릿 서브넷의 라우트에선 인터넷 게이트웨이가 설정되어 있어야 함.)
- 라우팅 테이블에서 확인한 NAT 게이트웨이가 정상적으로 작동하는지 확인합니다.
- 작업:
- AWS VPC 콘솔 > 'NAT 게이트웨이(NAT Gateways)' 메뉴로 이동합니다.
- 라우팅 테이블에 있던 nat-xxxxxxxx ID를 찾습니다.
- **상태(Status)**가 'available'인지 확인합니다.
- NAT 게이트웨이에 탄력적 IP(Elastic IP) 주소가 할당되어 있는지 확인합니다.
- NAT 게이트웨이가 위치한 서브넷을 확인합니다. 이 서브넷은 퍼블릭 서브넷이어야 합니다 (즉, 이 서브넷의 라우팅 테이블에는 0.0.0.0/0 -> igw-xxxxxxxx 경로가 있어야 함). 해당 서브넷의 라우팅 테이블도 확인합니다.
5단계: VPC 엔드포인트 상태 및 구성 확인 (3단계 B 시나리오 해당 시)
- CodeDeploy용 VPC 인터페이스 엔드포인트가 올바르게 설정되었는지 확인합니다.
- 작업:
- AWS VPC 콘솔 > '엔드포인트(Endpoints)' 메뉴로 이동합니다.
- 서비스 이름이 com.amazonaws.<region>.codedeploy 인 인터페이스(Interface) 유형의 엔드포인트를 찾습니다.
- **상태(Status)**가 'available'인지 확인합니다.
- 엔드포인트가 1단계에서 확인한 올바른 VPC에 연결되어 있는지 확인합니다.
- '서브넷(Subnets)' 탭에서 Lambda 함수가 사용하는 서브넷 (또는 해당 가용 영역의 다른 서브넷)이 연결되어 있는지 확인합니다.
- '보안 그룹(Security groups)' 탭에서 연결된 보안 그룹이 Lambda 함수의 보안 그룹으로부터 HTTPS (포트 443) 인바운드 트래픽을 허용하는지 확인합니다.
- 엔드포인트 정책(Policy)이 설정되어 있다면, Lambda 함수의 실행 역할(IAM Role)이 codedeploy:ListDeploymentInstances 작업을 수행하도록 허용하는지 확인합니다. (기본값은 전체 허용)
- VPC 설정에서 'DNS 호스트 이름 활성화' 및 'DNS 확인 활성화'가 모두 활성화되어 있는지 확인합니다.
6단계: Lambda 함수 보안 그룹의 아웃바운드 규칙 확인
- Lambda 함수 자체에 연결된 보안 그룹이 외부로 나가는 트래픽을 허용하는지 확인합니다.
- 작업:
- AWS EC2 콘솔 > '보안 그룹(Security Groups)' 메뉴로 이동합니다.
- 1단계에서 확인한 Lambda 함수에 연결된 보안 그룹 ID를 찾습니다.
- '아웃바운드 규칙(Outbound rules)' 탭을 확인합니다.
- HTTPS (포트 443) 트래픽을 대상 0.0.0.0/0 (NAT/IGW 사용 시) 또는 VPC 엔드포인트가 사용하는 IP 대역/보안 그룹 (VPC 엔드포인트 사용 시)으로 허용하는 규칙이 있는지 확인합니다. 가장 흔한 실수는 이 아웃바운드 규칙이 없거나 너무 제한적인 경우입니다.
7단계: 네트워크 ACL(NACL) 규칙 확인
- 서브넷 수준의 방화벽인 NACL이 트래픽을 차단하고 있지 않은지 확인합니다. NACL은 상태 비저장(Stateless)이므로 인바운드와 아웃바운드 규칙을 모두 확인해야 합니다.
- 작업:
- AWS VPC 콘솔 > '네트워크 ACLs(Network ACLs)' 메뉴로 이동합니다.
- Lambda 함수가 있는 서브넷과 (NAT 게이트웨이를 사용한다면) NAT 게이트웨이가 있는 서브넷에 연결된 NACL을 확인합니다.
- Lambda 서브넷 NACL:
- 아웃바운드 규칙: 대상 0.0.0.0/0 (또는 CodeDeploy 엔드포인트 IP 대역), 포트 443 (HTTPS)으로 나가는 TCP 트래픽을 허용하는 규칙이 있는지 확인합니다.
- 인바운드 규칙: 소스 0.0.0.0/0 (또는 CodeDeploy 엔드포인트 IP 대역), 포트 범위 1024-65535 (Ephemeral ports)로 들어오는 TCP 트래픽을 허용하는 규칙이 있는지 확인합니다. (API 응답 트래픽)
- NAT 게이트웨이 서브넷 NACL (NAT 사용 시): 유사하게 인바운드/아웃바운드 규칙을 확인합니다. (인터넷에서 오는 응답과 인터넷으로 나가는 요청)
- 참고: 기본 NACL은 모든 트래픽을 허용합니다. 사용자 정의 NACL이 적용되어 있다면 규칙 번호 순서대로 평가되므로 주의 깊게 확인해야 합니다.
8단계: (선택) EC2 인스턴스로 연결 테스트
- 문제 진단을 돕기 위해, Lambda 함수와 동일한 VPC 서브넷 및 동일한 보안 그룹을 사용하는 EC2 인스턴스를 임시로 생성합니다.
- 해당 인스턴스에 SSH로 접속하여 CodeDeploy 엔드포인트로 직접 연결 테스트를 수행합니다.
-
Bash
# 예시: 서울 리전 curl -v https://codedeploy.ap-northeast-2.amazonaws.com
- 여기서 연결이 성공하면 Lambda 환경 자체의 문제일 수 있고, 여기서도 실패하면 VPC 네트워크 경로 문제일 가능성이 높습니다.
이 단계들을 순서대로 차근차근 점검해 보시면 VPC 내부 Lambda 함수의 네트워크 연결 문제를 진단하고 해결하는 데 도움이 될 것입니다. 가장 먼저 Lambda 타임아웃 설정 증가와 보안 그룹 아웃바운드 규칙을 확인하는 것이 효과적인 경우가 많습니다.
♨ Lambda 함수가 호출되었는데, AccessDeniedException 오류가 발생할 경우 조치 방법
AccessDeniedException 오류는 Lambda 함수가 codedeploy:ListDeploymentInstances 권한이 없어서 발생한 것입니다. 이 오류를 해결하기 위해 아래 순서대로 조치하면 됩니다.
✅ 1단계: 오류 원인 파악
오류 메시지에 따르면, Lambda 함수가 사용하는 역할(myFunc-asg-update-role-n3ys1udk)에 codedeploy:ListDeploymentInstances 권한이 없습니다.
User: arn:aws:sts::...:assumed-role/myFunc-asg-update-role-n3ys1udk/myLambda-codedeploy is not authorized to perform: codedeploy:ListDeploymentInstances
✅ 2단계: Lambda 함수의 실행 역할(Role) 확인
- AWS Lambda 콘솔 접속
- 문제 발생한 Lambda 함수 선택 (myLambda-codedeploy)
- [구성] 탭 > 권한 > 실행 역할 클릭
- 여기서 확인되는 IAM Role이 myFunc-asg-update-role-n3ys1udk인지 다시 한번 확인
✅ 3단계: 해당 IAM Role에 권한 추가
이제 해당 Role에 필요한 CodeDeploy 권한을 추가해야 합니다.
- IAM 콘솔 접속
- 역할(Roles)에서 myFunc-asg-update-role-n3ys1udk 검색하여 클릭
- [권한] 탭에서 정책 추가 버튼 클릭
- 인라인 정책 추가 또는 기존 정책 편집
🔧 정책(JSON) 예시:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"codedeploy:ListDeploymentInstances",
"codedeploy:GetDeploymentInstance",
"codedeploy:GetDeployment",
"codedeploy:GetDeploymentGroup"
],
"Resource": [
"arn:aws:codedeploy:ap-northeast-2:148761669753:deploymentgroup:SpringBootApp-1/app-deploy-1",
"arn:aws:codedeploy:ap-northeast-2:148761669753:deployment:SpringBootApp-1/*"
]
}
]
}
✅ 필요 시 "Resource": "*"로 설정해 우선 테스트해보고, 이후 최소 권한 원칙에 따라 리소스를 좁히는 것이 좋습니다.
✅ 4단계: 정책 저장 및 적용 확인
- 정책 저장 후, Lambda 함수에서 다시 테스트 이벤트 실행
- 동일한 AccessDeniedException이 발생하지 않으면 권한 적용 완료
✅ 5단계 (선택): CloudTrail로 추가 분석
혹시 다른 권한도 누락됐을 수 있으므로, CloudTrail에서 Lambda 호출 이력을 확인해 어떤 API 호출에 실패했는지 추가로 점검할 수 있습니다.
필요하시면 IAM 정책 생성 화면에서 어떤 버튼을 눌러야 하는지도 스크린샷 기반으로 도와드릴 수 있어요. JSON 정책 붙여넣기 창이 잘 안 보이는 경우 알려주세요!