AWS

[AWS] aws 강의 섹션 23 (API GateWay)

대기업 가고 싶은 공돌이 2025. 2. 4. 17:48

API GateWay

  • 람다함수와 게이트웨이를 사용하면 완전히 인프라가 없는 서버리스 환경 구축이 가능하다.
    • 람다함수는 기본적으로 엔드포인트를 제공하지 않는다 때문에, 람다 함수를 호출하기 위해선 게이트웨이가 필요하다.
    • VPC 외부에 람다함수를 두면 외부 인터넷과 통신이 가능하다는 말은, 람다함수 내부에서 외부 인터넷 호출이 가능하다는 얘기다.
  • 웹 소켓을 지원하기 때문에 실시간 스트리밍이 가능하다.
  • 버전 컨트롤이 가능하다.
  • 때문에, 다른 환경에서 운용이 가능하다.
  • API 키를 만들어 많은 호출이 발생할 시, 쓰로틀링이 가능하다.
  • 스웨거 등을 통해 API를 빠르게 문서화 가능하다.
  • API 게이트웨이 단에서 요청 및 응답을 변환하고 무효화 시켜, 호출이 올바른지 확인할 수 있다.
  • SDK 및 API 규격을 생성하고 API 응답을 캐싱할 수 있다.

API 게이트웨이와 통합 가능한 서비스

  • 람다 함수
  • HTTP
    • 모든 HTTP 엔드포인트를 노출할 수 있다.
    • 만약 온프레미스의 로드밸런서를 사용중이라면, 온프레미스 로드밸런서를 게이트웨이를 통해 노출시켜 사용 가능하다.
    • 속도 제한, 캐싱, 사용자 인증, API 키 등이 사용가능하다.
  • AWS Service
    • 모든 AWS 서비스를 노출 가능하다.
    • 예를 들어 스텝펑션 워크 플로우를 실행하는 것
    • 아니면 바로 SQS에 메시지를 보내는 방법
    • 또는, 추가적인 인증을 사용하고 싶거나, API를 공개적으로 배포하고 싶을 때, 또는 
      AWS 서비스에 속도 제한을 걸고싶은 경우에 이용한다.

  • 이 예시는 게이트웨이에 요청을 보내 데이터 스트림에서 정보를 처리하고 파이어 호스에서 형식 변환을 통해 S3에 저장하는 예시다.

게이트웨이 배포 방식 세 가지 - EndPoint Types

  • Edge-Optimized (default)
    • 글로벌 클라이언트에 이용된다.
    • 세계 어디서든 게이트웨이에 액세스가 가능하고,
      클라우드 프론트 엣지에서 요청을 라우팅하므로, 지연 시간이 개선된다.
    • 게이트웨이는 한 곳에서 생성되지만 모든 클라우드 프론트 엣지에 캐시된 후 라우팅 되기에 효율적이다.
  • Regional
    • 클라우드 프론트 엣지를 사용하지 않을 때 쓴다.
    • 모든 사용자가 특정 리전 내에 위치할 것으로 예상할 때 사용한다.
    • 원한다면 클라우드 프론트 배포를 자체적으로 만들 수 있다.
    • 모든 글로벌 위치에 자체적으로 게이트웨이를 만들어 자체적으로 관리하는 방식으로 응용하는 것이다.
      • 더 세밀한 제어가 가능하다.
  • Private
    • VPC 내에서만 액세스가 가능하며 ENI를 사용한다.
    • 게이트웨이 액세스를 정의할 때 리소스 정책 사용이 가능하다.

게이트웨이 보안

  • IAM
    • EC2에서 접근할 때 IAM 룰을 적용시킬 수 있다.
  • Cognito
    • 모바일 애플리케이션 등 외부 사용자를 둘 때 사용한다.
  • Custom Authorizer
    • 자체 보안 로직을 구현할 경우 사용한다.
  • ACM
    • HTTPS 설정을 도메인을 통해 가능하다
      • Edge-Optimized 엔드포인트, 즉 클라우드 프론트를 사용한다면
        US-EAST-1에 인증서가 있어야 한다.
      • Regional 이라면 동일 리전에 인증서가 있어야한다.
      • Route53에 CNAME이나 A 레코드를 설정하여 도메인과 게이트 웨이를 연결해야한다.

