ES /docs

Missing Lambda function in eu-central-1 region — config mismatch

RCA: UploadCpcLogWorker | Function name typo in eu-central-1 config (dc96 → dcg6)

Overview#

What Happened#

2026-05-22 03:22~04:30 UTC 사이에 eu-central-1 리전의 cupixworks-worker에서 UploadCpcLogWorker가 Lambda 함수 cupix-json-collector-dc96을 호출했으나, 실제 배포된 함수 이름은 cupix-json-collector-dcg6(Terraform-managed, 2026-05-13에 마지막 수정)이라 ResourceNotFoundException이 발생했다. 9g가 한 글자 차이로 오탈자가 발생한 config typo다. 동일 시간대 다른 리전(us-west-2, ap-southeast-2)의 동일 worker는 정상 동작했다.

Quick Facts#

Field Value
exception.class Aws::Lambda::Errors::ResourceNotFoundException
exception.message Function not found: arn:aws:lambda:eu-central-1:002596530511:function:cupix-json-collector-dc96:$LATEST
top_frame app/workers/upload_cpc_log_worker.rb:24
deploy production-eu-central-1-20260519T0645Z0-3e770a15-cupixworks
env production, eu-central-1

Timeline#

  1. 2026-05-22 03:22:04 UTC — 최초 에러 발생 (job 101841)
  2. 2026-05-22 04:30:49 UTC — 마지막 확인된 에러 (job 101845)
  3. 2026-05-22T04:04:12 UTC — 클러스터 대표 에러 (job 101840)

Error Log#

Datadog Logs

text
UploadCpcLogWorker::perform | error on job 101840 - Function not found: arn:aws:lambda:eu-central-1:002596530511:function:cupix-json-collector-dc96:$LATEST

Impact#

  • Service: cupixworks-worker
  • 발생 횟수: 6건 (클러스터 내 2건, 확장 검색 시 6건 확인)
  • 최초 발생: 2026-05-22T03:22:04.483Z
  • 최근 발생: 2026-05-22T04:30:49.092Z
  • 영향: eu-central-1 리전의 create_capture_3d_reconstruction 작업 완료 후 CPC JSON 수집이 실패. capture의 processing metric 데이터가 수집되지 않음. 3D reconstruction 결과 자체에는 영향 없음 (worker가 에러를 swallow).

Root Cause Summary#

tesla/config/aws.yamlproduction-eu-central-1.lambda.cpc_json_collector_function_namecupix-json-collector-dc96으로 잘못 기재되어 있다. 실제 eu-central-1에 Terraform으로 배포된 Lambda의 이름은 cupix-json-collector-dcg6(마지막 수정 2026-05-13)이다. suffix 3번째 문자에서 9g 한 글자 오탈자로 인해 존재하지 않는 함수를 invoke하고, AWS SDK가 ResourceNotFoundException을 던진다. Lambda 자체나 IAM, 배포 파이프라인에는 문제가 없으며, config 값 한 글자만 고치면 즉시 해결된다.

Terraform 모듈(cupix-infrastructure/cupix-service/cpc-collector/main.tf:21)이 random_string(길이 4, 소문자+숫자)으로 suffix를 자동 생성하기 때문에 dcg6처럼 문자와 숫자가 섞인 값이 자연스럽게 나오며, 이를 tesla 애플리케이션의 정적 config YAML로 옮겨 적을 때 시각적으로 유사한 9g를 혼동한 사람 손 오류로 판단된다.

Technical Analysis#

Code Path#

  • Entry point: app/models/concerns/taskable/job.rb:63 — ECS task 완료 후 UploadCpcLogWorker 큐잉
app/models/concerns/taskable/job.rb:63ruby
if self.jobable_type == 'Capture'
  UploadCpcLogWorker.perform_in(3.second, self.id)
end
  • Worker 실행: app/workers/upload_cpc_log_worker.rb:5-25
app/workers/upload_cpc_log_worker.rb:5-25ruby
def perform(id)
  Cupix::Logger.info("UploadCpcLogWorker::perform | begins on job #{id}")
  job = ::Job.find_by_id(id)
  return if job.nil?
  return if job.jobable_type != 'Capture'

  job.upload_cpc_part_log

  if job.kind == 'create_capture_3d_reconstruction'
    capture_id = job.jobable_id
    Cupix::Logger.info("UploadCpcLogWorker::perform | run cpc json collector on job #{id}, capture #{capture_id}")
    Cupix::Aws::Lambda.run_cpc_json_collector(
      model_name: 'captures',
      model_key: capture_id
    )
  end

  Cupix::Logger.info("UploadCpcLogWorker::perform | done on job #{id}")
