EB 정복하기 - 1

EB 정복하기 - 2

EB 정복하기 - 3

EB 정복하기 - 4

EB 정복하기 - 5

EB 정복하기 - 6

 

우선적으로 EB 정복하기 - 6을 보고, 대략적인 틀을 보고 오자.

 

AWS IAM 사용자 생성, 정책 부여

 

AWS IAM 사용자를 생성하고, Github Action에서 EB 배포에 사용되는 정책들을 모두 줘야 한다. 

 

github-action-deploy 사용자를 생성해 주자. 정책은 생성한 후에 붙여줄 예정이므로 이름만 채우고 바로 생성해 준다.

 

AccssKey는 필요하므로 발급한 후 저장해 준다. (노출되면, 악용될 수 있으므로 노출되지 않게 한다.)

 

이제 필요한 정책을 알아보자.

 

1. AdministratorAccess-AWSElasticBeanstalk 

 

해당 정책은 AWS 관리형 정책인데, EB를 배포할 때 필요한 모든 권한을 부여해 준다.

 

관리형 정책을 사용하기보다는 최소 권한을 주는 게 좋지만 단일 인스턴스 일 때, 고가용성을 위한 로드밸런서 사용할 때 범용적으로 사용하기 위해서 해당 정책을 사용한다. 

 

2. ECR 정책

 

ECR에서 Private Repository를 사용하고 있어서, 인증 토큰을 얻는 정책, 이미지 푸시, ImageLayer를 추가하는 정책들이 필요하다.

 

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ecr:BatchCheckLayerAvailability",
                "ecr:PutImage",
                "ecr:InitiateLayerUpload",
                "ecr:UploadLayerPart",
                "ecr:CompleteLayerUpload"
            ],
            "Resource": [
                "arn:aws:ecr:{region}:{account_id}:repository/elastic-beanstalk"
            ]
        },
        {
            "Sid": "VisualEditor01",
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

 

region과 account_id는 각자에 맞게 채워주면 된다.

이전에 만든 Private ECR 레포지토리를 리소스로 최소 권한으로 지정해 준다.

 

ecr:GetAuthorizationToken 정책의 경우 특정 레포지토리를 지칭할 수 없어 *로 리소스를 설정해 준다.

 

3. S3 정책

 

EB 배포에 사용되는 S3 버킷만 사용하도록 정책을 특정시킨다. Bucket Policy도 설정하면 좋지만, 일단은 IAM 정책만 적용한다. 

 

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:Delete*",
                "s3:Get*",
                "s3:Put*",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::elastic-beanstalk-deploy-zip",
                "arn:aws:s3:::elastic-beanstalk-deploy-zip/*"
            ]
        }
    ]
}

 

정책들은 어렵지 않은데, 객체를 조회, 삭제, 삽입하는 것과 EB를 배포할 때 이름으로 조회하는 과정이 있어서 s3:ListBucket 정책이 필요다.

 

주의할 점은 리소스를 특정시킬 때 

 

1. arn:aws:s3:::elastic-beanstalk-deploy-zip