API Gateway - Deployment Stages

  • API 게이트웨이에서 변경사항을 만들고 배포를 하지 않는다면 변경 사항이 반영되지 않는다.
  • 변경사항은 stages에 저장된다.
  • 스테이징 영역은 마음대로 이름 붙여서 만들 수 있다. dev, test, prod 등등,,
  • 각 스테이지는 고유한 매개변수를 갖고, 원활하게 롤백할 수 있다.
    • 각 스테이지에서 수행한 모든 배포 이력이 다 보관되고 있기 때문이다.

Stage v1, Stage v2 예시

스테이지 두 가지를 예로 들어 변경 사항을 적용시킨다고 해보자

  • 기존 v1 버전과 연결된 람다함수를 변경하려한다.
  • 여기서 기존의 람다함수를 변경하면, 변경 사항이 적용되는 동안 v1 람다함수는 동작을 멈출 것이다.
  • 그러니 v2라는 새로운 스테이지를 만들고, 새로운 람다 함수를 만드는 것이다.
  • 이후 스테이지에 v2라는 URL을 만들고, 해당 URL로 클라이언트를 변경하기만 하면 된다.
  • 이점은 더더욱 많다, URL은 다르게, 그러나 API 구성은 똑같이 가져가고 매개변수만 다르게 설정해서
    각 배포환경별 다른 변수를 가져갈 수도 있다.
  • 스테이지를 통해 동일한 API 구성을 가져가며 개발 환경과 배포환경의 쉬운 분리가 가능하다.

게이트웨이 - 스테이지 변수

  • 스테이지 변수는 환경변수와 비슷하다.
  • API를 다시 배포하지 않아도 구성 값을 변경할 수 있다.
  • 사용 예시는 
    • 람다 함수 ARN
    • HTTP 엔드포인트
    • 매개변수 매핑 템플릿 등등에 사용 가능하다.
  • 각 스테이지 환경별로 사용하는 HTTP 엔드포인트를 자동으로 구성할 때 사용하고
  • 매핑 템플릿을 통해 람다 함수에 구성 배개변수를 전달하거나 
  • 람다함수를 가리킬 때도 사용한다.
  • 스테이지 변수는 람다 함수의 컨텍스트 객체에 전달되므로 이를 로그하여 람다함수에서 바로
    스테이지 변수의 값에 액세스 할 수 있다
  • Fromat: ${stageVariables.variableName} 형식으로 api 게이트웨이에서 사용한다.

가장 많이 사용하는 예시

게이트웨이는 스테이지 변수로 람다 함수 별칭을 가르킨다.

람다함수 별칭은 각각 다른 버전의 함수를 가르키고 있다.

 

여기서 별칭이 가르키는 람다함수의 비율을 변경하면 API 게이트웨이 만질 필요 없이 바로 변경사항 적용이 가능하다.

 

이런 식으로 엔드포인트를 환경별로 바꿔가며 연결 람다 함수 변경의 필요 없이 안전하게 변경 및 테스트가 가능하다.

 

API Gateway - Canary 배포 방식

  • 카나리란 배포할 때 소량의 트래픽을 먼저 보내 테스트하는 방식을 의미한다.
    • 카나리 채널이 수신할 트래픽의 양을 선택해야한다.
    • 이를 통해, 람다함수 등으로 API Gateway의 새 버전을 테스트할 수 있다.
  • 소량의 트래픽을 다른 새 배포 버전의 스테이지로 보내다, 트래픽을 정상적으로 수행한다면, 100%를 전부 새 채널로 돌리는 방식이다.

API Gateway - Intergration Types

