티스토리 뷰

들어가기 전에

예전에 잠깐 창업에 발을 살짝 들였을 때, 팀 사이트를 오늘 소개한 방법으로 배포한 적이 있다. 새로운 블로그를 최근에 만들었는데, 이 페이지를 배포할 방법으로 netlify 같은 서비스도 고민했지만, 그냥 깔끔하게 내가 다 만들어버리고 블로그 포스팅도 하자는 생각으로 다시 시도하면서 정리하게 되었다.

이 포스트에서는 vue, react 의 Client side application 뿐만 아니라 jekyll 과 같은 static web page 를 aws S3와 Cloudfront라는 CDN을 통해 배포하는 과정, 그리고 github Actions 을 통해 모든 것을 자동화하는 과정을 설명한다.

 

이 자동화 배포를 완성하기 위해서는 직접 초기 작업을 수행해야 한다. 물론 AWS CLI 를 사용한다거나, 여러가지옵션이 있겠지만 aws 를 제일 쉽게 사용할 수 있는 웹 콘솔 기준으로 설명한다.

IAM 만들기

github actions 상에서 사용할 aws credentials를 위하여 IAM 계정을 만들어야 한다. 절대로 AdministratorAccess 과 같은 권한을 주면 안된다. 이 때, 이 IAM에 쥐어주는 권하는 최대한 줄여 필요한 권한만 갖고 있도록 한다. 이 프로젝트에서 github actions 에서 사용하는 aws cli 명령은 aws s3 sync  aws cloudfront create-invalidation 이다. 이 명령어만 겨우 수행할 정도의 IAM 권한을 주는걸 추천한다. 이 분의 경험을 직접 겪고싶지 않다면 말이다. (https://youtu.be/r6TFnNQsQLY?t=1814) 요즘 회사에서 작업하고 있는 부분이 IAM 의 관리와 Security 에 대한 이야기인데, 나중에 더 이야기할 수 있었으면 좋겠다.

기존 정책을 갖다 쓸 수도 있겠지만, [정책 생성]을 눌러 손쉽게 사용할 정책json을 만들 수 있다.

IAM 을 만들어 aws credentials 를 받았다면 github repository 에 secrets 설정을 하러 가보자.

Github repository 생성 및 Secrets 설정

github repository 를 생성한다. 본인은 private repository 를 만들었다. 만들고 웹 소스코드를 push하도록 하자. 그 이후에 github actions 에서 aws cli 를 사용하여 당신의 aws 리소스에 접근시키도록 하려면, aws credentials 를 github actions 컨테이너 안에서 불러올 수 있어야 한다. 이를 위해 아래의 이미지처럼 settings > Secrets 탭에서 aws credentials를 등록하자. 이제 github actions 에서 aws 리소스들을 사용할 수 있다.

참고 문서 : https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions

Amazon S3 생성 및 구성

aws 웹 콘솔을 들어가서 S3 버킷을 생성하고, 퍼블릭 엑세스 차단을 비활성한다. 추가로 [속성] 탭에 진입하여 맨 밑에 있는 “정적 웹사이트 호스팅”을 활성화시킨다.

github actions 에서도 접근을 해야하기 때문에, 버킷 정책을 아래와 같이 설정한다.

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "GithubAction",
            "Effect": "Allow",
            "Principal": {
                "AWS": "<방금 만든 IAM의 arn>"
            },
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::<생성한 버킷 이름>",
                "arn:aws:s3:::<생성한 버킷 이름>/*"
            ]
        },
        {
            "Sid": "Access",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::<생성한 버킷 이름>",
                "arn:aws:s3:::<생성한 버킷 이름>/*"
            ]
        }
    ]
}

외부 도메인의 Route 53 DNS 설정

