[AWS] GitHub Actions 배포: SSH, PEM없이 AWS SSM으로 배포 방법 개선하기
2025년 4월 25일
기존 배포 파이프라인에서 GitHub Actions Runner가 EC2에 SSH로 접속해 Docker를 실행하는 단계가 있었다. appleboy/ssh-action을 사용하기 위해 GitHub Secrets에 **PEM(Private Key)**을 직접 등록해 사용했다.
문제:
- GitHub 계정이 탈취되면 서버의 개인키도 함께 노출된다.
- 외부 서비스(GitHub)에 PEM 키 원본을 저장하는 구조 자체가 보안 취약점이다.
해결: **AWS Systems Manager (SSM)**을 사용하면 SSH 없이 IAM 권한만으로 EC2에 명령을 실행할 수 있다. 접속 주체가 SSH에서 AWS SSM으로 바뀌는 구조다.
1단계 EC2에 SSM 권한 부여
EC2가 SSM 서비스와 통신할 수 있도록 IAM 역할을 부여한다.
- AWS 콘솔에서 IAM > 역할(Roles) > 역할 만들기(Create role) 클릭.
- 신뢰할 수 있는 엔터티 유형:
AWS 서비스선택. - 사용 사례:
EC2선택 후 다음. - 권한 정책 검색에서
AmazonSSMManagedInstanceCore추가. - 역할 이름 지정(예:
EC2-SSM-Role) 후 생성 완료.
기존에 ECR 접근 등을 위해 만들어둔 역할이 있다면, 해당 역할에
AmazonSSMManagedInstanceCore정책만 추가해도 된다.
2단계 GitHub Actions IAM 사용자에 권한 추가
aws-actions/configure-aws-credentials에서 사용하는 IAM 사용자에게 SSM 명령 실행 권한을 추가한다.
- IAM > 사용자(Users) > GitHub Secrets(
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY)에 등록된 사용자 클릭. - 권한 탭 > 권한 추가 > 정책 연결(Attach policies) 클릭.
AmazonSSMFullAccess검색 후 연결.
3단계 EC2에 역할 적용
- EC2 콘솔 > 인스턴스 선택.
- 작업(Actions) > 보안(Security) > IAM 역할 수정(Modify IAM role).
- 생성한
EC2-SSM-Role선택 후 IAM 역할 업데이트 클릭.
4단계 GitHub Actions 워크플로우 수정
deploy.yml에서 SSH 관련 부분을 SSM 명령으로 교체한다.
기존 방식 SSH
- name: Deploy to EC2
uses: appleboy/ssh-action@v1.0.0
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ secrets.ECR_REPOSITORY }}
IMAGE_TAG: ${{ env.IMAGE_TAG }}
AWS_REGION: ${{ secrets.AWS_REGION }}
with:
host: ${{ secrets.EC2_HOST }} # 퍼블릭 주소
username: ${{ secrets.EC2_USER }} # 우분투
key: ${{ secrets.EC2_SSH_KEY }} # pem
port: 22
script: |
# 도커 실행 스크립트...
변경 후 AWS SSM
- name: Deploy to EC2 via SSM
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ secrets.ECR_REPOSITORY }}
AWS_REGION: ${{ secrets.AWS_REGION }}
IMAGE_TAG: ${{ env.IMAGE_TAG }}
run: |
aws ssm send-command \
--document-name "AWS-RunShellScript" \
--targets "Key=instanceids,Values=${{ secrets.EC2_INSTANCE_ID }}" \
--comment "Deploy Next.js App ($IMAGE_TAG)" \
--parameters commands='[
# 도커 실행 스크립트...
]'
AWS-RunShellScript 문서를 사용하면 기존 배포 스크립트를 리스트 형태로 그대로 넣을 수 있다.
GitHub Secrets에서 관리하던 EC2_HOST, EC2_USER, EC2_SSH_KEY를 모두 제거하고 EC2_INSTANCE_ID 하나만 남긴다.