반응형

지난 포스팅에 이어, 이번에는 Codedeploy 설정을 진행한다.

1. CodeBuild 설정

2. Codedeploy 설정: 이번 포스팅

3. EC2 Ubuntu 설정

 

 

Codedeploy에서 deploy에 사용할 애플리케이션(Jane-codedeploy)을 생성한다. 

플랫폼은 EC2/온프레미스를 설정하면 끝난다.

 

애플리케이션 생성 후엔 '배포 그룹'에서 실제로 이 code deploy가 어떤 인스턴스에 배포될지 설정한다.

나는 EC2에 배포를 할 것이고, EC2 중에서도 어떤 인스턴스에 배포할지는 인스턴스에 설정된 '태그'를 통해 코드가 배포된다.

(난 Service:Test 태그를 설정했다.)

codedeploy의 배포그룹 구성
코드를 배포할 ec2 인스턴스의 태그

 

 

그리고, codedeploy-agent를 ec2에 설치하면 된다.

나는 ubuntu용 ec2이므로 아래 링크를 참고했고, 들어가보면 윈도우 등 다양한 옵션이 있다.

 

* Codedeploy agent 설치

1. ruby 설치: Codedeploy agent는 ruby로 작성되었으므로 이를 설치한다.

$ sudo apt-get install ruby  // (ubuntu 16.04)

 

2. wget 설치 (agent 설치파일을 들고오기 위해 쓰인다)

$ sudo apt-get install wget

 

3. Codedeploy Agent 설치

# 나는 jane계정을 사용하므로 /home/jane이며, ubuntu 계정을 사용한다면 /home/ubuntu로 가면 된다.

$ cd /home/jane

 

# 설치파일 다운로드 (Seoul region) 

$ wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install

 

# 실행권한 추가 및 설치

$ chmod +x ./install

$ sudo ./install auto

 

하다가 막힌다면 아래 aws docs를 참고한다.

https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/codedeploy-agent-operations-install-ubuntu.html

 

Ubuntu Server용 CodeDeploy 에이전트 설치 - AWS CodeDeploy

출력을 임시 로그 파일에 쓰는 것은 Ubuntu 20.04에서 install 스크립트를 사용하여 알려진 버그를 해결하는 동안 사용해야 하는 해결 방법입니다.

docs.aws.amazon.com

 

* Codedeploy agent 서비스 확인

$ sudo service codedeploy-agent status

* ubuntu 계정이 아닌, jane과 같이 별도의 root권한이 아닌 계정을 사용한다면 추가 설정이 필요하다. 

그렇지 않으면, codedeploy-agent가 root로 돌기 때문에(위 캡쳐본에 /etc/init.d/codedeploy/agent에서 돌고 있다),

코드가 배포되는 디렉토리가 root가 되어 추후 다른 문제들을 야기시킨다. 이는 별도로 포스팅 했으니 여기 참고!

https://countrymouse.tistory.com/entry/awscodedeployerr

 

[AWS] root 이외 계정에서 codedeploy 실행, codedeploy 'run as user jane failed with exit code 1', '[stderr]su: must be ru

문제 root 권한이 없는 계정을 통해 ubuntu를 운용하면, code deploy시 생성된 코드의 directory가 'root'로 변경되어 code deploy가 실패하거나(code deploy 후, build 디렉토리 소유자가 root로 변경되었다.),..

countrymouse.tistory.com

 

 

그리고, codedeploy 설정을 끝냈으니 codepipeline으로 돌아와서, '배포'부분에 codedeploy에서 만든 deploy를 추가해준다.

입력 아티팩트는 codebuild의 output이었던 BuildArifact이고, 애플리케이션은 codedeploy에서 만들었던 Jane-codedeploy,

배포 그룹은, jane-codedeploy에서 만들어줬던 jane-codedeploy이다.

 

 

그리고, codedeploy에는 appspec.yml이 필요한데, 이는 아래와 같이 작성했다.

appspec.yml

files: source, destination, runas

files은 source: / 내 파일들을 ec2의 destination( /home/jane/build/)로 옮긴다.

즉, build에서 산출된 artifacts의 모든 것들을 ec2의 /home/jane/build/로 옮긴다. (/home/jane/build/ 디렉토리는 생성시켜두자)

그리고, 그 동작은 'jane'이 run 한다.

 

permissions: 

복사한 파일들의 객체들은 모두(pattern: "**") owner/grp을 'jane'으로 준다.

