업무 중 진행한, ECS에서 Lambda Web Adapter를 이용한 Lambda 환경으로 전환한 인프라 작업에 대해 기록합니다.
1편에서는 전환 배경과 인프라 작업에 대한 전반적인 셋업에 대한 내용이며,
2편에서는 해당 작업을 진행하며 발생했던 이슈, 인프라를 전환하며 얻을 수 있었던 이점 그리고 개인적인 후기에 대해 작성하였습니다..
인프라 전환 배경
- Scrapping Lambda 작업에 따른 인프라 개선
- 새로운 Lambda Scrapper를 만들 때마다 Server에서 사용하는 모델과 DTO를 재구성하고, DB를 새롭게 설정해야 합니다. Scrapper 추가로 인한 관리 포인트 증가를 줄이기 위해 인프라 개선 작업을 진행합니다.
- 분리된 Lambda 함수 관리의 어려움
- Lambda 함수들이 프로젝트와 분리되어 있어, 운영 및 관리에 어려움이 발생하고 있습니다. 특히, 외부 정보를 수집하는 Scrapper와 같은 독립적인 Lambda 서비스들로 인하여 관리 복잡성이 증가하고 있습니다.
- 프로젝트 통합의 필요성
- 인프라 전환이 완료되면, 프로젝트를 하나의 레파지토리로 통합하는 작업을 진행할 수 있습니다. Main Server가 있는 프로젝트에서 코드를 관리할 수 있으므로, ORM, 공통 Model, Entity 등을 활용하여 생산성을 높이고, 로직 개발 시 발생할 수 있는 휴먼 에러를 방지할 수 있습니다.
- 비용 절감 효과
- ECS로 실행 중인 EC2 인스턴스의 수를 감소하여 운영 비용을 절감할 수 있습니다. EC2 인스턴스의 효율적인 관리를 통해 전체 운영 비용을 크게 줄일 수 있을 것으로 예상됩니다.
- 배포 시간 단축
- 인프라 전환 후 배포 시간이 단축되어, 개발 작업 및 에러 수정 사항이 빠르게 반영될 수 있습니다. 생산성을 높이고, 문제 해결 시간을 줄일 수 있습니다.
SAM (Severless Application Model)
- 코드형 인프라를 사용하여 서버리스 애플리케이션을 구축하기 위한 오픈 소스 프레임워크
- SAM의 간결한 구문을 사용하여 AWS CloudFormantion 리소스와 특수 서버리스 리소스를 선언할 수 있습니다.
SAM Template specification
- AWS CloudFormation 기반
- SAM 템플릿은 AWS CloudFormation구문을 사용하기 때문에 AWS CloudFormation 익숙하다면 추가적인 학습 없이 사용할 수 있습니다.
- CloudFormation 확장
- 서버리스 개발 속도를 높이는 데 특화된 구문을 제공하며, 동일한 템플릿 내에서 AWS CloudFormation과 AWS SAM 구문을 모두 사용할 수 있습니다.
- 추상적이고 간결한 문법
- 더 적은 코드 줄로 신속하게 인프라를 정의하고 오류 발생 가능성을 낮출 수 있습니다.
- 변환 과정
- AWS CloudFormation을 통해 인프라 프로비저닝을 자동으로 처리하여 복잡한 작업을 수행하기 때문에 개발자는 더 간단하게 인프라를 구축할 수 있습니다.
Lambda Web Adapter
- Lambda Web Adapter를 사용하면 익숙한 프레임워크로 웹 앱(http api)을 빌드하고 AWS Lambda에서 실행할 수 있습니다.
사용법
- Lambda Web Adapter는 Docker Image를 사용하는 환경에서 매우 쉽게 사용할 수 있습니다. Dockerfile에Lambda Web Adapter 바이너리를 복사하는 한 줄만 추가하면 됩니다.
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.8.4 /lambda-adapter /opt/extensions/lambda-adapter
- FAST API Dockerfile 예시
FROM python:3.11-buster as builder
WORKDIR /app
RUN pip install poetry==1.8.3
COPY . /app
RUN poetry install --without dev --no-root && rm -rf $POETRY_CACHE_DIR
FROM python:3.11-slim-buster as runtime
# Lambda Web Adapter 바이너리를 컨테이너에 복사
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.8.4 /lambda-adapter /opt/extensions/lambda-adapter
RUN apt-get update \
&& apt-get install -y default-mysql-client pkg-config curl
COPY --from=builder /app /app
WORKDIR /app
Lambda Web Adapter 바이너리는 ECR 공개 리포지토리에서 제공되며, x86_64와 arm64 CPU 아키텍처에서 모두 사용할 수 있습니다.
https://gallery.ecr.aws/awsguru/aws-lambda-adapter
작동 원리
Lambda Adapter는 들어오는 이벤트를 http 요청으로 변환하여 웹 애플리케이션으로 전달하고, 응답을 다시 Lambda 이벤트 응답으로 변환하는 방식으로 동작합니다.
- Lambda 환경에서의 동작
- Docker 이미지가 AWS Lambda Service 내부에서 실행 중일 때, Lambda는 Adapter와 런타임 프로세스를 자동으로 시작합니다.
- 외부 환경에서의 동작
- Lambda 외부에서 실행 중일 때, Lambda Adapter는 실행되지 않습니다.
이를 통해 개발자는 웹 애플리케이션을 컨테이너 이미지로 패키징하여 코드를 변경하지 않고도 AWS Lambda, AWS Fargate 및 Amazon EC2에서 실행할 수 있습니다.
Lambda Adapter가 애플리케이션을 시작한 후, 10ms 간격으로 http://localhost:8080/ 에서 health check를 수행하며, 애플리케이션이 200 응답을 반환하면 Lambda 런타임 클라이언트를 시작하고, 이후 모든 요청을 http://localhost:8080으로 전달합니다.
SAM Template 분석
Template Description
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Lambda functions for Prod Env deployments
Resource::API
Resources:
ChordpliApi:
Type: AWS::Serverless::Api
Properties:
Name: CHORDPLI-API
StageName: v1
Domain:
DomainName: prod-sam.chordpli.com
CertificateArn: arn:aws:acm:us-east-2:12345101010:certificate/aa1234z5-67a9-000z-zabd-0z99z090aaa1
Route53:
HostedZoneId: A0123456AAZZZZZZZZZ
Cors:
AllowMethods: "'*'"
AllowHeaders: "'*'"
AllowOrigin: "'http://localhost:3000/', 'https://stage.chordpli.com/', 'https://www.chordpli.com/'"
Auth:
Authorizers:
ProdAuth:
UserPoolArn: arn:aws:cognito-idp:us-east-2:12345101010:userpool/us-east-2_chordpli
IdentitySource: "$request.header.Authorization"
JwtConfiguration:
issuer: !Sub https://cognito-idp.${AWS::Region}.amazonaws.com/${UserPoolId}
- 해당 템플릿(
AWS::Serverless::Api
)은 HTTPS 엔드포인트를 통해 호출할 수 있는 Amazon API Gateway 리소스 및 메서드 컬렉션을 생성합니다. - Domain 지정, Cors 설정, Authorization 설정 등을 해당 구문에서 진행하였습니다.
- Domain Name을 설정하고, SSL CertificationArn을 지정하고, Route53에 있는 Hosted Zone Id를 명시해 주었습니다.
- Cors는 Method와 Header를 허용하였으며, AllowOrigin의 경우 와일드카드가 적용되지 않아, 직접적으로 명시하게 되었습니다.
- 해당 API의 경우 현재 인증을 위하여 cognito를 사용하고 있으므로, AWS Cognito의 정보를 명시하였습니다.
Resource::Function
- Function은 AWS Lambda, IAM 실행역할, 함수를 트리거하는 이벤트 소스 매핑을 생성합니다.
- 저희가 만든 API가 Lambda로 올라가게 됩니다.
ChordpliApiLambdaFunction:
Type: AWS::Serverless::Function
Metadata:
DockerContext: .
Dockerfile: Dockerfile
...
Container Image로 빌드하기 위하여, 메타데이터 리소스 속성을 지정합니다.
- DockerContext
- Dockerfile의 위치
- Dockerfile
- 람다 함수와 관련된 Dockerfile의 이름을 지정
Properties > Basic
ChordpliApiLambdaFunction:
...
Properties:
FunctionName: ChordpliApi
PackageType: Image
MemorySize: 1024
Timeout: 30
Environment:
Variables:
ENV: prod
TZ: Etc/UTC
ImageUri: chordpliapilambdafunction:latest
- ImageUri의 경우 Meatadata 항목을 사용하면 애플리케이션을 빌드하는 것이 ImageUri에 우선하므로 무시된다고 설명하지만, 배포 시 특정 환경의 Samtemplate 지정하게 되면 해당 칸을 작성해야 에러가 발생하지 않습니다.
ImageUri를 작성하지 않고 Sam Build를 진행하면 .aws-am/build/template.yaml에 ImageUri가 생성되어 있습니다. 해당 값을 복사하여 배포 템플릿에 지정하면 됩니다.
sam build --use-container --template-file template.prod.yml --config-file samconfig.prod.toml sam deploy --config-env prod --config-file samconfig.prod.toml --template-file template.prod.yml --no-fail-on-empty-changeset
Properties > VPC
ChordpliApiLambdaFunction:
...
Properties:
VpcConfig:
SecurityGroupIds:
- sg-00z00zz000a0aa000
- sg-111z1a11111z11a1z
SubnetIds:
- subnet-000z000zzaa0z0z00
- subnet-0000z0000z0zz00z0
- subnet-1z11z1a111z0a000
...
- Lambda 함수에 연결할 VPC 보안 그룹 및 서브넷을 설정합니다
Properties > ImageConfig
ChordpliLambdaFunction:
...
Properties:
...
ImageConfig:
EntryPoint:
- "python"
Command:
- "-m"
- "uvicorn"
- "app.cmd.api:app"
- "--host=0.0.0.0"
- "--port=8000"
- "--loop=uvloop"
- "--http=h11"
- "--proxy-headers"
- "--log-level=debug"
- "--no-access-log"
- "--no-use-colors"
- "--no-server-header"
- "--no-date-header"
- "--timeout-keep-alive=20"
- "--timeout-graceful-shutdown=30"
...
- Dockerfile 설정을 재정의하는 구성 값입니다.
- EntryPoint
- 애플리케이션의 진입점을 지정합니다. 런타임 실행 파일의 위치입니다.
- Command
- EntryPoint로 전달하려는 매개변수를 지정합니다.
Properties > Policies
ChordpliLambdaFunction:
...
Properties:
...
Policies:
- arn:aws:iam::12345101010:policy/lambda-chordpli-api_prod
...
- 해당 함수에 대한 정책을 정의합니다.
- AWS::IAM::Policy를 사용하여 정책을 새롭게 정의할 경우, 기본적으로 Lambda를 만들 때 생성되던 정책들이 사라지게 됩니다.(기본값 존재) 정책을 커스텀하게 추가해야 한다면, 기본 정책이 무엇인지 확인하고 관련 정책까지 추가해주어야 합니다.
- AWS::IAM::Policy 템플릿을 사용하여 정책을 만드는 것보다, AWS policy에 관련 정책을 한 번에 넣어 만든 후, arn으로 추가하는 것을 권장합니다.
Properties > Events
ChordpliLambdaFunction:
...
Properties:
...
Events:
ApiGetEvent:
Type: Api
Properties:
Auth:
Authorizer: ProdAuth
Path: /{all+}
Method: GET
RestApiId:
Ref: ChordpliApi
... (POST, DELETE, PATCH, PUT에 대한 Gateway 설정)
InternalProxyEvent:
Type: Api
Properties:
Path: /_internal/{proxy+}
Method: ANY
RestApiId:
Ref: ChordpliApi
...
- 해당 람다 함수를 트리거하는 이벤트 소스를 설정합니다.
- Type:Api는 AWS::Serverless::Api를 지칭하며, 해당 템플릿은 API 게이트웨이를 설정합니다.
- Auth
- 특정 API + 경로 + 방법에 대한 인증을 구성
- RestApiId
- 일반적으로 해당 템플릿에 정의된 AWS::Serverless::Api 리소스를 참조하도록 설정합니다.
- Auth
ChordpliApiLambdaFunction 전체 코드
ChordpliApiLambdaFunction:
Type: AWS::Serverless::Function
Metadata:
DockerContext: .
Dockerfile: Dockerfile
Properties:
FunctionName: ChordpliApi
PackageType: Image
VpcConfig:
SecurityGroupIds:
- sg-00z00zz000a0aa000
- sg-111z1a11111z11a1z
SubnetIds:
- subnet-000z000zzaa0z0z00
- subnet-0000z0000z0zz00z0
- subnet-1z11z1a111z0a000
ImageConfig:
EntryPoint:
- "python"
Command:
- "-m"
- "uvicorn"
- "app.cmd.api:app"
- "--host=0.0.0.0"
- "--port=8000"
- "--loop=uvloop"
- "--http=h11"
- "--proxy-headers"
- "--log-level=debug"
- "--no-access-log"
- "--no-use-colors"
- "--no-server-header"
- "--no-date-header"
- "--timeout-keep-alive=20"
- "--timeout-graceful-shutdown=30"
MemorySize: 1024
Timeout: 30
Environment:
Variables:
ENV: prod
TZ: Etc/UTC
Policies:
- arn:aws:iam::12345101010:policy/lambda-chordpli-api_prod
Events:
ApiGetEvent:
Type: Api
Properties:
Auth:
Authorizer: ProdAuth
Path: /{all+}
Method: GET
RestApiId:
Ref: ChordpliApi
... (POST, DELETE, PATCH, PUT에 대한 Gateway 설정)
InternalProxyEvent:
Type: Api
Properties:
Path: /_internal/{proxy+}
Method: ANY
RestApiId:
Ref: ChordpliApi
...
ImageUri: chordpliapilambdafunction:latest
Resource::Auto Scaling
Provisioning Concurrency를 사용하기 위해서는 Lambda의 Version과 Alias가 필수입니다.
version
version:
Type: AWS::Lambda::Version
Properties:
FunctionName: !Ref ChordpliApiLambdaFunction
Description: v1
- 함수를 새롭게 올릴 때마다 Lambda의 새 버전을 생성하게 됩니다.
Alias
alias:
Type: AWS::Lambda::Alias
Properties:
FunctionName: !Ref ChordpliApiLambdaFunction
FunctionVersion: !GetAtt version.Version
Name: prod
ProvisionedConcurrencyConfig:
ProvisionedConcurrentExecutions: 1
- Lambda 함수에 대한 별칭을 만듭니다. 별칭을 사용하여 다른 클라이언트에 다른 버전을 호출하도록 업데이트할 수 있는 함수 식별자를 제공합니다. 해당 값은 AWS::Function에서 지정하는 값과 동일합니다.
- ProvisionedConcurrencyConfig를 통하여 함수의 별칭에 대한 프로비저닝 컨커런시 구성을 지정할 수 있습니다.
Scalable Target
ChordpliApiConcurrency:
Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties:
MinCapacity: 1
MaxCapacity: 1
RoleARN: !Join
- ':'
- - 'arn:aws:iam:'
- !Ref 'AWS::AccountId'
- role/aws-service-role/lambda.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_LambdaConcurrency
ServiceNamespace: lambda
ScalableDimension: lambda:function:ProvisionedConcurrency
ResourceId: !Sub function:${ChordpliApiLambdaFunction}:prod
ScheduledActions:
- ScalableTargetAction:
MinCapacity: 1
MaxCapacity: 3
Schedule: 'cron(00 00 ? * TUE-SUN *)'
ScheduledActionName: scale-out
- ScalableTargetAction:
MinCapacity: 0
MaxCapacity: 1
Schedule: 'cron(00 11 ? * MON-SAT *)'
ScheduledActionName: scale-in
애플리케이션 오토스케일링이 가능한 리소스를 지정합니다.
- ResourceId
- Lambda provisioned concurrency - The resource type is
function
and the unique identifier is the function name with a function version or alias name suffix that is not$LATEST
. Example:function:my-function:prod
orfunction:my-function:1
. - 접미사가 $LATEST가 아닌 버전 또는 별칭 이름이 있는 고유한 식별자로 이루어진 함수가 필요합니다.
- 위 사항으로 인하여 Alias 또는 Version이 필요합니다.
- Lambda provisioned concurrency - The resource type is
- ScalableDimension
- 확장 가능한 대상과 연관된 확장 가능 디멘션입니다.
- Guide(docs)에 명시된 문자열을 입력합니다.
- ServiceNamespace
- 리소스를 제공하는 AWS 서비스의 이름을 지정합니다.
- Guide(docs)에 명시된 문자열을 입력합니다.
- Sechedlue Actions를 통하여 예약 작업을 지정할 수 있습니다.
전체 코드
version:
Type: AWS::Lambda::Version
Properties:
FunctionName: !Ref ChordpliApiLambdaFunction
Description: v1
alias:
Type: AWS::Lambda::Alias
Properties:
FunctionName: !Ref ChordpliApiLambdaFunction
FunctionVersion: !GetAtt version.Version
Name: prod
ProvisionedConcurrencyConfig:
ProvisionedConcurrentExecutions: 1
# Alias로 인하여 에러가 발생한다면 아래 템플릿을 주석 처리하고 배포한 후, 다시 주석을 해제하여 배포 해주세요.
ChordpliApiConcurrency:
Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties:
MinCapacity: 1
MaxCapacity: 1
RoleARN: !Join
- ':'
- - 'arn:aws:iam:'
- !Ref 'AWS::AccountId'
- role/aws-service-role/lambda.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_LambdaConcurrency
ServiceNamespace: lambda
ScalableDimension: lambda:function:ProvisionedConcurrency
ResourceId: !Sub function:${ChordpliApiLambdaFunction}:prod
ScheduledActions:
- ScalableTargetAction:
MinCapacity: 1
MaxCapacity: 3
Schedule: 'cron(00 00 ? * TUE-SUN *)'
ScheduledActionName: scale-out
- ScalableTargetAction:
MinCapacity: 0
MaxCapacity: 1
Schedule: 'cron(00 11 ? * MON-SAT *)'
ScheduledActionName: scale-in
추가 설정
RDS PROXY
- 데이터베이스 프록시를 사용하면 함수가 데이터베이스 연결을 소진하지 않고, 높은 동시성 레벨에 도달할 수 있도록 도와주는 공유 데이터베이스 연결 풀을 관리합니다.
- 즉, 짧게 데이터베이스를 연결하거나 다수의 데이터베이스 연결을 열고 닫는 Lambda 함수에서는 RDS 프록시를 사용하는 것이 좋습니다.
생성된 RDS Proxy
RDS 정책
- RDS PORXY를 사용하기 위해서는 정책이 추가되어야 합니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds-db:*"
],
"Resource": [
"*"
]
}
]
}
Provisioning Concurrency
AWS Lambda 함수는 일정 시간 동안 사용되지 않으면, 리소스 절약을 위해 자동으로 종료됩니다. 새로운 요청이 발생할 때 함수가 다시 시작되며, 이 과정에서 콜드 스타트 이슈가 발생할 수 있습니다. 콜드 스타트는 함수가 처음 실행되기 전에 초기화되는 데 걸리는 시간을 의미하며, 이로 인해 응답 시간이 길어질 수 있습니다.
이러한 문제를 해결하기 위해 Provisioned Concurrency 설정을 사용할 수 있습니다. Provisioned Concurrency란 함수에 할당된 사전 초기화된 실행 환경의 수를 의미합니다. 이러한 실행 환경은 수신된 함수 요청에 즉시 응답할 수 있도록 항상 준비되어 있어, 콜드 스타트로 인한 지연을 최소화할 수 있습니다.
Auto Scaling
참고 문서
AWS CloudFormation을 사용한 Application Auto Scaling 리소스 구성 - AWS CloudFormation
테스트
ChordpliApiConcurrency:
Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties:
MaxCapacity: 1
MinCapacity: 1
RoleARN: !Join
- ':'
- - 'arn:aws:iam:'
- !Ref 'AWS::AccountId'
- role/aws-service-role/lambda.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_LambdaConcurrency
ServiceNamespace: lambda
ScalableDimension: lambda:function:ProvisionedConcurrency
ResourceId: !Sub function:${ChordpliApiLambdaFunction}:stage
ScheduledActions:
- ScalableTargetAction:
MinCapacity: 7
MaxCapacity: 9
Schedule: 'cron(14 * * * ? *)'
ScheduledActionName: scale-out
- ScalableTargetAction:
MinCapacity: 4
MaxCapacity: 6
Schedule: 'cron(17 * * * ? *)'
ScheduledActionName: scale-in
- ScalableTargetAction:
MinCapacity: 2
MaxCapacity: 2
Schedule: 'cron(19 * * * ? *)'
ScheduledActionName: rest
오전 10:12 최초 배포
오전 10:14 scale-out - 10:16 완료
오전 10:17 scale-in
오전 10:19 reset
NAT
- NAT 게이트웨이는 프라이빗 서브넷 내의 인스턴스들이 VPC 외부의 인터넷 서비스에 연결할 수 있도록 하면서, 외부에서 프라이빗 서브넷 내 인스턴스로의 직접적인 접근을 차단하는 역할을 합니다.
- 보안성을 유지하면서, 필요한 외부 리소스 접근이 가능합니다.
현재 구조
- 구성
- Public Subnet과 Private Subnet의 구조에서, Public Subnet에 NAT 게이트웨이를 추가하여 Private Subnet과 연결한 형태입니다.
- NAT 게이트웨이
- 비용 절감을 위해 하나의 Public Subnet에 NAT 게이트웨이를 배치하고, 해당 NAT 게이트웨이를 모든 Private Subnet과 연결하여 외부 인터넷 접근을 허용하는 구조로 설계하였습니다.
일반적인 구조
- 구성
- Public Subnet, Private Subnet, Private Subnet with NAT로 이루어지는 구조를 사용합니다.
- Public Subnet: 로드 밸런서(LB)나 API Gateway와 같은 외부 접근이 필요한 서비스를 배치합니다.
- Private Subnet: 데이터베이스(DB)와 같은 스토리지를 배치하여 외부 접근을 차단합니다.
- Private Subnet with NAT: Public 네트워크에 있는 서비스를 이용해야 하는 애플리케이션이 위치하며, 이 서브넷은 NAT 게이트웨이를 통해 외부 서비스에 접근할 수 있습니다.
- Public Subnet, Private Subnet, Private Subnet with NAT로 이루어지는 구조를 사용합니다.
- NAT 게이트웨이
- 각 Public Subnet과 연결된 Private Subnet이 개별 NAT 게이트웨이를 통해 인터넷에 접근할 수 있도록 구성합니다.
Terraform
Policy
locals {
tags = {
...
ManagedBy = "terraform"
}
service_name = "lambda-chordpli-api"
}
module "deploy_role" {
...
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Sid": "AWSLambdaVPCAccessExecutionPermissions",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"ec2:CreateNetworkInterface",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeSubnets",
"ec2:DeleteNetworkInterface",
"ec2:AssignPrivateIpAddresses",
"ec2:UnassignPrivateIpAddresses"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"rds-db:*"
],
"Effect": "Allow",
"Resource": [
"*"
]
},
{
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:PutSecretValue",
"secretsmanager:UpdateSecretVersionStage",
"secretsmanager:UpdateSecret"
],
"Effect": "Allow",
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"cognito-idp:*"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"dynamodb:*"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"kms:*"
],
"Resource": "*"
},
{
"Action": [
"ssm:Describe*",
"ssm:Get*",
"ssm:List*"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": "logs:*",
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
}
NAT
- VPC NAT 생성
resource "aws_eip" "nat_a" {
domain = "vpc"
lifecycle {
create_before_destroy = true
}
}
resource "aws_nat_gateway" "nat_gateway_a" {
allocation_id = aws_eip.nat_a.id
subnet_id = aws_subnet.service_public_subnet_a.id
tags = {
Name = "NAT-GW-1"
}
}
- Private Subnet과 NAT 연결
resource "aws_route" "service_private_subnet_a_nat_route" {
route_table_id = aws_route_table.service_private_subnet_rtb_a.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.nat_gateway_a.id
}
resource "aws_route" "service_private_subnet_b_nat_route" {
route_table_id = aws_route_table.service_private_subnet_rtb_b.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.nat_gateway_a.id
}
resource "aws_route" "service_private_subnet_c_nat_route" {
route_table_id = aws_route_table.service_private_subnet_rtb_c.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.nat_gateway_a.id
}
다음 글
출처
AWS
AWS SAM
AWS Serverless Application Model (AWS SAM) 란 무엇입니까? - AWS Serverless Application Model
Template :: Serverless API
AWS::Serverless::Api - AWS Serverless Application Model
Template :: Serverless Function
AWS::Serverless::Function - AWS Serverless Application Model
NAT Gateway
NAT 게이트웨이 - Amazon Virtual Private Cloud
RDS Proxy
Amazon RDS 프록시 사용 - Amazon Relational Database Service
Lambda Web Adapter
Web Adapter Githuib
https://github.com/awslabs/aws-lambda-web-adapter
Using response streaming with AWS Lambda Web Adapter to optimize performance | Amazon Web Services
Terraform
AWS_IAM_POLICY
AWS_NAT_GATEWAY
'회고록 > 업무 기록' 카테고리의 다른 글
AWS SAM과 Lambda Web Adapter를 사용한 실무 인프라 전환기 [2/2] (0) | 2024.09.04 |
---|