Skip to content

fix: nginx 인증서 자동 갱신 안정화#55

Open
Hexeong wants to merge 4 commits into
mainfrom
fix/54-certificate-auto-renew-stabilization
Open

fix: nginx 인증서 자동 갱신 안정화#55
Hexeong wants to merge 4 commits into
mainfrom
fix/54-certificate-auto-renew-stabilization

Conversation

@Hexeong

@Hexeong Hexeong commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

관련 이슈

작업 내용

  • Monitoring Nginx 인증서 발급/갱신 방식을 standalone에서 webroot 방식으로 변경했습니다.

    • certbot이 80번 포트를 직접 점유하지 않고, nginx가 /.well-known/acme-challenge/ 요청을 처리합니다.
    • 인증서 발급/갱신 과정에서 monitoring EC2 또는 nginx를 중지하지 않도록 변경했습니다.
    • 자동 갱신 cron을 /etc/cron.d/certbot-$CONF_NAME 파일로 관리하도록 변경해 중복 등록을 방지했습니다.
  • Monitoring EC2에 nginx 설정 변경 반영 경로를 추가했습니다.

    • nginx_setup.sh.tftpl 렌더링 결과의 hash를 terraform_data.update_nginx 트리거로 사용합니다.
    • hash 변경 시 SSM RunCommand로 기존 monitoring EC2에서 nginx setup script를 재실행합니다.
    • monitoring EC2에 SSM 전용 instance profile을 주입할 수 있도록 ec2_iam_instance_profile 변수를 추가했습니다.
  • Prod/Stage 공용 app_stack Nginx 인증서 갱신도 동일하게 안정화했습니다.

    • certbot --standalonesystemctl stop nginx 흐름을 제거했습니다.
    • 기존 인증서가 있으면 443 설정을 유지한 상태로 nginx reload 후 webroot certbot을 실행합니다.
    • 인증서가 없는 최초 구성 시에는 HTTP challenge용 bootstrap config를 먼저 적용합니다.
    • null_resource.update_nginx의 기존 script hash 기반 재실행 구조는 유지했습니다.
  • Monitoring secrets submodule을 갱신했습니다.

    • monitoring 환경에서 전용 SSM instance profile을 사용하도록 tfvars를 갱신했습니다.

특이 사항

  • 이번 변경은 EC2 destroy/recreate를 유발하지 않습니다.
  • nginx 설정 반영은 정상 경로에서 reload로 수행되며, reload 실패 시에만 restart fallback을 사용합니다.
  • Prod/Stage는 기존처럼 nginx_setup.sh.tftpl 내용이 바뀌면 script hash 변경으로 null_resource.update_nginx가 재실행됩니다.
  • Monitoring은 이번 PR부터 terraform_data.update_nginx를 통해 동일한 hash 기반 재실행 구조를 갖습니다.

검증 결과:

  • bash -n modules/monitoring_stack/scripts/nginx_setup.sh.tftpl
  • bash -n modules/app_stack/scripts/nginx_setup.sh.tftpl
  • terraform validate for environment/monitoring
  • terraform validate for environment/stage
  • terraform validate for environment/prod
  • Monitoring plan: EC2 instance profile in-place update + terraform_data.update_nginx 생성
  • Stage plan: null_resource.update_nginx script hash replacement only
  • Prod plan: SSH tunnel 연결 후 full refresh plan 성공, null_resource.update_nginx script hash replacement only

리뷰 요구사항 (선택)

  • webroot 방식으로 전환한 nginx challenge location이 HTTP redirect/default server 차단 로직과 충돌하지 않는지 확인해주세요.
  • Monitoring 전용 SSM instance profile을 사용하는 방향이 prod/stage app instance profile과 권한 경계를 분리하는 방식으로 적절한지 확인해주세요.
  • Prod/Stage에서 인증서가 이미 있는 경우 443 설정을 유지하고, 인증서가 없는 경우 bootstrap HTTP config를 사용하는 분기 흐름이 적절한지 확인해주세요.

Summary by CodeRabbit

  • 새 기능

    • 모니터링 서버에 원격 명령 실행용 인스턴스 프로필 연결이 지원됩니다.
    • 인증서 발급/갱신 방식이 개선되어 웹서버를 유지한 채 자동 갱신이 가능해졌습니다.
  • 버그 수정

    • Nginx 재시작 방식과 설정 적용 흐름이 정리되어, 갱신 후 서비스 중단 가능성이 줄었습니다.
    • 인증서 자동 갱신 작업이 더 안정적으로 실행되도록 변경되었습니다.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Hexeong, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 27 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 80c13490-7393-4b64-beaf-aaac4e0a93ba

📥 Commits

Reviewing files that changed from the base of the PR and between 7b05728 and e5aaa1d.

📒 Files selected for processing (2)
  • modules/app_stack/scripts/nginx_setup.sh.tftpl
  • modules/monitoring_stack/scripts/nginx_setup.sh.tftpl
📝 Walkthrough

Walkthrough