근데, 이미 위에서 말한  "jane과 같이 별도의 root권한이 아닌 계정을 사용한다면 추가 설정이 필요하다. " 를 했으므로,

이 permission은 생략해도 된다.

 

hooks:

deploy는 아래 각 절차(hooks)마다 하나 이상의 스크립트를 통해 변수선언, 환경설정 등을 할 수 있는데

나는 간단한 코드를 올렸으므로 applicationStart에만 code를 실행시키는 간단한 event를 만들었다.

https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/reference-appspec-file-structure-hooks.html

 

start.sh

pm2로 nodejs 코드를 띄우는 sh이다. (pm2 reload ecosystem.json이 메인)

6번째 줄까지는 안 해도 된다. 나는 각 절차가 궁금해서 찍어봤다.

ecosystem.json

/home/jane/build 디렉토리에 있는 index.js를 실행한다. 

코드가 변경되는지 watch==true를 통해 확인하며, error_file, out_file이 쌓이는 위치를 지정해주었다.

 

이 모든 파일은(appspec,yml, scosystem.json, start.sh 등) 코드와 같이 git에 올리면 된다 :)

 

반응형
반응형

nvm(node version manager): 여러 버전의 node.js 설치 전환 가능.

. LTS(Long Term Supported) 장기적 안정된 버전. 유지보수 목적의 사용자에게 추천. 짝수 버전 (ex. 8.x.x.)

. Current(현재 버전): 최신 기능 제공, 업데이트 잦고 기능 자주 변경. 개발/테스트에 적당. 홀수 버전 (ex. 9.x.x)

 

npm(node package manager): nodejs에 사용되는 각종 코드 패키지 == 앱스토어st

 

. 설치여부, 버전 조회

$ node -v

  v8.9.4

$ npm -v

  5.6.0

 

. 패키지 매니저로 설치

. macOS - Homebrew (Homebrew: macOS용 패키지 관리자)

$ brew install node@8. // Major number만 입력

$ brew install nvm // nvm 설치

 

. NVM: node.js는 버전이 자주 바뀌어서 버전 관리 매니저 설치 필요.

$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash // NVM 설치

    . 설치 완료 후 ~/. bash_profile, ~/.zshrc, ~/.profile 에 nvm.sh이 실행되도록 아래 스크립트가 자동 추가됨.

       export NVM_DIR="$HOME/.nvm"

$ . ~/.nvm/nvm.sh // nvm 활성화

