Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 1 addition & 35 deletions IaC/2-v2/aws/environments/dev/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -174,42 +174,8 @@ module "compute" {
user_data = templatefile("${path.module}/scripts/startup-ai-server.sh", {
region = var.region
environment = var.environment
project_name = var.project_name
ecr_registry = "${data.aws_caller_identity.current.account_id}.dkr.ecr.${var.region}.amazonaws.com"
compose_content = templatefile("../../gcp/docker-compose/ai-server.yml", {
AI_SERVER_IMAGE = "${data.aws_caller_identity.current.account_id}.dkr.ecr.${var.region}.amazonaws.com/dev-dojangkok-ai:latest"
APP_ENV = var.environment
VLLM_BASE_URL = var.ai_vllm_base_url
VLLM_MODEL = var.ai_vllm_model
VLLM_LORA_ADAPTER_CHECKLIST = var.ai_vllm_lora_adapter_checklist
VLLM_LORA_ADAPTER_EASYCONTRACT = var.ai_vllm_lora_adapter_easycontract
CHROMADB_URL = ""
BACKEND_CALLBACK_BASE_URL = var.ai_backend_callback_base_url
HTTP_TIMEOUT_SEC = var.ai_http_timeout_sec
RABBITMQ_ENABLED = "true"
RABBITMQ_PREFETCH_COUNT = "3"
RABBITMQ_DECLARE_PASSIVE = "true"
RABBITMQ_REQUEST_EXCHANGE_EASY_CONTRACT = var.rabbitmq_request_exchange_easy_contract
RABBITMQ_REQUEST_QUEUE_EASY_CONTRACT = var.rabbitmq_request_queue_easy_contract
RABBITMQ_REQUEST_ROUTING_KEY_EASY_CONTRACT = var.rabbitmq_request_routing_key_easy_contract
RABBITMQ_REQUEST_EXCHANGE_CHECKLIST = var.rabbitmq_request_exchange_checklist
RABBITMQ_REQUEST_QUEUE_CHECKLIST = var.rabbitmq_request_queue_checklist
RABBITMQ_REQUEST_ROUTING_KEY_CHECKLIST = var.rabbitmq_request_routing_key_checklist
RABBITMQ_CANCEL_EXCHANGE_EASY_CONTRACT = var.rabbitmq_cancel_exchange_easy_contract
RABBITMQ_CANCEL_QUEUE_EASY_CONTRACT = var.rabbitmq_cancel_queue_easy_contract
RABBITMQ_CANCEL_ROUTING_KEY_EASY_CONTRACT = var.rabbitmq_cancel_routing_key_easy_contract
RABBITMQ_RESULT_EXCHANGE = var.rabbitmq_result_exchange
RABBITMQ_RESULT_QUEUE = var.rabbitmq_result_queue
RABBITMQ_RESULT_ROUTING_KEY = var.rabbitmq_result_routing_key
})
alloy_config = templatefile("../../gcp/docker-compose/alloy/config.alloy", {
hostname = "${var.project_name}-ai"
service_name = "ai-server"
loki_url = var.loki_url
tempo_endpoint = var.tempo_endpoint
prometheus_url = var.prometheus_url
enable_dcgm_exporter = false
})
s3_bucket = var.alloy_config_s3_bucket
})
}
}
Expand Down
28 changes: 12 additions & 16 deletions IaC/2-v2/aws/environments/dev/scripts/startup-ai-server.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,32 @@
set -euo pipefail

REGION="${region}"
ENVIRONMENT="${environment}"
ECR_REGISTRY="${ecr_registry}"
S3_BUCKET="${s3_bucket}"

# --- 1. SSM Parameter Store → .env ---
# --- 1. SSM Parameter Store → .env (시크릿) ---
mkdir -p /opt/app