게이트웨이를 백엔드와 통합할 수 있는 여러 방식을 다뤄보자

  1. MOCK
    • 백엔드로 요청을 전송하지 않고 임시 응답을 반환하는 방식
    • 배포 용도라기 보다, 개발하고 테스트할 용도이다.
  2. HTTP / AWS (Lambda & AWS Services)
    • 게이트웨이에서 요청을 람다함수나 aws 서비스로 보내 요청에 대한 로직을 수행하고 반환하는 방식
    • 통합 요청과 통합 응답 모두를 구성해야 한다.
    • 요청 및 응답 매핑 템플릿을 사용해 데이터 매핑을 구성할 수 있다.
      • 즉, 백엔드로 향하는 요청을 변경하고, 클라이언트에게 전송하기 전에, 백엔드에서 응답을 변경할 수 있다는 의미다.

  • 이런 식으로, 게이트웨이로 들어온 요청을 매핑 템플릿으로 변경시킨다.
    • 매핑 템플릿은 들어온 요청을 SQS Queue에서 해석하기 편리한 방식으로 변환 시키는 용도이다.
    • 이를 통해, 어떤 요청이던지 적절한 형식으로 변환하여 목표물로 보낼 수 있다.

   3.  AWS_PROXY 

  • 이처럼 중개자 역할만 하는 게이트웨이를 만들어 바로 람다함수에 보내버리는 역할이다.
    • 말 그대로 엔드포인트와 적절한 라우팅만을 목표로 한다.

   4. HTTP_PROXY

  • 마찬가지로 프록시기 때문에 매핑 템플릿 없이 요청이 바로 전달된다.
  • 필요하다면 HTTP 헤더를 추가할 수 있다.
    • 예를 들어, API 키를 헤더에 추가할 수 있다.
    • 클라이언트에서 API 키를 추가하지 않고, 게이트웨이에서 키를 포함하게 만듦으로서,
      게이트웨이를 통하지 않은 요청은 거부하는 식으로 만들 수있다.

Mapping Templates

  • 매핑 템플릿은 쿼리 문자열 매개변수의 이름을 바꾸거나
  • 본문 컨텐츠를 수정하거나 헤더 추가가 가능하다.
    • 수정을 위해서는 VTL (Velocity Template Language)를 사용해야한다.
    • 이 언어로 if문이나 for 문을 만들어 수정을 할 수 있다.
  • 마지막으로 응답을 반환할 때도 매핑 템플릿을 사용해 응답의 일부 결과를 제거할 수 있다.
  • 매핑 템플릿을 설정하려면, 컨텐츠 타입이 반드시
    application/json, 또는 application/xml 이어야 한다.

Mapping Example: Json to XML with SOAP

soap api란 XML을 기반으로 한 api를 의미한다.

 

하지만 우리가 평소에 사용하는 서버는 대부분 rest api를 사용한다.

이럴 때, 게이트웨이 매핑 템플릿을 통해 만약 json 요청이 들어오면 xml로 수정하고

다시 반환할 때도 xml을 json으로 수정해주는 것이다.

 

  • 위 사진은 매핑 템플릿의 또 다른 예시로 쿼리 스트링의 변수 명을 바꾸는 것에 탬플릿을 사용하는 예시다.

Open API Spec

  • open api 스펙이란 Rest API를 정의하는 아주 흔한 방법이다.
    • 그냥 api 명세서의 스펙을 생각하면 된다.
  • Open API 3.0 spec을 사용해서 API Gate way에 임포트하면, 그냥 바로 API 명세서가 만들어진다.
    • 메서드 명
    • Request
    • Intergration Request
    • Response
    • 추가로 게이트웨이를 위해 설정하는 어떤 AWS 익스텐션이라도 스펙에 정의할 수 있다.
  • 이러한 api 스펙을 활용해서 사전에 전송 데이터가 맞는지 검증을 할 수 있다.

