diff --git a/.gitignore b/.gitignore
index 6b82cb2e1e32070e9a6fec867854c8810ed301a6..54d579f0222f518760af9ef7b031e5c58ecb753b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ build/
 !gradle/wrapper/gradle-wrapper.jar
 !**/src/main/**/build/
 !**/src/test/**/build/
+/application-aws.properites
 
 **/*.properties
 
diff --git a/build.gradle b/build.gradle
index df58bc560c9437f75bef5437315933d3395914ea..bac4b34c3222d2e9e57c5108b56ecb52f9fa2736 100644
--- a/build.gradle
+++ b/build.gradle
@@ -31,17 +31,16 @@ dependencies {
     //H2 DB 추가
     runtimeOnly 'com.h2database:h2'
 	compileOnly 'org.projectlombok:lombok'
-//    mySQL
+    //    mySQL
 	runtimeOnly 'com.mysql:mysql-connector-j'
 	annotationProcessor 'org.projectlombok:lombok'
 	testImplementation 'org.springframework.boot:spring-boot-starter-test'
 
-
 	implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
 	implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
 	implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'
-
-
+    // AWS S3
+    implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
 }
 
 tasks.named('test') {
diff --git a/src/main/java/umc/spring/file/config/AwsConfig.java b/src/main/java/umc/spring/file/config/AwsConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a9329850a229048c8bc17054bfaedf0e132550c
--- /dev/null
+++ b/src/main/java/umc/spring/file/config/AwsConfig.java
@@ -0,0 +1,32 @@
+package umc.spring.file.config;
+
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSStaticCredentialsProvider;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.s3.AmazonS3ClientBuilder;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AwsConfig {
+
+    @Value("${cloud.aws.credentials.accessKey}")
+    private String accessKey;
+
+    @Value("${cloud.aws.credentials.secretKey}")
+    private String secretKey;
+
+    @Value("${cloud.aws.region.static}")
+    private String region;
+
+    @Bean
+    public AmazonS3 amazonS3() {
+        AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
+        return AmazonS3ClientBuilder.standard()
+                .withRegion(region)
+                .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
+                .build();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/umc/spring/file/controller/FileController.java b/src/main/java/umc/spring/file/controller/FileController.java
new file mode 100644
index 0000000000000000000000000000000000000000..677c28481dfd829084b2ea51b2d4bd68ea116edc
--- /dev/null
+++ b/src/main/java/umc/spring/file/controller/FileController.java
@@ -0,0 +1,66 @@
+package umc.spring.file.controller;
+
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import umc.spring.file.service.AmazonS3Service;
+import umc.spring.file.service.S3Service;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/api/file")
+public class FileController {
+
+    private final AmazonS3Service amazon3SService;
+
+    @PostMapping("/uploads")
+    public ResponseEntity<Object> uploadFiles(
+            @RequestParam(value = "uploadFilePath") String uploadFilePath,
+            @RequestPart(value = "files") List<MultipartFile> multipartFiles) {
+        return ResponseEntity
+                .status(HttpStatus.OK)
+                .body(amazon3SService.uploadFiles(uploadFilePath, multipartFiles));
+    }
+
+    @DeleteMapping("/delete")
+    public ResponseEntity<Object> deleteFile(
+            @RequestParam(value = "uploadFilePath") String uploadFilePath,
+            @RequestParam(value = "uuidFileName") String uuidFileName) {
+        return ResponseEntity
+                .status(HttpStatus.OK)
+                .body(amazon3SService.deleteFile(uploadFilePath, uuidFileName));
+    }
+
+    @GetMapping("/get")
+    public void getFile(HttpServletResponse response,
+                        @RequestParam String uploadFilePath,
+                        @RequestParam String uuidFileName) {
+        try {
+            InputStream inputStream = amazon3SService.getFile(uploadFilePath, uuidFileName);
+            if (inputStream != null) {
+                byte[] buffer = new byte[4048];
+                int bytesRead;
+                response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
+
+                try (OutputStream outStream = response.getOutputStream()) {
+                    while ((bytesRead = inputStream.read(buffer)) != -1) {
+                        outStream.write(buffer, 0, bytesRead);
+                    }
+                }
+            } else {
+                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+            }
+        } catch (Exception e) {
+            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+        }
+    }
+}
diff --git a/src/main/java/umc/spring/file/domain/S3FileDto.java b/src/main/java/umc/spring/file/domain/S3FileDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..24d16f4f3eec360e28a3753b2d952853e77c2d7d
--- /dev/null
+++ b/src/main/java/umc/spring/file/domain/S3FileDto.java
@@ -0,0 +1,18 @@
+package umc.spring.file.domain;
+
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+@Getter
+@Setter
+@ToString
+@Builder
+public class S3FileDto {
+
+    private String originalFileName;
+    private String uploadFileName;
+    private String uploadFilePath;
+    private String uploadFileUrl;
+}
\ No newline at end of file
diff --git a/src/main/java/umc/spring/file/service/AmazonS3Service.java b/src/main/java/umc/spring/file/service/AmazonS3Service.java
new file mode 100644
index 0000000000000000000000000000000000000000..0118d97888faeb256bb46ed5b35d25dd5b263350
--- /dev/null
+++ b/src/main/java/umc/spring/file/service/AmazonS3Service.java
@@ -0,0 +1,135 @@
+package umc.spring.file.service;
+
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.s3.model.CannedAccessControlList;
+import com.amazonaws.services.s3.model.ObjectMetadata;
+import com.amazonaws.services.s3.model.PutObjectRequest;
+import com.amazonaws.services.s3.model.S3Object;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+import umc.spring.file.domain.S3FileDto;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class AmazonS3Service {
+
+    @Value("${cloud.aws.s3.bucket}")
+    private String bucketName;
+
+    private final AmazonS3 amazonS3;
+
+    /**
+     * S3로 파일 업로드
+     */
+    public List<S3FileDto> uploadFiles(String uploadFilePath, List<MultipartFile> multipartFiles) {
+
+        List<S3FileDto> s3files = new ArrayList<>();
+
+//        String uploadFilePath = fileType + "/" + getFolderName();
+
+        for (MultipartFile multipartFile : multipartFiles) {
+
+            String originalFileName = multipartFile.getOriginalFilename();
+            String uploadFileName = getUuidFileName(originalFileName);
+            String uploadFileUrl = "";
+
+            ObjectMetadata objectMetadata = new ObjectMetadata();
+            objectMetadata.setContentLength(multipartFile.getSize());
+            objectMetadata.setContentType(multipartFile.getContentType());
+
+            try (InputStream inputStream = multipartFile.getInputStream()) {
+
+                String keyName = uploadFilePath + "/" + uploadFileName; // ex) 구분/파일.확장자
+
+                // S3에 폴더 및 파일 업로드
+                // 외부에 공개하는 파일인 경우 Public Read 권한을 추가, ACL 확인
+                amazonS3.putObject(
+                        new PutObjectRequest(bucketName, keyName, inputStream, objectMetadata)
+                                .withCannedAcl(CannedAccessControlList.PublicRead));
+
+
+                // S3에 업로드한 폴더 및 파일 URL
+                uploadFileUrl = amazonS3.getUrl(bucketName, keyName).toString();
+
+            } catch (IOException e) {
+                e.printStackTrace();
+                log.error("Filed upload failed", e);
+            }
+
+            s3files.add(
+                    S3FileDto.builder()
+                            .originalFileName(originalFileName)
+                            .uploadFileName(uploadFileName)
+                            .uploadFilePath(uploadFilePath)
+                            .uploadFileUrl(uploadFileUrl)
+                            .build());
+        }
+
+        return s3files;
+    }
+
+    /**
+     * S3에 업로드된 파일 삭제
+     */
+    public String deleteFile(String uploadFilePath, String uuidFileName) {
+
+        String result = "success";
+
+        try {
+            String keyName = uploadFilePath + "/" + uuidFileName; // ex) 구분/파일.확장자
+            boolean isObjectExist = amazonS3.doesObjectExist(bucketName, keyName);
+            if (isObjectExist) {
+                amazonS3.deleteObject(bucketName, keyName);
+            } else {
+                result = "file not found";
+            }
+        } catch (Exception e) {
+            log.debug("Delete File failed", e);
+        }
+
+        return result;
+    }
+
+    /**
+     * S3에서 파일 읽어오기
+     */
+    public InputStream getFile(String uploadFilePath, String uuidFileName) {
+        String keyName = uploadFilePath + "/" + uuidFileName; // ex) 구분/파일.확장자
+        boolean isObjectExist = amazonS3.doesObjectExist(bucketName, keyName);
+
+        if (isObjectExist) {
+            S3Object s3object = amazonS3.getObject(bucketName, keyName);
+            return s3object.getObjectContent();
+        } else {
+            log.error("File not found");
+            return null;
+        }
+    }
+
+    /**
+     * UUID 파일명 반환
+     */
+    public String getUuidFileName(String fileName) {
+        String ext = fileName.substring(fileName.indexOf(".") + 1);
+        return UUID.randomUUID().toString() + "." + ext;
+    }
+
+    /**
+     * 년/월/일 폴더명 반환
+     */
+    private String getFolderName() {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
+        Date date = new Date();
+        String str = sdf.format(date);
+        return str.replace("-", "/");
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/umc/spring/file/service/S3Service.java b/src/main/java/umc/spring/file/service/S3Service.java
new file mode 100644
index 0000000000000000000000000000000000000000..cce2f50900abfb34664e28e705dcc7040e117fb3
--- /dev/null
+++ b/src/main/java/umc/spring/file/service/S3Service.java
@@ -0,0 +1,76 @@
+package umc.spring.file.service;
+
+import com.amazonaws.AmazonServiceException;
+import com.amazonaws.HttpMethod;
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.s3.model.CannedAccessControlList;
+import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
+import com.amazonaws.services.s3.model.ObjectMetadata;
+import com.amazonaws.services.s3.model.PutObjectRequest;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.Date;
+
+/* S3Service.java */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class S3Service {
+
+    @Value("${cloud.aws.s3.bucket}")
+    private String bucket;
+
+    private final AmazonS3 amazonS3;
+
+    /* 1. 파일 업로드 */
+    public String upload(MultipartFile multipartFile, String s3FileName) throws IOException {
+        // 메타데이터 생성
+        ObjectMetadata objMeta = new ObjectMetadata();
+        objMeta.setContentLength(multipartFile.getInputStream().available());
+        // putObject(버킷명, 파일명, 파일데이터, 메타데이터)로 S3에 객체 등록
+        amazonS3.putObject(new PutObjectRequest(bucket, s3FileName, multipartFile.getInputStream(), objMeta)
+                .withCannedAcl(CannedAccessControlList.PublicRead));
+        // 등록된 객체의 url 반환 (decoder: url 안의 한글 or 특수문자 깨짐 방지)
+        return URLDecoder.decode(amazonS3.getUrl(bucket, s3FileName).toString(), "utf-8");
+    }
+
+    /* 2. 파일 삭제 */
+    public void delete (String keyName) {
+        try {
+            // deleteObject(버킷명, 키값)으로 객체 삭제
+            amazonS3.deleteObject(bucket, keyName);
+        } catch (AmazonServiceException e) {
+            log.error(e.toString());
+        }
+    }
+
+    /* 3. 파일의 presigned URL 반환 */
+    public String getPresignedURL (String keyName) {
+        String preSignedURL = "";
+        // presigned URL이 유효하게 동작할 만료기한 설정 (2분)
+        Date expiration = new Date();
+        Long expTimeMillis = expiration.getTime();
+        expTimeMillis += 1000 * 60 * 2;
+        expiration.setTime(expTimeMillis);
+
+        try {
+            // presigned URL 발급
+            GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucket, keyName)
+                    .withMethod(HttpMethod.GET)
+                    .withExpiration(expiration);
+            URL url = amazonS3.generatePresignedUrl(generatePresignedUrlRequest);
+            preSignedURL = url.toString();
+        } catch (Exception e) {
+            log.error(e.toString());
+        }
+
+        return preSignedURL;
+    }
+}
\ No newline at end of file
diff --git a/src/main/resources/application-aws.properties b/src/main/resources/application-aws.properties
new file mode 100644
index 0000000000000000000000000000000000000000..d9eb924fd0d117367c27d5d29cae9d18e8c6769e
--- /dev/null
+++ b/src/main/resources/application-aws.properties
@@ -0,0 +1,5 @@
+cloud.aws.s3.bucket=anak-s3
+cloud.aws.stack.auto=false
+cloud.aws.region.static=ap-northeast-2
+cloud.aws.credentials.accessKey=AKIAUK4OA4SHAQ4Y76RL
+cloud.aws.credentials.secretKey=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
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
new file mode 100644
index 0000000000000000000000000000000000000000..2a40ba3846f941e37e08a5e9b96d0cf1b55b67fc
--- /dev/null
+++ b/src/main/resources/application.properties
@@ -0,0 +1,28 @@
+#spring.config.activate.on-profile=aws
+spring.profiles.active=aws
+
+# mySql
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+spring.datasource.url=jdbc:mysql://localhost:3306/study?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8&serverTimezone=UTC
+spring.datasource.username=root
+spring.datasource.password=1234
+spring.jpa.properties.hibernate.jdbc.batch_size=100
+
+# jpa
+spring.jpa.database=mysql
+spring.jpa.show-sql=true
+spring.jpa.hibernate.ddl-auto=update
+spring.jpa.properties.hibernate.format_sql=true
+spring.jpa.open-in-view=false
+
+# MULTIPART (MultipartProperties)
+# Enable multipart uploads
+spring.servlet.multipart.enabled=true
+# Threshold after which files are written to disk.
+spring.servlet.multipart.file-size-threshold=2KB
+# Max file size.
+spring.servlet.multipart.max-file-size=200MB
+# Max Request Size
+spring.servlet.multipart.max-request-size=215MB
+
+jwt.secret=secret