rescue StandardError => e
  Cupix::Logger.error("UploadCpcLogWorker::perform | error on job #{id} - #{e.message}")
end
  • Lambda 호출: lib/cupix/aws/lambda.rb:39-59
lib/cupix/aws/lambda.rb:39-59ruby
def run_cpc_json_collector(opts = {})
  raise Cupix::Errors::Argument.new(code: 'ARG10001', reason: 'model_name is blank') if opts[:model_name].blank?
  raise Cupix::Errors::Argument.new(code: 'ARG10001', reason: 'model_key is blank') if opts[:model_key].blank?

  resp = lambda_client.invoke(
    function_name: $AWS[:lambda][:cpc_json_collector_function_name],
    invocation_type: 'RequestResponse',
    payload: {
      bucket_name: $AWS[:s3][:cpc_results_bucket_name],
      service_name: Cupix::Tesla.service_name,
      model_name: opts[:model_name],
      model_key: opts[:model_key]
    }.to_json
  )

  resp
rescue => e
  raise e
end
  • Lambda client 생성: app/models/concerns/aws_adapter/lambda.rb:8-10
app/models/concerns/aws_adapter/lambda.rb:8-10ruby
def lambda_client
  Aws::Lambda::Client.new region: ENV['CUPIX_REGION'] || 'us-west-2'
end
  • Failure point: lambda_client.invoke 호출 시 AWS SDK가 ResourceNotFoundException 반환. worker의 rescue 블록에서 에러 메시지만 로깅하고 swallow.

  • 오탈자 위치: tesla/config/aws.yaml:521 — 실제 배포 이름은 cupix-json-collector-dcg6이지만 config는 -dc96으로 기재됨 (g9)

tesla/config/aws.yaml:521yaml
production-eu-central-1:
  lambda:
    cpc_json_collector_function_name: 'cupix-json-collector-dc96'  # typo: should be dcg6
  • 실제 배포 정의 (Terraform, random_string으로 suffix 생성): cupix-infrastructure/cupix-service/cpc-collector/main.tf:17-60
cupix-infrastructure/cupix-service/cpc-collector/main.tf:17-60hcl
module "lambda_function" {
  source  = "terraform-aws-modules/lambda/aws"
  version = "8.0.1"

  function_name = "cupix-json-collector-${random_string.service_key.result}"
  ...
}

resource "random_string" "service_key" {
  length  = 4
  special = false
  upper   = false
}
  • 다른 리전의 정상 config 값 (참고, 모두 4자리 소문자+숫자 무작위 suffix):
tesla/config/aws.yaml (regional excerpts)yaml
production-us-west-2:      cpc_json_collector_function_name: 'cupix-json-collector-n9my'
production-ap-southeast-2: cpc_json_collector_function_name: 'cupix-json-collector-boge'
production-ap-southeast-1: cpc_json_collector_function_name: 'cupix-json-collector-xuqh'
production-eu-central-1:   cpc_json_collector_function_name: 'cupix-json-collector-dc96'  # ← typo

Log Evidence#

검색 쿼리:

text
service:cupixworks-worker status:error @environment:production "UploadCpcLogWorker::perform"

에러 로그 (6건 모두 동일 패턴):

text
2026-05-22T03:22:04.483Z | error | UploadCpcLogWorker::perform | error on job 101841 - Function not found: arn:aws:lambda:eu-central-1:002596530511:function:cupix-json-collector-dc96:$LATEST
2026-05-22T03:23:44.500Z | error | UploadCpcLogWorker::perform | error on job 101829 - Function not found: ...
2026-05-22T03:48:36.731Z | error | UploadCpcLogWorker::perform | error on job 101828 - Function not found: ...
2026-05-22T04:04:12.863Z | error | UploadCpcLogWorker::perform | error on job 101840 - Function not found: ...
2026-05-22T04:12:42.965Z | error | UploadCpcLogWorker::perform | error on job 101842 - Function not found: ...
2026-05-22T04:30:49.092Z | error | UploadCpcLogWorker::perform | error on job 101845 - Function not found: ...

정상 처리 로그 (동일 시간대, 다른 리전):