[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

 

$ nvm install 16.14.0 // 16.14.0 노드 설치 

$ node -v // 노드 버전 조회

 

$ npm init -y // default 값으로 설정된 package.json을 만듦 

(index.js 만들면 js script 들어오고. main으로 이걸 실행시키겠다. 라고 pakcage.json 들어옴. )

 

 

. 원하는 nvm version 설치

$ nvm install <version> // nvm install 8.9.4

 

. 설치된 Node 버전 목록 확인

$ nvm ls

 

. 사용할 Node 설정

$ nvm use <version> // nvm use 8.9.4

$ nvm use <alias> // nvm use default

 

 

. package.json (프로젝트 정보와 의존성을 관리하는 문서)

어느 곳에서도 동일한 개발 환경을 구축할 수 있게 해줌. json format.

 

{

  "name": "project-name",

  "version": "1.0.0",

  "keywords": [], // npm search 사용 시 도움됨

  "description": "",   // 프로젝트 (패키지) 설명. npm search 시 도움됨

  "main": "index.js",  // 프로그램의 기본 진입 점(entry point)

  "scripts": {. // pkg 라아프 사이클에서 여러 번 실행되는 스크립트 명령. 

    "test": "echo \"Error: no test specified\" && exit 1"

  },

  "author": "HEROPY",

  "license": "MIT",

  "dependencies": {},       // 패키지 배포 시 포함될 의존성 모듈 지정

  "devDependencies": {}  // 개발 시 사용될 의존성 모듈 (배포 시는 포함되지 않음) 

  “files” // 패키지가 의존성으로 설치될 때 같이 포함된 파일들의 배열. 생략하면 모든 파일이 포함됨.

  “bugs”: { } // 패키지에 문제가 있을 때 보고될 이슈 트래커 및 이메일 주소 등에 대한 url

  “repository”: {} // 코드가 존재하는 장소. github 주소 지정 

} 

 

// package-lock.json: 개발 환경에서 내부 모듈 변경(ex. 버전)이 있을 경우, 

이를 방지하기 위해 package.json을 수정하는 모든 작업에 대해 package-lock.json이 자동으로 생성됨. 

 

. 의존성 모듈 설치

$ npm install <package>@<version>

 

. 전역으로 모듈 설치

$ npm install -g webpack  // -g 플래그

 

. 오래된 패키지 확인

$ npm outdated     // 설치된 패키지가 구형인지 확인하기 위해 레지스트리 검사

 

. 패키지를 최신 버전으로 업데이트

$ npm update <package>

$ npm upgrade   // pkg 입력하지 않으면 지정된 위치의 모든 패키지 업데이트

 

. 패키지 제거

 $ npm uninstall <pkg>

 $ npm remove

 $ npm unlink

 

. dockerfile

FROM node:12-alpine

WORKDIR /usr/src/app

MAINTAINER Jane Baek

RUN mkdir -p /usr/src/app

ADD . /usr/src/app

RUN npm install --silent

 

반응형
반응형

이전 포스팅에서, cloudwatch에서 알람이 발생할 때마다 SNS, 그리고 lambda를 trigger해서 slack으로 알람을 보냈다.

* 이전 포스팅:

https://countrymouse.tistory.com/entry/awscloudwatchslack

 

[AWS] cloudwatch, lambda를 통해 slack으로 알람 보내기 (Nodejs)

Cloudwatch에서 알람 조건을 만들어서, 해당 알람이 발생할 때 slack으로 notify하는 환경을 만들어보자. 1. AWS > CloudWatch > 경보 생성 1) 지표 선택 2) 지표에서 원하는 tracking값 및 임계치 선택 (알람..

countrymouse.tistory.com

 

그런데, alarm으로 받는 text의 포맷이 아래와 같이 가독성이 떨어진다. 그래서, 보다 가독성 있게 수정해보기로 한다.

 

위 가독성 없는 텍스트를 아래 포맷으로 수정한다.

 

코드는 아래 티스토리 블로거 향로님의 코드를 사용하였고 아래는 한줄한줄 해석을 달아보았다. 

(직접 하나씩 만들어보려고 했는데, 반나절의 삽질을 해도 원하는 대로 잘 안돼서 다른 분의 코드를 사용하기로 했다...)

https://jojoldu.tistory.com/586

 

CloudWatch 이상 지표를 슬랙 알람으로 받기 (feat. SNS, Lambda)

AWS 서비스를 이용하면 CloudWatch를 통해 서비스의 이상 지표를 손쉽게 확인할 수 있습니다. 이를테면 다음과 같은 경우인데요. 평소보다 로드밸런서로 들어오는 요청양이 2배이상 높다거나 RDS의 C

jojoldu.tistory.com

 

향로님 코드에 cause부분과 관련된 코드는 삭제하였고(나는 '원인'을 '설명'으로 대체했다), 일부분에 주석을 추가하였다.

// 구성 -> 환경변수로 webhook을 받도록 합니다.
const ENV = process.env
if (!ENV.webhook) throw new Error('Missing environment variable: webhook')

const webhook = ENV.webhook;
const https = require('https')

const statusColorsAndMessage = {
    ALARM: {"color": "danger", "message":"위험"},
    INSUFFICIENT_DATA: {"color": "warning", "message":"데이터 부족"},
    OK: {"color": "good", "message":"정상"}
}


// 1. 여기서부터 시작 
exports.handler = async (event) => {
    await exports.processEvent(event);
}


// 2. processEvent로 넘어간다.
exports.processEvent = async (event) => {
    console.log('Event:', JSON.stringify(event))
    const snsMessage = event.Records[0].Sns.Message;
    console.log('SNS Message:', snsMessage);
    const postData = exports.buildSlackMessage(JSON.parse(snsMessage))  // 3. buildSlackMessage
    await exports.postSlack(postData, webhook);
}

// snsMessage는 이전 포스팅 값들이 담겨 있는데, 참고해보자.


// 3. buildSlackMessage(위 jane_bot2에서 출력한 snsMessage를 받아와서 각각 처리한다.)
exports.buildSlackMessage = (data) => {
    const newState = statusColorsAndMessage[data.NewStateValue];  // 위 jane_bot2 기준 ALARM
    const oldState = statusColorsAndMessage[data.OldStateValue];     // 위 jane_bot2 기준 OK
    const executeTime = exports.toYyyymmddhhmmss(data.StateChangeTime); // 2022-05-23T03:16:02.297+0000
    const description = data.NewStateReason;  // 기존 코드엔 description, cause가 둘 다 있지만 나는 description에 대체했다.
    return {
        attachments: [
            {
                title: `[${data.AlarmName}]`,
                color: newState.color,
                fields: [
                    {
                        title: 'Timestamp',
                        value: executeTime
                    },
                    {
                        title: 'Alarm',
                        value: description
                    },
                    {
                        title: 'Previous Status',
                        value: oldState.message,
                        short: true
                    },
                    {
                        title: 'Current Status',
                        value: `*${newState.message}*`,
                        short: true
                    },
                    {
                        title: 'Link',
                        value: exports.createLink(data)
                    }
                ]
            }
        ]
    }
}

// CloudWatch 알람 바로 가기 링크
exports.createLink = (data) => {
    return `https://console.aws.amazon.com/cloudwatch/home?region=${exports.exportRegionCode(data.AlarmArn)}#alarm:alarmFilter=ANY;name=${encodeURIComponent(data.AlarmName)}`;
}

exports.exportRegionCode = (arn) => {
    return  arn.replace("arn:aws:cloudwatch:", "").split(":")[0];
}


// 타임존 UTC -> KST (2022-05-23T03:16:02.297+0000 --> 2022-05-23 13:14:48)
exports.toYyyymmddhhmmss = (timeString) => {

    if(!timeString){
        return '';
    }

    const kstDate = new Date(new Date(timeString).getTime() + 32400000);

    function pad2(n) { return n < 10 ? '0' + n : n }

    return kstDate.getFullYear().toString()
        + '-'+ pad2(kstDate.getMonth() + 1)
        + '-'+ pad2(kstDate.getDate())
        + ' '+ pad2(kstDate.getHours())
        + ':'+ pad2(kstDate.getMinutes())
        + ':'+ pad2(kstDate.getSeconds());
}  

exports.postSlack = async (message, slackUrl) => {
    return await request(exports.options(slackUrl), message);
}

exports.options = (slackUrl) => {
    const {host, pathname} = new URL(slackUrl);
    return {
        hostname: host,
        path: pathname,
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
    };
}

function request(options, data) {

    return new Promise((resolve, reject) => {
        const req = https.request(options, (res) => {
            res.setEncoding('utf8');
            let responseBody = '';

            res.on('data', (chunk) => {
                responseBody += chunk;
            });

            res.on('end', () => {
                resolve(responseBody);
            });
        });

        req.on('error', (err) => {
            console.error(err);
            reject(err);
        });

        req.write(JSON.stringify(data));
        req.end();
    });
}

 

완성!

반응형
반응형

배경 설명

lambda에 S3를 연동시켜 두고, 해당 S3에 이벤트가 있을 때마다 람다를 실행시키는 코드를 해석해본다.

 

코드

const aws = require('aws-sdk');
const fs = require('fs');
var s3 = new aws.S3({ apiVersion: '2006-03-01' });


exports.handler = async(event, context,  callback) => {
    const bucket = event.Records[0].s3.bucket.name;

    console.log(event);   // 실행결과 테스트 1번
    console.log(event.Records);  // 실행결과 테스트 2번
    console.log(event.Records[0]);  // 실행결과 테스트 3번

    console.log(bucket); // 그럼 이건 .s3.bucket.name인 jane-bkt만 출력됨.
    const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' ')); // 여기부턴 실행결과 2로 이동
    const params = {
        Bucket: bucket,
        Key: key,
    };
    var theObject = await s3.getObject(params).promise();
    const data = JSON.parse(theObject.Body);
    console.log(data);
    // console.log(theObject.Body.toString('utf8'));  // 위와 결과값이 같지만, 보기 좋은 형태로
        try {
        const { ContentType } = await s3.getObject(params).promise();
        console.log('CONTENT TYPE:', ContentType);
        console.log('********** Event generated by S3 ************* ');
        return ContentType;
        
    } catch (err) {
        console.log(err);
        const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
        console.log(message);
        throw new Error(message);
    }
};

 

 

