Cloudflare + AWS SSM 자동화 가이드
Cloudflare + AWS SSM 자동화 가이드
목적
- Cloudflare 배포 필수값을 AWS SSM에 저장
- GitHub Actions Secret을 AWS SSM에 최초 등록·회전
- SSM 최신값을 GitHub Actions에 동기화
mainpush 시 블로그 자동 배포
필요한 값 (사용자가 제공)
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 경로
| 키 | SSM 경로 | 타입 |
|---|---|---|
| Cloudflare Account ID | /solodev/ci/blog/cloudflare/account-id |
String |
| Cloudflare API Token | /solodev/ci/blog/cloudflare/api-token |
SecureString |
| Cloudflare Pages Project | /solodev/ci/blog/cloudflare/project-name |
String |
| Cloudflare Web Analytics Token | /solodev/ci/blog/cloudflare/web-analytics-token |
SecureString |
GitHub Secret은 GitHub API로 값을 읽을 수 없습니다. 따라서 Secret → SSM 등록은 GitHub Actions가 Secret을 실행 환경에 주입한 뒤 수행합니다. 로컬에서는 동일한 등록 스크립트에 같은 이름의 환경변수를 직접 주입합니다.
GitHub Secret → SSM 등록
GitHub에서 Sync Blog Cloudflare Secrets to SSM workflow를 workflow_dispatch로 실행합니다. workflow는 다음 값을 로그에 출력하지 않고 SSM에 기록합니다.
CLOUDFLARE_ACCOUNT_ID→StringCLOUDFLARE_API_TOKEN→SecureStringCLOUDFLARE_WEB_ANALYTICS_TOKEN→SecureStringCLOUDFLARE_PAGES_PROJECT=kjg-blog→String
AWS 접근에는 기존 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY GitHub Secret을 사용합니다. 이 두 AWS bootstrap credential은 Cloudflare SSM 값으로 복사하지 않습니다.
로컬 실행
로컬은 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 파라미터 등록
- GitHub Secret/Variable 동기화
- Cloudflare Pages 프로젝트 생성 시도
- 배포 워크플로우 실행
- 준비 상태 점검
수동 단계별 실행
1) SSM 등록
CF_ACCOUNT_ID=... \
CF_API_TOKEN=... \
CF_PROJECT_NAME=kjg-blog \
scripts/blog/register-cloudflare-blog-ssm.sh --overwrite
2) GitHub 동기화
scripts/blog/sync-cloudflare-blog-secrets-from-ssm.sh
3) 준비 상태 점검
scripts/blog/check-cloudflare-blog-ready.sh
4) 배포 실행
gh workflow run deploy-cloudflare-pages-blog.yml
값 회전(최신화)
Cloudflare 토큰 변경 시 아래 2개만 재실행:
CF_ACCOUNT_ID=... \
CF_API_TOKEN=... \
CF_PROJECT_NAME=kjg-blog \
scripts/blog/register-cloudflare-blog-ssm.sh --overwrite
scripts/blog/sync-cloudflare-blog-secrets-from-ssm.sh
실패 시 점검
- AWS 권한:
aws sts get-caller-identity - SSM 값 확인:
aws ssm get-parameter --name /solodev/ci/blog/cloudflare/account-idaws ssm get-parameter --name /solodev/ci/blog/cloudflare/api-token --with-decryption
- GitHub 설정 확인:
gh secret listgh variable list
- 워크플로우 로그:
gh run list --workflow deploy-cloudflare-pages-blog.yml
전체 GitHub Repository Secret의 SSM 이관
현재 Repository Secret 25개는 scripts/blog/github-repository-secrets.txt에 이름만 manifest로 관리합니다. Secret 값은 GitHub API로 읽을 수 없으므로, Sync GitHub Repository Secrets to SSM workflow가 Secret을 실행 환경에 주입해 등록합니다.
- Secret 파라미터:
/solodev/ci/github-secrets/<SECRET_NAME>(SecureString) - 배포 변수:
/solodev/ci/github-variables/CLOUDFLARE_PAGES_PROJECT(String) - 등록 workflow:
.github/workflows/sync-cloudflare-blog-secrets-to-ssm.yml - 로컬 등록:
scripts/blog/sync-github-repository-secrets-to-ssm.sh - Consumer workflow:
scripts/ci/load-github-secrets-from-ssm.sh로 필요한 값만 주입 - 준비 상태 확인:
scripts/blog/check-github-secrets-ssm-ready.sh
등록 workflow는 AWS_GITHUB_SECRETS_WRITE_ROLE_ARN GitHub Variable의 OIDC role을 사용합니다. Consumer workflow는 AWS_GITHUB_SECRETS_READ_ROLE_ARN을 사용합니다. 두 role은 main branch ref만 신뢰합니다.
GITHUB_TOKEN은 Repository Secret이 아니라 실행마다 생성되는 GitHub 내장 token이므로 SSM manifest에 포함하지 않습니다. workflow에서는 $을 사용합니다.
새 Repository Secret을 추가하면 manifest와 등록 workflow의 Secret env mapping을 함께 갱신해야 합니다. GitHub Secret 목록과 manifest가 일치하지 않으면 등록을 진행하지 않습니다.