text
service:cupixworks-worker status:info "UploadCpcLogWorker::perform"
text
2026-05-22T04:30:13Z | info | UploadCpcLogWorker::perform | done on job 1082117
2026-05-22T04:29:31Z | info | UploadCpcLogWorker::perform | done on job 1082565
2026-05-22T04:29:15Z | info | UploadCpcLogWorker::perform | done on job 1082411

Job 101840 전체 라이프사이클:

text
2026-05-22T04:03:48.858Z | info  | job_id: 101840, task_id: arn:aws:ecs:eu-central-1:002596530511:task/cupix-tesla-ece-eu/a237e57a1593443cb939899e7dee6356
2026-05-22T04:04:12.862Z | info  | UploadCpcLogWorker::perform | begins on job 101840
2026-05-22T04:04:12.863Z | info  | UploadCpcLogWorker::perform | run cpc json collector on job 101840, capture 36895
2026-05-22T04:04:12.863Z | error | UploadCpcLogWorker::perform | error on job 101840 - Function not found: arn:aws:lambda:eu-central-1:002596530511:function:cupix-json-collector-dc96:$LATEST

공통 속성:

  • Host: ip-10-1-80-125.eu-central-1.compute.internal
  • Deploy: production-eu-central-1-20260519T0645Z0-3e770a15-cupixworks

Hypotheses Considered#

# Hypothesis Evidence for Evidence against Verdict
H1 tesla/config/aws.yaml의 eu-central-1 Lambda 함수명 오탈자 (dc96dcg6, 9g) 실제 배포된 Lambda 이름은 cupix-json-collector-dcg6 (Terraform-managed, 마지막 수정 2026-05-13); config 값은 -dc96; ARN에 config 값 그대로 사용되어 ResourceNotFoundException 발생; random_string이 생성하는 4자리 소문자+숫자 suffix에서 9/g는 시각적으로 혼동하기 쉬움 Confirmed
H2 Lambda 함수 cupix-json-collector-dc96가 삭제되거나 배포 누락됨 AWS SDK가 ResourceNotFoundException 반환 사용자 확인 결과 eu-central-1에 cupix-json-collector-dcg6가 정상 배포되어 있음 (Terraform state 기준). 삭제/배포 누락이 아니라 config 오탈자 Rejected
H3 IAM 권한 부족으로 Lambda invoke 실패 IAM 권한 문제 시 AccessDeniedException 발생하지만, 실제는 ResourceNotFoundException Rejected
H4 일시적 AWS 장애 1시간 이상 지속적으로 실패; AWS 장애라면 다른 서비스도 영향 받아야 하나 ECS 작업은 정상 완료 Rejected

Fix Recommendation#

즉시 조치 (Critical)#

  • tesla/config/aws.yaml:521production-eu-central-1.lambda.cpc_json_collector_function_name 값을 cupix-json-collector-dc96cupix-json-collector-dcg6로 수정 (한 글자 9g)
  • 배포 후 eu-central-1 리전에서 UploadCpcLogWorker 로그가 done 상태로 마무리되는지 확인

단기 개선 (1주 이내)#

  • 다른 리전 config 값도 실제 Terraform state의 Lambda 이름과 일치하는지 대조 검증 (n9my, 2cl5, uaif, boge, xuqh, dl4j, t7af, 3fph, wrnq, 0dxt, t5s0, cl7v 등)
  • UploadCpcLogWorker에서 Lambda 호출 실패 시 리전/함수명/capture_id를 구조화 로깅하여 재발 시 즉시 원인 식별 가능하게 개선
  • 현재 retry: 1이므로 config 오탈자는 재시도로 해결되지 않음. ResourceNotFoundException은 재시도 대상에서 제외하고 즉시 알람으로 승격

장기 개선 (재발 방지)#

  • Config 값을 사람이 수기로 관리하지 않기: Terraform output 또는 SSM Parameter Store를 통해 실제 배포된 Lambda 이름을 tesla 런타임이 직접 조회하도록 리팩터. 수기 복사 자체를 제거하면 9/g 유형의 오탈자 재발이 원천 차단됨
  • 리전별 Lambda 존재 여부를 확인하는 synthetic check 또는 CloudWatch alarm 구성 — 함수가 존재하지 않으면 Errors 메트릭조차 뜨지 않으므로, Invocations == 0 for > 1h 조건으로 감시
  • CI에서 tesla/config/aws.yaml의 Lambda 이름 필드를 Terraform state와 대조하는 검증 스텝 추가 검토