monitoring_stack 및 app_stack의 nginx 설정 스크립트가 standalone certbot 방식에서 webroot 기반 HTTP-01 challenge 방식으로 전환되었다. monitoring_stack ec2.tf에는 IAM instance profile과 SSM RunCommand를 통해 기존 인스턴스에 nginx 설정을 재실행하는 terraform_data 리소스가 추가되었고, 관련 변수와 모듈 호출부가 함께 갱신되었다. config/secrets 서브모듈 커밋도 갱신되었다.

Changes

Nginx SSL 인증서 webroot 전환 및 SSM 기반 재실행 경로

Layer / File(s) Summary
monitoring_stack nginx 스크립트 webroot 전환
modules/monitoring_stack/scripts/nginx_setup.sh.tftpl
Certbot 발급이 standalone에서 webroot 방식으로 전환되고, 자동 갱신이 /etc/cron.d/certbot-$CONF_NAME 파일과 --deploy-hook 기반 nginx reload로 변경됨.
app_stack nginx 스크립트 함수화 및 webroot 전환
modules/app_stack/scripts/nginx_setup.sh.tftpl
reload_nginx, write_http_challenge_conf, write_full_nginx_conf 함수 도입, 인증서 미존재 시 challenge 설정 후 발급, 발급 후 full 설정 재적용, 갱신 cron 및 reload 방식 변경.
monitoring_stack ec2.tf IAM 프로파일 및 SSM 재실행
modules/monitoring_stack/ec2.tf
nginx_setup 스크립트를 locals로 추출·base64 인코딩, EC2에 iam_instance_profile 지정, terraform_data.update_nginx로 SSM send-command 및 상태 폴링을 통한 기존 인스턴스 재설정 경로 추가.
변수 선언 및 모듈 배선
modules/monitoring_stack/variables.tf, environment/monitoring/variables.tf, environment/monitoring/main.tf
ec2_iam_instance_profile 변수 추가 및 모듈 호출부 인자 재정렬을 통해 신규 변수 전달.
서브모듈 커밋 갱신
config/secrets
서브프로젝트 커밋 해시 업데이트.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Cron as cron.d/certbot
  participant Certbot
  participant Nginx
  participant Terraform
  participant SSM as AWS SSM
  participant EC2 as monitoring_server EC2

  Terraform->>EC2: 인스턴스 생성(iam_instance_profile 부여)
  Terraform->>SSM: SSM 에이전트 온라인 대기
  SSM-->>Terraform: 온라인 확인
  Terraform->>SSM: send-command(setup_nginx.sh 실행)
  SSM->>EC2: nginx 설정 스크립트 실행
  EC2->>Nginx: challenge 설정 작성 및 reload
  EC2->>Certbot: certonly --webroot 인증서 발급
  EC2->>Nginx: full 설정 재작성 및 reload
  Terraform->>SSM: get-command-invocation 폴링
  SSM-->>Terraform: Success/Failed 반환
  Cron->>Certbot: 주기적 renew --webroot
  Certbot->>Nginx: --deploy-hook reload
Loading

Possibly related PRs

  • solid-connection/solid-connection-infra#14: 이전에 monitoring_stack EC2/Nginx/certbot 프로비저닝(ec2.tf, nginx_setup.sh.tftpl)을 최초 구현한 PR로, 본 PR이 동일 파일들의 발급/갱신 흐름을 직접 리팩터링함.

Suggested labels: 인프라

Suggested reviewers: wibaek, whqtker, JAEHEE25, sukangpunch, Gyuhyeok99

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed 제목이 nginx 인증서 자동 갱신 안정화라는 핵심 변경을 간결하게 잘 요약합니다.
Description check ✅ Passed 관련 이슈, 작업 내용, 특이 사항, 리뷰 요구사항이 모두 포함되어 있어 템플릿을 충분히 충족합니다.
Linked Issues check ✅ Passed #54의 webroot 전환, reload 후 갱신, monitoring 기존 인스턴스 재실행 경로 추가 요구를 충족합니다.
Out of Scope Changes check ✅ Passed app_stack과 secrets 변경도 PR 목적과 설명에 포함되어 있어 명백한 범위 밖 변경은 보이지 않습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/54-certificate-auto-renew-stabilization

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

Terraform Plan: monitoring

Plan: 1 to add, 1 to change, 0 to destroy.

전체 plan 결과는 보안을 위해 댓글에 포함되지 않습니다. 워크플로우 실행 아티팩트를 확인하세요.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

Terraform Plan: global

No changes. Your infrastructure matches the configuration.

전체 plan 결과는 보안을 위해 댓글에 포함되지 않습니다. 워크플로우 실행 아티팩트를 확인하세요.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

Terraform Plan: stage

Plan: 1 to add, 0 to change, 1 to destroy.

전체 plan 결과는 보안을 위해 댓글에 포함되지 않습니다. 워크플로우 실행 아티팩트를 확인하세요.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

Terraform Plan: prod

Plan: 1 to add, 0 to change, 1 to destroy.

전체 plan 결과는 보안을 위해 댓글에 포함되지 않습니다. 워크플로우 실행 아티팩트를 확인하세요.

