Lambda에 Python CLI를 얹으려니 계속 걸렸다. 결국 라이브러리를 통째로 바꿨다.
기존 EdgeTTSAdapter는 edge-tts Python CLI를 execSync로 호출하는 구조였다. Lambda Layer로 Python 바이너리를 빌드해서 올려야 했는데, ffprobe 레이어까지 겹치니 배포 크기와 콜드스타트가 둘 다 부담스러웠다.
// 이전
execSync(
`"${this.edgeTtsPath}" --voice ko-KR-SunHiNeural --rate +20% --file "${textFile}" --write-media "${outputPath}" --write-subtitles "${vttOut}"`,
{ stdio: 'inherit', timeout: 120_000 }
);
msedge-tts라는 Node.js 라이브러리로 바꿨다. Edge TTS 서비스를 직접 스트림으로 호출하는 방식이라 CLI도, Layer도 필요 없다.
const tts = new MsEdgeTTS();
await tts.setMetadata(
'ko-KR-SunHiNeural',
OUTPUT_FORMAT.AUDIO_24KHZ_48KBITRATE_MONO_MP3,
);
const { audioStream } = await tts.toStream(text, { rate: '+20%' });
const chunks: Buffer[] = [];
for await (const chunk of audioStream) {
chunks.push(chunk as Buffer);
}
writeFileSync(outputPath, Buffer.concat(chunks));
tts.close();
serverless.yml에서 EDGE_TTS_PATH 환경변수와 Lambda Layer 참조를 통째로 지웠다. env.ts의 zod 스키마에서도 해당 필드를 뺐다. 배포 아티팩트가 확 가벼워졌다.
같은 날 web 서비스 배포도 자동화했다. GitHub Actions에서 OIDC로 AWS 역할을 assume하고, ECR에 이미지를 푸시한 다음 ECS 서비스를 강제 재배포하는 흐름이다.
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::682251233572:role/github-actions-deploy
aws-region: ${{ env.AWS_REGION }}
- name: Deploy to ECS
run: |
aws ecs update-service \
--cluster $ECS_CLUSTER \
--service $ECS_SERVICE \
--force-new-deployment \
--region $AWS_REGION
빌드 시점에 필요한 NEXT_PUBLIC_API_URL 같은 값은 SSM에서 읽어서 Docker --build-arg로 넘겼다. 로컬에서도 같은 순서로 수동 배포할 수 있게 PowerShell 스크립트를 하나 만들어뒀는데, 이건 하루 뒤에 EC2로 갈아타면서 통째로 버렸다.