실행 결과 1

1) console.log(event)

Function Logs
START RequestId: a4ff7ef5-b647-40b7-9e6d-8eb2fb95360f Version: $LATEST
2022-05-22T02:23:56.937Z a4ff7ef5-b647-40b7-9e6d-8eb2fb95360f INFO {
  Records: [
    {
      eventVersion: '2.0',
      eventSource: 'aws:s3',
      awsRegion: 'us-east-1',
      eventTime: '1970-01-01T00:00:00.000Z',
      eventName: 'ObjectCreated:Put',
      userIdentity: [Object],
      requestParameters: [Object],
      responseElements: [Object],
      s3: [Object]
    }
  ]
}

 2) console.log(event.Records);  // 실행결과 테스트 2번. 좀 더 자세히 나온다.

Function Logs
START RequestId: 35e8439b-4ac0-44fa-a006-85a3fdd6d4aa Version: $LATEST
2022-05-22T02:27:20.107Z 35e8439b-4ac0-44fa-a006-85a3fdd6d4aa INFO [
  {
    eventVersion: '2.0',
    eventSource: 'aws:s3',
    awsRegion: 'us-east-1',
    eventTime: '1970-01-01T00:00:00.000Z',
    eventName: 'ObjectCreated:Put',
    userIdentity: { principalId: 'EXAMPLE' },
    requestParameters: { sourceIPAddress: '127.0.0.1' },
    responseElements: {
      'x-amz-request-id': 'EXAMPLE123456789',
      'x-amz-id-2': 'EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH'
    },
    s3: {
      s3SchemaVersion: '1.0',
      configurationId: 'testConfigRule',
      bucket: [Object],
      object: [Object]
    }
  }
]


 3) console.log(event.Records[0]);  // 테스트 3번. 테스팅 json에서 언급한 jane-bkt, s3test.json을 포함한 결과값이 나온다.