2. arn:aws:s3:::elastic-beanstalk-deploy-zip/* 

 

모두 해줘야 한다. 1번은 버킷 자체에 대한 리소스이고, 2번째는 버킷 안의 객체들을 의미하는 리소스다.

 

1번만 줄경우 객체를 조회, 삭제, 삽입할 수 없고, 2번만 줄경우 이름으로 버킷을 조회할 수 없다. 

 

여기까지 완료했으면, AWS 설정은 끝이 났다. 

 

Github Action 설정

 

이제 Github Action을 사용하기 위한 레포지토리 설정이 필요하다.

 

레포지토리 -> Setting -> Secrets and variables의 Action으로 들어가서 Secret을 만든다. 

 

만들어야 하는 Secret은 아래와 같다.

 

 

위에서 생성한 AccessKey와 Region을 넣어준다. 이때 ECR URL은 레포지토리 들어가면 푸시 명령보기에서 얻을 수 있다. 

 

Github Action Yaml 작성

 

yaml 파일은 어렵지 않다. 숫자 각주를 달고 밑에 설명을 적겠다.

 

name: single-instance

on:
  push:
    branches: [ single-instance ] #1

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up JDK 17
        uses: actions/setup-java@v4 #2
        with:
          java-version: '17'
          distribution: 'corretto'

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Build with Gradle
        run: ./gradlew build -x test

      - name: Configure AWS credentials #3
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: ${{ secrets.REGION }}
          mask-aws-account-id: 'false'
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }}

      - name: Login to Amazon ECR #4
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2
        with:
          mask-password: 'false'

      - name: Build, tag, and push docker image to Amazon ECR #5
        run: |
          docker build -t ${{ secrets.AWS_ECR_URL }}/elastic-beanstalk:latest .
          docker push ${{ secrets.AWS_ECR_URL }}/elastic-beanstalk:latest

      - name: Create Dockerrun.aws.json #6
        run: |
          echo '{
            "AWSEBDockerrunVersion": "1",
            "Image": {
              "Name": "'${{ secrets.AWS_ECR_URL }}/elastic-beanstalk:latest'",
              "Update": "true"
            },
            "Ports": [
              {
                "ContainerPort": "8080",
                "HostPort": "80"
              }
            ]
          }' > Dockerrun.aws.json

      - name: Get current time #7
        uses: 1466587594/get-current-time@v2
        id: current-time
        with:
          format: YYYY-MM-DDTHH-mm-ss
          utcOffset: "+09:00"

      - name: Generate deployment package #8
        run: |
          mkdir -p deploy
          cp Dockerrun.aws.json deploy/Dockerrun.aws.json
          cp -r .ebextensions deploy/.ebextensions
          cd deploy && zip -r deploy.zip .

      - name: Deploy to EB #9
        uses: einaregilsson/beanstalk-deploy@v22
        with:
          aws_access_key: ${{ secrets.AWS_ACCESS_KEY }}
          aws_secret_key: ${{ secrets.AWS_SECRET_KEY }}
          application_name: elastic-beanstalk
          environment_name: elastic-beanstalk-dev
          version_label: github-action-${{steps.current-time.outputs.formattedTime}}
          region: ${{ secrets.REGION }}
          existing_bucket_name: elastic-beanstalk-deploy-zip
          deployment_package: deploy/deploy.zip

 

1. 특정 브랜치에 merge 됐을 경우 해당 workflow가 동작

2. 아마존 코레토 자바 17을 베이스로 코드를 빌드 환경 세팅

3. AWS를 사용하기 위해서 Credential을 등록함 (AccessKey, AccessSecretKey 활용)

4. AWS Credential을 이용해서 ECR 사용을 위한 AuthorizationToken을 획득

5. 만든 이미지를 ECR로 푸시

6. EB가 Image를 어떻게 설정할 지에 대한 Dockerrun.aws.json 생성 (사용할 이미지 위치와 포트 맵핑을 명시)

7. 환경 버저닝을 위한 DateTime 추출

8. EB가 배포할 때 필요한 파일들을 zip 형태로 압축 ( .ebextentions EB 설정에 필요한 세팅을 담음 환경변수, 헬스체크 url)

9. EB 배포 시작

 

.ebextentions 파일은 아래와 같다.

 

option_settings:
  aws:elasticbeanstalk:environment:process:default:
    HealthCheckPath: /health-check
  aws:elasticbeanstalk:application:environment:
    ENVIRONMENT: dev

 

테스트

 

여기까지 모두 작성했다면, PR을 하나 만들고 명시한 브랜치에 merge 해보면 배포가 된 것을 확인할 수 있다. 

 

EB 환경을 들어가서 도메인을 복사해서 브라우저에 입력한다. 

 

 

다음은 단일 인스턴스 멀티 컨테이너에 대한 배포를 해보자.