AWS ECR & CodeDeploy
Docker, ECR, CodeDeploy를 이용한 CI/CD 구축 과정
목차
구조
IAM 역할 생성
EC2
EC2 콘솔에 들어가서 EC2에게 IAM 역할을 부여한다.
CodeDeploy
CodeDeploy Agent 설치
EC2에 code-deploy-agent 설치
❗️ 권한 설정이 잘 못 된 채로 agent를 설치했다면(agent 설치 후 console에서 IAM 정책을 변경했다면) EC2에서 권한 관련한 파일을 삭제하고 agent를 restart하는 과정이 필요하다.
# AWS 자격증명 파일 삭제
$ sudo rm -rf /root/.aws/credentials
# codedeploy-agent 재시작
$ sudo systemctl restart codedeploy-agent
ECR 생성
돈을 지불하고 싶지 않아 Public Registry로 생성했다.
❗️ Public으로 repository를 생성하니 리전이 us-east-1
로 생성되었다(private은 서울 리전으로 잘 생성됨).
github actions에서 ECR에 로그인 하는 과정에서 리전 헷갈리면 안된다.
CodeDeploy 생성
- 애플리케이션 생성
- 배포그룹 생성
이때 앞서 IAM 역할 생성할 때 만든 code-deploy-role를 서비스 역할에 입력한다.
S3 생성
모든 퍼블릭 액세스는 차단했다.
Dockerfile
프로젝트 최상단에 Dockerfile를 작성한다.
FROM openjdk:17 AS builder
COPY gradlew .
COPY gradle gradle
COPY build.gradle .
COPY settings.gradle .
COPY src src
RUN chmod +x ./gradlew
RUN microdnf install findutils
RUN ./gradlew build -x test --no-daemon
FROM openjdk:17-alpine
RUN mkdir /opt/app
COPY --from=builder build/libs/gifthub-0.0.1-SNAPSHOT.jar /opt/app/spring-boot-application.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar","/opt/app/spring-boot-application.jar"]
이때 xargs is not available
error가 발생해서 아래 명령을 추가했다. gradle 7.5 버전에서 발생한다고 한다.
RUN microdnf install findutils
이 Dockerfile은 이미지 빌드 시 실행될 것이다. 또한 이미지 용량을 줄이는 다양한 최적화 방법이 시도될 수 있을 것이다.
또한 EC2에 미리 docker가 설치, 권한 설정이 되어 있어야 한다.
appspec.yml
프로젝트 최상단에 작성한다.
codedeploy를 사용하기 위해 필요하며, 후에 github actions에 동적으로 작성되는 deploy.sh
와 함께 S3에 zip파일로 저장될 것이다.
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/app
overwrite: yes
permissions:
- object: /
pattern: "**"
owner: ubuntu
group: ubuntu
mode: 755
hooks:
AfterInstall:
- location: scripts/deploy.sh
timeout: 1800
runas: ubuntu
Github Actions
name: ci/cd
on:
push:
branches: [ "dev" ]
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout Pull Request
uses: actions/checkout@v3
with:
ref: $
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: $
aws-secret-access-key: $
aws-region: ap-northeast-2
- name: Login to public ECR
uses: docker/login-action@v2
with:
registry: public.ecr.aws
username: $
password: $
env:
AWS_REGION: us-east-1
- name: check file path
run: |
ls -al
pwd
shell: bash
- name: build and push image to AWS ECR
env:
IMAGE_TAG: $
run: |
docker build -t $/ci-cd-test:$IMAGE_TAG .
docker push $/ci-cd-test:$IMAGE_TAG
mkdir scripts
touch scripts/deploy.sh
echo "aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $" >> scripts/deploy.sh
echo "docker pull $/ci-cd-test:$IMAGE_TAG" >> scripts/deploy.sh
echo "docker run -p 8080:8080 -d --restart always --name ci-cd-test $/ci-cd-test:$IMAGE_TAG" >> scripts/deploy.sh
- name: upload to s3 with appspec.yml and deploy.sh
env:
IMAGE_TAG: $
run: |
zip -r deploy-$IMAGE_TAG.zip ./scripts appspec.yml
aws s3 cp --region ap-northeast-2 --acl private ./deploy-$IMAGE_TAG.zip s3://inhee-ci-cd-test
- name: deploy to EC2 server
env:
IMAGE_TAG: $
run: |
aws deploy create-deployment --application-name ci-cd-test \
--deployment-config-name CodeDeployDefault.OneAtATime \
--deployment-group-name ci-cd-test \
--s3-location bucket=inhee-ci-cd-test,bundleType=zip,key=deploy-$IMAGE_TAG.zip
- github 레포의 최신상태를 가져온다.
- java 17 버전 setup
- AWS 로그인 (IAM에서 보안자격증명에 CSV파일 받을 수 있음)
- ECR 로그인 (private ECR인지 public ECR인지 로그인 방법이 다르므로 자료 참고하기)
- 파일 확인
- docker 이미지 빌드 및 ECR에 이미지 push
- 이미지 별로 버전을 구분할 수 있도록
github.sha
값으로 이미지 태그 값을 설정함 - 이미지가 계속 바뀌므로
deploy.sh
를 동적으로 작성함
- 이미지 별로 버전을 구분할 수 있도록
deploy.sh
와appspec.yml
을 S3에 업로드- CodeDeploy 실행
- S3에서 deploy.sh와 appspec.yml을 가져와 배포
결과
- Github Actions
- ECR
- S3
- CodeDeploy
- EC2
장점
복잡하긴 하다. ssh tunnelling이용해서 docker image pull 해서 배포하는게 가장 쉬운 것 같다.
그래도 장점이 있다면 배포 시간이나 어떤 버전을 배포했는지 모두 기록되기 때문에 배포 버전관리가 쉽다는 장점이 있는 것 같다.
또한 나중에 무중단 배포 할때, AWS CodeDeploy에서 Console로 쉽게 제공하기 때문에 이 부분에서도 이점이 있는 것 같다.