[AWS] AWS 스터디 4주차 회고, S3으로 이미지 업로드

SSO·2022년 6월 1일
0

[AWS] AWS 스터디

목록 보기
3/4
post-thumbnail

Retrospect


작년 캡스톤에서 이미지 데이터로 스트레스 엄청 받았던 기억이 있다 😥 그 때 S3와 DB에 이미지 링크를 저장하는 방식을 알았으면 아주아주 유용했을 것 같다. 지금이라도 깨우쳐서 다행 ~! 아무튼 어려운 이미지! AWS의 S3에 Node.js로 이미지를 올리는 방법을 4주차에서 배울 수 있었다. 물론 복합적인 기능이 더해진다면 어려워지겠지만 단순히 이미지 파일을 올리는 거여서 간단하게 하지만 확실히 배울 수 있었다 :)

🧡 4주차


일단 먼저! S3가 뭘까..? Simple Storage Service (S3)의 약자로 파일 서버의 역할을 하는, 즉 클라우드 저장공간이다.

EBS 볼륨 유형인 HSD 또는 SSD가 있는데, 이 저장공간 장치들은 PC에 붙어있지만,
S3는 AWS 자체에서 제공하면서 독립적인 느낌을 가지는 저장공간이라고 배웠다.

그럼 EBS는 뭔지 ..?
EBS 또한 AWS의 스토리지 서비스 중 하나로 Elastic Block Storage (EBS)의 약자이다. 고성능 블록 스토리지 서비스로 보면 된다.

그럼 S3과의 차이는 무엇일까? 이 부분 면접에서 질문 받았다는 썰을 들었다 🙄 간단하게나마 알아두자 ㅋ.ㅋ
EBS는 좀 더 빠른 서비스가 필요할 때 선택한다. 고성능임!!
S3는 객체로 저장할 필요가 있을 때, 또는 여러 컴퓨터에서 접근해야 할 때 선택한다. 객체 방식이고, 독립적이기 때문이다. 하지만 EBS 보다 속도는 당연히 떨어진다.

결국은 각각의 장단점을 잘 고려하여 필요한 스토리지 서비스를 선택해야 한다.


간단히 배울 S3 서비스에 대해 배워보았고, 본격적으로 실습을 시작하기 위해 AWS 서비스로 들어가주자.


👩‍💻 Bucket (버킷) 생성

💥 로그인 후 S3 서비스 > 버킷(bucket)으로 들아가서 새로운 버킷을 생성해주자.

SOPT 4차 세미나 회고
👆 새로운 버킷을 생성하는 방식은 SOPT 4차 세미나 회고에서 다루었으니 위의 링크를 참고해서 새로운 버킷을 생성해주자.



👩‍💻 Key (키) 생성

외부에서 버킷에 연결하기 위해서는 액세스 키가 필요하다. 생성해보자!
(IAM 서비스에 관한 더 자세한 내용은 다음 스터디에서 다루기로 했다 >.< 두근두근)

💥 IAM 서비스 > 사용자로 들어가서 사용자 추가를 클릭해서 새로운 사용자를 추가하자.

사용자 이름 : 고유한 사용자 이름 정해서 입력
AWS 자격 증명 유형 선택 : 필요한 유형 선택 (여기서는 key를 만들 것이므로 액세스 키-프로그래밍 방식 액세스로 선택함)

💥 입력 및 선택 후 다음으로 넘어가자

💥 그룹에 사용자 추가를 선택하고 그룹 생성 클릭

그룹 이름 : 지정해서 입력
정책 필터 : s3 검색 및 AmazonS3FullAccess 선택
그룹 생성 클릭

S3-manager라는 그룹에 AmazonS3FullAccess 가능한 권한을 줄 수 있는 그룹을 생성하고, 생성한 그룹 내에 사용자를 추가하는 작업이다.

💥 다음으로 넘어가자 (태그 관련도 넘어가면 된다.)

💥 검토 페이지에서 그룹 및 권한 등 설정한 정보 확인 후 사용자 만들기 클릭


위와 같은 과정을 마치면 키 (key)를 발급받을 수 있다.

해당 페이지를 한번 나가면 다시는 액세스 키, 특히 Secret Access Key는 찾을 수 없기 때문에 .csv 파일로 다운로드하여 보관해주자. (파일 다운로드 안되면 캡처라도 ㅇㅅㅇ)

암튼 어떤 방식으로든 key 정보를 보관해두고 절대절대 public한 공간에 노출되면 안된다 !!!! (해킹 당하고 싶지 않으면) 꼭꼭 private한 공간에 보관해두자 !!!


💥 이제 닫기를 누르고 IAM의 사용자 페이지를 확인하면 새로운 사용자가 추가된 것을 확인할 수 있다.



👩‍💻 Node.js에서 S3로 이미지 파일 업로드

Node.js에서는 multer이란 모듈을 사용해서 이미지 파일을 받아오고 S3에 저장하고, 이미지 링크를 받아올 것이다.

multer 모듈은 메모리 상에 이미지를 업로드하기 때문에 속도가 빠르다.

https://bytearcher.com/articles/formidable-vs-busboy-vs-multer-vs-multiparty/
👆 그 외에도 multer 모듈과 같이 nodejs 환경에서 이미지나 파일을 managing 할 수 있는 다른 패키지가 몇몇 있는데, 자세한 사항은 위 url을 참고해보면 되겠다.


이미지를 업로드 하는 간단한 코드 내용을 살펴보고 이미지를 S3에 업로드 해보자.