Request Validation

  • api 게이트웨이를 통해 api 요청에 대한 검증을 진행할 수 있다.
  • 검증에 실패하면 400 에러를 게이트웨이에서 반환한다.
    • 이 말은, 게이트웨이에서 에러를 반환하기 때문에 요청이 서버로 들어가지 않고 불필요한 요청을 줄일 수 있다는 의미다.
  • 헤더가 비어있는지, 쿼리 스트링은 괜찮은지, 메서드에 대해 지정된 JSON 스펙을 준수하고 있는지 등등 확인할 수 있다.

  • 다음과 같은 옵션들을 설정해두면, 검증이 가능하다.
  • 위의 파일은 Open API 정의 파일로 이것을 게이트웨이에 설정해두는 것이다.
  • POST만 검증하기, 인자만 검증하기 등등 다양한 옵션 설정이 가능하다.

게이트웨이 캐시 활성화 시키기

  • 기본 TTL은 300초이다.
    • 최소 시간은 0초, 최대 시간은 1시간까지 캐싱이 가능하다.
  • 메서드 수준에서 캐시 정의가 가능하다.
    • 이 말은 특정 메서드는 캐시 사용을 하지 않고, 특정 메서드는 캐시 사용이 가능하게 설정할 수 있다는 의미다.
  • 캐시 크기는 0.5GB에서 237GB까지이다.
  • 캐시는 정말 비싸기 때문에 운영환경에서만 사용하도록 하자

캐시 무효화 방법

  • UI에서 전체 캐시를 즉시 무효화할 수 있다.
  • 또는 클라이언트에서 게이트웨이로 보내는 쿼리에 
    Cache-Control: max-age=0 이라는 헤더를 추가해 무효화 시킬 수도 있다.
    • 클라이언트에서 이 헤더를 사용하려면 적절한 IAM 인증이나 권한이 있어야 한다.
    • 아래는 클라이언트가 특정 리소스의 캐시를 무효화하도록 허용하는 IAM 정책이다.

  • 캐시 무효화 정책을 정책을 적용하지 않거나 콘솔에서 인증을 요구하지 않을 경우
    어떤 클라이언트던지 캐시를 무효화할 수 있다.
  • 이러면 누구든지 캐시 무효화가 가능하므로 재앙이 펼쳐질 수 있다.

게이트웨이 Usage plans & API Keys

사용량 계획과 API 키

API를 고객들이 사용할 수 있게 하고 호출에 따른 비용을 받기 위한 방법이다.

 

챗 지피티 API Key를 생각하면 편하다.

 

  • 사용량 계획
    • 누가 API 특정 단계나 메서드에 접근할 수 있는지
    • 얼마나 많이, 얼마나 빠르게 접속할 수 있는지
    • 어떤 API 키가 고객을 식별하고 그들의 접근을 계산하기 위해 어떤 계획을 사용할지
    • 이 모든 것을 정의하는 것이 사용량 계획 Usage Plan이다.
  • API Keys
    • 이 특정 키를 사용해 API Gateway를 사용하고 요청을 처리할 수 있다.
    • 사용량 계획과 같이 사용하여, 사용량을 제한할 수 있다.
    • 만약 조절한도를 설정한다면, 이는 API키 수준에서 적용된다.
    • Quota limit(할당량)은 요청의 전체적인 수로 사용량 계획과 API 키를 이용해서 
      고객들에게 API를 제공하고 제한하며 모니터링 할 수 있다.

게이트웨이 - 키와 사용량 계획을 만드는 순서

  1. 우선 하나 이상의 API를 만들고 API키가 필요한 메서드를 구성하고 API를 stage에 배포한다.
  2. 이후 키를 생성하거나 임포트한다.
  3. 원하는 조절 한도와 할당량으로 사용량 계획을 생성한다.
  4. API stage와 키들을 사용량 계획과 연결 짓는다.
  5. API 호출 시 할당된 키를 API 요청의 x-api-key 헤더에 삽입한다.