@Hexeong Hexeong marked this pull request as ready for review July 8, 2026 05:54
@Hexeong Hexeong self-assigned this Jul 8, 2026
@Hexeong Hexeong added the bug Something isn't working label Jul 8, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7b05728b97

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread modules/app_stack/scripts/nginx_setup.sh.tftpl Outdated
Comment thread modules/monitoring_stack/scripts/nginx_setup.sh.tftpl Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
modules/monitoring_stack/scripts/nginx_setup.sh.tftpl (1)

22-45: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

인증서가 있으면 80 전용 설정으로 먼저 덮어쓰지 마세요
modules/monitoring_stack/scripts/nginx_setup.sh.tftpl:22-45에서 매번 80 전용 설정으로 reload한 뒤 full 설정을 다시 쓰고 있어서, 기존 인증서가 있는 재실행에서도 443 서버 블록이 잠깐 사라집니다. 인증서가 이미 있으면 처음부터 full 설정을 적용하고, challenge location만 추가하는 분기로 바꾸는 편이 좋습니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@modules/monitoring_stack/scripts/nginx_setup.sh.tftpl` around lines 22 - 45,
The nginx setup flow in the script template is overwriting the existing config
with an HTTP-only server block before restoring the full TLS config, which can
temporarily drop the 443 block on reruns. Update the branching around the nginx
config generation so the existing-cert path writes the full server configuration
from the start, and only adds the ACME challenge location needed for certbot;
keep the no-cert path on the current 80-only bootstrap. Use the nginx config
generation and reload logic in the script template to locate the change.
modules/app_stack/scripts/nginx_setup.sh.tftpl (1)

154-180: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

중복된 full 설정 작성/심볼릭 링크 처리.

인증서가 이미 존재하는 경로(154-162행)에서 write_full_nginx_conf + 심볼릭 링크 + default 제거를 수행한 뒤, 176-180행에서 동일 작업이 다시 반복됩니다. challenge→full 전환이 필요한 최초 발급 경로를 제외하면 중복이므로, 발급이 실제로 필요한 경우에만 재작성하도록 정리하면 흐름이 단순해집니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@modules/app_stack/scripts/nginx_setup.sh.tftpl` around lines 154 - 180, The
nginx setup flow is duplicating the full config write and site symlink/default
cleanup in the certificate-present branch and again after certbot runs. Refactor
the logic around write_full_nginx_conf, write_http_challenge_conf, the ln -sf
/etc/nginx/sites-available/$CONF_NAME step, and reload_nginx so the full
configuration and symlink cleanup happen only once after a successful
issuance/renewal, while the challenge config remains only for the initial
HTTP-01 path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@modules/monitoring_stack/scripts/nginx_setup.sh.tftpl`:
- Around line 102-108: Split the cron file name used in the certbot setup from
CONF_NAME, since the current /etc/cron.d/certbot-$CONF_NAME naming can inherit
dots from nginx_conf_name and be ignored by cron. Update the
nginx_setup.sh.tftpl block that writes the cron entry so the /etc/cron.d
filename is a fixed or sanitized value, while keeping CONF_NAME only for the
rest of the setup logic. Use the certbot renewal cron stanza as the location to
make this change.

---

Nitpick comments:
In `@modules/app_stack/scripts/nginx_setup.sh.tftpl`:
- Around line 154-180: The nginx setup flow is duplicating the full config write
and site symlink/default cleanup in the certificate-present branch and again
after certbot runs. Refactor the logic around write_full_nginx_conf,
write_http_challenge_conf, the ln -sf /etc/nginx/sites-available/$CONF_NAME
step, and reload_nginx so the full configuration and symlink cleanup happen only
once after a successful issuance/renewal, while the challenge config remains
only for the initial HTTP-01 path.

In `@modules/monitoring_stack/scripts/nginx_setup.sh.tftpl`:
- Around line 22-45: The nginx setup flow in the script template is overwriting
the existing config with an HTTP-only server block before restoring the full TLS
config, which can temporarily drop the 443 block on reruns. Update the branching
around the nginx config generation so the existing-cert path writes the full
server configuration from the start, and only adds the ACME challenge location
needed for certbot; keep the no-cert path on the current 80-only bootstrap. Use
the nginx config generation and reload logic in the script template to locate
the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 60bcfba8-8100-433c-8ed4-208cdfeb15f6

📥 Commits

Reviewing files that changed from the base of the PR and between fc79ded and 7b05728.

📒 Files selected for processing (7)
  • config/secrets
  • environment/monitoring/main.tf
  • environment/monitoring/variables.tf
  • modules/app_stack/scripts/nginx_setup.sh.tftpl
  • modules/monitoring_stack/ec2.tf
  • modules/monitoring_stack/scripts/nginx_setup.sh.tftpl
  • modules/monitoring_stack/variables.tf

Comment thread modules/monitoring_stack/scripts/nginx_setup.sh.tftpl
@wibaek

wibaek commented Jul 8, 2026

Copy link
Copy Markdown
Member

👍 Caddy 사용도 고려해볼 수 있을 것 같네요

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: nginx SSL 인증서 자동 갱신 안정화

2 participants