infra: prod 박스 관측 배선 스크립트 추가#3
Conversation
- infra/scripts/provision-observability.sh: TeamPiKi/infra 공통 Alloy 블록을 fetch 하고, Grafana Cloud 자격을 SSM Parameter Store 에서 읽어 extractor 값 (environment=prod, box=piki-extractor)으로 공통 블록을 호출한다. --ref 로 infra PR 머지 전 브랜치 선검증 가능. - infra/scripts/run-extractor.sh: 지금까지 임시(수동 SSM)로 기동되던 앱 컨테이너의 run 파라미터를 이 스크립트 한 곳으로 흡수한다 - docker label opt-in(관측 대상 선언)과 트레이스 export env 를 신설 배선한다. - README.md: 운영(prod 박스) 섹션 추가 - terraform/기동/관측 스크립트 좌표 안내. 앱 코드 변경 없음 - TRACING_OTLP_ENABLED/OTLP_ENDPOINT env 배선은 application.yml 에 이미 있다.
📝 WalkthroughWalkthrough프로덕션 박스에서 Extractor 컨테이너를 SSM 시크릿과 함께 재기동하고 헬스체크하는 스크립트가 추가되었다. Grafana Alloy 설정 프로비저닝과 관련 운영 절차도 문서화되었다. Changes프로덕션 운영 자동화
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)Extractor 실행 및 헬스체크sequenceDiagram
participant Operator
participant run-extractor.sh
participant AWS SSM
participant Docker
participant healthcheck.sh
Operator->>run-extractor.sh: --image 전달
run-extractor.sh->>AWS SSM: GEMINI_API_KEY 조회
AWS SSM-->>run-extractor.sh: 복호화된 시크릿 반환
run-extractor.sh->>Docker: piki-extractor 재기동
run-extractor.sh->>healthcheck.sh: actuator health 검사
healthcheck.sh-->>Operator: 검사 결과 반환
Alloy 관측 설정 프로비저닝sequenceDiagram
participant Operator
participant provision-observability.sh
participant GitHub
participant AWS SSM
participant provision-alloy.sh
Operator->>provision-observability.sh: --ref 실행
provision-observability.sh->>GitHub: Alloy 파일 다운로드
provision-observability.sh->>AWS SSM: Grafana 파라미터 조회
AWS SSM-->>provision-observability.sh: 관측 설정 반환
provision-observability.sh->>provision-alloy.sh: prod 및 piki-extractor 설정 전달
provision-alloy.sh-->>Operator: Alloy 설정 적용
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (4)
infra/scripts/run-extractor.sh (2)
36-42: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winPin the
amazon/aws-cliimage tag.No tag is specified, so this resolves to
amazon/aws-cli:latest, which can change unexpectedly between prod runs (e.g. incompatible CLI flags, breaking output changes) since this is invoked repeatedly over time without any build/lock step.🤖 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 `@infra/scripts/run-extractor.sh` around lines 36 - 42, Pin the Docker image used by the `docker run` command to a specific `amazon/aws-cli` version tag instead of relying on the mutable `latest` default. Keep the existing AWS SSM arguments and command behavior unchanged.
45-91: 🩺 Stability & Availability | 🔵 TrivialNo rollback path if the new container fails health check, and no explicit pull before run.
The old container is force-removed (line 46) before the new one is confirmed healthy (lines 82-91). If the new image fails to start or fails the healthcheck, the script exits 1 leaving the box with either no running container or an unhealthy one — there's no fallback to the previously-working container. Also,
docker rundoesn'tdocker pull "$IMAGE"first, so if$IMAGEuses a mutable tag (e.g.:latest) that was already pulled once, the script may silently restart the old cached image instead of a newly-pushed one.Given the fixed
-p 8090:8090binding, true blue/green isn't trivial here, but consider at minimum: (1) an explicitdocker pull "$IMAGE"before removing the old container so pull failures are caught before service is torn down, and (2) capturing enough context (e.g. previous image ID) to make manual rollback faster if the healthcheck fails.🤖 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 `@infra/scripts/run-extractor.sh` around lines 45 - 91, Update the deployment flow around the piki-extractor container lifecycle to explicitly pull "$IMAGE" before removing the existing container, so pull failures leave the running service untouched. Before docker rm, capture the current container/image context when available, and when the subsequent healthcheck fails, report that context clearly to support restoring the previous image or container; preserve the existing healthcheck and failure exit behavior.infra/scripts/provision-observability.sh (2)
51-60: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicated dockerized-aws-cli SSM helper across both scripts; unpinned
amazon/aws-clitag.
get_ssm_param()here re-implements the samedocker run --rm --network host -e AWS_DEFAULT_REGION=... amazon/aws-cli ssm get-parameter ...pattern thatrun-extractor.shinlines separately (lines 36-42 there). Consider extracting a shared helper (e.g.infra/scripts/lib/ssm.sh) sourced by both scripts, and pinning theamazon/aws-cliimage to a specific tag instead of implicitlatestfor reproducibility.🤖 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 `@infra/scripts/provision-observability.sh` around lines 51 - 60, Extract the duplicated AWS SSM Docker invocation from get_ssm_param and run-extractor.sh into a shared sourced helper such as lib/ssm.sh, preserving the existing parameter and decryption behavior. Update both scripts to use that helper, and replace the unpinned amazon/aws-cli image reference with one specific, consistently used version tag.
62-73: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winFive near-identical SSM fetch blocks — candidate for a loop.
The required-params section repeats the same fetch/error pattern five times. A small map+loop reduces duplication and the risk of a copy-paste error (e.g. mismatched param name vs. error message) creeping in on the next edit.
♻️ Proposed refactor
-GRAFANA_METRICS_URL=$(get_ssm_param /piki-extractor/grafana-metrics-url) \ - || { echo "필수 SSM 파라미터 조회 실패: /piki-extractor/grafana-metrics-url" >&2; exit 1; } -GRAFANA_METRICS_USER=$(get_ssm_param /piki-extractor/grafana-metrics-user) \ - || { echo "필수 SSM 파라미터 조회 실패: /piki-extractor/grafana-metrics-user" >&2; exit 1; } -GRAFANA_LOGS_URL=$(get_ssm_param /piki-extractor/grafana-logs-url) \ - || { echo "필수 SSM 파라미터 조회 실패: /piki-extractor/grafana-logs-url" >&2; exit 1; } -GRAFANA_LOGS_USER=$(get_ssm_param /piki-extractor/grafana-logs-user) \ - || { echo "필수 SSM 파라미터 조회 실패: /piki-extractor/grafana-logs-user" >&2; exit 1; } -GRAFANA_CLOUD_TOKEN=$(get_ssm_param /piki-extractor/grafana-cloud-token) \ - || { echo "필수 SSM 파라미터 조회 실패: /piki-extractor/grafana-cloud-token" >&2; exit 1; } +declare -A REQUIRED_PARAMS=( + [GRAFANA_METRICS_URL]=/piki-extractor/grafana-metrics-url + [GRAFANA_METRICS_USER]=/piki-extractor/grafana-metrics-user + [GRAFANA_LOGS_URL]=/piki-extractor/grafana-logs-url + [GRAFANA_LOGS_USER]=/piki-extractor/grafana-logs-user + [GRAFANA_CLOUD_TOKEN]=/piki-extractor/grafana-cloud-token +) +for var in "${!REQUIRED_PARAMS[@]}"; do + value=$(get_ssm_param "${REQUIRED_PARAMS[$var]}") \ + || { echo "필수 SSM 파라미터 조회 실패: ${REQUIRED_PARAMS[$var]}" >&2; exit 1; } + export "$var=$value" +done🤖 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 `@infra/scripts/provision-observability.sh` around lines 62 - 73, Refactor the required-parameter fetch section into a small mapping and loop that associates each Grafana variable with its SSM parameter path, while preserving the existing immediate failure behavior and error message context. Replace the five duplicated assignments for GRAFANA_METRICS_URL, GRAFANA_METRICS_USER, GRAFANA_LOGS_URL, GRAFANA_LOGS_USER, and GRAFANA_CLOUD_TOKEN without changing their resulting environment values.
🤖 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 `@infra/scripts/provision-observability.sh`:
- Around line 29-34: Update the argument parser’s --ref branch in the while loop
to validate that a following value exists before assigning REF and shifting two
arguments. When the value is missing, exit through the existing argument-error
path so the intended “인자 오류” message is emitted instead of letting shift fail.
- Around line 44-47: Update the default ref configuration used by
provision-observability.sh and run-extractor.sh so fetched observability scripts
resolve to a tagged release or commit SHA instead of main. Preserve the existing
--ref override behavior, and ensure config.alloy, provision-alloy.sh, and
blocks/healthcheck.sh continue using the selected ref.
In `@infra/scripts/run-extractor.sh`:
- Around line 25-30: Update the --image branch in the argument-parsing loop to
validate that a following value exists before assigning IMAGE and shifting two
arguments. When --image is the final token, emit the script’s documented
argument-error usage message and exit cleanly instead of invoking shift 2 with
insufficient parameters; preserve existing handling for valid values and unknown
arguments.
- Around line 48-60: Remove the inline GEMINI_API_KEY assignment from the docker
run command in run-extractor.sh. Create a temporary environment file with
restricted permissions, write the key there, pass it using Docker’s env-file
option, and ensure the file is cleaned up after the container starts while
preserving the existing container configuration.
- Around line 82-85: Update the healthcheck download flow in run-extractor.sh
around HEALTHCHECK_SH to pin the fetched healthcheck.sh to a trusted immutable
ref or validate it with a checksum/signature, following the existing approach in
provision-observability.sh; ensure the script is only executed after that pin or
verification succeeds.
---
Nitpick comments:
In `@infra/scripts/provision-observability.sh`:
- Around line 51-60: Extract the duplicated AWS SSM Docker invocation from
get_ssm_param and run-extractor.sh into a shared sourced helper such as
lib/ssm.sh, preserving the existing parameter and decryption behavior. Update
both scripts to use that helper, and replace the unpinned amazon/aws-cli image
reference with one specific, consistently used version tag.
- Around line 62-73: Refactor the required-parameter fetch section into a small
mapping and loop that associates each Grafana variable with its SSM parameter
path, while preserving the existing immediate failure behavior and error message
context. Replace the five duplicated assignments for GRAFANA_METRICS_URL,
GRAFANA_METRICS_USER, GRAFANA_LOGS_URL, GRAFANA_LOGS_USER, and
GRAFANA_CLOUD_TOKEN without changing their resulting environment values.
In `@infra/scripts/run-extractor.sh`:
- Around line 36-42: Pin the Docker image used by the `docker run` command to a
specific `amazon/aws-cli` version tag instead of relying on the mutable `latest`
default. Keep the existing AWS SSM arguments and command behavior unchanged.
- Around line 45-91: Update the deployment flow around the piki-extractor
container lifecycle to explicitly pull "$IMAGE" before removing the existing
container, so pull failures leave the running service untouched. Before docker
rm, capture the current container/image context when available, and when the
subsequent healthcheck fails, report that context clearly to support restoring
the previous image or container; preserve the existing healthcheck and failure
exit behavior.
🪄 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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: cf799076-6ece-4b08-99bd-5b57d6aab9a6
📒 Files selected for processing (3)
README.mdinfra/scripts/provision-observability.shinfra/scripts/run-extractor.sh
| while [ $# -gt 0 ]; do | ||
| case "$1" in | ||
| --ref) REF="${2:-}"; shift 2;; | ||
| *) echo "unknown arg: $1" >&2; exit 2;; | ||
| esac | ||
| done |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Same missing-value edge case as run-extractor.sh's --image parsing.
If --ref is passed with no following value, shift 2 on a single remaining positional param fails under set -e, crashing before the [ -n "$REF" ] check at line 36 can produce the intended "인자 오류" message.
🤖 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 `@infra/scripts/provision-observability.sh` around lines 29 - 34, Update the
argument parser’s --ref branch in the while loop to validate that a following
value exists before assigning REF and shifting two arguments. When the value is
missing, exit through the existing argument-error path so the intended “인자 오류”
message is emitted instead of letting shift fail.
| curl -fsSL "$INFRA_RAW_BASE/config.alloy" -o "$WORK_DIR/config.alloy" \ | ||
| || { echo "config.alloy fetch 실패 (ref=$REF)" >&2; exit 1; } | ||
| curl -fsSL "$INFRA_RAW_BASE/provision-alloy.sh" -o "$WORK_DIR/provision-alloy.sh" \ | ||
| || { echo "provision-alloy.sh fetch 실패 (ref=$REF)" >&2; exit 1; } |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== infra/scripts/provision-observability.sh ==\n'
wc -l infra/scripts/provision-observability.sh
sed -n '1,140p' infra/scripts/provision-observability.sh
printf '\n== Search for REF defaults and integrity checks ==\n'
rg -n --no-heading -S 'REF=|--ref|checksum|sha256|signature|gpg|cosign|main' infra/scriptsRepository: TeamPiKi/extractor
Length of output: 4591
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== infra/scripts/run-extractor.sh ==\n'
wc -l infra/scripts/run-extractor.sh
sed -n '1,220p' infra/scripts/run-extractor.shRepository: TeamPiKi/extractor
Length of output: 3331
Pin the fetched observability scripts instead of defaulting to main
infra/scripts/provision-observability.sh:27,44-47fetchesconfig.alloyandprovision-alloy.shfromTeamPiKi/infra/mainby default, then executes the fetchedprovision-alloy.shdirectly.infra/scripts/run-extractor.sh:84does the same forblocks/healthcheck.sh.- Pin the default ref to a tagged release or commit SHA; keep
--reffor intentional overrides.
🤖 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 `@infra/scripts/provision-observability.sh` around lines 44 - 47, Update the
default ref configuration used by provision-observability.sh and
run-extractor.sh so fetched observability scripts resolve to a tagged release or
commit SHA instead of main. Preserve the existing --ref override behavior, and
ensure config.alloy, provision-alloy.sh, and blocks/healthcheck.sh continue
using the selected ref.
| while [ $# -gt 0 ]; do | ||
| case "$1" in | ||
| --image) IMAGE="${2:-}"; shift 2;; | ||
| *) echo "unknown arg: $1" >&2; exit 2;; | ||
| esac | ||
| done |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
--image with no value crashes ambiguously instead of a clean usage error.
If --image is the last token (no value follows), shift 2 runs with only one positional param left. Under set -euo pipefail, shift's nonzero exit (n > $#) triggers immediate script exit — before reaching the --image is required check at line 32 — with a confusing failure instead of the documented "인자 오류".
🐛 Proposed fix
case "$1" in
- --image) IMAGE="${2:-}"; shift 2;;
+ --image)
+ [ $# -ge 2 ] || { echo "--image requires a value" >&2; exit 2; }
+ IMAGE="$2"; shift 2;;
*) echo "unknown arg: $1" >&2; exit 2;;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| while [ $# -gt 0 ]; do | |
| case "$1" in | |
| --image) IMAGE="${2:-}"; shift 2;; | |
| *) echo "unknown arg: $1" >&2; exit 2;; | |
| esac | |
| done | |
| while [ $# -gt 0 ]; do | |
| case "$1" in | |
| --image) | |
| [ $# -ge 2 ] || { echo "--image requires a value" >&2; exit 2; } | |
| IMAGE="$2"; shift 2;; | |
| *) echo "unknown arg: $1" >&2; exit 2;; | |
| esac | |
| done |
🤖 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 `@infra/scripts/run-extractor.sh` around lines 25 - 30, Update the --image
branch in the argument-parsing loop to validate that a following value exists
before assigning IMAGE and shifting two arguments. When --image is the final
token, emit the script’s documented argument-error usage message and exit
cleanly instead of invoking shift 2 with insufficient parameters; preserve
existing handling for valid values and unknown arguments.
| docker run -d --name piki-extractor --restart unless-stopped \ | ||
| -p 8090:8090 \ | ||
| --add-host=host.docker.internal:host-gateway \ | ||
| --label piki.observe=true \ | ||
| --label piki.service=piki-extractor \ | ||
| --label piki.metrics.port=8090 \ | ||
| --label piki.metrics.path=/actuator/prometheus \ | ||
| -e AWS_REGION=ap-northeast-2 \ | ||
| -e GEMINI_API_KEY="$GEMINI_API_KEY" \ | ||
| -e TRACING_OTLP_ENABLED=true \ | ||
| -e OTLP_ENDPOINT=http://host.docker.internal:4318/v1/traces \ | ||
| -e LOGGING_STRUCTURED_FORMAT_CONSOLE=ecs \ | ||
| "$IMAGE" |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Secret leaked via process command line.
GEMINI_API_KEY is passed with -e GEMINI_API_KEY="$GEMINI_API_KEY" on the docker run invocation. This value becomes part of the docker process's argv, which is visible to any local user via ps aux / /proc/<pid>/cmdline (and shell history if run interactively) while the command executes — a classic CWE-214-style secret exposure. docker inspect will still show the resolved env either way, but avoiding argv exposure is a straightforward hardening step.
🛡️ Proposed fix using an env-file with restricted permissions
+ENV_FILE=$(mktemp)
+chmod 600 "$ENV_FILE"
+trap 'rm -f "$ENV_FILE"' EXIT
+cat > "$ENV_FILE" <<EOF
+AWS_REGION=ap-northeast-2
+GEMINI_API_KEY=$GEMINI_API_KEY
+TRACING_OTLP_ENABLED=true
+OTLP_ENDPOINT=http://host.docker.internal:4318/v1/traces
+LOGGING_STRUCTURED_FORMAT_CONSOLE=ecs
+EOF
+
docker run -d --name piki-extractor --restart unless-stopped \
-p 8090:8090 \
--add-host=host.docker.internal:host-gateway \
--label piki.observe=true \
--label piki.service=piki-extractor \
--label piki.metrics.port=8090 \
--label piki.metrics.path=/actuator/prometheus \
- -e AWS_REGION=ap-northeast-2 \
- -e GEMINI_API_KEY="$GEMINI_API_KEY" \
- -e TRACING_OTLP_ENABLED=true \
- -e OTLP_ENDPOINT=http://host.docker.internal:4318/v1/traces \
- -e LOGGING_STRUCTURED_FORMAT_CONSOLE=ecs \
+ --env-file "$ENV_FILE" \
"$IMAGE"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| docker run -d --name piki-extractor --restart unless-stopped \ | |
| -p 8090:8090 \ | |
| --add-host=host.docker.internal:host-gateway \ | |
| --label piki.observe=true \ | |
| --label piki.service=piki-extractor \ | |
| --label piki.metrics.port=8090 \ | |
| --label piki.metrics.path=/actuator/prometheus \ | |
| -e AWS_REGION=ap-northeast-2 \ | |
| -e GEMINI_API_KEY="$GEMINI_API_KEY" \ | |
| -e TRACING_OTLP_ENABLED=true \ | |
| -e OTLP_ENDPOINT=http://host.docker.internal:4318/v1/traces \ | |
| -e LOGGING_STRUCTURED_FORMAT_CONSOLE=ecs \ | |
| "$IMAGE" | |
| ENV_FILE=$(mktemp) | |
| chmod 600 "$ENV_FILE" | |
| trap 'rm -f "$ENV_FILE"' EXIT | |
| cat > "$ENV_FILE" <<EOF | |
| AWS_REGION=ap-northeast-2 | |
| GEMINI_API_KEY=$GEMINI_API_KEY | |
| TRACING_OTLP_ENABLED=true | |
| OTLP_ENDPOINT=http://host.docker.internal:4318/v1/traces | |
| LOGGING_STRUCTURED_FORMAT_CONSOLE=ecs | |
| EOF | |
| docker run -d --name piki-extractor --restart unless-stopped \ | |
| -p 8090:8090 \ | |
| --add-host=host.docker.internal:host-gateway \ | |
| --label piki.observe=true \ | |
| --label piki.service=piki-extractor \ | |
| --label piki.metrics.port=8090 \ | |
| --label piki.metrics.path=/actuator/prometheus \ | |
| --env-file "$ENV_FILE" \ | |
| "$IMAGE" |
🤖 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 `@infra/scripts/run-extractor.sh` around lines 48 - 60, Remove the inline
GEMINI_API_KEY assignment from the docker run command in run-extractor.sh.
Create a temporary environment file with restricted permissions, write the key
there, pass it using Docker’s env-file option, and ensure the file is cleaned up
after the container starts while preserving the existing container
configuration.
| # --- 3. 헬스 대기 - 공통 healthcheck 블록을 dogfooding --- | ||
| HEALTHCHECK_SH="/tmp/piki-run-extractor-healthcheck.sh" | ||
| curl -fsSL https://raw.githubusercontent.com/TeamPiKi/infra/main/blocks/healthcheck.sh -o "$HEALTHCHECK_SH" \ | ||
| || { echo "healthcheck.sh fetch 실패" >&2; exit 1; } |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== run-extractor excerpt ==\n'
sed -n '60,120p' infra/scripts/run-extractor.sh
printf '\n== provision-observability excerpt ==\n'
sed -n '1,220p' infra/scripts/provision-observability.sh
printf '\n== search for healthcheck.sh and ref override ==\n'
rg -n "healthcheck\.sh|--ref|raw\.githubusercontent|bash .*healthcheck|HEALTHCHECK_SH" infra/scriptsRepository: TeamPiKi/extractor
Length of output: 6109
Pin the fetched healthcheck script instead of pulling main. run-extractor.sh downloads blocks/healthcheck.sh from TeamPiKi/infra/main and runs it with bash, so any change on that branch is immediately trusted on the prod extractor box. Add a --ref/commit-SHA pin or checksum/signature check like provision-observability.sh.
🤖 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 `@infra/scripts/run-extractor.sh` around lines 82 - 85, Update the healthcheck
download flow in run-extractor.sh around HEALTHCHECK_SH to pin the fetched
healthcheck.sh to a trusted immutable ref or validate it with a
checksum/signature, following the existing approach in
provision-observability.sh; ensure the script is only executed after that pin or
verification succeeds.
Situation
extractor prod 박스(EC2)에는 지금 수집기가 없어 메트릭을 core 박스 Alloy 가 크로스박스로 긁어가고 있다. 이를 "박스마다 Alloy" 구조로 바꾸려 한다. 또한 앱 컨테이너(piki-extractor)는 지금까지 임시(수동 SSM)로 기동돼 run 파라미터가 repo 어디에도 없다.
Task
Action
infra/scripts/provision-observability.sh: TeamPiKi/infra 의 공통 Alloy 블록(blocks/alloy/config.alloy,provision-alloy.sh)을 fetch 하고, Grafana Cloud 자격(metrics/logs/token 필수 5종, traces 선택 2종)을 SSM Parameter Store 에서 조회해 env 로 얹은 뒤 extractor 값(environment=prod,box=piki-extractor)으로 공통 블록을 호출한다.--ref로 infra PR 머지 전 브랜치 선검증 가능.infra/scripts/run-extractor.sh: GEMINI_API_KEY 를 SSM 에서 조회해 앱 컨테이너를 재기동한다. 관측 label opt-in 4종(piki.observe/piki.service/piki.metrics.port/piki.metrics.path)과 트레이스 export env(TRACING_OTLP_ENABLED,OTLP_ENDPOINT), 구조화 로깅 env(LOGGING_STRUCTURED_FORMAT_CONSOLE=ecs)를 신설 배선하고, 공통 healthcheck 블록으로 기동 완료를 확인한다.README.md: "운영 (prod 박스)" 섹션 추가.TRACING_OTLP_ENABLED/OTLP_ENDPOINTenv 배선은application.yml에 이미 존재.Result
bash -n두 스크립트 통과.run-extractor.sh인자 없이 → exit 2, 알 수 없는 인자 → exit 2.provision-observability.sh알 수 없는 인자 → exit 2.의존성: TeamPiKi/infra 의 공통 Alloy 블록(
blocks/alloy/config.alloy,provision-alloy.sh) PR 이 아직 main 에 없다. 그 PR 이 머지된 후provision-observability.sh를 적용할 수 있다(머지 전에는--ref로 그 PR 의 브랜치를 지정해 선검증 가능).Summary by CodeRabbit
New Features
Documentation