[CI/CD] CI/CD Pipeline 구축 (6) - SSM Document 작성 & 테스트 배포
해당 프로젝트의 전체소스는 여기 에서 확인하실 수 있습니다.
1. SSM Document란?
AWS Systems Manager(SSM)의 Document는 EC2 인스턴스에 실행할 명령어를 정의한 스크립트 파일입니다.
CI/CD 파이프라인에서는 배포 스크립트를 이 Document로 관리하여,
GitHub Actions → SSM RunCommand → EC2 순서로 원격 배포를 실행합니다.
- 형식: JSON 또는 YAML
- 버전:
schemaVersion으로 명시 (주로2.2) - 실행 방식:
aws:runShellScript사용 → EC2에서 쉘 스크립트 실행
2. Document 생성
콘솔: Systems Manager > Documents > Create document > Command or Session
- 이름:
spring-plus-deploy - 유형:
Command document - 형식:
YAML
Document 내용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
schemaVersion: '2.2'
description: Deploy spring-plus container on /opt/spring-plus using /spring-plus/prod/* parameters
parameters:
ImageTag:
type: String
default: latest
description: Docker image tag (e.g., commit SHA or latest)
mainSteps:
- action: aws:runShellScript
name: deploy
inputs:
runCommand:
- |
#!/usr/bin/env bash
set -euo pipefail
APP_NAME="spring-plus"
IMAGE="younghunkimm/spring-plus:"
PORT=8080
ENV_DIR="/opt/spring-plus/env"
# 1) 디렉토리 준비
mkdir -p "$ENV_DIR"
# 2) Parameter Store -> app.env 생성
aws ssm get-parameters-by-path \
--path "/spring-plus/prod/" \
--with-decryption \
--region ap-northeast-2 \
| jq -r '.Parameters[] | "\(.Name | split("/")[-1])=\(.Value)"' > "$ENV_DIR/app.env"
echo "[env] written -> $ENV_DIR/app.env"
# 3) (선택) Docker Hub private이면 로그인
if grep -q "^DOCKERHUB_TOKEN=" "$ENV_DIR/app.env"; then
DOCKERHUB_USERNAME=$(grep "^DOCKERHUB_USERNAME=" "$ENV_DIR/app.env" | cut -d= -f2- || true)
DOCKERHUB_TOKEN=$(grep "^DOCKERHUB_TOKEN=" "$ENV_DIR/app.env" | cut -d= -f2- || true)
if [ -n "$DOCKERHUB_USERNAME" ] && [ -n "$DOCKERHUB_TOKEN" ]; then
echo "$DOCKERHUB_TOKEN" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin || true
fi
fi
# 4) 이미지 풀 & 기존 컨테이너 정리
docker pull "$IMAGE"
docker rm -f "$APP_NAME" || true
# 5) 컨테이너 실행
docker run -d --name "$APP_NAME" \
--env-file "$ENV_DIR/app.env" \
-p ${PORT}:8080 \
--restart unless-stopped \
"$IMAGE"
# 6) 헬스체크
MAX_RETRIES=30
SLEEP_SEC=2
for ((i=1; i<=MAX_RETRIES; i++)); do
if curl -fsS "http://localhost:${PORT}/actuator/health" >/dev/null; then
echo "HEALTH: UP"
break
fi
echo "[$i/$MAX_RETRIES] waiting..."
sleep "$SLEEP_SEC"
done
if [ "$i" -gt "$MAX_RETRIES" ]; then
echo "HEALTH CHECK FAILED"
docker logs --tail=200 "$APP_NAME" || true
exit 1
fi
환경변수(env) 적용 과정 설명 [1 ~ 2 단계]
SSM Parameter Store에서 저장된 값을 가져와app.env파일에 내용을 작성하고 서버에 파일 생성- 도커 컨테이너가 실행될 때 해당
app.env파일을 환경 변수 파일로 지정mkdir -p옵션으로/opt폴더 내에/opt/spring-plus/env폴더 생성하는데spring-plus폴더가 없다면 같이 생성
Docker Hub 로그인 과정 설명 [3 단계]
- Docker Hub가 private 이면
parameter store에DOCKERHUB_USERNAME,DOCKERHUB_TOKEN설정
- 해당 값이 있다면 자동 로그인, 없다면 public으로 판단
배포 경로
/opt/spring-plus: 애플리케이션 관련 파일 저장 위치
✅ 장점
- 시스템 표준 위치라 “서비스 배포 경로”라는 의도가 명확
- root 권한으로 관리되므로 보안/권한 제어 용이
- 다른 사용자 계정과 충돌 없음
❌ 단점
- 매번
sudo필요 - 일반 사용자 계정에서 접근할 때 번거로움
3. Document 실행 테스트
태깅된 EC2 인스턴스(e.g. SSMTarget=spring-plus)가 있다면,
AWS에서 제공하는 SSM Run Command 기능을 통해 Document를 실행할 수 있습니다.
또, DockerHub에 Push된 이미지가 있어야 합니다.
만약 실행에 실패했다면
인스턴스 중 하나에 SSH로 접속하여 아래 명령어를 실행해 로그를 확인합니다.
1
2
3
4
5
docker ps -a
docker logs <YOUR_CONTAINER_NAME> --tail=200
# 특정 문자열로 로그를 검색하고 싶다면
docker logs <YOUR_CONTAINER_NAME> | grep "<SEARCH_KEYWORD>"
실행에 성공했다면
인스턴스 중 하나에 SSH로 접속하여 스프링 부트 실행 확인 및 헬스 체크를 해봅니다.
1
2
3
4
5
docker ps -a
docker logs <YOUR_CONTAINER_NAME> --tail=200
# Health check
curl -i http://localhost:8080/actuator/health
4. 파이프라인 연계
이제 이 Document는 CD 워크플로우에서 호출하게 됩니다.
- GitHub Actions에서 OIDC Role Assume
aws ssm send-command실행- 파라미터로
ImageTag=$전달 - 태그(
SSMTarget=spring-plus) 붙은 모든 EC2에 배포
즉, 배포 스크립트를 GitHub Actions 안에 직접 쓰는 대신, SSM Document에 캡슐화하여 관리하는 방식입니다.
장점:
- 배포 로직을 AWS에 중앙 집중 관리
- 배포 스크립트 변경 시 GitHub Actions YAML을 수정할 필요 없음
- EC2 개수 증가 시 태그 기반으로 자동 확장 적용
다음 포스팅
이번 포스팅에서는 SSM Document 작성 & 테스트 배포 과정을 정리했습니다.
다음 포스팅에서는 GitHub Actions CI/CD 워크플로우 과정을 다룹니다.

