배포 정의#9
Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
개요전체 배포 파이프라인이 도입되었습니다. Docker 빌드 자동화, GitHub Actions CI/CD 워크플로우, Kubernetes 배포를 위한 Helm 차트, Terraform 인프라스트럭처 코드(Argo CD, Infisical 연동)가 추가되었습니다. 변경사항
시퀀스 다이어그램sequenceDiagram
actor Dev as 개발자
participant GH as GitHub
participant GHA as GitHub Actions
participant GHCR as GHCR<br/>(이미지 레지스트리)
participant K8s as Kubernetes<br/>클러스터
participant ArgoCD as Argo CD
participant Infisical as Infisical
Dev->>GH: main 브랜치에 푸시
GH->>GHA: deploy 워크플로우 트리거
GHA->>GHA: Dockerfile 빌드<br/>(Bun 기반)
GHA->>GHCR: 이미지 푸시<br/>(ghcr.io/byulmaru/media-api:latest)
ArgoCD->>GH: Helm 차트 변경 감지<br/>(apps/helm)
ArgoCD->>Infisical: 프로젝트/자격증명 조회
Infisical->>ArgoCD: 암호 반환
ArgoCD->>GHCR: 이미지 풀<br/>(최신 버전)
ArgoCD->>K8s: Kubernetes Deployment 적용<br/>(Helm 템플릿 렌더링)
K8s->>GHCR: Pod 이미지 다운로드
K8s->>K8s: 헬스 프로브 실행<br/>(/healthz)
K8s->>K8s: 필요시 HPA 자동 스케일링
검토 예상 시간🎯 4 (복잡) | ⏱️ ~45분 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Show Terraform PlanTerraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# argocd_application.media_api will be created
+ resource "argocd_application" "media_api" {
+ cascade = true
+ id = (known after apply)
+ status = (known after apply)
+ validate = true
+ wait = false
+ metadata {
+ generation = (known after apply)
+ name = "media-api"
+ namespace = "argocd"
+ resource_version = (known after apply)
+ uid = (known after apply)
}
+ spec {
+ project = "byulmaru"
+ revision_history_limit = 10
+ destination {
name = null
+ namespace = "media"
+ server = "https://kubernetes.default.svc"
}
+ source {
+ path = "apps/helm"
+ repo_url = "https://github.com/byulmaru/media.git"
+ target_revision = "main"
+ helm {
+ parameter {
# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
+ parameter {
# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
}
}
+ sync_policy {
+ sync_options = [
+ "CreateNamespace=true",
]
+ automated {
+ prune = true
+ self_heal = true
}
}
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (5)
apps/api/Dockerfile (1)
1-1: 베이스 이미지 버전을 명시적으로 고정하세요.
:latest태그는 가변적(mutable)이므로 재현성과 보안 스캔이 불안정합니다. 프로덕션에서는 버전 태그와 다이제스트를 함께 고정하는 것을 권장합니다:FROM oven/bun:1.3.9@sha256:<digest>또는 최소한 버전 태그 고정:
FROM oven/bun:1.3.9현재 안정 버전은
oven/bun:1.3.9입니다.또한 적용됨: 10-10
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/api/Dockerfile` at line 1, The Dockerfile currently uses a mutable base image tag in the FROM instruction ("FROM oven/bun:latest AS deps"); replace that with a fixed version (preferably with an immutable digest) by changing the FROM line to a pinned image such as oven/bun:1.3.9@sha256:<digest> or at minimum oven/bun:1.3.9 so builds are reproducible and security scans are stable.apps/terraform/main.tf (1)
21-24: Argocd 공급자 설정 확인 필요합니다.provider 블록이 비어 있고, Argocd 공급자는 환경변수(
ARGOCD_SERVER,ARGOCD_AUTH_TOKEN등)를 통해 인증해야 합니다. 현재 CI/CD에서는 Infisical을 통해 secrets를 관리하고 있으나, Infisical의 terraform 프로젝트에서 실제로 Argo CD 관련 시크릿이 정의되어 있고 자동으로 환경변수로 내보내지는지 명시적으로 확인이 필요합니다. var.argocd_cluster_server는 destination용이므로 provider 인증과는 별개입니다.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/terraform/main.tf` around lines 21 - 24, The provider block for the Argocd module is empty and missing authentication configuration; verify and populate the argocd provider (the Terraform provider named "argocd") to use environment variables ARGOCD_SERVER and ARGOCD_AUTH_TOKEN (or explicit provider attributes) and ensure your CI/Infisical setup actually exports those secrets as environment variables for Terraform. Confirm that var.argocd_cluster_server remains only the destination cluster address (not the provider auth) and, if Infisical is responsible, update the Infisical terraform project to declare and export the ARGOCD_* secrets to the Terraform runtime or switch to passing credentials via provider configuration in the argocd provider block. Ensure the provider block and secret export are present before applying so auth is available to the argocd provider.apps/terraform/variables.tf (1)
6-9:infisical_machine_identity_id변수 설명 추가 권장다른 변수들과 문서화 수준을 맞추기 위해 설명을 추가하는 편이 좋습니다.
♻️ 제안 변경
variable "infisical_machine_identity_id" { type = string sensitive = true + description = "Infisical 머신 아이덴티티 ID" }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/terraform/variables.tf` around lines 6 - 9, 변수 선언 variable "infisical_machine_identity_id"에 설명(description) 속성을 추가해 다른 변수들과 문서화 수준을 맞추세요; variable "infisical_machine_identity_id" 블록에 description = "..." 형태로 간단한 용도(예: Infisical에서 발급된 머신 아이덴티티 ID, 민감 정보)와 민감(sensitive = true)임을 명시하는 설명을 추가하면 됩니다.apps/terraform/argocd.tf (1)
10-14:target_revision고정값은 배포 재현성 저하
main브랜치 고정은 릴리스 재현성을 떨어뜨립니다. Argo CD 모범 사례에 따르면 배포 재현성을 위해 커밋 SHA를 고정하거나 릴리스 태그를 사용하는 것을 권장합니다. 변수화하여 환경별로 다른 값을 사용하는 방식도 좋은 선택입니다.♻️ 제안 변경
- target_revision = "main" + target_revision = var.argocd_target_revision🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/terraform/argocd.tf` around lines 10 - 14, The hardcoded target_revision = "main" in the source block reduces deployment reproducibility; change target_revision to use a variable (e.g., var.target_revision) and set its default or per-environment value to a specific commit SHA or release tag instead of "main", update any module/terraform variable definitions to include target_revision and document/override it per environment so Argo CD uses an immutable revision (reference the source { repo_url, path, target_revision } and the target_revision variable).apps/helm/templates/infisicalsecret.yaml (1)
10-18: 환경별 배포를 위해 하드코딩된 구성값 외부화 필요
envSlug: prod,secretsPath: /,serviceAccountRef의 name과 namespace가 고정되어 있어 다양한 환경 배포가 제한됩니다. 특히envSlug은 values.yaml에 정의되어 있음에도 템플릿에서 사용되지 않고 있습니다. 다음과 같이 모든 값을 외부화해 주세요:♻️ 제안 변경
kubernetesAuth: identityId: {{ .Values.infisical.identityId }} autoCreateServiceAccountToken: true serviceAccountRef: - name: secret - namespace: infisical + name: {{ .Values.infisical.serviceAccount.name }} + namespace: {{ .Values.infisical.serviceAccount.namespace }} secretsScope: projectId: {{ .Values.infisical.projectId }} - envSlug: prod - secretsPath: / + envSlug: {{ .Values.infisical.envSlug | default "prod" }} + secretsPath: {{ .Values.infisical.secretsPath | default "/" }}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/helm/templates/infisicalsecret.yaml` around lines 10 - 18, The template hardcodes envSlug, secretsPath and the serviceAccountRef name/namespace which prevents multi-environment deployments; update the template to use values from .Values.infisical (e.g., .Values.infisical.envSlug, .Values.infisical.secretsPath, and .Values.infisical.serviceAccountRef.name/.namespace) instead of literals, and provide sensible defaults in values.yaml for these keys so deployments can override per-environment.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/helm/templates/deployment.yaml`:
- Around line 19-43: Add a container-level securityContext under the container
definition for the container named {{ .Chart.Name }}: set runAsNonRoot: true,
allowPrivilegeEscalation: false, readOnlyRootFilesystem: true, and capabilities
with drop: [ALL]; place this block directly inside the same container spec that
contains image/ports/envFrom/livenessProbe/readinessProbe so the Pod follows the
Kubernetes "restricted" PSS.
---
Nitpick comments:
In `@apps/api/Dockerfile`:
- Line 1: The Dockerfile currently uses a mutable base image tag in the FROM
instruction ("FROM oven/bun:latest AS deps"); replace that with a fixed version
(preferably with an immutable digest) by changing the FROM line to a pinned
image such as oven/bun:1.3.9@sha256:<digest> or at minimum oven/bun:1.3.9 so
builds are reproducible and security scans are stable.
In `@apps/helm/templates/infisicalsecret.yaml`:
- Around line 10-18: The template hardcodes envSlug, secretsPath and the
serviceAccountRef name/namespace which prevents multi-environment deployments;
update the template to use values from .Values.infisical (e.g.,
.Values.infisical.envSlug, .Values.infisical.secretsPath, and
.Values.infisical.serviceAccountRef.name/.namespace) instead of literals, and
provide sensible defaults in values.yaml for these keys so deployments can
override per-environment.
In `@apps/terraform/argocd.tf`:
- Around line 10-14: The hardcoded target_revision = "main" in the source block
reduces deployment reproducibility; change target_revision to use a variable
(e.g., var.target_revision) and set its default or per-environment value to a
specific commit SHA or release tag instead of "main", update any
module/terraform variable definitions to include target_revision and
document/override it per environment so Argo CD uses an immutable revision
(reference the source { repo_url, path, target_revision } and the
target_revision variable).
In `@apps/terraform/main.tf`:
- Around line 21-24: The provider block for the Argocd module is empty and
missing authentication configuration; verify and populate the argocd provider
(the Terraform provider named "argocd") to use environment variables
ARGOCD_SERVER and ARGOCD_AUTH_TOKEN (or explicit provider attributes) and ensure
your CI/Infisical setup actually exports those secrets as environment variables
for Terraform. Confirm that var.argocd_cluster_server remains only the
destination cluster address (not the provider auth) and, if Infisical is
responsible, update the Infisical terraform project to declare and export the
ARGOCD_* secrets to the Terraform runtime or switch to passing credentials via
provider configuration in the argocd provider block. Ensure the provider block
and secret export are present before applying so auth is available to the argocd
provider.
In `@apps/terraform/variables.tf`:
- Around line 6-9: 변수 선언 variable "infisical_machine_identity_id"에
설명(description) 속성을 추가해 다른 변수들과 문서화 수준을 맞추세요; variable
"infisical_machine_identity_id" 블록에 description = "..." 형태로 간단한 용도(예:
Infisical에서 발급된 머신 아이덴티티 ID, 민감 정보)와 민감(sensitive = true)임을 명시하는 설명을 추가하면 됩니다.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
.dockerignore.github/workflows/deploy.yamlapps/api/Dockerfileapps/api/src/index.tsapps/helm/Chart.yamlapps/helm/templates/_helpers.tplapps/helm/templates/deployment.yamlapps/helm/templates/hpa.yamlapps/helm/templates/infisicalsecret.yamlapps/helm/templates/service.yamlapps/helm/values.yamlapps/terraform/argocd.tfapps/terraform/cloudflare.tfapps/terraform/infisical.tfapps/terraform/main.tfapps/terraform/variables.tf
💤 Files with no reviewable changes (1)
- apps/terraform/cloudflare.tf
Show Terraform PlanTerraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# argocd_application.media_api will be created
+ resource "argocd_application" "media_api" {
+ cascade = true
+ id = (known after apply)
+ status = (known after apply)
+ validate = true
+ wait = false
+ metadata {
+ generation = (known after apply)
+ name = "media-api"
+ namespace = "argocd"
+ resource_version = (known after apply)
+ uid = (known after apply)
}
+ spec {
+ project = "byulmaru"
+ revision_history_limit = 10
+ destination {
name = null
+ namespace = "media"
+ server = "https://kubernetes.default.svc"
}
+ source {
+ path = "apps/helm"
+ repo_url = "https://github.com/byulmaru/media.git"
+ target_revision = "main"
+ helm {
+ parameter {
# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
+ parameter {
# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
}
}
+ sync_policy {
+ sync_options = [
+ "CreateNamespace=true",
]
+ automated {
+ prune = true
+ self_heal = true
}
}
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
|
| @@ -0,0 +1,25 @@ | |||
| FROM oven/bun:latest AS deps | |||
There was a problem hiding this comment.
WARNING: latest 태그 사용으로 인한 재현 불가능한 빌드
oven/bun:latest를 사용하면 빌드 시점마다 다른 버전의 Bun이 설치될 수 있어 재현 가능한 빌드가 보장되지 않습니다. 특정 버전을 고정하는 것을 권장합니다.
| FROM oven/bun:latest AS deps | |
| FROM oven/bun:1 AS deps |
|
|
||
| RUN bun install --frozen-lockfile --production | ||
|
|
||
| FROM oven/bun:latest |
There was a problem hiding this comment.
WARNING: 런타임 스테이지도 동일하게 고정 버전을 사용해야 합니다.
| FROM oven/bun:latest | |
| FROM oven/bun:1 |
| context: . | ||
| file: apps/api/Dockerfile | ||
| push: true | ||
| tags: ghcr.io/byulmaru/media-api:latest |
There was a problem hiding this comment.
WARNING: latest 태그만 사용하면 롤백이 불가능합니다
latest 태그만 push하면 이전 버전으로 롤백할 수 없습니다. Git SHA나 버전 태그를 함께 push하는 것을 권장합니다.
| tags: ghcr.io/byulmaru/media-api:latest | |
| tags: ghcr.io/byulmaru/media-api:latest,ghcr.io/byulmaru/media-api:${{ github.sha }} |
|
|
||
| image: | ||
| repository: ghcr.io/byulmaru/media-api | ||
| tag: latest |
There was a problem hiding this comment.
WARNING: 프로덕션 환경에서 latest 이미지 태그 사용
tag: latest는 배포 시점마다 다른 이미지가 실행될 수 있어 예측 불가능한 동작을 유발할 수 있습니다. ArgoCD를 통한 배포 시 Terraform의 helm parameter로 image.tag를 명시적으로 주입하거나, Image Updater를 사용하는 것을 권장합니다.
| labels: | ||
| {{- include "media-api.selectorLabels" . | nindent 8 }} | ||
| spec: | ||
| containers: |
There was a problem hiding this comment.
WARNING: GHCR private 이미지 접근을 위한 imagePullSecrets 누락
ghcr.io/byulmaru/media-api 이미지가 private 레지스트리에 있는 경우, imagePullSecrets가 없으면 Kubernetes가 이미지를 pull할 수 없어 ImagePullBackOff 오류가 발생합니다. GHCR 인증을 위한 Secret을 생성하고 imagePullSecrets를 추가하세요.
| } | ||
| } | ||
|
|
||
| provider "argocd" {} |
There was a problem hiding this comment.
WARNING: provider "argocd" {} 설정이 비어 있습니다
ArgoCD provider에 서버 주소, 인증 정보 등이 설정되지 않았습니다. 환경 변수(ARGOCD_SERVER, ARGOCD_AUTH_TOKEN 등)로 설정하는 경우라면 주석으로 명시하는 것이 좋습니다. 설정이 누락되면 terraform apply 시 ArgoCD 서버에 연결할 수 없습니다.
Code Review SummaryStatus: 6 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Other Observations (not in diff)추가 관찰 사항
Files Reviewed (9 files)
|
Summary by CodeRabbit
릴리스 노트
새로운 기능
기타