[CI/CD] GitHub Actions CI/CD
들어가며
이번 주에는 GitHub Actions를 이용한 CI/CD에 대해 알아보겠습니다.
GitHub Actions CI/CD
GitHub Actions란?
- 공식문서 - 개요 - 요금 - GitHub Actions의 다양한 기능 활용하기
- GitHub Actions는 GitHub에서 호스팅되는 지속적 통합(CI) 및 지속적 배포(CD) 서비스입니다.
- 푸시나 풀 리퀘스트와 같은 이벤트에 반응하여 사용자 지정된 워크플로를 실행할 수 있습니다. 이를 통해 CI/CD를 GitHub Actions로 구현할 수 있습니다.
- GitHub Actions는 GitHub Marketplace에서 기존에 작성된 워크플로를 가져와 사용할 수 있습니다. Slack 알림, AWS 배포 등 다양한 워크플로가 있습니다.
- GitHub Actions는 YAML 파일을 사용하여 워크플로를 정의합니다. 워크플로는 job으로 구성되며, 각 job은 step으로 구성됩니다.
-
GitHub Actions의 요금은 아래와 같으며 500MB 스토리지와 매월 2000분을 무료로 사용할 수 있습니다.
계획 스토리지 분(월) GitHub Free 500 MB 2,000 GitHub Pro 1GB 3,000 조직용 GitHub Free 500 MB 2,000 GitHub Team 2GB 3,000 GitHub Enterprise Cloud 50GB 50,000
첫 GitHub Actions 워크플로 만들기
- GitHub Actions는 repository 내의
.github/workflows
디렉터리에 저장된 워크플로우 정의 파일을 읽어서 실행합니다. - 간단한 GitHub Repository를 만들고 그 안에 워크플로우를 만들어서 테스트 해보겠습니다.
- 새로운 Repository 만들기 링크
- git clone으로 repository를 로컬로 가져옵니다.
$ git clone https://github.com/sweetlittlebird/2024-cicd-w2-1.git $ cd 2024-cicd-w2-1
-
.github/workflows
디렉터리를 만들고 그 안에main.yml
파일을 만듭니다. (파일명은 자유롭게 지정 가능합니다.)$ mkdir -p .github/workflows $ touch .github/workflows/main.yml
-
main.yml
파일에 워크플로우 작성합니다.# .github/workflows/main.yml name: Hello World # Github 웹 사이드바 이름 on: workflow_dispatch: # 수동으로 실행할 수 있는 워크플로우 push: # push 이벤트 발생 시 실행 jobs: build: # Jobs 이름 runs-on: ubuntu-latest # 실행 환경 steps: # Job 내부의 Step 들 - uses: actions/checkout@v3 # actions/checkout 레포지토리의 v3 버전의 워크플로우 사용 - name: Hello World # Step 이름 run: echo "Hello World"
- GitHub에 push하여 워크플로우를 실행합니다.
$ git add . $ git commit -m "GitHub Actions 추가" $ git push origin main
- GitHub Repository에서 Actions 탭을 클릭하여 워크플로우를 확인합니다. 링크
- 새로운 Repository 만들기 링크
- 워크플로우가 잘 실행되어서
Hello World
가 잘 출력되었습니다.
워크플로우를 수동으로 트리거 하기
- 앞서 작성한 워크플로우 처럼 on: workflow_dispatch를 사용하면 워크플로우를 수동으로 실행할 수 있습니다.
- GitHub Repository에서 Actions 탭을 클릭하고
Run workflow
버튼을 클릭하여 워크플로우를 수동으로 실행할 수 있습니다.
직접 개발 후 실행
- 이번에는 가상머신을 만들고 그 안에서 간단한 웹 서버를 만들어서 GitHub Actions로 배포해보겠습니다.
- 가상머신은 Vagrant를 사용하여 만들어 보겠습니다.
# Vagrantfile Vagrant.configure("2") do |config| config.vm.box = "ubuntu/jammy64" config.vm.network "forwarded_port", guest: 22, host: 20022 config.vm.network "forwarded_port", guest: 80, host: 20080 config.vm.provision "shell", inline: <<-SHELL sudo apt-get update sudo apt install -y tree SHELL end
-
위와 같이 Vagrantfile을 작성하고
vagrant up
으로 가상머신을 만들어 줍니다.$ vagrant up $ vargrant ssh # -------- $ python3 -V # => Python 3.10.12 $ cat > server.py <<EOF from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler from datetime import datetime class RequestHandler(BaseHTTPRequestHandler): def do_GET(self): self.send_response(200) self.send_header('Content-type', 'text/plain') self.end_headers() now = datetime.now() response_string = now.strftime("The time is %-I:%M:%S %p, CloudNeta Study.\n") self.wfile.write(bytes(response_string, "utf-8")) def startServer(): try: server = ThreadingHTTPServer(('', 80), RequestHandler) print("Listening on " + ":".join(map(str, server.server_address))) server.serve_forever() except KeyboardInterrupt: server.shutdown() if __name__== "__main__": startServer() EOF $ sudo python3 server.py # 아래 확인 후 # CTRL+C 로 실행 취소 # (신규터미널) 서버1 SSH 접속 $ curl localhost # => The time is 2:50:56 PM, CloudNeta Study. $ sudo ss -tnlp # => State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess # LISTEN 0 5 0.0.0.0:80 0.0.0.0:* users:(("python3",pid=2299,fd=3)) # LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1030,fd=3)) # --------
- Git 작업
- 토큰 발급해두기 : scope (repo, workflow) 필요합니다.
- Private Repo 신규 생성
- 가상머신에서 Git 작업
$ GITUSER="sweetlittlebird" $ git config --global user.name $GITUSER $ git config --global user.email "sweetlittlebird@sweetlittlebird.com" $ git clone https://github.com/$GITUSER/2024-cicd-w2-2.git # => Cloning into '2024-cicd-w2-2'... # Username for 'https://github.com': git # Password for 'https://git@github.com': # remote: Enumerating objects: 3, done. # remote: Counting objects: 100% (3/3), done. # remote: Compressing objects: 100% (2/2), done. # remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0) # Receiving objects: 100% (3/3), done. $ cp server.py 2024-cicd-w2-2/ $ cd 2024-cicd-w2-2 $ git status # => On branch main # Your branch is up to date with 'origin/main'. # # Untracked files: # (use "git add <file>..." to include in what will be committed) # server.py # # nothing added to commit but untracked files present (use "git add" to track) $ git add . $ git commit -m "Initial commit" # => [main 30500ca] Initial commit # 1 file changed, 22 insertions(+) # create mode 100644 server.py $ git push origin main # => Username for 'https://github.com': git # Password for 'https://git@github.com': *** # <span style="color: green;">👉 ghp로 시작하는 발급해둔 토큰을 사용합니다.</span> # Enumerating objects: 4, done. # Counting objects: 100% (4/4), done. # Delta compression using up to 2 threads # Compressing objects: 100% (3/3), done. # Writing objects: 100% (3/3), 665 bytes | 332.00 KiB/s, done. # Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 # To https://github.com/sweetlittlebird/2024-cicd-w2-2.git # ceaed76..30500ca main -> main
- 토큰 발급해두기 : scope (repo, workflow) 필요합니다.
- 서버 실행
$ nohup sudo python3 server.py > server.log 2>&1 & $ cat server.log # => nohup: ignoring input $ curl localhost # => The time is 3:13:00 PM, CloudNeta Study. $ cat server.log # => nohup: ignoring input # 127.0.0.1 - - [14/Dec/2024 15:13:00] "GET / HTTP/1.1" 200 - # $ grep log .gitignore # => # Installer logs # pip-log.txt # *.log # <span style="color: green;">👉 로그 파일은 git에서 무시하도록 되어있습니다.</span> # $ git add . $ git commit -m "add log file" # => nothing to commit, working tree clean <span style="color: green;">👉 로그 파일은 git에서 무시하도록 되어있어서 git add . 의 영향을 받지 않습니다.</span> $ git status # => nothing to commit, working tree clean
- 코드 수정 후 재실행
# $ sed -i "s/CloudNeta/CICD/g" server.py # 프로세스 종료 $ sudo ss -tnlp # => State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess # LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=883,fd=3)) # LISTEN 0 5 0.0.0.0:80 0.0.0.0:* users:(("python3",pid=2287,fd=3)) $ sudo fuser -k -n tcp 80 # <span style="color: green;">👉 80번 포트를 사용하는 프로세스를 종료합니다.</span> # => 80/tcp: 2287 # [1]+ Killed nohup sudo python3 server.py > server.log 2>&1 (wd: ~) # (wd now: ~/2024-cicd-w2-2) $ sudo ss -tnlp # => State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess # LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=883,fd=3)) # <span style="color: green;">👉 80 포트를 사용하던 python3가 종료되어서 없어졌습니다.</span> # 재실행 $ nohup sudo python3 server.py > server.log 2>&1 & $ curl localhost # => The time is 3:24:23 PM, CICD Study. # <span style="color: green;">👉 수정사항이 반영되었습니다.</span>
- 코드 push
# 매번 사용자 인증을 요구하지 않도록 인증 정보를 저장하도록 설정하겠습니다. $ git config --global credential.helper store # $ git add . && git commit -m "version update" && git push origin main # => [main 11f7a3d] version update # 1 file changed, 1 insertion(+), 1 deletion(-) # Username for 'https://github.com': git # Password for 'https://git@github.com': # Enumerating objects: 5, done. # Counting objects: 100% (5/5), done. # Delta compression using up to 2 threads # Compressing objects: 100% (3/3), done. # Writing objects: 100% (3/3), 312 bytes | 156.00 KiB/s, done. # Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 # remote: Resolving deltas: 100% (1/1), completed with 1 local object. # To https://github.com/sweetlittlebird/2024-cicd-w2-2.git # 30500ca..11f7a3d main -> main $ git push origin main # => Everything up-to-date # <span style="color: green;">👉 인증정보가 저장되어서 별도의 인증과정 없이 사용할 수 있습니다.</span>
GitHub Actions로 배포하기
- 개인 PC에서 작업 후 Github에 push하면 GitHub Actions를 통해 VM에 배포가 되도록 CI/CD를 구성해보겠습니다.
SSH 키 생성
- 먼저 가상머신에 ssh 접속을 위해 ssh key를 생성하고 GitHub에 등록합니다.
$ cd ~/.ssh $ ssh-keygen -t ed25519 # => Enter file in which to save the key (/home/vagrant/.ssh/id_ed25519): # Enter passphrase (empty for no passphrase): # <span style="color: green;">👉 비밀번호 없이 엔터만 입력합니다.</span> # Enter same passphrase again: # <span style="color: green;">👉 엔터만 입력합니다.</span> # 생성된 공개키를 로그인 허용 키 목록에 추가합니다 $ cat id_ed25519.pub >> authorized_keys $ cat id_ed25519 # <span style="color: green;">👉 개인키를 복사합니다. 복사한 키는 github secret에 추가할 것입니다.</span>
GitHub에 SSH 키와 가상머신 외부 IP 등록
- GitHub의 Repository에서
Settings
->Secrets and variables
->Actions
->New repository secret
를 클릭하여 아래와 같이 추가합니다.-
SSH_PRIVATE_KEY
: 앞에서 복사한 개인키를 추가합니다. -
EC2_PIP
: 가상머신의 외부 IP를 추가합니다. (인터넷에서 접속가능한 IP여야 합니다.)
-
내 PC에서 코드 작업
-
내 PC에서 작업을 합니다.
$ git clone https://github.com/sweetlittlebird/2024-cicd-w2-2.git # => Cloning into '2024-cicd-w2-2'... # remote: Enumerating objects: 9, done. # remote: Counting objects: 100% (9/9), done. # remote: Compressing objects: 100% (7/7), done. # remote: Total 9 (delta 1), reused 6 (delta 1), pack-reused 0 (from 0) # Receiving objects: 100% (9/9), done. # Resolving deltas: 100% (1/1), done. $ cd 2024-cicd-w2-2 # 워크플로우 파일 생성 $ mkdir -p .github/workflows/ $ touch .github/workflows/deploy.yaml # 소스 수정 $ sed -i -e "s/CICD/CICD 2w/g" server.py
-
.github/workflows/deploy.yaml
파일을 작성합니다.# .github/workflows/deploy.yaml name: CICD1 on: workflow_dispatch: push: branches: - main jobs: deploy: runs-on: ubuntu-latest steps: - name: Configure the SSH Private Key Secret run: | mkdir -p ~/.ssh/ echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa - name: Set Strict Host Key Checking run: echo "StrictHostKeyChecking=no" > ~/.ssh/config - name: Git Pull run: | export MY_HOST="${{ secrets.EC2_PIP }}" ssh vagrant@$MY_HOST << EOF cd /home/vagrant/2024-cicd-w2-2 || exit 1 git pull origin main || exit 1 EOF - name: Run service run: | export MY_HOST="${{ secrets.EC2_PIP }}" ssh vagrant@$MY_HOST sudo fuser -k -n tcp 80 || true ssh vagrant@$MY_HOST "nohup sudo -E python3 /home/vagrant/2024-cicd-w2-2/server.py > /home/vagrant/2024-cicd-w2-2/server.log 2>&1 &"
-
코드를 push합니다.
$ git add . && git commit -m "add workflow" && git push origin main
- GitHub Actions를 확인해보겠습니다.
- 가상머신에서 확인해보겠습니다.
$ vagrant ssh #------- $ cd 2024-cicd-w2-2/ $ grep -i cicd server.py # => response_string = now.strftime("The time is %-I:%M:%S %p, CICD 2w Study.\n") $ sudo ps -ef |grep server.py # => root 2620 1 0 15:57 ? 00:00:00 sudo -E python3 /home/vagrant/2024-cicd-w2-2/server.py # root 2621 2620 0 15:57 ? 00:00:00 python3 /home/vagrant/2024-cicd-w2-2/server.py $ tail /home/vagrant/2024-cicd-w2-2/server.log # => nohup: ignoring input #-------
- 변경사항을 브라우저로 확인해보겠습니다.
- 변경사항이 잘 반영되어서 CICD
2w
로 변경되었습니다.
- 변경사항이 잘 반영되어서 CICD
코드 수정 후 동작 확인
- 개인 PC에서 코드와 워크플로우를 수정하고 GitHub에 push하여 배포가 잘 되는지 확인해보겠습니다.
- 코드 수정
$ sed -i -e "s/CICD 2w/CICD1 End/g" server.py
-
워크플로우 수정
# .github/workflows/deploy.yaml name: CICD1 End on: workflow_dispatch: push: branches: - main jobs: deployfinal: runs-on: ubuntu-latest steps: - name: Configure the SSH Private Key Secret run: | mkdir -p ~/.ssh/ echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa - name: Set Strict Host Key Checking run: echo "StrictHostKeyChecking=no" > ~/.ssh/config - name: Git Pull run: | export MY_HOST="${{ secrets.EC2_PIP }}" ssh vagrant@$MY_HOST << EOF cd /home/vagrant/2024-cicd-w2-2 || exit 1 git pull origin main || exit 1 EOF - name: Run service run: | export MY_HOST="${{ secrets.EC2_PIP }}" ssh vagrant@$MY_HOST sudo fuser -k -n tcp 80 || true ssh vagrant@$MY_HOST "nohup sudo -E python3 /home/vagrant/2024-cicd-w2-2/server.py > /home/vagrant/2024-cicd-w2-2/server.log 2>&1 &"
- 코드 push
# $ git add . && git commit -m "edit workflow" && git push origin main # [가상머신] $ grep -i cicd server.py # => response_string = now.strftime("The time is %-I:%M:%S %p, CICD1 End Study. # <span style="color: green;">👉 변경된 소스가 서버에 반영되었습니다.</span> $ sudo ps -ef |grep server.py # => root 3011 1 0 16:17 ? 00:00:00 sudo -E python3 /home/vagrant/2024-cicd-w2-2/server.py # root 3012 3011 0 16:17 ? 00:00:00 python3 /home/vagrant/2024-cicd-w2-2/server.py # vagrant 3035 2255 0 16:18 pts/0 00:00:00 grep --color=auto server.py $ tail /home/vagrant/2024-cicd-w2-2/server.log
- 코드 수정
- 변경사항을 브라우저로 확인해보겠습니다.
- 변경사항이 잘 반영되어서 CICD1 End로 변경되었습니다.
GitHub Actions의 Marketplace 활용하기
- 이번에는 GitHub Actions의 Marketplace에서 다른 액션을 가져와서 사용해보겠습니다.
- Marketplace는 https://github.com/marketplace로 접속할 수 있습니다.
- 이번 실습에서 사용할 액션은 ssh와 scp 입니다.
SSH for GitHub Actions
- 관련 주소 : Github, marketplace
- SSH for GitHub Actions는 원격 서버에 SSH로 접속하여 명령을 실행할 수 있습니다.
- 앞의 실습처럼 쉘 명령으로 ssh 접속이 가능하지만 이 액션을 사용하면 더 간편하게 사용할 수 있습니다.
- 사용 예
-
아이디/비밀번호로 원격 서버에 접속하여
whoami
명령을 실행합니다.name: remote ssh command on: [push] jobs: build: name: Build runs-on: ubuntu-latest steps: - name: executing remote ssh commands using password uses: appleboy/ssh-action@v1.2.0 with: host: ${{ secrets.HOST }} username: linuxserver.io password: ${{ secrets.PASSWORD }} port: ${{ secrets.PORT }} script: whoami
-
비밀번호 대신 private key를 사용하여 로그인 합니다.
# Using private key - name: executing remote ssh commands using ssh key uses: appleboy/ssh-action@v1.2.0 with: host: ${{ secrets.HOST }} username: ${{ secrets.USERNAME }} key: ${{ secrets.KEY }} port: ${{ secrets.PORT }} script: whoami
-
여러 명령을 실행할 수 있습니다.
# Multiple Commands - name: multiple command uses: appleboy/ssh-action@v1.2.0 with: host: ${{ secrets.HOST }} username: ${{ secrets.USERNAME }} key: ${{ secrets.KEY }} port: ${{ secrets.PORT }} script: | whoami ls -al
-
환경 변수를 쉘에 전달할 수 있습니다.
# Pass environment variable to shell script - name: pass environment uses: appleboy/ssh-action@v1.2.0 env: FOO: "BAR" BAR: "FOO" SHA: ${{ github.sha }} with: host: ${{ secrets.HOST }} username: ${{ secrets.USERNAME }} key: ${{ secrets.KEY }} port: ${{ secrets.PORT }} envs: FOO,BAR,SHA script: | echo "I am $FOO" echo "I am $BAR" echo "sha: $SHA"
-
-
워크플로우 설정 후 테스트
# .github/workflows/ssh-deploy.yaml name: CICD2 on: workflow_dispatch: push: branches: - main jobs: ssh-deploy: runs-on: ubuntu-latest steps: - name: Github Repository Checkout uses: actions/checkout@v4 - name: executing remote ssh commands uses: appleboy/ssh-action@v1.2.0 env: AWS_KEYS: | ACCESSKEY : asdf1234end SECRETKEY : qwer1234end with: host: ${{ secrets.EC2_PIP }} port: 22 username: vagrant key: ${{ secrets.SSH_PRIVATE_KEY }} envs: AWS_KEYS script_stop: true script: | cd /home/vagrant/2024-cicd-w2-2 echo "$AWS_KEYS" > .env
$ git add . && git commit -m "add ssh action test" && git push origin main
-
가상머신에서 확인
$ ls -al ~/2024-cicd-w2-2/ # => total 32 # drwxrwxr-x 4 vagrant vagrant 4096 Oct 01 16:46 . # drwxr-x--- 5 vagrant vagrant 4096 Oct 01 16:46 .. # -rw-rw-r-- 1 vagrant vagrant 49 Oct 01 16:46 .env # <span style="color: green;">👉 .env파일이 생성되었습니다.</span> # drwxrwxr-x 8 vagrant vagrant 4096 Oct 01 16:46 .git # drwxrwxr-x 3 vagrant vagrant 4096 Oct 01 15:57 .github # -rw-rw-r-- 1 vagrant vagrant 3139 Oct 01 15:11 .gitignore # -rw-rw-r-- 1 vagrant vagrant 0 Oct 01 16:46 server.log # -rw-rw-r-- 1 vagrant vagrant 761 Oct 01 16:17 server.py # -rw-rw-r-- 1 vagrant vagrant 759 Oct 01 16:17 server.py-e $ cat ~/2024-cicd-w2-2/.env # => ACCESSKEY : asdf1234end # SECRETKEY : qwer1234end
- GitHub에서 .env가 있는지 확인해보겠습니다.
.env 파일이 Git에는 없습니다! 하지만 가상머신 서버에 .env 파일이 있었던 것은 SSH for GitHub Actions를 통해 전달된 것입니다.
SCP for GitHub Actions
- 관련 주소 : Github, marketplace
- SCP for GitHub Actions는 원격 서버로 파일을 전송해주는 액션입니다.
- 실습을 통해 기능을 알아보겠습니다.
- server.py 수정하기
$ sed -i -e "s/CICD1 End Study/SCP Test/g" server.py
-
워크플로우 파일 수정하기
# .github/workflows/scp-ssh-deploy.yaml name: CICD2 on: workflow_dispatch: push: branches: - main jobs: scp-ssh-deploy: runs-on: ubuntu-latest steps: - name: Github Repository Checkout uses: actions/checkout@v4 - name: executing remote ssh commands uses: appleboy/ssh-action@v1.2.0 env: AWS_KEYS: ${{ secrets.MYKEYS }} with: host: ${{ secrets.EC2_PIP }} username: vagrant port: 22 key: ${{ secrets.SSH_PRIVATE_KEY }} envs: AWS_KEYS script_stop: true script: | cd /home/vagrant/2024-cicd-w2-2 echo "$AWS_KEYS" > .env sudo fuser -k -n tcp 80 || true - name: copy file via scp uses: appleboy/scp-action@v0.1.7 with: host: ${{ secrets.EC2_PIP }} username: vagrant port: 22 key: ${{ secrets.SSH_PRIVATE_KEY }} source: server.py target: /home/vagrant/2024-cicd-w2-2
- 코드 push하기
$ git add . && git commit -m "using scp ssh action" && git push origin main
- 가상서버에서 확인
# 서버 1 $ ls -al ~/2024-cicd-w2-2/ # => total 28 # drwxrwxr-x 4 vagrant vagrant 4096 Dec 14 17:04 . # drwxr-x--- 5 vagrant vagrant 4096 Dec 14 17:04 .. # -rw-rw-r-- 1 vagrant vagrant 1 Dec 14 17:03 .env # drwxrwxr-x 8 vagrant vagrant 4096 Dec 14 17:02 .git # drwxrwxr-x 3 vagrant vagrant 4096 Dec 14 15:57 .github # -rw-rw-r-- 1 vagrant vagrant 3139 Dec 14 15:11 .gitignore # -rw-rw-r-- 1 vagrant vagrant 0 Dec 14 17:02 server.log # -rw-r--r-- 1 vagrant vagrant 754 Dec 14 17:03 server.py $ cat ~/2024-cicd-w2-2/server.py | grep SCP # => response_string = now.strftime("The time is %-I:%M:%S %p, SCP Test.\n") # <span style="color: green;">👉 변경사항이 잘 반영되었습니다.</span>
최종 실습
- 앞서 쉘 명령으로 진행했던 작업을 GitHub Actions의 Marketplace에서 가져온 ssh, scp 액션을 사용하여 진행해보겠습니다.
- 내 PC에서 소스 수정하기
$ sed -i -e "s/SCP Test/CICD2 End 🥳/g" server.py
-
워크플로우 수정하기
# .github/workflows/deploy.yaml name: CICD2 on: workflow_dispatch: push: branches: - main jobs: deploy: runs-on: ubuntu-latest steps: - name: Github Repository Checkout uses: actions/checkout@v4 - name: copy file via ssh uses: appleboy/scp-action@v0.1.7 with: host: ${{ secrets.EC2_PIP }} username: vagrant port: 22 key: ${{ secrets.SSH_PRIVATE_KEY }} source: server.py target: /home/vagrant - name: executing remote ssh commands uses: appleboy/ssh-action@v1.2.0 env: AWS_KEYS: ${{ secrets.MYKEYS }} with: host: ${{ secrets.EC2_PIP }} username: vagrant port: 22 key: ${{ secrets.SSH_PRIVATE_KEY }} envs: AWS_KEYS script_stop: true script: | cd /home/vagrant/2024-cicd-w2-2 echo "$AWS_KEYS" > .env sudo fuser -k -n tcp 80 || true rm server.py cp /home/vagrant/server.py ./ nohup sudo -E python3 /home/vagrant/2024-cicd-w2-2/server.py > /home/vagrant/2024-cicd-w2-2/server.log 2>&1 & echo "test" >> /home/vagrant/text.txt
- 코드 push하기
$ git add . && git commit -m "Deploy CICD2 Final" && git push origin main
- 웹으로 접속해서 확인해보겠습니다.
- 변경사항이 잘 반영되어서 CICD2 End 🥳로 변경되었습니다.
GitHub Actions with Ansible
- 이번에는 GitHub Actions를 사용하여 Ansible을 실행해보겠습니다.
- 상세한 Ansible 사용법은 Ansible 공식문서를 참고하시고, 이번 실습에서는 간단하게 Ansible을 이용해서 Ping 테스트를 해보겠습니다. (여기에서의 ping은 ansible이 해당 호스트와 통신이 가능한지 확인하는 것이고 일반적인 ping과는 다릅니다.)
-
워크플로우 작성
# .github/workflows/ansible-deploy.yaml name: Run Ansible on: workflow_dispatch: push: branches: - main jobs: run-playbooks: runs-on: ubuntu-latest steps: - name: Github Repository Checkout uses: actions/checkout@v4 - name: Setup Python 3 uses: actions/setup-python@v5 with: python-version: "3.8" - name: Upgrade Pip & Install Ansible run: | python -m pip install --upgrade pip python -m pip install ansible - name: Implement the Private SSH Key run: | mkdir -p ~/.ssh/ echo "$" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa - name: Ansible Inventory File for Remote host run: | mkdir -p ./devops/ansible/ export INVENTORY_FILE=./devops/ansible/inventory.ini echo "[my_host_group]" > $INVENTORY_FILE echo "$" >> $INVENTORY_FILE - name: Ansible Default Configuration File run: | mkdir -p ./devops/ansible/ cat <<EOF > ./devops/ansible/ansible.cfg [defaults] ansible_python_interpreter = '/usr/bin/python3' ansible_ssh_private_key_file = ~/.ssh/id_rsa remote_user = vagrant inventory = ./inventory.ini host_key_checking = False EOF - name: Ping Ansible Hosts working-directory: ./devops/ansible/ run: | ansible all -m ping # - name: Run Ansible Playbooks # working-directory: ./devops/ansible/ # run: | # ansible-playbook install-nginx.yaml # - name: Deploy Python via Ansible # working-directory: ./devops/ansible/ # run: | # ansible-playbook deploy-python.yaml
- 워크플로우 push 하기
$ git add . && git commit -m "Deploy Ansible Test" && git push origin main
- GitHub Actions에서 ping 결과를 확인해보겠습니다.
- 정상적으로 ping이 가서 “pong”이라는 응답이 돌아왔습니다.
마치며
지금까지 GitHub Actions의 기본적인 사용하고, Marketplace에서 제공하는 액션 사용해보고, Ansible까지 맛보기로 사용해보았습니다.
GitHub Actions는 일부 제약이 있지만 무료로 편리하게 사용할 수 있고 Marketplace를 통해 다양한 추가기능을 손쉽게 사용할 수 있어서 매력적입니다.
하지만 매번 가상환경을 프로비저닝하고, 필요한 패키지를 설치하는 등의 작업이 시간이 의외로 많이 들어서, 실제 동작 시간이 예상보다 오래 걸릴 수 있다는 점이 있습니다. 또한 Jenkins나 다른 CI/CD 도구들은 실패한 상태의 쉘에 직접 로그인해서 트러블 슈팅을 할 수 있지만, Github Actions는 그렇게 할 수 없는 점도 아쉽습니다.
그래도 GitHub를 사용하면서 저렴한 가격으로 간단하게 CI/CD를 구성할 수 있다는 점은 매력적인것 같습니다.
추운 날씨에도 애써주신 모든 분들 고생 많으셨습니다. 감사합니다!