AWS Lambda의 ESModule

왜 모듈 시스템인가
  • 소스 코드를 기능에 따라 여러 파일로 구성합니다.
  • SDK의 코드, 다른 사용자의 프레임워크 및 패키지를 애플리케이션에 포함합니다.

  • NodeJS 기본 모듈 시스템
    CommonJS입니다(AWS SDK를 추가하는 CommonJS 방식const AWS = require('aws-sdk');).
  • 기본적으로 AWS Lambda는 aws-sdk Version2(CommonJS)를 추가합니다.
  • 따라서 AWS에 아카이브 파일을 종속시키고 업로드할 필요가 없습니다npm install aws-sdk.

  • CommonJS를 사용하는 Lambda 코드의 예를 들어 보겠습니다.
  • '비밀'이라는 환경 변수가 고객 관리 KMS 키를 사용하여 암호화됩니다.
  • 전역 변수 'decrypted'가 아래와 같이 동작합니다.
  • 콜드 스타트: 'decrypted' 값이 null입니다... 따라서 lambda의 "if 조건"이 전달되고 fetchDecryptedValue를 호출합니다.
  • 웜 스타트: '암호 해독됨'이 null이 아니므로 "조건이 통과하지 않는 경우"... 이미 암호 해독된 값을 재사용합니다.


  • CommonJS 예제

    const AWS = require('aws-sdk');
    //Brings in entire AWS SDK that contains all services clients.
    
    const functionName = process.env.AWS_LAMBDA_FUNCTION_NAME;
    const encrypted = process.env['secret'];
    //Environment variable 'secret' is encrypted using Customer Managed Key.
    
    let decrypted;
    //Cold Start: 'decrypted' value is null.
    //Warm Start: 'decrypted' value is not null - contains decrypted value.
    
    exports.handler = async (event) => {
        if (!decrypted) {
            //matches only during Cold Start
            await fetchDecryptedValue();
        }
        processEvent(event, decrypted);
    };
    
    let fetchDecryptedValue = async function() {
        const kms = new AWS.KMS();
        try {
            const req = {
                CiphertextBlob: Buffer.from(encrypted, 'base64'),
                EncryptionContext: { LambdaFunctionName: functionName},
            };
            const data = await kms.decrypt(req).promise();
            decrypted = data.Plaintext.toString('ascii');
        } catch (err) {
            console.log('Decrypt error:', err);
            throw err;
        }
    }
    
    let processEvent = function(event, decrypted) {
        // use decrypted credential here
    }
    


    ESModule 예제
  • JavaScript는 진화하고 있으며 현재 표준은 ECMAScript 모듈(ESModule) 시스템입니다.
  • ESModule은 버전 14부터 최신 브라우저 및 NodeJS 런타임에서 지원됩니다.

  • ESModule이 Lambda에서 작동하도록 하기 위한 전제 조건
  • package.json은 'module' 형식을 포함해야 합니다.

  • {
        "name": "blog-esmodule",
        "type": "module",
        "description": "Example for esmodule usage in AWS Lambda.",
        "version": "1.0",
        "main": "index.js",
        "dependencies": {
            "@aws-sdk/client-kms": "^3.76.0"
        }
    }
    


  • npm install @aws-sdk/client-kms
  • 이것은 AWS SDK 버전 3입니다. ESModule 시스템을 지원합니다
  • .
  • 코드 및 종속성을 보관하고 AWS Lambda에 업로드합니다. (단계별 데모는 별도의 게시물에 있습니다).

  • //ESModule example
    import { KMSClient, DecryptCommand } from "@aws-sdk/client-kms";
    // Imports only the kms service client. Reduced code size. Improved cold start time
    
    const functionName = process.env.AWS_LAMBDA_FUNCTION_NAME;
    const encrypted = process.env['secret'];
    let decrypted;
    //during Cold/Warm start behaves same as CommonJS lambda code
    
    export const handler = async (event) => {
        if (!decrypted) {
            await fetchDecryptedValue();
        }
        processEvent(event, decrypted);
    };
    
    let fetchDecryptedValue = async function() {
        const client = new KMSClient();
    
        try {
            const req = {
                CiphertextBlob: Buffer.from(encrypted, 'base64'),
                EncryptionContext: { LambdaFunctionName: functionName },
            };
            const command = new DecryptCommand(req);
            const data = await client.send(command);
            decrypted = Buffer.from(data.Plaintext).toString();
        } catch (err) {
            console.log('Decrypt error:', err);
            throw err;
        }
    }
    
    let processEvent = function(event, decrypted) {
        // use decrypted credential here
    }
    
    


    ESModule의 이점
  • 필요한 코드만 가져옵니다.
  • 콜드 스타트 ​​시간이 개선되었습니다(패키지 크기가 줄어들었기 때문).
  • 최상위 레벨이 기다리고 있습니다.

  • AWS Lambda의 최상위 대기
  • NodeJS 런타임 버전 >= 14 사용
  • 처리기 외부에서 '대기'할 수 있습니다.
    아래 예는 최상위 대기 기능을 사용하는 ESModule Lambda를 보여줍니다.

  • //Top-level await ESModuleJS
    import { KMSClient, DecryptCommand } from "@aws-sdk/client-kms"; // ES Modules import
    const functionName = process.env.AWS_LAMBDA_FUNCTION_NAME;
    const encrypted = process.env['secret'];
    let decrypted = await fetchDecryptedValue();
    //This is not possible in CommonJS
    
    export const handler = async (event) => {
        //Clean code - No need of condition checking on 'decrypted' global variable.
        processEvent(event, decrypted);
    };
    
    async function fetchDecryptedValue() {
        let decryptedValue = '';
        const client = new KMSClient();
    
        try {
            const req = {
                CiphertextBlob: Buffer.from(encrypted, 'base64'),
                EncryptionContext: { LambdaFunctionName: functionName },
            };
            const command = new DecryptCommand(req);
            const data = await client.send(command);
            decryptedValue = Buffer.from(data.Plaintext).toString();
    
        } catch (err) {
            console.log('Decrypt error:', err);
            throw err;
        }
        return decryptedValue;
    }
    
    let processEvent = function(event, decrypted) {
        // use decrypted credential here
    }
    


    giovanni gargiulo에서 Pixabay의 이미지

    좋은 웹페이지 즐겨찾기