Monitoring#

  • Lambda 함수 호출 에러 모니터링:
text
service:cupixworks-worker "UploadCpcLogWorker" status:error
  • 리전별 정상 완료 카운트 (dashboard timeseries에서 measure/group by 사용):
text
service:cupixworks-worker "UploadCpcLogWorker::perform | done"
  • CloudWatch 메트릭: AWS/Lambda > Invocations for function cupix-json-collector-dcg6 in eu-central-1 — config 오탈자가 남아 있으면 이 실제 함수의 Invocations는 0이지만 error 로그는 계속 발생. 두 지표를 나란히 비교하면 재발 시 즉시 식별 가능

Risk Assessment#

  • Risk level: low
  • 예상 복잡도: trivial — config YAML 한 글자 수정 후 배포. Lambda나 인프라 자체는 정상이며 Terraform 변경 불필요

Revision History#

Revision 1#

Feedback: "오타가 있어서 그런거임. 이걸로 다시 보고서 써줘 — Actually deployed in eu-central-1 → cupix-json-collector-dcg6 (Terraform-managed, last modified 2026-05-13, one char off: 9↔g)"

판정:

피드백 항목 판정 근거
실제 배포된 Lambda 이름이 cupix-json-collector-dcg6이며, config의 -dc969g 오탈자 수용 사용자가 Terraform state 기반으로 실제 배포명을 확인해 제공. Terraform 정의(cupix-infrastructure/cupix-service/cpc-collector/main.tf:21)는 function_name = "cupix-json-collector-${random_string.service_key.result}"로 4자리 소문자+숫자 무작위 suffix를 생성하며 다른 리전 값들(n9my, 2cl5, uaif, boge 등)도 동일한 패턴 — dcg6는 이 규칙에 완전히 부합. config 값 dc96(tesla/config/aws.yaml:521)은 이 배포명을 사람이 옮겨 적는 과정에서 시각적으로 유사한 g/9를 혼동한 것으로 해석
근본 원인이 "Lambda 미배포/삭제"가 아니라 "config 오탈자" 수용 위와 동일. Lambda는 정상 배포되어 있으므로 재배포/파이프라인 수정이 아니라 config 한 글자 수정이 fix

변경 사항:

  • 문서 제목·description·What Happened 을 "함수 미배포"에서 "config typo (dc96 → dcg6)"로 재작성
  • Root Cause Summary 를 오탈자 시나리오로 전면 교체하고, random_string suffix 생성 규칙과 시각적 혼동 근거 추가
  • Technical Analysis → Code Path 에 실제 오탈자 위치(tesla/config/aws.yaml:521), Terraform 정의(cpc-collector/main.tf:17-60), 타 리전 config 대조 블록 추가
  • Hypotheses: H1을 "config 오탈자"로 재정의하고 Confirmed, 기존 H1("함수 미배포/삭제")을 H2로 강등하고 Rejected. Rev0의 잘못된 H2("config 오타" Rejected)는 삭제
  • Fix Recommendation: Lambda 재배포 → config 한 글자 수정으로 교체. 재발 방지에 "Terraform output/SSM으로 자동 조회" 및 "CI에서 config↔Terraform state 대조" 추가
  • Monitoring: 잘못된 | stats count by region 파이프 쿼리를 제거하고(dashboard timeseries에서는 렌더링되지 않음), 실제 배포명 -dcg6의 CloudWatch Invocations와 error 로그를 병행 감시하도록 변경
  • Risk Assessment: medium/standard → low/trivial

추가 조사 내용:

  • cupix-infrastructure/cupix-service/cpc-collector/main.tf — Lambda function_name 생성 로직 확인 (random_string length=4, 소문자+숫자)
  • cupix-infrastructure/cupix-aws2-eu/production/terragrunt.hcl — eu-central-1 배포 컨텍스트 확인 (cpc-collector 모듈이 이 스택에서 provisioned)
  • tesla/config/aws.yaml — 12개 리전의 cpc_json_collector_function_name 값 전수 조사, 모두 4자리 소문자+숫자 suffix 패턴 확인
  • 저장소 전체 grep 결과 dcg6는 tesla/cupix-infrastructure 소스 어디에도 하드코딩돼 있지 않음 — 사용자 제보(Terraform state)만이 유일한 출처이므로 판정 근거는 사용자 확인 + 다른 리전 패턴 대조에 기반