나는 gabia라는 곳에서 도메인을 구매하였다. 비용으로 Route53 안에서 구매하는 것도 좋은 방법이었지만, [co.kr](<http://co.kr>) 과 같은 한국 도메인은 구매할 수 없었다. 만약 .com 으로 끝나는 도메인이 비어있었다면 Route53 안에서 구매하였을 것이다.

gabia에서 도메인을 구매하여, gabia의 네임서버를 사용하지 않고 Route53 의 네임서버를 사용해야 한다. Route 53 의 대시보드에서 “호스팅 영역” 에 진입, [호스팅 영역 생성] 버튼을 클릭한다. 도메인 이름을 입력하고 호스팅 영역을 생성하면, 아래와 같은 테이블을 확인할 수 있을 것이다.

aws 에서 제공되는 네임서버이며, 이 정보를 gabia 의 네임서버 세팅에 1차~4차 네임서버로 입력하면 된다. 순서는 상관없다.

ACM 설정

HTTPS 프로토콜로 구매한 도메인을 통해 호스팅하기 위해서는 인증서 발급이 필요하다. ACM (AWS Certificate Manager)를 통해 인증서를 발급받을 수 있다. 여기서 중요한 점은 ACM 대시보드에 진입하고 나서 Region을 꼭 “us-east-1”으로 세팅한다. 그래야 Cloudfront 에서 인증서를 불러올 수 있다.

Route53에 DNS 설정을 마무리하였으므로, 인증서를 발급하는 건 쉽다. [인증서 요청]을 통하여 해당 도메인의 인증서를 발급받도록 하자. 약 30분정도 걸린다고 하는데, 10분쯤 걸린 것 같다.

Cloudfront 초기 세팅

[Create Distribution] 을 눌러 디스트리뷰션을 만든다. Origin Domain Name 에서는 웹 콘솔의 폼에 나오는 url 을 선택하지 않고 S3 웹 콘솔에 있는 아래의 주소를 입력하도록 한다.

그 외의 Distribution Settings 은 아래와 같이 세팅한다.

Github actions 설정

이제 코드 개발 이후 github 레포지토리에 push만 하면 trigger 되는 빌드/배포 작업을 세팅해야 한다. 이 작업을 마무리하게 되면, 앞으로 git push 명령어만으로 AWS CDN에 새로 빌드된 정적 웹페이지가 수 분 내로 배포되게 된다.

로컬에서 하던 대로 github actions 스크립트를 만들면 된다. 레포지토리에서 .github/workflow/<FILE_NAME>.yml 로 정의하면 알아서 github actions 이 수행된다.

name: OWLSNESTBLOG
on: 
  push:
    branches:
      - master
jobs:
  build:
    runs-on: ubuntu-20.04
    steps:
      - name: Checkout source code.
        uses: actions/checkout@master
      - name: Cache node modules
        uses: actions/cache@v1
        with:
          path: node_modules
          key: ${{ runner.OS }}-build-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.OS }}-build-
            ${{ runner.OS }}-
      - name: Install dependencies
        run: npm install
      - name: Set up Ruby 2.6
        uses: actions/setup-ruby@v1
        with:
          ruby-version: 2.6
      - name: Install bundler
        run: 
          gem install bundler
          
      - name: Run bundle install
        run: 
          bundle install
      - name: Build scss
        run: gulp styles && gulp scripts
      - name: Build _site
        run: bundle exec jekyll build
      - name: SHOW AWS CLI VERSION
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_EC2_METADATA_DISABLED: true
        run: |
          aws --version
      - name: Sync Bucket
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_EC2_METADATA_DISABLED: true
        run: |
          aws s3 sync \
            --region ap-northeast-2 \
            _site s3://owlsnest-kr-blog \
            --delete
      - name: Invalidate Cache
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_EC2_METADATA_DISABLED: true
        run: |
          aws cloudfront create-invalidation \
          --distribution-id {{ secrets.AWS_CLOUDFRONT_DISTRIBUTION_ID }} \
          --paths "/*"

 

 

⚠️ UBUNTU 20.04 이미지를 사용할 때

github actions 의 컨테이너 이미지 OS 설정 시 Ubuntu 20.04 를 사용할 경우, aws cli v2를 사용할 수 있고 Ubuntu 18.04 이하의 디스트로에서는 aws cli v1을 사용한다. 그 이유는 공식 레포의 스크립트를 참고하면 확인할 수 있다. (https://github.com/actions/virtual-environments/blob/main/images/linux/scripts/installers/aws.sh) 당연히 18.04에서 aws cli v2를 쓸 줄 알고 썼다가 시행 착오를 몇 번 했다.

CLI 2 로 넘어오면서 이런 에러를 확인할 수 있다. 이에 대한 해결법으로는 환경 변수에 AWS_EC2_METADATA_DISABLED: true 를 추가해주면 해결 가능하다.

빌드와 배포에 성공한 모습이다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함