GitHub Actions
GitHub Actions를 사용하여 레포지토리에서 바로 소프트웨어 개발 워크플로를 자동화, 사영자 지정 및 실행합니다.
CI/CD를 포함하여 하는 작업을 수행하기 위한 작업을 검색, 생성 및 공유하고 완전히 사용자 정의된 워크플로에서 작업을 결합할 수 있습니다. [GitHub Action]
- CI/CD를 포함하여 원하는 작업을 수행하기 위한 작업을 검색, 생성 및 공유하고 완전히 사용자 정의된 워크플로에서 작업을 결합할 수 있습니다.
실습 환경
CSP : AWS
Spec : t3.small
VM : EC2 1ea
OS : Ubuntu 22.04
Python 코드 실행
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()
## 코드 실행
ubuntu@MyServer:~$ sudo python3 server.py
Listening on 0.0.0.0:80
- Port Listen 및 Curl 통신 확인
- GitHub Token 발급하기
[Profile > Settings > Developer Settings]
- 작업용 Repo 만들기
- Git Clone
- 만들어둔 server.py 파일 push하기
$ cp server.py cicd-2w/
$ cd cicd-2w
$ git status
$ git add . ; git commit -m "init commit"
$ git push origin main
- 서버 실행
$ nohup sudo python3 server.py > server.log 2>&1 &
$ cat server.log
$ curl localhost
$ cat server.log
- 코드 수정 후 재실행
## 코드 수정
$ sed -i "s/CloudNeta/CICD/g" server.py
## 프로세스 종료
$ sudo ss -tnlp
$ sudo fuser -k -n tcp 80 ## Process kill
$ sudo ss -tnlp
## 재실행
$ nohup sudo python3 server.py > server.log 2>&1 &
$ curl localhost
- Update code push
GitHub Actions으로 CI/CD 자동화 작업 실행
- 자동화의 사용 준비로 GitHub의 Repo가 EC2에 접근할 수 있도록 Key Pair와 EC2_PIP를 등록합니다.
이 정보는 민감 정보이므로 repo settings의 secret에 등록하여 노출되지 않도록 등록합니다.
- 여기까지 진행했으면 이제부터는 개인 로컬 PC에서 작업을 수행합니다.
## 로컬 PC에 Git Clone
git clone https://github.com/ssungz789/cicd-2w.git
cd cicd-2w
## workflow 파일 생성
mkdir -p .github/workflows/
touch .github/workflows/deploy.yaml
## server.py 수정
sed -i -e "s/CICD/CICD 2w/g" server.py
- workflow/deploy.yaml
## workflow 이름
name: CICD1
on:
## 사용자가 github웹에서 수동으로 배포했을 때
workflow_dispatch:
push:
branches:
## 브랜치가 main일때 실행
- main
## Jobs 리스트
jobs:
deploy:
## 실행하는 OS 이미지
runs-on: ubuntu-latest
## 실행 Step
steps:
- name: Configure the SSH Private Key Secret
run: |
mkdir -p ~/.ssh/
## repo에 등록한 secret을 실행 OS에 주입
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
- name: Set Strict Host Key Checking
## key exchange disable
run: echo "StrictHostKeyChecking=no" > ~/.ssh/config
- name: Git Pull
run: |
export MY_HOST="${{ secrets.EC2_PIP }}"
ssh ubuntu@$MY_HOST << EOF
cd /home/ubuntu/cicd-2w || exit 1
## git pull로 현재 상태의 코드 갱신
git pull origin main || exit 1
EOF
- name: Run service
run: |
## 서버 IP 환경 변수 등록
export MY_HOST="${{ secrets.EC2_PIP }}"
## 재실행을 위한 기존 Process kill
ssh ubuntu@$MY_HOST sudo fuser -k -n tcp 80 || true
## nohup으로 프로세스 재기동
ssh ubuntu@$MY_HOST "nohup sudo -E python3 /home/ubuntu/cicd-2w/server.py > /home/ubuntu/cicd-2w/server.log 2>&1 &"
- code push
git add . && git commit -m "add workflow" && git push origin main
- VM 내부에서 변경 사항 확인
코드가 잘 갱신됐고, 배포도 정상적으로 된것을 서버에서도 확인해 볼 수 있습니다.
- 추가 코드 수정 해보기
sed -i -e "s/CICD 2w/CICD1 End/g" server.py
- workflow 이름 변경
- job 이름 변경
- commit 메시지 변경
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 ubuntu@$MY_HOST << EOF
cd /home/ubuntu/cicd-2w || exit 1
git pull origin main || exit 1
EOF
- name: Run service
run: |
export MY_HOST="${{ secrets.EC2_PIP }}"
ssh ubuntu@$MY_HOST sudo fuser -k -n tcp 80 || true
ssh ubuntu@$MY_HOST "nohup sudo -E python3 /home/ubuntu/cicd-2w/server.py > /home/ubuntu/cicd-2w/server.log 2>&1 &"
#
git add . && git commit -m "edit workflow" && git push origin main
# [서버1]
grep -i cicd server.py
sudo ps -ef |grep server.py
tail /home/ubuntu/cicd-2w/server.log
- 변경 사항들이 잘 적용되어 배포된 것을 확인할 수 있습니다.
웹 페이지 접속 확인
GitHub Actions으로 CI/CD 자동화 작업 실행 -2
- GitHub Actions에서 코드 가져오기
- GitHub Action에서 .gitignore 제외된 민감 파일 내용을 안전하게 가져와서 사용하기
- scp로 대상 서버 ec2에 py 파일 전송
- 대상 서버 ec2에 기존 서비스 중지하고 다시 실행
- Github action 파이썬 버전 확인
name: CICD2
on:
workflow_dispatch:
push:
branches:
- main
jobs:
deployfinal:
runs-on: ubuntu-latest
steps:
- name: Test
run: |
python -V || true
python3 -V || true
which python || true
which python3 || true
env
GitHub Actions에서 .gitignore 제외된 민감 파일 내용을 을 안전하게 가져와서 사용하기
- Secret 생성 : MYKEYS
ACCESSKEY : asdf1234
SECRETKEY : qwer1234
- github market place
https://github.com/marketplace
- ssh for github actions
- 워크플로 설정 후 테스트
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: ${{ secrets.MYKEYS }}
with:
host: ${{ secrets.EC2_PIP }}
username: ubuntu
key: ${{ secrets.SSH_PRIVATE_KEY }}
envs: AWS_KEYS
script_stop: true
script: |
cd /home/ubuntu/cicd-2w
echo "$AWS_KEYS" > .env
## 수정 파일 배포
$ git add . && git commit -m "ssh action test" && git push origin main
서버 내부에서도 .env파일이 잘 저장된 것을 확인할 수 있습니다.
Secret을 수정하는 방법
1) repo secret 수정
2) git push를 하거나 web ui에서 수동으로 Run Workflow 수행
- workflow 종료 후 .env 전/후 비교
scp: GitHub Action that copy files and artifacts via SSH
- server.py 수정
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, SCP Test.\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()
- workflow 파일 수정
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: ubuntu
key: ${{ secrets.SSH_PRIVATE_KEY }}
envs: AWS_KEYS
script_stop: true
script: |
cd /home/ubuntu/cicd-2w
echo "$AWS_KEYS" > .env
sudo fuser -k -n tcp 80 || true
- name: copy file via ssh
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.EC2_PIP }}
username: ubuntu
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: server.py
target: /home/ubuntu/cicd-2w
- 수정된 파일 배포
git add . && git commit -m "using scp ssh action" && git push origin main
- 서버에서 정상 배포 확인
github action 에서 코드 가져오고 변경된 py 파일을 전송 후 기존 서비스 중지 후 재기동
- server.py 수정
response_string = now.strftime("The time is %-I:%M:%S %p, CICD2 End\n")
- 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: ubuntu
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: server.py
target: /home/ubuntu
- name: executing remote ssh commands
uses: appleboy/ssh-action@v1.2.0
env:
AWS_KEYS: ${{ secrets.MYKEYS }}
with:
host: ${{ secrets.EC2_PIP }}
username: ubuntu
key: ${{ secrets.SSH_PRIVATE_KEY }}
envs: AWS_KEYS
script_stop: true
script: |
cd /home/ubuntu/cicd-2w
echo "$AWS_KEYS" > .env
sudo fuser -k -n tcp 80 || true
rm server.py
cp /home/ubuntu/server.py ./
nohup sudo -E python3 /home/ubuntu/cicd-2w/server.py > /home/ubuntu/cicd-2w/server.log 2>&1 &
echo "test" >> /home/ubuntu/text.txt
- 배포 수행
git add . && git commit -m "Deploy CICD2 Final" && git push origin main
- 접속 확인 및 서버 내부 확인
GitHub Actions with 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
## 특정 Python 버전 지정
- name: Setup Python 3
uses: actions/setup-python@v5
with:
python-version: "3.8"
## pip install, ansibel install
- 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 "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.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 "${{ secrets.EC2_PIP }}" >> $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 = ubuntu
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
- 배포 확인
'Cloud > CICD' 카테고리의 다른 글
Jenkins CI/ArgoCD + K8S (0) | 2024.12.23 |
---|---|
Jenkins CI/CD + Docker (1) | 2024.12.08 |