cat > /opt/app/.env << EOF
VLLM_API_KEY=$(aws ssm get-parameter --name "/dojangkok/${environment}/ai/vllm-api-key" --with-decryption --query "Parameter.Value" --output text --region $REGION)
BACKEND_INTERNAL_TOKEN=$(aws ssm get-parameter --name "/dojangkok/${environment}/ai/backend-internal-token" --with-decryption --query "Parameter.Value" --output text --region $REGION)
OCR_API=$(aws ssm get-parameter --name "/dojangkok/${environment}/ai/ocr-api" --with-decryption --query "Parameter.Value" --output text --region $REGION)
RABBITMQ_URL=$(aws ssm get-parameter --name "/dojangkok/${environment}/ai/rabbitmq-url" --with-decryption --query "Parameter.Value" --output text --region $REGION)
VLLM_API_KEY=$(aws ssm get-parameter --name "/dojangkok/$ENVIRONMENT/ai/vllm-api-key" --with-decryption --query "Parameter.Value" --output text --region $REGION)
BACKEND_INTERNAL_TOKEN=$(aws ssm get-parameter --name "/dojangkok/$ENVIRONMENT/ai/backend-internal-token" --with-decryption --query "Parameter.Value" --output text --region $REGION)
OCR_API=$(aws ssm get-parameter --name "/dojangkok/$ENVIRONMENT/ai/ocr-api" --with-decryption --query "Parameter.Value" --output text --region $REGION)
RABBITMQ_URL=$(aws ssm get-parameter --name "/dojangkok/$ENVIRONMENT/ai/rabbitmq-url" --with-decryption --query "Parameter.Value" --output text --region $REGION)
EOF
chmod 600 /opt/app/.env

# --- 2. Alloy monitoring config ---
cat > /opt/app/config.alloy << 'ALLOY'
${alloy_config}
ALLOY
# --- 2. S3 → docker-compose.yml + config.alloy (비민감 설정) ---
aws s3 cp "s3://$S3_BUCKET/ai/$ENVIRONMENT/docker-compose.yml" /opt/app/docker-compose.yml --region "$REGION"
aws s3 cp "s3://$S3_BUCKET/ai/$ENVIRONMENT/config.alloy" /opt/app/config.alloy --region "$REGION"

# --- 3. App log directory ---
mkdir -p /var/log/dojangkok

# --- 4. Docker Compose ---
cat > /opt/app/docker-compose.yml << 'COMPOSE'
${compose_content}
COMPOSE

# --- 5. Stop host Alloy (Packer AMI default) to avoid port conflict with container ---
# --- 4. Stop host Alloy (Packer AMI default) to avoid port conflict with container ---
systemctl stop alloy 2>/dev/null || true
systemctl disable alloy 2>/dev/null || true

# --- 6. ECR Login + Start ---
# --- 5. ECR Login + Start ---
aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin $ECR_REGISTRY
cd /opt/app && docker compose up -d
61 changes: 0 additions & 61 deletions IaC/2-v2/aws/environments/dev/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -190,67 +190,6 @@ variable "ai_http_timeout_sec" {
default = "180"
}

# RabbitMQ (same as GCP defaults)
variable "rabbitmq_request_exchange_easy_contract" {
type = string
default = "fast.exchange"
}

variable "rabbitmq_request_queue_easy_contract" {
type = string
default = "easy-contract.request"
}

variable "rabbitmq_request_routing_key_easy_contract" {
type = string
default = "easy-contract.request"
}

variable "rabbitmq_request_exchange_checklist" {
type = string
default = "fast.exchange"
}

variable "rabbitmq_request_queue_checklist" {
type = string
default = "checklist.request"
}

variable "rabbitmq_request_routing_key_checklist" {
type = string
default = "checklist.request"
}

variable "rabbitmq_cancel_exchange_easy_contract" {
type = string
default = "fast.exchange"
}

variable "rabbitmq_cancel_queue_easy_contract" {
type = string
default = "cancel.request"
}

variable "rabbitmq_cancel_routing_key_easy_contract" {
type = string
default = "cancel.request"
}

variable "rabbitmq_result_exchange" {
type = string
default = "fast.exchange"
}

variable "rabbitmq_result_queue" {
type = string
default = "ai.response"
}

variable "rabbitmq_result_routing_key" {
type = string
default = "ai.response"
}