게이트웨이 - Logging, Tracing

  • cloudWatch Logs
    • 클라우드 워치 로그를 게이트웨이와 통합 사용하기 설정하면 게이트웨이를 통과하는 요청과 응답 내용에 대한 정보를 로깅한다.
    • stage 수준에서 사용 설정할 수 있고, 로그 수준(ERROR, DEBUG, INFO)도 정의할 수 있다.
    • 만든 설정을 API 별로 오버라이드 할 수 있다.

  • 위와 같은 방식으로 중간에 정보를 채가서 기록한다.
  • 이 기능을 사용 설정하면 민감 정보도 cloudwatch logs에 기록될 수 있으니 주의해야한다.
  • X-Ray
    • API가 흘러가는 전체 그림 정보를 제공한다.
    • 그러면 게이트웨이를 클라우드워치 메트릭으로 단계 별로 모니터링 할 수 있고,
      상세 메트릭도 사용 설정이 가능하다.
    • 메트릭 종류 
      • CacheHitCount, CacheMissCount: 캐시 적중률과 캐시 미스 횟수를 나타내는 메트릭이다.
      • Count는 단위 시간당 API 요청 수 이다.
      • IntergrationLatency는 API가 요청을 백엔드에 전달하고 백엔드로부터 응답을 
        기다리는 시간을 말한다.
      • Latency는 게이트웨이가 클라이언트로부터 요청을 받을 때부터 클라이언트로 응답을 
        반환할 때까지의 시간이다. 그러니까 통합 지연시간 + API 게이트웨이가 수행하는 모든 작업 시간이다.
        • 예를 들면 권한, 인증 확인, 캐시 확인, 매필 템플릿 수행 등등이 있다.
        • 따라서 Latency는 Intergration Latency보다 항상 높다.
        • 게이트웨이가 요청을 수행할 수 있는 최대 시간은 29초이다. 이 시간이 넘으면 타임 초과가 반환된다.
      • 4XX 에러, 5XX 에러
        • 이 메트릭은 클라이언트 측에서 받는 오류가 몇 개인지
        • 서버 측에서 받는 오류가 몇 개인지 알려준다.

게이트웨이 Trottling

  • API 요청을 초당 10000건으로 제한할 수 있다.
  • API 중 하나가 과하게 사용되고 있다면 다른 API도 조절될 수 있다는 뜻이다.
  • 요청이 너무 많으면 429 오류가 반환된다.
  • 이는 클라이언트 오류로 클라이언트가 요청을 너무 많이 보냈을 때 반환된다.
  • 쓰로틀링과 성능을 늘릴 수도 있고, stage 한도와 메서드 한도를 설정해서 
    공격을 당할 경우 각 stage가 요청 할당량을 소진하지 않도록 할 수 있다.
  • 고객당 조절을 하고 싶을 경우 사용 계획을 정의하면 되는데 
    람다 동시성과 마찬가지로 API 하나가 과부하되고 제한이 없다면 이 때문에 다른 모든 람다 함수가 정지될 수 있다.
    • (예약된 동시성이란 전체 동시 사용가능 횟수가 10000이라면 한 곳에 1000을 할당해 한 함수가 1000을 넘기지 못하게 하는 것)
  • 이러한 동시성 개념을 게이트웨이에도 똑같이 적용할 수 있다.

게이트웨이 - CORS

  • cross origin resource sharing이라는 기능을 지원한다.
  • 그러므로 타 도메인에서 API 호출을 허용하려면 CORS를 활성화해야 한다.
  • 게이트웨이가 동작하기 위해 preflight 요청이라는 옵션을 만들어야 한다.
  • 다음과 같은 CORS 헤더들이 포함되어야 한다.
    • Access-Control-Allow-Methods
    • Access-Control-Allow-Headers
    • Access-Control-Allow-Origin

먼저 브라우저에서 s3 버킷의 정적 컨텐츠를 가져온다.

 

정적 컨텐츠에서 게이트웨이의 리소스를 가져오려 할 때 옵션으로 설정해둔 preflight request가 실행된다.

 

게이트웨이는 오리진을 확인하고 허용된 오리진과 메서드라면 preflight response를 반환하고

 

반환받은 브라우저는 통신을 할 수 있게 된다.

 

게이트웨이 - 보안 IAM Permission

  • IAM 정책을 사용하고 이를 사용자나 역할에 연결한다.
    • 이제 사용자는 게이트웨이를 호출할 수 있다.
    • 이 경우 인증은 IAM을 통해 이루어지고 권한 부여는 IAM 정책을 통해 이루어 진다.
  • Sig v4 방법 (IAM 인증정보를 암호화 후 헤더에 실어 전송하는 방법)을 사용한다.

