Skip to content

Commit 1b46118

Browse files
authored
[DEPLOY] 파트 정보 업데이트, 솝탬프 캐싱 리팩토링 배포 (#700)
2 parents 04b9ac6 + a5d245a commit 1b46118

File tree

55 files changed

+4184
-1922
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+4184
-1922
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,10 @@
88

99
<!-- 작업 내용을 간단히 소개주세요 -->
1010

11-
## Trouble Shooting ⚽️
12-
13-
<!-- 어떤 위험이나 장애를 발견했는지 적어주세요 -->
14-
1511
## Related ScreenShot 📷
1612

1713
<!-- 관련 스크린샷을 첨부해주세요 -->
1814

19-
## Uncompleted Tasks 😅
20-
21-
<!-- 끝내지 못한 작업을 적어주세요 -->
22-
2315
## To Reviewers 📢
2416

25-
<!-- 리뷰어들에게 물어볼 점, 할 말 등을 적어주세요 -->
17+
<!-- 리뷰어들에게 물어볼 점, 할 말 등을 적어주세요 -->

.github/workflows/app-cd-dev.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: ⚙️ MAKERS-DEV-APP-DEPLOY
22

33
on:
44
push:
5-
branches: [ dev ]
5+
# branches: [ dev ]
66

77
env:
88
SPRING_PROFILES_ACTIVE: dev
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
name: Deploy Lambda to Dev
2+
3+
on:
4+
workflow_dispatch: # 수동 실행
5+
push:
6+
branches:
7+
- dev # dev 브랜치 푸시 시 자동 실행
8+
9+
jobs:
10+
deploy:
11+
name: Deploy Lambda Dev
12+
runs-on: ubuntu-latest
13+
14+
env:
15+
S3_BUCKET: sopt-makers-app
16+
STACK_NAME: app-dev
17+
AWS_REGION: ap-northeast-2
18+
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v3
22+
23+
- name: Set up JDK 21
24+
uses: actions/setup-java@v3
25+
with:
26+
distribution: 'corretto'
27+
java-version: '21'
28+
29+
- name: Configure AWS credentials
30+
uses: aws-actions/configure-aws-credentials@v2
31+
with:
32+
aws-access-key-id: ${{ secrets.AWS_ACCESS_ID }}
33+
aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}
34+
aws-region: ${{ env.AWS_REGION }}
35+
36+
- name: copy application.yml files
37+
run: |
38+
mkdir -p ./src/main/resources
39+
mkdir -p ./src/test/resources
40+
echo "${{ secrets.APPLICATION_DEV_YML }}" > ./src/main/resources/application-dev.yml
41+
echo "${{ secrets.APPLICATION_LAMBDA_YML }}" > ./src/main/resources/application-lambda.yml
42+
echo "${{ secrets.APPLICATION_TEST_YML }}" > ./src/test/resources/application-test.yml
43+
44+
- name: Grant execute permission for gradlew
45+
run: chmod +x gradlew
46+
47+
- name: Build Lambda JAR
48+
run: ./gradlew clean jar lambdaJar -x test
49+
50+
- name: Upload JAR to S3
51+
id: upload
52+
run: |
53+
# 빌드된 ZIP 파일 찾기
54+
JAR_FILE=$(ls build/distributions/*-lambda.zip | head -1)
55+
if [ -z "$JAR_FILE" ]; then
56+
echo "Error: Lambda ZIP file not found"
57+
exit 1
58+
fi
59+
60+
# 타임스탬프 생성
61+
TIMESTAMP=$(date +"%Y%m%d-%H%M%S")
62+
S3_KEY="lambda/${{ env.STACK_NAME }}-${TIMESTAMP}.zip"
63+
64+
# S3 업로드
65+
aws s3 cp "$JAR_FILE" "s3://${{ env.S3_BUCKET }}/$S3_KEY"
66+
67+
echo "S3_KEY=$S3_KEY" >> $GITHUB_ENV
68+
echo "s3_key=$S3_KEY" >> $GITHUB_OUTPUT
69+
70+
- name: Install SAM CLI
71+
uses: aws-actions/setup-sam@v2
72+
73+
- name: Deploy with SAM
74+
working-directory: ./lambda
75+
run: |
76+
sam deploy \
77+
--config-env dev \
78+
--stack-name ${{ env.STACK_NAME }} \
79+
--no-fail-on-empty-changeset \
80+
--parameter-overrides \
81+
S3Bucket=${{ env.S3_BUCKET }} \
82+
S3Key=${{ env.S3_KEY }} \
83+
Profile="dev,lambda"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: Review Assign
2+
3+
on:
4+
pull_request:
5+
types: [opened, ready_for_review]
6+
7+
permissions:
8+
pull-requests: write # [중요] PR에 리뷰어를 추가할 수 있는 권한 부여
9+
10+
jobs:
11+
assign:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: hkusu/review-assign-action@v1
15+
with:
16+
assignees: ${{ github.actor }}
17+
reviewers: jher235, kyoooooong

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ application-local.yml
4444
application-prod.yml
4545
application-dev.yml
4646
application-test.yml
47+
application-lambda.yml
4748
docker-compose.yml
4849

4950
### HTTP 관련

build.gradle

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ dependencies {
9090
// jwt
9191
implementation 'com.nimbusds:nimbus-jose-jwt:9.37.3'
9292
implementation 'com.github.ben-manes.caffeine:caffeine:3.1.8'
93-
implementation 'org.springframework.boot:spring-boot-starter-webflux'
9493

9594
// test
9695
testImplementation 'org.springframework.boot:spring-boot-starter-test'
@@ -104,6 +103,11 @@ dependencies {
104103
// slack
105104
implementation 'com.slack.api:slack-api-client:1.30.0'
106105

106+
// AWS Lambda Dependencies for JAR deployment
107+
implementation 'com.amazonaws.serverless:aws-serverless-java-container-springboot3:2.1.5'
108+
implementation 'com.amazonaws:aws-lambda-java-core:1.4.0'
109+
implementation 'com.amazonaws:aws-lambda-java-events:3.16.1'
110+
107111
}
108112
tasks.named('test') {
109113
useJUnitPlatform()
@@ -118,4 +122,43 @@ dependencyManagement {
118122
mavenBom "org.springframework.cloud:spring-cloud-dependencies:$springCloudVersion"
119123
mavenBom "software.amazon.awssdk:bom:2.20.0"
120124
}
121-
}
125+
}
126+
127+
// Lambda ZIP 빌드 설정
128+
task lambdaJar(type: Zip) {
129+
dependsOn jar, bootJar
130+
131+
archiveClassifier = 'lambda'
132+
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
133+
zip64 = true
134+
135+
// 최상단 클래스 (jar 방식에서는 생략해도 무방하지만 기존 구조 유지를 위해 남겨둠)
136+
into('/') {
137+
from sourceSets.main.output
138+
}
139+
140+
into('lib') {
141+
from(jar)
142+
from(configurations.runtimeClasspath) {
143+
exclude "tomcat-embed-*"
144+
exclude "META-INF/*.SF"
145+
exclude "META-INF/*.DSA"
146+
exclude "META-INF/*.RSA"
147+
exclude "META-INF/MANIFEST.MF"
148+
exclude "**/module-info.class"
149+
}
150+
}
151+
}
152+
153+
// Lambda 빌드를 기본 빌드에 포함
154+
build.dependsOn lambdaJar
155+
156+
// JAR 설정
157+
jar {
158+
enabled = true
159+
archiveClassifier = 'plain'
160+
}
161+
162+
bootJar {
163+
enabled = true
164+
}

