본문 바로가기
개발 및 운영/AWS GCP Cloud

AWS Lambda 기본 (삽질기)

by Joseph.Lee 2019. 10. 24.

요즘 AWS Lambda를 써보는데 기본적인 걸로 삽질을 했다..ㅋㅋ

1. VPC의 Subnet는 기본적으로 서로 통신이 가능하다.

삽질한 내용은 아니지만 기본적인 내용인데 인터넷을 보면 잘못 설명한 글이 몇몇 있었다.

한 VPC내의 모든 Subnet들은 라우터로 연결된 것으로 묘사되는데 서로 통신이 가능하단 뜻이다.

2. API Gateway이랑 연동할 때 Lambda에서 Timeout발생시 502 Bad Gateway가 뜬다.

3. Security Group는 Rule이 없으면 기본적으로 모든 Inbound를 거부한다.

4. Lambda를 VPC로 연결했을 때 기본적으로 AWS Service에 연결할 수 없다.

따라서 VPC에 Endpoint를 만들어서 외부 endpoint가 아닌 VPC 내부의 endpoint를 타도록 해야 한다.

여기서 VPC에 Endpoint만들 때 Security Group선택하는데 443포트에 대한 Inbound를 허용해야 한다.

그리고 DNS가 활성화되기 때문에 lambda 소스에서 따로 endpoint를 지정해줄 필요는 없다. ({service}.{region}.amazonaws.com 이 자동으로 VPC Endpoint IP로 Resolve된다)

5. UnrecognizedClientException: The security token included in the request is invalid. 오류시...

    await new Promise((resolve, reject) => {
        AWS.config.getCredentials(function(err) {
            if (err)
                reject(err);
            else {
                resolve();
            }
        });
    });
    const kms = new AWS.KMS({
        credentials: AWS.config.credentials // 필요!
    }));

6. Private Subnet에서 실행중인 Lambda는 다른 Lambda를 호출할 수 없다.

4번과 같은 문제인데 진짜 문제는 AWS PrivateLink에 Lambda 서비스 (lambda.{region}.amazonaws.com)가 없다는 것이다.

따라서 Private Subnet에서 돌아가는 Lambda에서 다른 Lambda를 Invoke하려면 NAT이 필수적이다.

이참에.. KMS도 써야하고 Lambda도 써야하는데 PrivateLink는 비싸서(시간당 0.01달라인가.. 여러개면...ㅠㅠ) NAT Instance를 구축했다. (NAT Gateway는 비싸다...ㅠㅠ)

AWS때문에 지갑이 얇아진다... 아니 지네 서비스안에서 지네 서비스 연결하는데도 돈이 든다니... 인터넷 통신비용도 또 따로 책정하면서... 이런...

7. NodeJs에서 exports = require(...) 이런 형식의 handler는 안된다.

무슨 말이냐면...

index.js

exports = require('./dist/main.js')

dist/main.js

const server = JsExpressServer.createServer();
exports.handler = server.lambdaHandler;

이렇게 했는데 안되었다.

웃긴건 index.js에서 exports.handler를 출력해보면 자알 존재하는데 딱히 실행하면 오류도 안나고 그저 502 Bad Gateway (Timeout)가 떠버린다..

이유는 lambdaHandler가 Promise로 작동하는거 때문인거 같은데 쨋든 웃기다기보단 내가 아직 node.js를 잘 몰라서 그렇다..ㅎㅎ

this 참조때문인가 했는데 그건 아니었다. lambdaHandler안에서 this객체들은 너무도 잘 참조되었다.

지금은 dist/main.js를 직접 실행하고 (WebPack을 쓰고있다. 용량도 확 줄고 alias도 쓸 수 있고 좋다~)

const server = JsExpressServer.createServer();
exports.handler = (event, context) => server.lambdaHandler(event, context);

이렇게 하니 잘 된다!

반응형

댓글