게이트웨이 - 리소스 정책

  • 말 그대로 JSON을 이용한 리소스 정책이다.
  • 특정 IP 주소를 허용하거나 거부할 수 있다.

게이트웨이 - 코그니토 유저 풀

  • 코그니토란 유저를 모아둔 데이터베이스이다.
  • 코그니토는 사용자 라이프을 관리하고 코그니토 연결 토큰은 자동적으로 만료되기 때문에
  • 게이트웨이에 접근하려는 사용자의 신분을 코그니토로 간단하게 식별할 수 있다.
  • 사용자는 코그니토 사용자 풀에 의해 인증을 받고
  • 인가는 메서드 레벨에서 구분된다.

  • 맨 처음 사용자는 코그니토에서 인증을 진행한다.
  • 사용자 풀에 유저가 등록되어 있으면 인증에 성공하고 토큰을 발급받는다.
  • 토큰을 통해 게이트웨이에 접근한다.
  • 게이트웨이는 토큰을 코그니토에 보내 유효한지 확인한다.
  • 유효하다면 람다함수를 호출할 수 있다.

게이트웨이 - 람다 권한 부여

  • 이는 토큰 기반 권한 부여로 bearer token이 있는데
  • 헤더 쿼리 스트링, 스테이지 변수 등의 변수를 람다 권한 부여자로 전달한다.
  • 람다함수는 전달 받은 것을 평가하며 이상이 없으면 요청을 만든 클라이언트를 위한 IAM 정책을 반환하고
  • 해당 정책은 캐싱되게 된다.
  • 인증은 외부(본인 서버)에서 이뤄지며, 인가는 람다 함수에서 이뤄지는 방식이다.

  • 클라이언트는 외부 서드파티 시스템을 통해 인증을 한다.
  • 인증에 성공하면 토큰을 발급받는다.
  • 해당 토큰을 파라미터나 뭐 바디나 아무튼 게이트웨이로 보낸다.
  • 게이트웨이는 람다 권한부여자를 호출해 해당 토큰을 전송한다.
  • 람다 함수에서 해당 토큰의 진위 여부를 판단하는 코드를 작성해야 한다.
  • 토큰 진위 여부 판단은 JWT 토큰을 생각하면 된다.
  • 만약 토큰이 유효하다면 IAM 정책을 반환한다.
  • 이제 람다 함수에 접근할 수 있다.

게이트웨이 보안 요약

  • IAM 정책
    • 계정이 이미 생성된 사용자가 있을 때 쓰기 좋다.
    • 교차 계정 접근을 위해서는 리소스 정책을 사용해야 한다.
    • signature v4를 사용한다.
  • 커스텀(람다) 권한 부여
    • 서드파티 어플리케이션을 통해 토큰을 발급 받을 때 좋다.
    • 어떤 IAM 정책을 리턴하는 지를 고르기 때문에 유연하고
    • 람다함수에서 권한 부여를 다뤄야 한다.
    • 결과가 캐싱돼 있어도 람다 호출시 마다 요금이 발생하고 
    • 다소 시간이 걸릴 수 있다.
  • 코그니토
    • 코그니토 사용자 풀은 코그니토에서직접 사용자 풀을 관리하는데
    • 직접 코드를 작성하지 않아도 됨으로 선호된다.
    • 백엔드의 람다함수에 직접 권한부여를 구현해야 한다.

  • 대표적인 게이트웨이를 활용한 아키텍쳐이다.
  • 여러 개의 로드밸런서와 버킷을 게이트웨이를 통해 하나의 도메인으로 사용할 수 있다.
  • 매핑 템플릿을 통한 데이터 수정 포워딩 등의 작업을 모두 게이트웨이에서 정의할 수 있으며
  • 내부 작업을 외부에 노출하지 않아도 된다.
  • 보안도 게이트웨이 수준에서 모두 설정 가능하다.