# Monitoring
variable "loki_url" {
type = string
Expand Down
2 changes: 2 additions & 0 deletions IaC/3-v3/ansible/playbooks/site.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@
- calico
- ebs-csi
- gateway-fabric
- external-secrets
- argocd
70 changes: 70 additions & 0 deletions IaC/3-v3/ansible/roles/argocd/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# ============================================================
# V3 K8S Ansible — ArgoCD 설치
# Branch: main
# values.yaml: k8s/infra/argocd/values.yaml 과 동일한 설정
# ============================================================

- name: Add ArgoCD Helm repository
command: >
helm --kubeconfig=/home/ubuntu/.kube/config
repo add argo https://argoproj.github.io/argo-helm
register: repo_add
changed_when: "'has been added' in repo_add.stdout"
failed_when: false

- name: Update Helm repositories
command: >
helm --kubeconfig=/home/ubuntu/.kube/config repo update
changed_when: false

- name: Install ArgoCD
command: >
helm --kubeconfig=/home/ubuntu/.kube/config
upgrade --install argocd argo/argo-cd
--namespace argocd --create-namespace
--set server.service.type=ClusterIP
--set dex.enabled=false
--set notifications.enabled=false
--set applicationSet.enabled=false
--set server.resources.requests.cpu=50m
--set server.resources.requests.memory=128Mi
--set controller.resources.requests.cpu=100m
--set controller.resources.requests.memory=128Mi
--set repoServer.resources.requests.cpu=50m
--set repoServer.resources.requests.memory=128Mi
register: argocd_install
changed_when: "'deployed' in argocd_install.stdout or 'upgraded' in argocd_install.stdout"

- name: Wait for ArgoCD server to be ready
command: >
kubectl --kubeconfig=/home/ubuntu/.kube/config
rollout status deployment/argocd-server
-n argocd --timeout=120s
changed_when: false

- name: Apply ArgoCD Application (apps-dev)
shell: |
cat <<'EOF' | kubectl --kubeconfig=/home/ubuntu/.kube/config apply -f -
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: dojangkok-apps-dev
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/100-hours-a-week/14-team-dojangkok-cloud.git
targetRevision: main
path: k8s/apps/overlays/dev
destination:
server: https://kubernetes.default.svc
namespace: dojangkok
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
EOF
register: app_apply
changed_when: "'configured' in app_apply.stdout or 'created' in app_apply.stdout"
56 changes: 56 additions & 0 deletions IaC/3-v3/ansible/roles/external-secrets/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# ============================================================
# V3 K8S Ansible — External Secrets Operator 설치
# Branch: feat/v3-k8s-iac
# values.yaml: k8s/infra/external-secrets/values.yaml 과 동일한 설정
# ============================================================

- name: Add External Secrets Helm repository
command: >
helm --kubeconfig=/home/ubuntu/.kube/config
repo add external-secrets https://charts.external-secrets.io
register: repo_add
changed_when: "'has been added' in repo_add.stdout"
failed_when: false

- name: Update Helm repositories
command: >
helm --kubeconfig=/home/ubuntu/.kube/config repo update
changed_when: false

- name: Install External Secrets Operator
command: >
helm --kubeconfig=/home/ubuntu/.kube/config
upgrade --install external-secrets external-secrets/external-secrets
--namespace external-secrets --create-namespace
--set replicaCount=1
--set webhook.replicaCount=1
--set certController.replicaCount=1
--set resources.requests.cpu=25m
--set resources.requests.memory=64Mi
--set serviceAccount.create=true
--set serviceAccount.name=external-secrets-sa
register: eso_install
changed_when: "'deployed' in eso_install.stdout or 'upgraded' in eso_install.stdout"

- name: Wait for ESO to be ready
command: >
kubectl --kubeconfig=/home/ubuntu/.kube/config
rollout status deployment/external-secrets
-n external-secrets --timeout=120s
changed_when: false

- name: Apply ClusterSecretStore
shell: |
cat <<'EOF' | kubectl --kubeconfig=/home/ubuntu/.kube/config apply -f -
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
name: aws-secrets-manager
spec:
provider:
aws:
service: SecretsManager
region: ap-northeast-2
EOF
register: css_apply
changed_when: "'configured' in css_apply.stdout or 'created' in css_apply.stdout"
8 changes: 6 additions & 2 deletions IaC/3-v3/aws/environments/k8s-dev/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,15 @@ resource "aws_security_group_rule" "alb_to_worker_nodeport" {
# 3. IAM — K8S 노드 역할
# ============================================================

data "aws_caller_identity" "current" {}

module "iam" {
source = "../../modules/iam"

project_name = var.project_name
common_tags = local.common_tags
project_name = var.project_name
aws_region = var.region
aws_account_id = data.aws_caller_identity.current.account_id
common_tags = local.common_tags
}

# ============================================================
Expand Down
19 changes: 19 additions & 0 deletions IaC/3-v3/aws/modules/iam/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,25 @@ resource "aws_iam_role_policy_attachment" "ssm" {
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}

# --- Secrets Manager Read Policy (ESO) ---

resource "aws_iam_role_policy" "secrets_manager" {
name = "secrets-manager-read"
role = aws_iam_role.k8s_node.id

policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret"
]
Resource = "arn:aws:secretsmanager:${var.aws_region}:${var.aws_account_id}:secret:dojangkok/*"
}]
})
}

