2020년 6월 23일 화요일

AWS + LAMBDA + (Elastic cache) REDIS 연동 방법

일단 AWS Elastic cache 는 외부에서 바로 연결이 안된다. 고로, VPC 설정을 해서 , 내부의 AWS Lambda 함수에서 접근이 가능하도록 해야한다.
그걸 하기위해서
IAM 롤 설정-VPC-SUBNET-LAMBA-API GATEWAY-REDIS-REDIS SUBNET GROUP 설정을 해야한다. 정말 귀찮다.

1. IAM 설정

Role 에 가서 Lambda 선택(어쭈, 아예 상단에 있네. 많이 쓰란 얘긴가) -> AwsLambdaBasicExecutionRole 선택해서 생성해둔다. 이건 나중에 LAMBDA 기능에서 권한 설정할때 쓴다.

2.VPC
2-1. VPC 생성

2-2.그밑의 Subnet 도 생성
10.0.0.0/28 , 10.0.0.16/28 , 10.0.0.32/28
이런식으로 나누어서 생성하면 나중에 zone 별로 지정하기 좋다.

2-3.Security Group 도 설정해야 한다. (VPC IP 로 데이터가 나가고 들어오는 보안설정이다)

3.Elastic cache Redis
3-1 Subnet group 부터 설정한다. 여기서 Zone 별로 Subnet 을 설정하는데, 2-2 에서 여러개 설정해놓았다면 존별로 그것들을 지정하면된다.
3-2 Redis 생성 하면 end-point 가 나오는데 그게 내부에서 접속가능한 주소다. 람다에서 접속하자.

4.Lambda
4-1 새로운 함수를 언어에 맞게 생성한다. 아마존은 크롬을 싫어하니 에디터는 파이어팍스에서 하자. NodeJs 의 경우는 관련패키지가 많이 필요하니 로컬에서 압축파일 만들어서 zip 으로 올리자. [작업->.zip 업로드]
4-2 VPC 지정해야 Lambda 에서 Redis 접속이 가능하다. 설정하자. 보안그룹등도 같이 지정하자.
4-3 권한 탭화면에서 IAM 의 권한 지정하자.
4-4 이제 외부에서 접속가능하게 API GATEWAY 추가하자

5.API GATEWAY
5-1 람다화면에서 트리거 추가.
5-2 API GATEWAY 설정화면에서 리소스 화면에서 메서드/리소스 다 추가하자
5-3 Restful 의 /mymy/sum/1/11 -> /mymy/{whichoper}/{firstvalue}/{lastvalue} 식으로 get/post 하고 싶으면 차례대로 추가하면된다. 단 LAMBDA_PROXY 를 선택해야 된다.

6. 외부에서 curl 등으로 접속해보면 된다.

const redis   = require("ioredis");


exports.handler = async (event, context, callback) => {
    context.callbackWaitsForEmptyEventLoop = false;     
    try {
        //Redis서버접속
        client = await connectRedis();

        switch (currentMethos) {

            case "GET":

                let value = await getValueOfKey(client, keyNameForRedis);
                break;
            case "POST":

                await setValueOfKey(client, keyNameForRedis, setVal);
                break;

       
        //Redis 접속 해제
        disconnectRedis();

        return {
            statusCode: 200,
            headers: {
                "Access-Control-Allow-Headers" : "Content-Type",
                "Access-Control-Allow-Origin": "*"
            },
            body: JSON.stringify(
                    {
                        code :  resultCode,
                        uuid :  in_uuid
                    }
                )
        }
    } catch (error) {
        console.error('error:', error);
    }
};
function connectRedis() {
    return new Promise(function (resolve, reject) {
        
          const client = new redis.Cluster(['//xxxxxxxx.cache.amazonaws.com:6379'],
            {
                slotsRefreshTimeout: 5000
            }
        );


        client.on('connect', () => {
            console.log('Connected');
            resolve(client);
        });
        client.on('error', (error) => {
            console.log(`Connection Error`, error);
            reject(error);
        });
    });
}

function disconnectRedis() {
    if (client) {
       client.disconnect();
    }
}

function getValueOfKey(client, inkey) {
    return new Promise(function (resolve) {
        client.get(inkey, (err, reply) => {
            if(err){
                resolve('error');
                return;
          } else {
            resolve(reply);
          }

        });
    });
}

function setValueOfKey(client, inkey, invalue) {
    
    return new Promise(function (resolve) {
        resolve(client.set(inkey, invalue));
    });
}

function setExpireOfKey(client, inkey, inExpire) {
    
    return new Promise(function (resolve) {
        resolve(client.expire(inkey, inExpire ));
    });
}

외부에서 접속하려면 API GATEWAY 항목에서 확인하면된다. 잘된다.

0 comments:

댓글 쓰기