본문 바로가기
Study/AWS

ECR,ECS을 활용한 server 배포 + CI/CD (Django)

by 왕방개 2024. 5. 24.

1.Python Web 애플리케이션 ECS 배포

1)python가상환경 생성

python -m env myvenv

myvenv/Scripts/activate

 

 

2)이미지 생성을 위해 project root 디렉토리  Dockerfile 작성

FROM --platform=linux/amd64 python:3.8-slim-buster as build

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
            postgresql-client \
	        && rm -rf /var/lib/apt/lists/*
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .

EXPOSE 80
#fastapi랑 django랑 이 부분만 바뀌면 됨
CMD ["python", "manage.py", "runserver", "0.0.0.0:80"]

=>dockerfile 작성하다가 생긴 오류

RUN pip install -r requirements.txt가 오류가 생길시에

그냥 직접 pip install djangorestframework 이런식으로 저장하는걸 확인

 

=>docker image가 잘 생성되었는지 확인

 

=>잘 실행되는지 확인 :docker run --name (이미지이름)  -p 80:80 -dit (이미지이름):latest

 

3)image 만들어서 실행까지 수행할 수 있도록 docker-compose.yml 파일 생성

version: "3"

services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    #django인지 fastapi인지는 여기만 바뀌면 됨  
    command: "python manage.py runserver 0.0.0.0:80"
    ports:
      - "80:80"

 

=>docker-compose 파일 실행: docker-compose -f docker-compose.yml up -d --build

 

4)CI/CD 구축을 위한 .github/workflows/(이름).yml 파일 생성

name: django

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  build:
    runs-on: ubuntu-latest
      
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Set up Python 3.10
        uses: actions/setup-python@v4
        with: 
            python-version: '3.10'
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Build Docker Compose
        run: docker-compose

 

5)ECR(private image repository) 에 image push

=>여기서부터는 python이든 java든 동일

 

=>ECR repository 생성(이름 주고 생성)

리포지토리 생성

 

 

=>ECR 에 이미지를 push 할 수 있는 정책을 생성

 

-IAM 서비스에 접속

-왼쪽의 [정책] 탭 클릭하고 [정책 생성] ( 리전을 수정하고 숫자 와 이름은 ECR에서 가져와서 작성)

 

-JSON클릭하고 수정

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:CompleteLayerUpload",
                "ecr:UploadLayerPart",
                "ecr:InitiateLayerUpload",
                "ecr:BatchCheckLayerAvailability",
                "ecr:PutImage"
            ],
            "Resource": "arn:aws:ecr:ap-northeast-2:[ECR번호]:repository/[ecr이름]" },
        {
            "Effect": "Allow",
            "Action": "ecr:GetAuthorizationToken",
            "Resource": "*"
        }
    ]
}

 

하고 이름 부여하고 [정책 생성]

 

=>github와 연동을 위한 OpenID Connect 생성

-IAM에서 [자격 증명 공급자]를 클릭해서 [추가]를 선택

-OpenID connect 를 선택해서 github 정보를 이용해서 공급자 생성

 

공급자URL을 얻는 방법
https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services


https://token.actions.githubusercontent.com을 공급자URL에 넣고
대상에는sts.amazonaws.com 채움

 

- [자격 증명 공급자]에게 새로운 역할 할당

 

Github조직에는 github이름

Github 레포지안에는 github 레포지 주소가 들어가야합니다

권한 정책 아까 만들었던거 부여 하고 생성

 

-기존의 workflows안에 있는 [이름].yml 파일 수정해서 로그인되는지 확인

name: django

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

permissions:
  id-token: write # This is required for requesting the JWT
  contents: read  # This is required for actions/checkout
  
 jobs:
  build:
    runs-on: ubuntu-latest
      
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up Python 3.10
        uses: actions/setup-python@v4
        with: 
            python-version: '3.10'
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
      - name: Build Docker Compose
        run: docker-compose
        

    - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::[수정]:role/[수정]
          role-session-name: sampleSessionName
          aws-region: ap-northeast-2

 

 

6)ECS에 배포

=>task definiton을 생성

task definiton을 생성:Fargate을 선택하고 컨테이너 이름과 이미지 이름을 설정

=>cluster 를 생성

 

=>cluster 에 service 를 생성

까지하고 생성 버튼 누름

 

=>이전에 만든 task 를 선택해서 json 내용을 복사해서 project의 root 디렉토리에 json파일을 저장

JSON을 클릭하고 JSON download 하고 root 디렉토리에 옮기고 이름 변경(task-definition.json)
image 키는 삭제

 

=>git action 파일에 내용을 추가 (우리환경에 맞게 변경)

name: django

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

permissions:
  id-token: write 
  contents: read  
####수정해야해####
env:
  AWS_REGION: ap-northeast-2
  ECR_REPOSITORY: itstudydjangoecs  
  ECS_SERVICE: itstudyservice2
  ECS_CLUSTER: deploytest                 
  ECS_TASK_DEFINITION: ./task-definition.json
  CONTAINER_NAME: itstudy1       
########
jobs:
  build:
    runs-on: ubuntu-latest
      
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up Python 3.10
        uses: actions/setup-python@v4
        with: 
            python-version: '3.10'
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
      - name: Build Docker Compose
        run: docker-compose build
      ###수정해야해####
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::641022061021:role/imagepush
          role-session-name: sampleSessionName
          aws-region: ap-northeast-2

      - 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: 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: ${{ env.ECS_TASK_DEFINITION }}
          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
주로 생기는 오류: 권한 안줘서그럼
IAM에서 ECS FULL ACCESS 권한을 추가해야함
이떄는 코드를 따로 고치지 않았을떄 github에 re-run jobs을 누르면 다시 실행됨

 

build 과정에서 시간체크해보기