Function Logs
START RequestId: cda13909-6eab-410a-9582-dc00d25732f2 Version: $LATEST
2022-05-22T02:28:47.364Z cda13909-6eab-410a-9582-dc00d25732f2 INFO {
  eventVersion: '2.0',
  eventSource: 'aws:s3',
  awsRegion: 'us-east-1',
  eventTime: '1970-01-01T00:00:00.000Z',
  eventName: 'ObjectCreated:Put',
  userIdentity: { principalId: 'EXAMPLE' },
  requestParameters: { sourceIPAddress: '127.0.0.1' },
  responseElements: {
    'x-amz-request-id': 'EXAMPLE123456789',
    'x-amz-id-2': 'EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH'
  },
  s3: {
    s3SchemaVersion: '1.0',
    configurationId: 'testConfigRule',
    bucket: {
      name: 'jane-bkt',
      ownerIdentity: [Object],
      arn: 'arn:aws:s3:::jane-bkt'
    },
    object: {
      key: 's3test.json',
      size: 1024,
      eTag: '0123456789abcdef0123456789abcdef',
      sequencer: '0A1B2C3D4E5F678901'
    }
  }
}

 

 

 

다시 코드

   const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' ')); // 여기부턴 실행결과 2로 이동
   console.log(event.Records[0].s3.object.key.replace(/\+/g.''));  //  object.key에 +제거(/+) 및 전역으로 확장(/g) 

    const params = {
        Bucket: bucket,
        Key: key,
    };
    var theObject = await s3.getObject(params).promise();
    console.log(theObject);  // 결과 1)
    const data = JSON.parse(theObject.Body);
    console.log(data);
    // console.log(theObject.Body.toString('utf8'));  // 위와 결과값이 같지만 보기 좋은 형태로
        try {
        const { ContentType } = await s3.getObject(params).promise();
        console.log('CONTENT TYPE:', ContentType);
        console.log('********** Event generated by S3 ************* ');
        return ContentType;
        
    } catch (err) {
        console.log(err);
        const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
        console.log(message);
        throw new Error(message);
    }
};

 

실행결과 2

1)  console.log(theObject);  // 결과 1)

Function Logs
START RequestId: ed9a9525-9994-48da-8834-16ec0ab5c2d6 Version: $LATEST
2022-05-22T02:41:07.808Z ed9a9525-9994-48da-8834-16ec0ab5c2d6 INFO {
  AcceptRanges: 'bytes',
  LastModified: 2022-05-20T02:49:10.000Z,
  ContentLength: 80,
  ETag: '"5704c18c8279716da4b82c028dddb5d4"',
  ContentType: 'application/json',
  Metadata: {},
  Body: <Buffer 7b 0a 20 20 22 6e 61 6d 65 22 3a 20 22 4a 61 6e 65 22 2c 0a 20 20 22 61 67 65 22 3a 20 22 32 38 22 2c 0a 20 20 22 63 6f 6d 70 61 6e 79 22 3a 20 22 53 ... 30 more bytes> 
// 이 body를 아래 코드에서 JSON으로 파싱 후 출력함.
 const data = JSON.parse(theObject.Body);

}

 

