11월 15일(금) ~ 11월 18일(월) 수업 중
AWS Elastic Container Registry(ECR)와 Elastic Container Service(ECS)를 활용하면 애플리케이션 배포 프로세스를 자동화하여 안정성과 효율성을 극대화할 수 있다. ECR과 ECS를 활용한 CI/CD 파이프라인을 단계별로 구축하는 방법을 정리하였다.
전체 목차는 아래와 같다.
0. ECR과 ECS 소개
1. Spring Boot 프로젝트 생성
2. Docker 이용한 CI/CD 적용
3. Git Ops 설정
4. Docker Hub와 연동하여 이미지 빌드 및 배포 자동화
5. AWS ECR(Elastic Container Registry)
6. GitHub Actions에서 ECR에 접근 설정
7. AWS ECS(Elastic Container Service)
8. Github Actions에서 ECS 적용하기 => CD
이전 단계와 다음 단계는 아래 두 글에서 확인 가능하다.
2024.11.19 - [분류 전체보기] - AWS ECR과 ECS를 이용한 CI/CD 구현(1)
5. AWS ECR(Elastic Container Registry)
AWS ECR(Elastic Container Registry)은 Docker 컨테이너 이미지를 저장하고 관리하는 완전 관리형 컨테이너 레지스트리 서비스
ECR(Elastic Container Registry) 에서 Private Repository 만들기
(5-1) ECR 접속해서 Repository 생성
🧐 Private Repository vs Public Repository
- Private Repository: 보안이 중요한 이미지 저장. 기본적으로 공개되지 않으며, 오직 인증된 사용자나 특정 IAM 권한을 가진 사용자만 접근.
- Public Repository: 공개적으로 접근이 가능, 인증 없이 누구나 이미지 다운로드가 가능하지만, 업로드하려면 인증 필요. 오픈소스 및 공공 이미지 배포에 적합.
(5-2) Repository 설정
1. 리포지토리 이름 설정
2. 리포지토리 암호화 설정
3. [생성]
아래와 같이 생성된 것을 확인할 수 있다.
Private Repository 에 Image Push 할 수 있는 정책 생성
(5-3) [IAM] > [정책] > [정책 생성]
(5-4) 정책 편집기에서 [JSON] 파일 수정
사용자가 AWS Elastic Container Registry (ECR) 서비스와 상호 작용할 수 있는 권한을 정의한다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:CompleteLayerUpload",
"ecr:UploadLayerPart",
"ecr:InitiateLayerUpload",
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage"
],
"Resource": "arn:aws:ecr:region:account-id:repository/cicd"
},
{
"Effect": "Allow",
"Action": "ecr:GetAuthorizationToken",
"Resource": "*"
}
]
}
구체적으로 살펴보면,
(1) 첫 번째 Statement는 특정 리포지토리(cicd)에 대해 컨테이너 이미지 업로드 및 관련 작업을 수행할 수 있는 권한을 부여한다.
{
"Effect": "Allow",
"Action": [
"ecr:CompleteLayerUpload",
"ecr:UploadLayerPart",
"ecr:InitiateLayerUpload",
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage"
],
"Resource": "arn:aws:ecr:region:account-id:repository/repository-name"
}
- Effect: "Allow" 이 부분은 해당 액션이 허용
- Action: 이 배열은 사용자가 수행할 수 있는 ECR 액션을 나열한다.
- ecr:CompleteLayerUpload: 레이어 업로드 완료 작업을 수행할 수 있다.
- ecr:UploadLayerPart: ECR에 컨테이너 이미지 레이어의 일부를 업로드할 수 있다.
- ecr:InitiateLayerUpload: ECR에 컨테이너 이미지 레이어 업로드를 시작할 수 있다.
- ecr:BatchCheckLayerAvailability: 특정 이미지 레이어가 ECR에 존재하는지 확인할 수 있다.
- ecr:PutImage: ECR에 이미지를 푸시할 수 있다.
- Resource: "arn주소:repository/cicd" 이 리소스 ARN(자원 이름)은 특정 ECR 리포지토리(여기서는 cicd라는 리포지토리)에 대한 권한을 부여하는 것이다.
(2) 두 번째 Statement는 ECR에 대한 인증 토큰을 요청할 수 있다.
{
"Effect": "Allow",
"Action": "ecr:GetAuthorizationToken",
"Resource": "*"
}
- Effect: "Allow" 이 부분은 해당 액션이 허용
- Action: ecr:GetAuthorizationToken ECR 인증 토큰을 요청할 수 있는 권한을 제공. 이 토큰은 ECR 리포지토리에 대한 인증을 위해 사용되고 ECR에 이미지를 푸시하거나 풀(pull)하려면 인증이 필요하므로, 이를 위한 권한을 부여한다.
- Resource: "*" 이 액션이 모든 리포지토리에 대해 허용된다. 즉, ECR 인증 토큰을 요청할 때는 어떤 리포지토리에 대해서도 요청이 가능하다.
(5-5) [다음] > 정책 이름 설정
나는 private_image_push로 설정했다.
(5-6) 생성된 정책 확인
Github에서 AWS에 로그인 할 수 있는 자격 증명 공급자 생성
(5-7) [IAM] > [자격 증명 공급자] > [공급자 추가]
(5-8) 자격 증명 공급자 구성
✏️ GitHub Actions를 OpenID Connect (OIDC) 자격 증명 공급자로 AWS에 추가하기
- 공급자 유형: OpenID Connect
- 공급자 URL: https://token.actions.githubusercontent.com
- 대상: sts.amazonaws.com
(5-9) 자격 증명 공급자 확인
자격 증명 공급자에서 역할 할당
(5-10) 해당 공급자로 들어가서 [역할 할당] > [새 역할 생성]
(5-11) 역할 생성 > 신뢰할 수 있는 엔터티 선택
- [웹 자격 증명] 선택 후 [자격 증명 공급자]는 github로 설정한다.
- Github 조직: 깃허브 ID
- Github 레포지토리: 연결할 레포지토리 이름
- Github 브랜치: 연결할 브랜치 이름
(5-12) 역할 생성 > 권한 추가
아래 권한들을 추가한다.
- private_image_push 권한: 위에서 만들었던 정책
- AmazonECS_FullAccess 권한
(5-13) 이름 지정, 검토 및 생성
역할의 이름을 정해준다.
6. GitHub Actions에서 ECR에 접근 설정
이제 GitHub Actions 워크플로우 파일을 수정하여, GitHub Actions가 AWS ECR에 접근하도록 설정해야 한다. 이를 위해 OIDC(OpenID Connect) 인증을 사용하여 AWS IAM 역할을 활성화하고, Docker 이미지를 빌드 및 푸시할 수 있도록 한다.
yaml 파일 수정
GitHub의 .github/workflows/ 디렉토리 내에 있는 YAML 파일을 수정하여 AWS ECR과 통합한다.
name: Java and AWS ECS CICD
on:
push:
branches: [ "main" ]
permissions:
id-token: write
contents: read
env:
AWS_REGION: ap-northeast-2
ECR_REPOSITORY: cicd
jobs:
build-docker-image:
#ubuntu 환경에서 수행
runs-on: ubuntu-latest
steps:
#소스 코드 가져오기
- uses: actions/checkout@v3
#JDK 설치
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
#Spring Boot Application Build
- name: Build with Gradle
uses: gradle/gradle-build-action@v3
with:
arguments: clean bootJar
#AWS 로그인
- name: AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::575108919464:role/cicdrole
role-session-name: sampleSeesionName
aws-region: ap-northeast-2
#ECR 로그인
- name: Login to ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@62f4f872db3836360b72999f4b87f1ff13310f3a
#이미지를 등록하고 ECR에 Push
- 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
#Docker Hub 로그인
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
#이미지 업로드
- name: build and release
run: |
docker build -t ${{ secrets.DOCKERHUB_REPOSITORY }} .
docker tag ${{ secrets.DOCKERHUB_REPOSITORY }}:latest ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_REPOSITORY }}:latest
docker push ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_REPOSITORY }}:latest
전반적인 코드는 지난번과 유사하지만, AWS 로그인을 위한 아래 부분이 추가되었다.
env:
AWS_REGION: ap-northeast-2
ECR_REPOSITORY: cicd
환경 변수를 따로 저장한다.
# AWS 로그인
- name: AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::575108919464:role/cicdrole
role-session-name: sampleSeesionName
aws-region: ap-northeast-2
- name: AWS Credentials: GitHub Actions의 로그에서 작업 이름을 지정한다. 이 경우 "AWS Credentials"라는 이름을 사용하여 해당 단계를 나타낸다.
- uses: aws-actions/configure-aws-credentials@v4: AWS와 통신할 수 있도록 aws-actions/configure-aws-credentials 액션을 사용한다는 의미. 해당 액션은 AWS 자격 증명을 설정하여 후속 작업에서 AWS 리소스를 사용할 수 있도록 한다.
- role-to-assume: arn:aws:iam::575108919464:role/cicdrole: IAM 역할 ARN (Amazon Resource Name)을 지정. GitHub Actions가 AWS 리소스에 접근하기 위해 IAM 역할을 가정(Assume) 하여 권한을 얻는다. 여기서 cicdrole이라는 IAM 역할을 사용하여 AWS 리소스에 접근할 수 있습니다. (위에서 미리 만든 role의 ARN을 적으면 된다.)
- role-session-name: sampleSeesionName: 세션 이름 지정. 이 세션 이름은 역할을 가정할 때 AWS에서 생성되는 임시 보안 자격 증명에 포함된다. 이름을 지정하는 이유는 여러 세션을 구분할 수 있도록 하기 위해서.
- aws-region: ap-northeast-2: AWS 리전을 설정하는 부분. 나는 ap-northeast-2(서울 리전)을 지정했다. 리전은 사용하려는 AWS 서비스가 배포된 지역을 지정해야 하며, 리전에 따라 사용 가능한 서비스가 다를 수 있습니다.
#ECR 로그인
- name: Login to ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@62f4f872db3836360b72999f4b87f1ff13310f3a
- ECR에 로그인하여 인증을 완료하고, 이후 Docker 이미지 푸시 작업을 할 수 있도록 자격 증명을 설정하는 단계.
#이미지를 등록하고 ECR에 Push
- 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
- ECR_REGISTRY와 IMAGE_TAG 환경 변수 설정:
- ECR_REGISTRY: ECR 로그인 시 반환된 레지스트리 URL을 가져온다.
- IMAGE_TAG: GitHub 커밋 SHA를 사용하여 이미지의 태그를 설정한다.
- Docker 이미지 빌드: Docker 이미지를 빌드하고, 태그를 지정한다.
- 이미지 푸시: 빌드한 이미지를 ECR에 푸시한다.
- 이미지 URI 출력: 빌드된 이미지의 URI를 GitHub Actions의 출력으로 설정하여 후속 작업에서 참조할 수 있도록 한다.
github actions 확인
yaml 파일 코드를 수정한 후, 다시 github의 main 브랜치에 push 하면 github actions이 다시 실행될 것이다.
ECR에서 리포지토리 확인
workflow가 SUCCESS 한다면, 연결한 ECR 리포지토리에 이미지가 생성된 것을 확인할 수 있다.