lambda/lambda-deploy-test.sh

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/bin/bash
2+
3+
# 간단한 Lambda JAR 배포 스크립트
4+
set -e # 에러 발생시 중단
5+
6+
# 설정
7+
ENV=${1:-dev}
8+
S3_BUCKET="sopt-makers-app"
9+
STACK_NAME="app-${ENV}"
10+
AWS_REGION="ap-northeast-2"
11+
TARGET_PROFILE="${ENV},lambda"
12+
13+
# 색상 정의
14+
GREEN='\033[0;32m'
15+
NC='\033[0m' # No Color
16+
17+
echo "🚀 Lambda JAR 배포 시작 (환경: $ENV)"
18+
19+
# 0. S3에서 yml 파일 가져오기
20+
#echo "📥 S3에서 설정 파일 다운로드 중..."
21+
#aws s3 cp s3://${S3_BUCKET}/dev/deploy/application-lambda-dev.yml src/main/resources/application-lambda-dev.yml
22+
23+
# 1. JAR 빌드
24+
echo "📦 JAR 빌드 중..."
25+
./gradlew clean lambdaJar -x test
26+
27+
# 2. S3 업로드
28+
JAR_FILE=$(ls build/distributions/*-lambda.zip | head -1)
29+
TIMESTAMP=$(date +"%Y%m%d-%H%M%S")
30+
S3_KEY="lambda/${STACK_NAME}-${TIMESTAMP}-lambda.zip"
31+
32+
echo "☁️ S3 업로드 중..."
33+
echo " 파일: $JAR_FILE"
34+
echo " S3 경로: s3://${S3_BUCKET}/${S3_KEY}"
35+
aws s3 cp "$JAR_FILE" "s3://${S3_BUCKET}/${S3_KEY}"
36+
37+
# 3. SAM으로 배포
38+
echo "🔄 SAM 배포 중..."
39+
cd lambda
40+
41+
sam deploy \
42+
--config-env ${ENV} \
43+
--stack-name ${STACK_NAME} \
44+
--no-fail-on-empty-changeset \
45+
--parameter-overrides \
46+
"S3Bucket=${S3_BUCKET} S3Key=${S3_KEY} Profile=${TARGET_PROFILE}"
47+
48+
cd ..
49+
50+
echo -e "${GREEN}✅ 배포 완료!${NC}"
51+
52+
# API 엔드포인트 출력
53+
API_ENDPOINT=$(aws cloudformation describe-stacks \
54+
--stack-name ${STACK_NAME} \
55+
--query "Stacks[0].Outputs[?OutputKey=='ApiEndpoint'].OutputValue" \
56+
--output text \
57+
--region ${AWS_REGION})
58+
59+
echo -e "${GREEN}🌐 API Endpoint: ${API_ENDPOINT}${NC}"

lambda/samconfig.toml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
version = 0.1
2+
3+
[default.build.parameters]
4+
cached = true
5+
parallel = true
6+
7+
[dev.deploy.parameters]
8+
stack_name = "app-dev"
9+
region = "ap-northeast-2"
10+
capabilities = "CAPABILITY_IAM"
11+
confirm_changeset = false
12+
template = "template-dev.yaml"
13+
resolve_s3 = true
14+
15+
[prod.deploy.parameters]
16+
stack_name = "app-prod"
17+
region = "ap-northeast-2"
18+
capabilities = "CAPABILITY_IAM"
19+
confirm_changeset = true # 운영은 변경사항 확인
20+
template = "template-prod.yaml"
21+
resolve_s3 = true

lambda/template-dev.yaml

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
AWSTemplateFormatVersion: "2010-09-09"
2+
Transform: AWS::Serverless-2016-10-31
3+
Description: >
4+
Sopt makers App Backend DEV - Spring Boot JAR on AWS Lambda with SnapStart
5+
6+
Globals:
7+
Function:
8+
Timeout: 300 # 최대 실행 시간 (초)
9+
MemorySize: 3072 # 메모리 (MB) - 프로젝트 크기에 따라 조정
10+
Runtime: java21 # Java 버전
11+
12+
Parameters:
13+
S3Bucket:
14+
Type: String
15+
Default: ""
16+
Description: S3 bucket containing the Lambda JAR
17+
S3Key:
18+
Type: String
19+
Default: ""
20+
Description: S3 key (path) to the Lambda JAR file
21+
Profile:
22+
Type: String
23+
Default: "lambda,dev"
24+
Description: Spring profile to use
25+
26+
27+
Resources:
28+
ApiFunction:
29+
Type: AWS::Serverless::Function
30+
Properties:
31+
FunctionName: !Sub "${AWS::StackName}-api"
32+
CodeUri:
33+
Bucket: !Ref S3Bucket
34+
Key: !Ref S3Key
35+
Handler: org.sopt.app.LambdaHandler
36+
SnapStart:
37+
ApplyOn: PublishedVersions # SnapStart 활성화
38+
AutoPublishAlias: live
39+
Environment:
40+
Variables:
41+
SPRING_PROFILES_ACTIVE: !Ref Profile
42+
TZ: Asia/Seoul
43+
JAVA_TOOL_OPTIONS: "-XX:+TieredCompilation -XX:TieredStopAtLevel=1"
44+
Policies:
45+
- AWSLambdaBasicExecutionRole
46+
- Statement:
47+
- Effect: Allow
48+
Action:
49+
- s3:GetObject
50+
Resource: !Sub "arn:aws:s3:::${S3Bucket}/*"
51+
Events:
52+
ApiProxy:
53+
Type: Api
54+
Properties:
55+
RestApiId: !Ref ApiGateway
56+
Path: /{proxy+}
57+
Method: ANY
58+
ApiRoot:
59+
Type: Api
60+
Properties:
61+
RestApiId: !Ref ApiGateway
62+
Path: /
63+
Method: ANY
64+
65+
ApiGateway:
66+
Type: AWS::Serverless::Api
67+
Properties:
68+
StageName: dev
69+
EndpointConfiguration: REGIONAL
70+
Cors:
71+
AllowOrigin: "'*'"
72+
AllowHeaders: "'*'"
73+
AllowMethods: "'*'"
74+
AllowCredentials: "'false'"
75+
76+
Outputs:
77+
ApiEndpoint:
78+
Description: "API Gateway endpoint URL"
79+
Value: !Sub "[https://${ApiGateway}.execute-api.${AWS::Region}.amazonaws.com/dev](https://${ApiGateway}.execute-api.${AWS::Region}.amazonaws.com/dev)"

src/main/java/org/sopt/app/AppApplication.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
package org.sopt.app;
22

33
import jakarta.annotation.PostConstruct;
4+
import java.util.TimeZone;
45
import org.sopt.app.common.external.auth.AuthClientProperty;
56
import org.springframework.boot.SpringApplication;
67
import org.springframework.boot.autoconfigure.SpringBootApplication;
78
import org.springframework.boot.context.properties.EnableConfigurationProperties;
89
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
910
import org.springframework.scheduling.annotation.EnableAsync;
1011

11-
import java.util.TimeZone;
12-
import org.springframework.scheduling.annotation.EnableScheduling;
13-
1412
@EnableJpaAuditing // JPA Auditing(감시, 감사) 기능을 활성화 하는 어노테이션 createdDate, modifiedDate 저장 활성화
1513
@EnableAsync
16-
@EnableScheduling
1714
@SpringBootApplication
1815
@EnableConfigurationProperties(AuthClientProperty.class)
1916
public class AppApplication {

0 commit comments

Comments
 (0)