From fca2de9e5d2109f774cfe8f9a9ec5856fe39563b Mon Sep 17 00:00:00 2001 From: 2ghrms Date: Mon, 29 Dec 2025 01:39:52 +0900 Subject: [PATCH 1/4] =?UTF-8?q?refactor:=20nginx=EC=99=80=20cerbot=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=A0=9C=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- userdata-examples/was-userdata.sh | 114 ------------------------------ 1 file changed, 114 deletions(-) diff --git a/userdata-examples/was-userdata.sh b/userdata-examples/was-userdata.sh index afd8929..ab9cbbe 100644 --- a/userdata-examples/was-userdata.sh +++ b/userdata-examples/was-userdata.sh @@ -93,120 +93,6 @@ else echo "❌ Nginx 서비스 시작 실패" fi -# Nginx 설정 파일 백업 -echo "Nginx 설정 파일 백업 중..." -sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup -if [ $? -eq 0 ]; then - echo "✅ Nginx 설정 파일 백업 완료" -else - echo "❌ Nginx 설정 파일 백업 실패" -fi - -# Nginx 설정 파일 생성 -echo "Nginx 설정 파일 생성 중..." -sudo tee /etc/nginx/nginx.conf > /dev/null << 'EOF' -user www-data; -worker_processes auto; -pid /run/nginx.pid; -error_log /var/log/nginx/error.log; -include /etc/nginx/modules-enabled/*.conf; - -events { - worker_connections 768; - # multi_accept on; -} - -http { - server { - listen 80; - server_name clokey.shop; - location / { - proxy_pass http://localhost:8080; - proxy_http_version 1.1; - proxy_set_header Connection ""; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } - } - - ## - # Basic Settings - ## - - sendfile on; - tcp_nopush on; - types_hash_max_size 2048; - # server_tokens off; - - # server_names_hash_bucket_size 64; - # server_name_in_redirect off; - - include /etc/nginx/mime.types; - default_type application/octet-stream; - - ## - # SSL Settings - ## - - ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE - ssl_prefer_server_ciphers on; - - ## - # Logging Settings - ## - - access_log /var/log/nginx/access.log; - - ## - # Gzip Settings - ## - - gzip on; - - # gzip_vary on; - # gzip_proxied any; - # gzip_comp_level 6; - # gzip_buffers 16 8k; - # gzip_http_version 1.1; - # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; - - ## - # Virtual Host Configs - ## - - include /etc/nginx/conf.d/*.conf; - include /etc/nginx/sites-enabled/*; - - client_max_body_size 100M; -} -EOF - -if [ $? -eq 0 ]; then - echo "✅ Nginx 설정 파일 생성 완료" -else - echo "❌ Nginx 설정 파일 생성 실패" -fi - -# Nginx 설정 테스트 -echo "Nginx 설정 테스트 중..." -sudo nginx -t -if [ $? -eq 0 ]; then - echo "✅ Nginx 설정 테스트 성공" - # Nginx 재시작 - sudo systemctl restart nginx - if [ $? -eq 0 ]; then - echo "✅ Nginx 재시작 완료" - else - echo "❌ Nginx 재시작 실패" - fi -else - echo "❌ Nginx 설정 테스트 실패" - # 백업 파일로 복원 - sudo cp /etc/nginx/nginx.conf.backup /etc/nginx/nginx.conf - sudo systemctl restart nginx -fi - # Swap 메모리 설정 (2GB) echo "Swap 메모리 설정 중..." sudo fallocate -l 2G /swapfile From f7ef7f3babe98b8c30b073fde5441526e0604f93 Mon Sep 17 00:00:00 2001 From: 2ghrms Date: Mon, 29 Dec 2025 01:43:27 +0900 Subject: [PATCH 2/4] =?UTF-8?q?refactor:=20cicd=EC=97=90=EC=84=9C=20domain?= =?UTF-8?q?=20=EC=A0=9C=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cd_dev.yml | 1 - .github/workflows/cd_prod.yml | 1 - .github/workflows/ci_dev.yml | 1 - .github/workflows/ci_prod.yml | 1 - 4 files changed, 4 deletions(-) diff --git a/.github/workflows/cd_dev.yml b/.github/workflows/cd_dev.yml index 1b3f0dc..b3f1a38 100644 --- a/.github/workflows/cd_dev.yml +++ b/.github/workflows/cd_dev.yml @@ -39,7 +39,6 @@ jobs: aws_secret_access_key = "${{ secrets.DEV_AWS_SECRET_ACCESS_KEY }}" rds_username = "${{ secrets.RDS_USERNAME }}" rds_password = "${{ secrets.RDS_PASSWORD }}" - domain_name = "${{ secrets.DEV_DOMAIN_NAME }}" EOF - name: Terraform Apply (dev) diff --git a/.github/workflows/cd_prod.yml b/.github/workflows/cd_prod.yml index 1558889..f3dab95 100644 --- a/.github/workflows/cd_prod.yml +++ b/.github/workflows/cd_prod.yml @@ -40,7 +40,6 @@ jobs: aws_secret_access_key = "${{ secrets.PROD_AWS_SECRET_ACCESS_KEY }}" rds_username = "${{ secrets.RDS_USERNAME }}" rds_password = "${{ secrets.RDS_PASSWORD }}" - domain_name = "${{ secrets.PROD_DOMAIN_NAME }}" EOF - name: Terraform Apply (prod) diff --git a/.github/workflows/ci_dev.yml b/.github/workflows/ci_dev.yml index d9797cf..cca18c6 100644 --- a/.github/workflows/ci_dev.yml +++ b/.github/workflows/ci_dev.yml @@ -43,7 +43,6 @@ jobs: aws_secret_access_key = "${{ secrets.DEV_AWS_SECRET_ACCESS_KEY }}" rds_username = "${{ secrets.RDS_USERNAME }}" rds_password = "${{ secrets.RDS_PASSWORD }}" - domain_name = "${{ secrets.DEV_DOMAIN_NAME }}" EOF - name: Terraform Plan (dev) diff --git a/.github/workflows/ci_prod.yml b/.github/workflows/ci_prod.yml index d14ea87..abf0887 100644 --- a/.github/workflows/ci_prod.yml +++ b/.github/workflows/ci_prod.yml @@ -43,7 +43,6 @@ jobs: aws_secret_access_key = "${{ secrets.PROD_AWS_SECRET_ACCESS_KEY }}" rds_username = "${{ secrets.RDS_USERNAME }}" rds_password = "${{ secrets.RDS_PASSWORD }}" - domain_name = "${{ secrets.PROD_DOMAIN_NAME }}" EOF - name: Terraform Plan (prod) From 4af625e65a846a0c39f376981fc5309a34b915c5 Mon Sep 17 00:00:00 2001 From: 2ghrms Date: Mon, 29 Dec 2025 01:44:32 +0900 Subject: [PATCH 3/4] =?UTF-8?q?refactor:=20cicd=EC=97=90=EC=84=9C=20domain?= =?UTF-8?q?=20=EC=A0=9C=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- terraform/env/dev/variables.tf | 8 -------- terraform/env/prod/variables.tf | 8 -------- 2 files changed, 16 deletions(-) diff --git a/terraform/env/dev/variables.tf b/terraform/env/dev/variables.tf index 0bb9ff5..f0ef5e7 100644 --- a/terraform/env/dev/variables.tf +++ b/terraform/env/dev/variables.tf @@ -22,11 +22,3 @@ variable "rds_password" { type = string sensitive = true } - -# Route53 설정 (도메인 관련) -variable "domain_name" { - description = "Base domain name for Route53 records" - type = string - default = "example.com" - sensitive = true -} diff --git a/terraform/env/prod/variables.tf b/terraform/env/prod/variables.tf index f1f8a76..943f958 100644 --- a/terraform/env/prod/variables.tf +++ b/terraform/env/prod/variables.tf @@ -23,11 +23,3 @@ variable "rds_password" { type = string sensitive = true } - -# Route53 설정 (도메인 관련) -variable "domain_name" { - description = "Base domain name for Route53 records" - type = string - default = "example.com" - sensitive = true -} From 4ea87f45aff4f77e99cc2a149c50580336e72776 Mon Sep 17 00:00:00 2001 From: 2ghrms Date: Mon, 29 Dec 2025 03:57:58 +0900 Subject: [PATCH 4/4] =?UTF-8?q?refactor:=20=EB=AF=B8=EC=82=AC=EC=9A=A9=20?= =?UTF-8?q?=EA=B0=92=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- terraform/env/dev/compute.tf | 7 -- terraform/env/dev/example.tfvars | 3 - terraform/env/dev/locals.tf | 4 - terraform/env/dev/network.tf | 124 ++++------------------------ terraform/env/dev/terraform.tfvars | 3 - terraform/env/prod/backend.tf | 14 ++-- terraform/env/prod/compute.tf | 10 --- terraform/env/prod/database.tf | 18 ++-- terraform/env/prod/example.tfvars | 4 - terraform/env/prod/locals.tf | 4 - terraform/env/prod/network.tf | 121 ++++----------------------- terraform/env/prod/storage.tf | 5 +- terraform/env/prod/terraform.tfvars | 4 - 13 files changed, 44 insertions(+), 277 deletions(-) diff --git a/terraform/env/dev/compute.tf b/terraform/env/dev/compute.tf index 2f49204..a05e3f1 100644 --- a/terraform/env/dev/compute.tf +++ b/terraform/env/dev/compute.tf @@ -27,10 +27,3 @@ module "ec2" { user_data = local.user_data_base64 } -# ALB Target Group 추가 -resource "aws_lb_target_group_attachment" "ec2" { - target_group_arn = module.alb.target_group_arn - target_id = module.ec2.instance_id - port = 80 -} - diff --git a/terraform/env/dev/example.tfvars b/terraform/env/dev/example.tfvars index ceb8fb4..ba287da 100644 --- a/terraform/env/dev/example.tfvars +++ b/terraform/env/dev/example.tfvars @@ -12,6 +12,3 @@ availability_zone = "ap-northeast-2a" # RDS Configuration rds_username = "admin" # 실제 환경에서는 더 복잡한 비밀번호 사용 -# Route53 Configuration -# hosted_zone_id = "YOUR_HOSTED_ZONE_ID" # 도메인의 hosted zone ID -# domain_name = "yourdomain.com" # 실제 도메인으로 변경 diff --git a/terraform/env/dev/locals.tf b/terraform/env/dev/locals.tf index 0f88f15..a48d14c 100644 --- a/terraform/env/dev/locals.tf +++ b/terraform/env/dev/locals.tf @@ -13,10 +13,6 @@ locals { # 이름 규칙 name_prefix = "${local.environment}-clokey" - # Backend 설정 (하드코딩) - state_bucket_name = "clokey-terraform-state-116541188992" - state_key = "dev/terraform.tfstate" - # UserData 설정 (파일에서 base64로 인코딩하여 로드) user_data_base64 = filebase64("${path.module}/../../../userdata-examples/was-userdata.sh") } diff --git a/terraform/env/dev/network.tf b/terraform/env/dev/network.tf index 73dcbba..1afce06 100644 --- a/terraform/env/dev/network.tf +++ b/terraform/env/dev/network.tf @@ -98,12 +98,20 @@ module "sg_ec2" { ingress_rules = [ { - from_port = 80 - to_port = 80 - protocol = "tcp" - use_cidr = false - use_sg = true - source_security_group_id = module.sg_alb.security_group_id + from_port = 80 + to_port = 80 + protocol = "tcp" + use_cidr = true + use_sg = false + cidr_blocks = ["0.0.0.0/0"] + }, + { + from_port = 443 + to_port = 443 + protocol = "tcp" + use_cidr = true + use_sg = false + cidr_blocks = ["0.0.0.0/0"] }, { from_port = 22 @@ -159,107 +167,3 @@ module "sg_rds" { ] } -# ALB Security Group -module "sg_alb" { - source = "../../modules/security/security_group" - vpc_id = module.vpc.vpc_id - - environment = local.environment - purpose = "alb" - security_group_name = "${local.name_prefix}-sg-alb" - - ingress_rules = [ - { - from_port = 80 - to_port = 80 - protocol = "tcp" - use_cidr = true - use_sg = false - cidr_blocks = ["0.0.0.0/0"] - }, - { - from_port = 443 - to_port = 443 - protocol = "tcp" - use_cidr = true - use_sg = false - cidr_blocks = ["0.0.0.0/0"] - } - ] - - egress_rules = [ - { - from_port = 0 - to_port = 0 - protocol = "-1" - use_cidr = true - use_sg = false - cidr_blocks = ["0.0.0.0/0"] - } - ] -} - -# ACM Certificate (1단계: 인증서만 생성, 검증은 나중에) -module "acm" { - source = "../../modules/network/acm" - - name_prefix = local.name_prefix - domain_name = var.domain_name - hosted_zone_id = module.route53_zone.hosted_zone_id - create_validation = false # 1단계에서는 검증 비활성화 - - tags = local.common_tags -} - -# Application Load Balancer -module "alb" { - source = "../../modules/network/alb" - - name_prefix = local.name_prefix - internal = false - security_groups = [module.sg_alb.security_group_id] - subnet_ids = [module.subnet_public_a.subnet_id, module.subnet_public_c.subnet_id] - vpc_id = module.vpc.vpc_id - - target_group_port = 80 - target_group_protocol = "HTTP" - - health_check_path = "/health" - health_check_matcher = "200" - - # HTTPS 리스너 비활성화 (인증서 검증 완료 후 활성화) - create_https_listener = false - certificate_arn = null - - tags = local.common_tags -} - -# Route53 - Hosted Zone 생성 -module "route53_zone" { - source = "../../modules/network/route53" - - # 새로운 hosted zone 생성 - create_hosted_zone = true - domain_name = var.domain_name - create_a_record = false - - tags = local.common_tags -} - -# Route53 - ALB를 A 레코드로 설정 (ALB 생성 후) -module "route53_record" { - source = "../../modules/network/route53" - - # 기존 hosted zone 사용 - create_hosted_zone = false - hosted_zone_id = module.route53_zone.hosted_zone_id - - # A 레코드 생성 (ALB로 변경) - create_a_record = true - record_name = "${local.environment}.${var.domain_name}" - target_alias = module.alb.load_balancer_dns_name - target_zone_id = module.alb.load_balancer_zone_id - ttl = 300 - - depends_on = [module.alb] -} diff --git a/terraform/env/dev/terraform.tfvars b/terraform/env/dev/terraform.tfvars index 5720a2b..33c0168 100644 --- a/terraform/env/dev/terraform.tfvars +++ b/terraform/env/dev/terraform.tfvars @@ -7,8 +7,5 @@ availability_zone = "ap-northeast-2a" # RDS 설정 (기본값 - 민감한 정보는 secret.tfvars에서 관리) # rds_username은 secret.tfvars에서 관리 -# Route53 설정 (기본값 - 민감한 정보는 secret.tfvars에서 관리) -# domain_name은 secret.tfvars에서 관리 - # User Data (기본값 - 민감한 정보는 secret.tfvars에서 관리) # userdata는 locals.tf에서 filebase64() 함수로 로드됨 diff --git a/terraform/env/prod/backend.tf b/terraform/env/prod/backend.tf index f3a0f8b..4d0eafd 100644 --- a/terraform/env/prod/backend.tf +++ b/terraform/env/prod/backend.tf @@ -1,14 +1,10 @@ -# S3 + DynamoDB Backend Configuration -# 주석을 해제하고 실제 값으로 변경하여 사용 -/* +# S3 Backend Configuration terraform { backend "s3" { - bucket = "clokey-terraform-state" - key = "prod/terraform.tfstate" - region = "ap-northeast-2" - dynamodb_table = "clokey-terraform-locks" - encrypt = true + bucket = "clokey-terraform-state-prod" + key = "prod/terraform.tfstate" + region = "ap-northeast-2" + encrypt = true } } -*/ diff --git a/terraform/env/prod/compute.tf b/terraform/env/prod/compute.tf index 70538f3..17ac8f6 100644 --- a/terraform/env/prod/compute.tf +++ b/terraform/env/prod/compute.tf @@ -20,9 +20,6 @@ module "ec2" { root_volume_type = "gp3" root_volume_encrypted = true - # 종료 보호 활성화 (프로덕션 환경) - disable_api_termination = true - # 종료 시 중지 (삭제하지 않음) instance_initiated_shutdown_behavior = "stop" @@ -30,10 +27,3 @@ module "ec2" { user_data = local.user_data_base64 } -# ALB Target Group 추가 -resource "aws_lb_target_group_attachment" "ec2" { - target_group_arn = module.alb.target_group_arn - target_id = module.ec2.instance_id - port = 80 -} - diff --git a/terraform/env/prod/database.tf b/terraform/env/prod/database.tf index d2e0100..129823e 100644 --- a/terraform/env/prod/database.tf +++ b/terraform/env/prod/database.tf @@ -6,10 +6,10 @@ module "rds" { module.subnet_private_a.subnet_id, module.subnet_private_c.subnet_id ] - storage = 50 + storage = 30 engine = "mysql" engine_version = "8.0.42" - instance_class = "db.t3.small" + instance_class = "db.t3.micro" db_name = "clokey_db" username = var.rds_username password = var.rds_password @@ -21,24 +21,24 @@ module "rds" { publicly_accessible = false # 프라이빗 서브넷에 위치하므로 false # 백업 설정 - backup_retention_period = 30 # 프로덕션에서는 30일 보관 - backup_window = "02:00-03:00" - maintenance_window = "sun:02:00-sun:03:00" + backup_retention_period = 7 + backup_window = "03:00-04:00" + maintenance_window = "sun:04:00-sun:05:00" # 성능 설정 - multi_az = true # 프로덕션에서는 Multi-AZ 활성화 + multi_az = false storage_type = "gp3" storage_encrypted = true # 보안 설정 - deletion_protection = true # 프로덕션에서는 삭제 보호 활성화 + deletion_protection = false - # 파라미터 그룹 설정 (선택적) + # 파라미터 그룹 설정 parameter_group_family = "mysql8.0" parameter_group_parameters = [ { name = "max_connections" - value = "200" + value = "100" }, { name = "innodb_buffer_pool_size" diff --git a/terraform/env/prod/example.tfvars b/terraform/env/prod/example.tfvars index 6e6f75c..de26740 100644 --- a/terraform/env/prod/example.tfvars +++ b/terraform/env/prod/example.tfvars @@ -12,7 +12,3 @@ availability_zone = "ap-northeast-2a" # RDS Configuration rds_username = "admin" # 실제 환경에서는 더 복잡한 비밀번호 사용 -# Route53 Configuration -# hosted_zone_id = "YOUR_HOSTED_ZONE_ID" # 도메인의 hosted zone ID -# domain_name = "yourdomain.com" # 실제 도메인으로 변경 - diff --git a/terraform/env/prod/locals.tf b/terraform/env/prod/locals.tf index fba7aaf..7b04742 100644 --- a/terraform/env/prod/locals.tf +++ b/terraform/env/prod/locals.tf @@ -13,10 +13,6 @@ locals { # 이름 규칙 name_prefix = "${local.environment}-clokey" - # Backend 설정 (하드코딩) - state_bucket_name = "clokey-terraform-state-116541188992" - state_key = "prod/terraform.tfstate" - # UserData 설정 (파일에서 base64로 인코딩하여 로드) user_data_base64 = filebase64("${path.module}/../../../userdata-examples/was-userdata.sh") } diff --git a/terraform/env/prod/network.tf b/terraform/env/prod/network.tf index 75d39c7..2a256d2 100644 --- a/terraform/env/prod/network.tf +++ b/terraform/env/prod/network.tf @@ -98,12 +98,20 @@ module "sg_ec2" { ingress_rules = [ { - from_port = 80 - to_port = 80 - protocol = "tcp" - use_cidr = false - use_sg = true - source_security_group_id = module.sg_alb.security_group_id + from_port = 80 + to_port = 80 + protocol = "tcp" + use_cidr = true + use_sg = false + cidr_blocks = ["0.0.0.0/0"] + }, + { + from_port = 443 + to_port = 443 + protocol = "tcp" + use_cidr = true + use_sg = false + cidr_blocks = ["0.0.0.0/0"] }, { from_port = 22 @@ -159,105 +167,4 @@ module "sg_rds" { ] } -# ALB Security Group -module "sg_alb" { - source = "../../modules/security/security_group" - vpc_id = module.vpc.vpc_id - - environment = local.environment - purpose = "alb" - security_group_name = "${local.name_prefix}-sg-alb" - - ingress_rules = [ - { - from_port = 80 - to_port = 80 - protocol = "tcp" - use_cidr = true - use_sg = false - cidr_blocks = ["0.0.0.0/0"] - }, - { - from_port = 443 - to_port = 443 - protocol = "tcp" - use_cidr = true - use_sg = false - cidr_blocks = ["0.0.0.0/0"] - } - ] - - egress_rules = [ - { - from_port = 0 - to_port = 0 - protocol = "-1" - use_cidr = true - use_sg = false - cidr_blocks = ["0.0.0.0/0"] - } - ] -} - -# ACM Certificate -module "acm" { - source = "../../modules/network/acm" - - name_prefix = local.name_prefix - domain_name = var.domain_name - hosted_zone_id = module.route53_zone.hosted_zone_id - - tags = local.common_tags -} - -# Application Load Balancer -module "alb" { - source = "../../modules/network/alb" - - name_prefix = local.name_prefix - internal = false - security_groups = [module.sg_alb.security_group_id] - subnet_ids = [module.subnet_public_a.subnet_id, module.subnet_public_c.subnet_id] - vpc_id = module.vpc.vpc_id - - target_group_port = 80 - target_group_protocol = "HTTP" - - health_check_path = "/health" - health_check_matcher = "200" - - certificate_arn = module.acm.certificate_arn - - tags = local.common_tags -} - -# Route53 - Hosted Zone 생성 -module "route53_zone" { - source = "../../modules/network/route53" - - # 새로운 hosted zone 생성 - create_hosted_zone = true - domain_name = var.domain_name - create_a_record = false - - tags = local.common_tags -} - -# Route53 - ALB를 A 레코드로 설정 (ALB 생성 후) -module "route53_record" { - source = "../../modules/network/route53" - - # 기존 hosted zone 사용 - create_hosted_zone = false - hosted_zone_id = module.route53_zone.hosted_zone_id - - # A 레코드 생성 (ALB로 변경) - create_a_record = true - record_name = "${local.environment}.${var.domain_name}" - target_alias = module.alb.load_balancer_dns_name - target_zone_id = module.alb.load_balancer_zone_id - ttl = 300 - - depends_on = [module.alb] -} diff --git a/terraform/env/prod/storage.tf b/terraform/env/prod/storage.tf index d42b352..9078227 100644 --- a/terraform/env/prod/storage.tf +++ b/terraform/env/prod/storage.tf @@ -5,9 +5,8 @@ module "s3" { environment = local.environment purpose = "storage" - # Public read access (GET only) - AWS SDK로 업로드/삭제, 외부에서 읽기만 허용 - enable_public_read = true - enable_block_public_access = false # public read를 위해 비활성화 + enable_public_read = false + enable_block_public_access = true enable_versioning = true enable_sse = true sse_algorithm = "AES256" diff --git a/terraform/env/prod/terraform.tfvars b/terraform/env/prod/terraform.tfvars index 78ce5d5..8fc8e89 100644 --- a/terraform/env/prod/terraform.tfvars +++ b/terraform/env/prod/terraform.tfvars @@ -7,9 +7,5 @@ availability_zone = "ap-northeast-2a" # RDS 설정 (기본값 - 민감한 정보는 secret.tfvars에서 관리) # rds_username은 secret.tfvars에서 관리 -# Route53 설정 (기본값 - 민감한 정보는 secret.tfvars에서 관리) -# hosted_zone_id는 secret.tfvars에서 관리 -# domain_name은 secret.tfvars에서 관리 - # User Data (기본값 - 민감한 정보는 secret.tfvars에서 관리) # userdata는 locals.tf에서 filebase64() 함수로 로드됨