# --- S3 for Ansible SSM file transfer ---

resource "aws_iam_role_policy" "ssm_s3" {
Expand Down
8 changes: 8 additions & 0 deletions IaC/3-v3/aws/modules/iam/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ variable "project_name" {
type = string
}

variable "aws_region" {
type = string
}

variable "aws_account_id" {
type = string
}

variable "common_tags" {
type = map(string)
default = {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ metadata:
app.kubernetes.io/name: ai-server
data:
# --- App ---
APP_ENV: "prod"
HTTP_TIMEOUT_SEC: "30"
APP_ENV: "dev"
HTTP_TIMEOUT_SEC: "180"
CHROMADB_URL: ""

# --- vLLM ---
Expand All @@ -24,17 +24,17 @@ data:

# --- RabbitMQ 라우팅 ---
RABBITMQ_REQUEST_EXCHANGE_EASY_CONTRACT: "fast.exchange"
RABBITMQ_REQUEST_QUEUE_EASY_CONTRACT: "easy-contract.request"
RABBITMQ_REQUEST_ROUTING_KEY_EASY_CONTRACT: "easy-contract.request"
RABBITMQ_REQUEST_QUEUE_EASY_CONTRACT: "quorum.easy-contract.request"
RABBITMQ_REQUEST_ROUTING_KEY_EASY_CONTRACT: "quorum.easy-contract.request"
RABBITMQ_REQUEST_EXCHANGE_CHECKLIST: "fast.exchange"
RABBITMQ_REQUEST_QUEUE_CHECKLIST: "checklist.request"
RABBITMQ_REQUEST_ROUTING_KEY_CHECKLIST: "checklist.request"
RABBITMQ_REQUEST_QUEUE_CHECKLIST: "quorum.checklist.request"
RABBITMQ_REQUEST_ROUTING_KEY_CHECKLIST: "quorum.checklist.request"
RABBITMQ_CANCEL_EXCHANGE_EASY_CONTRACT: "fast.exchange"
RABBITMQ_CANCEL_QUEUE_EASY_CONTRACT: "cancel.request"
RABBITMQ_CANCEL_ROUTING_KEY_EASY_CONTRACT: "cancel.request"
RABBITMQ_CANCEL_QUEUE_EASY_CONTRACT: "quorum.cancel.request"
RABBITMQ_CANCEL_ROUTING_KEY_EASY_CONTRACT: "quorum.cancel.request"
RABBITMQ_RESULT_EXCHANGE: "fast.exchange"
RABBITMQ_RESULT_QUEUE: "ai.response"
RABBITMQ_RESULT_ROUTING_KEY: "ai.response"
RABBITMQ_RESULT_QUEUE: "quorum.ai.response"
RABBITMQ_RESULT_ROUTING_KEY: "quorum.ai.response"

# --- 재시도 ---
WORKER_RETRY_MAX_ATTEMPTS: "3"
Expand Down
Loading
Loading