오늘은 Github Actions를 이용하여 Github Repository에 새로운 코드가 push 되었을 때 ECS 서비스에 코드를 반영하는 워크플로를 만들어봅시다.
1. AWS 리소스 준비
Fargate를 사용하는 ECS Service와 ALB를 같이 준비합니다.
Go 애플리케이션은 /v1/color에 접속하면 Red, Green, Yellow를 랜덤으로 반환하게 합니다.
Docker Image를 생성하기 위해 Dockerfile을 작성합니다.
이미지를 가볍게 하기 위해 Multi Stage Build를 사용합니다. 빌드 후 실행파일을 Alpine으로 보내 애플리케이션을 실행합니다.
FROM public.ecr.aws/docker/library/golang:alpine AS builder
WORKDIR /build
COPY go.mod main.go ./
RUN go build -o main .
FROM public.ecr.aws/docker/library/alpine
WORKDIR /app
COPY --from=builder /build/main .
RUN apk --no-cache add curl
CMD ["./main"]
2. Github Actions 설정
Github에서 새 Repository 하나를 생성합니다. 그 후 Settings > Secrets and variables > Actions를 누릅니다.
배포에 필요한 권한을 가지고 있는 IAM User에서 Access Key를 발급받은 후, Repository secrets에서 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY를 각각 등록합니다.
로컬로 Repository를 clone 하여 CI/CD에 필요한 파일들을 작성합니다.
- .github/workflows/main.yml : CI/CD 워크플로가 진행되는 조건이나 과정 등을 명시합니다. 꼭 .github/workflows에 위치해야 하고, yml 파일 이름은 상관없습니다.
- Dockerfile, main.go, go.mod : Golang 애플리케이션 빌드 및 실행에 필요한 파일들입니다.
main.yml의 코드는 다음과 같습니다.
- .on : main 브랜치의 파일들이 push 되었을 때 워크플로가 진행되도록 합니다. workflow_dispatch도 추가하여 수동으로 워크플로를 실행할 수 있게 합니다.
- .env : 워크플로에 사용되는 환경변수를 정의합니다. (배포 리전, ECR Repository 이름, ECS Service 이름, ECS Cluster 이름, Task Definition의 이름, ECS Service의 Container 이름)
- .job.deploy.steps
- Checkout release : Github Repository의 코드를 Github가 제공하는 CI 서버로 전달시킵니다.
- AWS configure credentials : Secret으로 입력한 Access Key를 등록합니다.
- Login to Amazon ECR : ECR Repository에 이미지를 저장할 수 있도록 로그인합니다.
- Build, tag, and push image to Amazon ECR : SHA 해시를 태그로 사용하여 이미지를 빌드하고, ECR Repository로 보냅니다.
- Download task definition : ECS Task Definition 정보를 다운로드하여 json 파일로 저장합니다.
- Fill in the new image ID in the Amazon ECS task definition : 새로운 이미지를 사용하여 새로운 Task Definition을 생성합니다.
- Deploy Amazon ECS task definition : ECS Service가 새로운 버전의 Task Definition을 사용하도록 합니다.
name: Deploy to Amazon ECS
on:
push:
branches:
- main
workflow_dispatch:
env:
AWS_REGION: ap-northeast-2
ECR_REPOSITORY: color
ECS_SERVICE: color-svc
ECS_CLUSTER: demo-cluster
TD_NAME: color-td
CONTAINER_NAME: color
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
- name: Download task definition
run: |
aws ecs describe-task-definition --task-definition $TD_NAME --query taskDefinition > task-definition.json
- name: Fill in the new image ID in the Amazon ECS task definition
id: task-def
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: task-definition.json
container-name: ${{ env.CONTAINER_NAME }}
image: ${{ steps.build-image.outputs.image }}
- name: Deploy Amazon ECS task definition
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.task-def.outputs.task-definition }}
service: ${{ env.ECS_SERVICE }}
cluster: ${{ env.ECS_CLUSTER }}
wait-for-service-stability: true
3. CI/CD 테스트
이번에는 Red, Green, Blue를 랜덤으로 반환하도록 코드를 수정해 보겠습니다.
이제 코드를 commit & push 하여 애플리케이션에 반영됐는지 확인해 봅시다.
Github Repository의 Actions 탭에 가보면 CI/CD가 성공적으로 진행된 것을 확인할 수 있습니다.
웹사이트를 새로고침 하면 Red, Green, Blue가 랜덤으로 반환되는 것을 볼 수 있습니다.
오늘의 글은 여기까지입니다. 감사합니다!
'AWS' 카테고리의 다른 글
[AWS] AWS Config로 Security group 감시하기 (0) | 2024.01.02 |
---|---|
[AWS] Github Actions로 ECS 서비스에 배포 (Blue / Green) (2) | 2023.12.31 |
[AWS] Github Actions로 CodeDeploy 실행 (EC2) (0) | 2023.12.29 |
[AWS] SSH 액세스 실패를 감지하여 이메일에 알리기 (0) | 2023.11.28 |
[AWS] Golang Gin 이미지를 만들어서 ECR에 Push (0) | 2023.10.14 |