빠른 진행을 위해서 다같이 수업 설명자 분의 github 레포를 clone하여 진행하였다.
clone 받은 후 꼭 터미널에 yarn을 쳐준 후 프로젝트를 실행하자. (아니면 오류 가능성 다분)


💥 .env 파일에 발급받은 액세스 키랑 버킷 이름을 넣어주자. .env 파일은 유출되면 안되는 정보들을 포함하기 때문에 꼭 .gitignore 파일에 포함해주어야 한다.

PORT="포트 번호"
S3_ACCESS_KEY="ACCESS_KEY_ID"
S3_SECRET_KEY="SECRET_KEY_ID"
BUCKET_NAME="버킷 이름"

키 ID는 위에서 다운로드 받은 .csv 파일을 보고 해당되는 위치에 복붙 해넣어주면 된다.


💥 config 폴더 내의 index.ts에서는 (AWS S3 주석 밑에서) .env 파일에 적어둔 key ID와 bucket 이름을 가져오고 있다.

> src/config/index.ts


import dotenv from "dotenv";

const envFound = dotenv.config();
if (envFound.error) {
  throw new Error("⚠️  Couldn't find .env file  ⚠️");
}
process.env.NODE_ENV = process.env.NODE_ENV || "development";

export default {
  port: process.env.PORT || "8000",
  environment: process.env.NODE_ENV,

  /**
   * AWS S3
   */
  s3AccessKey: process.env.S3_ACCESS_KEY as string,
  s3SecretKey: process.env.S3_SECRET_KEY as string,
  bucketName: process.env.BUCKET_NAME as string,
};

💥 config 폴더 내의 s3Config.ts에서는 액세스 키와 asw-sdk 모듈을 가지고 S3 객체를 생성한다. 이로써 AWS의 버킷 저장소와 연결되는 것이다.

> src/config/s3Config.ts


import AWS from "aws-sdk";
import config from ".";

const storage: AWS.S3 = new AWS.S3({
    accessKeyId: config.s3AccessKey,
    secretAccessKey: config.s3SecretKey,
    region: 'ap-northeast-2'
});

export default storage;

💥 config 내부의 multer.ts에서는 핸들링을 도와준다. 업로드 한(request) file을 받아와서 저장해주는 방식인데, multer.diskStorage({ .. })에서 로컬 경로인 uploads/ 경로에도 파일이 저장된다.

src/config/multer.ts


import { Request } from "express";
import multer, { FileFilterCallback } from "multer";

type FileNameCallback = (error: Error | null, filename: string) => void;

export const multerConfig = {
  storage: multer.diskStorage({
    // diskStorage
    destination: "uploads/", // file 경로는 uploads
    filename: function (
      req: Request,
      file: Express.Multer.File,
      cb: FileNameCallback
    ) {
      cb(null, file.originalname); // 이름을 이런 식으로 저장할 것
    },
  }),
};

💥 index.ts에서는 post 라우터가 지정되어 있고, 내부에서 upload 미들웨어를 거쳐 파일을 저장하고 저장한 파일의 링크(url)을 반환하고 있다.

> src/index.ts


import express, { Request, Response, NextFunction } from "express";
import multer from "multer";
import fs from "fs";

import config from "./config";
import storage from "./config/s3Config";
import { multerConfig } from "./config/multer";

const app = express();

app.use(express.json());
const upload = multer(multerConfig); // multer 객체

app.get("/", (req: Request, res: Response, next: NextFunction) => {
  res.send("Hello World!");
});

app.post(
  "/api/fileUpload",
  upload.single("image"), // key -> image 속성을 파일로 만들어준다
  
  // upload 미들웨어를 거치면 request에 file 속성이 생김
  async (req: Request, res: Response, next: NextFunction) => {
    if (!req.file)
      return res.status(400).send({ message: "잘못된 요청입니다." });

    const fileData: Express.Multer.File = req.file;

    try {
      const fileContent: Buffer = fs.readFileSync(fileData.path);

      const params: {
        Bucket: string;
        Key: string;
        Body: Buffer;
      } = {
        Bucket: config.bucketName,
        Key: fileData.originalname,
        Body: fileContent,
      };

      const result = await storage.upload(params).promise();

      const data = {
        link: result.Location,
      };
      res.status(200).send({ message: "성공적인 요청입니다.", data: data });
    } catch (error) {
      console.log(error);
      res.status(500).send({ message: "서버 내부에 에러가 발생했습니다." });
    }
  }
);

app.listen(config.port, () => {
  console.log(`
        #############################################
            🛡️ Server listening on port: ${config.port} 🛡️
        #############################################
    `);
});

라우터 관련 파일 없이 index.ts에서 바로 만들어져 있는데, AWS의 S3 서비스에 파일을 업로드하는 것을 연습해보기 위한 용도로 코드가 간단하게 짜여졌다.



👩‍💻 API 테스트

thunder clinet에서 API 테스트를 해보면 성공한 것을 확인할 수 있었다 😊

/uploads 경로에도 올라갔고

연결한 버킷에도 잘 올라갔다 !! 오예 ~~



🙇‍♀️ Feeling


위에서도 말했지만 작년 캡스톤 프로젝트 중 이미지 파일 관리가 너무 어려워서 이미지 파일은 너무 어려워.. 라는 인식을 계속 가지고 있었는데 이번 스터디와 SOPT 7차 세미나를 통해서도 이미지 파일 업로드와 관리에 대해 제대로 다뤄볼 수 있어서 너무 재밌고 뿌듯했다 ㅎㅎ 엄청 어렵다는 인식도 깨졌다! 하면 된다 !!

profile
쏘's 코딩·개발 일기장

0개의 댓글