프로필사진
DevOps 부트캠프 기록일지
DevOps_04_김재환
2023.05.10(sprint - API Gateway와 서버리스 애플리케이션)
2023.05.10(sprint - API Gateway와 서버리스 애플리케이션)

2023. 5. 11. 03:13부트캠프/DevOps (TIL)

Step 1: API Gateway - Lambda 배포 Instruction

먼저 lambda 함수와 API Gateway 세팅을 한꺼번에 할 수 있게 SAM을 이용한다https://serverlessland.com/patterns/lambda-dynamodb

 

Serverless Land

Your resource for learning serverless technology.

serverlessland.com

  1. 현재 람다가 런타임 nodejs 14.x을 지원하므로 template.yaml 파일에서 Runtime 부분을 찾아 다음과 같이 바꾼다.
1 - Runtime: nodejs12.x
2 + Runtime: nodejs14.x
  1. 사용자 컴퓨터에 node.js 런타임을 설치한다.
  2. sam build를 통해 빌드가 되는지 확인해 본다.
  3. sam deploy --guided를 통해 배포를 시도한다.
  4. 람다 및 DynamoDB에 어떤 리소스가 생성이 되었는지 직접 콘솔에 들어가서 확인해보게 한다.
  5. 잘 작동되는지 명령어를 통해 확인한다. 202 status가 도착하면 성공!
aws lambda invoke --function-name {Lambda함수의Arn를입력} --invocation-type Event  --payload '{ "Metadata": "Hello" }'  response.json --cli-binary-format raw-in-base64-out

 

 

 

STEP 2: API 게이트웨이 - Lambda

 

트리거 추가 버튼을 누른다

추가 트리거에서 다음 옵션을 통해 API 게이트웨이를 생성한다.

  • API 게이트웨이를 선택
  • 새 API를 생성
  • REST API 유형
  • 보안은 "열기"

 

이제 API 엔드포인트에 HTTP 요청을 보내면, 함수를 호출할 수 있다. 요청의 상세 내용이 DynamoDB에 저장된다

STEP 3: API 게이트웨이에 제한 추가하기

POST 전용으로만 작동하게 만들기

참고 래퍼런스 : https://docs.aws.amazon.com/ko_kr/apigateway/latest/developerguide/api-gateway-create-api-from-example.html

 

자습서: 예제를 가져와 REST API 생성 - Amazon API Gateway

자습서: 예제를 가져와 REST API 생성 Amazon API Gateway 콘솔을 사용하여 PetStore 웹 사이트에 대한 HTTP 통합으로 간단한 REST API를 생성 및 테스트할 수 있습니다. API 정의는 OpenAPI 2.0 파일로 미리 구성되

docs.aws.amazon.com

메서드에서 기본 any로 되어있는 메서드를 삭제하고 post 메서드 생성

생성 후 꼭 api 배포를 눌러줘야합니다.

api 엔드포인트로 접속했을때 post 메서드만 사용가능하므로 위와 같은 메세지가 뜹니다.

포스트맨으로 post시 정상적으로 200이 뜨는것을 확인 할 수 있었습니다.

 

본문만 저장하도록 만들기

위의 evevt 부분을 event.body로 변경하여 sam build 후 sam deploy하여 새로 aws에 배포하면 본문만 저장하도록 만들수 있습니다.

API 키를 이용한 인증 추가하기

먼저 POST의 메서드 요청에 들어가서 API 키 필요 에 대한 설정을 true로 바꾸어 줍니다.

API key 생성이 완료되면 해당 key에 대한 사용량 계획을 추가해줍니다.

사용량 계획 생성화면(요청수와 할당량 설정 후 다음)

현재 작업중인 API 선택 후 스테이지 default 선택하고 다음 방금 만든 API 키 이름 작성 후 생성완료

처음 메서드 조절이 설정이 안되어있다면 조절 구성을 눌러 설정해줍니다.

이 과정까지 모두 마치면 API key 키를 이용한 인증 구현이 완료되었습니다. 이 과정 이후 postman등을 이용하여 request header에 x-api-key를 이용하여 POST 요청을 진행하면 정상적으로 수행되는 것을 확인할 수 있습니다.

 

postman 프로그램을 이용하여 Headers에 x-api-key와 그 값을 넣어주니 정상적으로 200을 띄우는걸 확인할 수 있습니다.

체크를 해제하면 Forbidden이 반환됩니다.

 

 

권한 부여자를 이용한 인증 부여하기 (optional)

원래 호출하려는 람다 함수 전에 Authorizer 람다 함수를 한 번 거칩니다.

Authorizer를 통과하지 못하면 원래 호출하려는 람다 함수에 접근할 수 없습니다.

생성 후 코드 - 코드편집기에서 다음과 같이 수정합니다.

// A simple token-based authorizer example to demonstrate how to use an authorization token 
// to allow or deny a request. In this example, the caller named 'user' is allowed to invoke 
// a request if the client-supplied token value is 'allow'. The caller is not allowed to invoke 
// the request if the token value is 'deny'. If the token value is 'unauthorized' or an empty
// string, the authorizer function returns an HTTP 401 status code. For any other token value, 
// the authorizer returns an HTTP 500 status code. 
// Note that token values are case-sensitive.

export const handler =  function(event, context, callback) {
    var token = event.authorizationToken;
    switch (token) {
        case 'allow':
            callback(null, generatePolicy('user', 'Allow', event.methodArn));
            break;
        case 'deny':
            callback(null, generatePolicy('user', 'Deny', event.methodArn));
            break;
        case 'unauthorized':
            callback("Unauthorized");   // Return a 401 Unauthorized response
            break;
        default:
            callback("Error: Invalid token"); // Return a 500 Invalid token response
    }
};

// Help function to generate an IAM policy
var generatePolicy = function(principalId, effect, resource) {
    var authResponse = {};
    
    authResponse.principalId = principalId;
    if (effect && resource) {
        var policyDocument = {};
        policyDocument.Version = '2012-10-17'; 
        policyDocument.Statement = [];
        var statementOne = {};
        statementOne.Action = 'execute-api:Invoke'; 
        statementOne.Effect = effect;
        statementOne.Resource = resource;
        policyDocument.Statement[0] = statementOne;
        authResponse.policyDocument = policyDocument;
    }
    
    // Optional output with custom properties of the String, Number or Boolean type.
    authResponse.context = {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": true
    };
    return authResponse;
}
    수정후 배포까지 눌러줍니다.

이제 API gateway에서 권한 부여자로 가서 권한 부여자 생성을 클릭해서 다음과 같이 생성해줍니다.

테스트를 누르고 값에 allow을 입력 후 코드 200을 응답하면 성공입니다.

이제 리소스에서 메서드 승인을 권한 부여자 설정한걸로 바꾸고 요청 검사기을 본문 검사로 바꾼다음 api 배포로 현재 상태로 변경해줍니다.

authorizationToken이 있을 때와 없을 때의 모습입니다.

 

 

API Gateway - Lambda - DynamoDB 아키텍처로 구성된 서버리스 애플리케이션을 만들고, DynamoDB에 레코드를 추가하는 간단한 람다 함수를 하나 만들고, API Gateway를 통해 이를 호출하고, API Gateway의 인증 기능을 이용해서  HTTP 요청에 특정 API Key를 사용 그리고 authorizationToken까지 진행해 보았습니다.

 

MSA을 간단하게 구현해 봄으로써 MSA에 대해 조금 더 이해를 할 수 있게됐습니다.