Note

1) try - catch: 에러 핸들링 코드 (출처:https://ko.javascript.info/try-catch)

  1. try { } 안의 코드가 먼저 실행된다.
  2. 에러가 없다면, try 안의 마지막 줄까지 실행, catch 블록은 건너뜀
  3. 에러가 있다면, try 안 코드의 실행이 중단, catch(err) 블록으로 제어 흐름이 넘어감. 변수 err(아무 이름이나 사용 가능)는 무슨 일이 일어났는지에 대한 설명이 담긴 에러 객체를 포함. 
  try {
        const { ContentType } = await s3.getObject(params).promise();
        console.log('CONTENT TYPE:', ContentType);
        console.log('********** Event generated by S3 ************* ');
        return ContentType;
        
    } catch (err) {
        console.log(err);
        const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
        console.log(message);
        throw new Error(message);  // 에러 던지기.
    }
};

 

- event: 호출상황에 대한 정보.

- context: 실행되는 함수 환경에 대한 정보 

- callback: 응답을 전송하기 위한 함수. (Error 및 응답을 사용)

      -> 이벤트 루프가 비워질 때까지 기다린 다음, 응답이나 오류를 호출자에게 반환. 

- async: 비동기 핸들러를 sync 맞춰주기 위함. 

반응형
반응형

1. Trigger를 S3로 설정한 lambda를 만든다.

   (S3는 미리 만들어놔야 함)

   

1) Lambda > 함수생성 > 블루프린트 사용(aws에서 제공하는 템플릿) > s3 검색 > nodejs의 경우 s3-get-object

 

 2) 구성 누른 후 나머지 설정은 기존 사용하던 값으로 설정,

     S3 트리거에서 버킷을 만들어놓은 버킷으로 설정 + 이벤트 유형: 모든 객체 생성 이벤트

     // 이렇게 하면, 모든 객체 생성 이벤트(생성삭제수정 등)가 일어날 때마다 lambda 함수가 호출된다.

 

3) 만들어진 람다

 

2. index.js 코드

const aws = require('aws-sdk');
const fs = require('fs');
var s3 = new aws.S3({ apiVersion: '2006-03-01' });

exports.handler = async(event, context,  callback) => {
    const bucket = event.Records[0].s3.bucket.name;
    const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    const params = {
        Bucket: bucket,
        Key: key,
    };

// json 파일을 읽어와서 json 형태로 출력
    var theObject = await s3.getObject(params).promise();
    const data = JSON.parse(theObject.Body);
    console.log(data);
   // console.log(theObject.Body.toString('utf8'));  // 보기 예쁜 형태로
        

 

 // S3에서 이벤트가 발생할 때마다 로그에 찍어줄 값.

  try {
        const { ContentType } = await s3.getObject(params).promise();
        console.log('CONTENT TYPE:', ContentType);
        console.log('********** Event generated by S3 ************* ');
        return ContentType;
        
    } catch (err) {
        console.log(err);
        const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
        console.log(message);
        throw new Error(message);
    }
};

 

3. 람다의 테스트에서 awsRegion, bucket-name, arn, key를 바꾸어주어야 정상 테스팅됨.

람다 테스트

      "awsRegion": “ap-northeast-2",

      "s3": {

        "s3SchemaVersion": "1.0",

        "configurationId": "testConfigRule",

        "bucket": {

          "name": "jane-bkt”,

          "ownerIdentity": {

            "principalId": "EXAMPLE"

          },

          "arn": "arn:aws:s3:::jane-bkt"

        },

        "object": {

          "key": "s3test.json",

          "size": 1024,

          "eTag": "0123456789abcdef0123456789abcdef",

          "sequencer": "0A1B2C3D4E5F678901"

        }

 

 

4. 테스팅 결과

1) json 파일이 예쁘게 나온다.

2) S3의 해당 버킷에 새로운 파일을 업로드할 경우, 람다가 실행되어 Cloudwatch에서 로그를 확인할 수도 있다.

 

반응형

+ Recent posts