Cloudflare + AWS SSM 자동화 가이드
Cloudflare + AWS SSM 자동화 가이드
목적
- Cloudflare 배포 필수값을 AWS SSM 한 곳에 저장
- 배포 워크플로가 SSM 에서 직접 읽게 한다 (GitHub Secret/Variable 복사본을 두지 않는다)
mainpush 시 블로그 자동 배포
2026-09-13 에 GitHub Repository Secret 25개·Variable 8개를 전량 삭제했다. 워크플로에
$·$가 하나라도 있으면scripts/ci/check-no-github-config.mjs가 CI 를 실패시킨다. 그래서 이 문서에서 “GitHub 에 동기화” 하는 절차는 더 이상 없다.
필요한 값 (사용자가 제공)
CLOUDFLARE_ACCOUNT_ID또는CF_ACCOUNT_IDCLOUDFLARE_API_TOKEN또는CF_API_TOKENCLOUDFLARE_WEB_ANALYTICS_TOKEN또는CF_WEB_ANALYTICS_TOKENCLOUDFLARE_PAGES_PROJECT또는CF_PROJECT_NAME(kjg-blog) — 비밀이 아니고 SSM 에 두지 않는다. 배포 워크플로가CLOUDFLARE_PROJECT_NAME리터럴로 들고 있다.
SSM 경로
배포 워크플로가 실제로 읽는 경로다. 예전 문서는 /solodev/ci/blog/cloudflare/* 를
적어 두었는데 그 경로에는 파라미터가 한 번도 만들어진 적이 없었다 — 등록하는 곳과
읽는 곳이 달라서, 등록 스크립트를 돌려도 배포에는 아무 영향이 없었다(2026-09-13 수정).
| 키 | SSM 경로 | 타입 |
|---|---|---|
| Cloudflare Account ID | /solodev/ci/github-secrets/CLOUDFLARE_ACCOUNT_ID |
SecureString |
| Cloudflare API Token | /solodev/ci/github-secrets/CLOUDFLARE_API_TOKEN |
SecureString |
| Cloudflare Web Analytics Token | /solodev/ci/github-secrets/CLOUDFLARE_WEB_ANALYTICS_TOKEN |
SecureString |
워크플로가 읽는 방법
- uses: ./.github/actions/aws-secrets-read
with: { role-session-name: solodev-blog-secrets-read }
- run: |
bash scripts/ci/load-ssm-into-env.sh \
CLOUDFLARE_ACCOUNT_ID CLOUDFLARE_API_TOKEN CLOUDFLARE_WEB_ANALYTICS_TOKEN
로더가 값을 GITHUB_ENV 에 넣고 로그에서 가린다. 비밀이 아닌 값은
--prefix /solodev/ci/github-variables --no-mask 로 읽는다.
로컬 실행
로컬은 Secret 값을 출력하지 않는 동일한 등록 경로를 사용합니다. --dry-run은 AWS에 쓰지 않고 대상 파라미터와 타입만 확인합니다.
CLOUDFLARE_ACCOUNT_ID=... \
CLOUDFLARE_API_TOKEN=... \
CLOUDFLARE_WEB_ANALYTICS_TOKEN=... \
CLOUDFLARE_PAGES_PROJECT=kjg-blog \
bash scripts/blog/sync-cloudflare-blog-secrets-to-ssm.sh --dry-run
실제 등록:
CLOUDFLARE_ACCOUNT_ID=... \
CLOUDFLARE_API_TOKEN=... \
CLOUDFLARE_WEB_ANALYTICS_TOKEN=... \
CLOUDFLARE_PAGES_PROJECT=kjg-blog \
bash scripts/blog/sync-cloudflare-blog-secrets-to-ssm.sh --overwrite
원클릭 실행
CF_ACCOUNT_ID=... \
CF_API_TOKEN=... \
CF_WEB_ANALYTICS_TOKEN=... \
CF_PROJECT_NAME=kjg-blog \
scripts/blog/bootstrap-cloudflare-pages-from-values.sh --overwrite --create-project --trigger-deploy
실행 내용:
- SSM 파라미터 등록
- Cloudflare Pages 프로젝트 생성 시도
- 배포 워크플로우 실행
- 준비 상태 점검
GitHub 쪽 동기화 단계는 없앴다 — 워크플로가 SSM 에서 직접 읽는다.
수동 단계별 실행
1) SSM 등록
CF_ACCOUNT_ID=... \
CF_API_TOKEN=... \
CF_PROJECT_NAME=kjg-blog \
scripts/blog/register-cloudflare-blog-ssm.sh --overwrite
2) GitHub 동기화 — 없앴다
배포 워크플로가 SSM 에서 직접 읽으므로 GitHub 쪽 복사본을 만들지 않는다.
복사본이 있으면 SSM 과 갈라지고, 갈라진 순간 어느 쪽이 맞는지 알 수 없다.
scripts/ci/check-no-github-config.mjs 가 이 규칙을 CI 에서 막는다.
3) 준비 상태 점검
scripts/blog/check-cloudflare-blog-ready.sh
4) 배포 실행
gh workflow run deploy-cloudflare-pages-blog.yml
값 회전(최신화)
Cloudflare 토큰 변경 시 SSM 만 갱신하면 된다. 다음 배포가 그 값을 읽는다.
CF_ACCOUNT_ID=... \
CF_API_TOKEN=... \
CF_PROJECT_NAME=kjg-blog \
scripts/blog/register-cloudflare-blog-ssm.sh --overwrite
실패 시 점검
- AWS 권한:
aws sts get-caller-identity - SSM 값 확인:
aws ssm get-parameter --name /solodev/ci/github-secrets/CLOUDFLARE_ACCOUNT_ID --with-decryptionaws ssm get-parameter --name /solodev/ci/github-secrets/CLOUDFLARE_API_TOKEN --with-decryptionscripts/blog/check-cloudflare-blog-ready.sh가 위를 한 번에 본다
- GitHub 쪽은 볼 것이 없다 — Secret·Variable 을 두지 않는다(
gh secret list는 비어 있어야 정상) - 워크플로우 로그:
gh run list --workflow deploy-cloudflare-pages-blog.yml
GitHub Repository Secret 은 전량 SSM 으로 옮겼고, GitHub 쪽은 비웠다
2026-09-13 에 Repository Secret 25개와 Variable 8개를 전부 삭제했다. 값은 전에 이관해
둔 /solodev/ci/github-secrets/<이름>(SecureString)에 그대로 있고, 워크플로는 거기서만 읽는다.
- 비밀값:
/solodev/ci/github-secrets/<이름>(SecureString) - 비밀 아닌 설정값:
/solodev/ci/github-variables/<이름>(String) - 읽는 방법:
scripts/ci/load-ssm-into-env.sh(기본은 secrets 프리픽스 + 자동 마스킹,--prefix/--no-mask로 설정값용) - 규칙 강제:
scripts/ci/check-no-github-config.mjs— 워크플로에$나$가 하나라도 있으면 CI 가 실패한다 - 준비 상태 확인:
scripts/blog/check-github-secrets-ssm-ready.sh
scripts/blog/github-repository-secrets.txt 는 이관 당시 무엇이 있었는지의 기록이다.
GitHub 에는 이제 대응물이 없으므로 새 비밀값을 만들 때 여기 적을 필요가 없다.
자격증명을 얻기 전에 필요한 값(러너 라벨·OIDC 역할 ARN·리전)만 워크플로에 리터럴로 둔다. SSM 을 읽으려면 먼저 역할을 맡아야 하는데 그 역할 ARN 을 SSM 에서 읽을 수는 없기 때문이다. 셋 다 비밀이 아니고, 리터럴이어야 바뀐 이유가 PR diff 에 남는다.
GITHUB_TOKEN 은 Repository Secret 이 아니라 실행마다 발급되는 내장 token 이라 대상이 아니다.
워크플로에서는 $ 을 쓴다.