Ansible (μ€μλΈ) μ΄λβ
μ€μλΈ(Ansible)μ 리λ
μ€μ μ λμ€ κΈ°λ° μμ€ν
μ μ€μ λ° λ°°ν¬ μμ
μ μλννκΈ° μν IT μλν λꡬ μ€ νλμ΄λ€. μ€μλΈμ μμ΄μ νΈ(agent)κ° νμνμ§ μμΌλ©°, YAML νμμΌλ‘ μμ±λ Playbook
μ μ¬μ©νμ¬ κ°λ¨νκ² λ°°ν¬ μμ
μ μνν μ μλ€.
λν λ©±λ±μ±
( Idempotency, μ¬λ¬ λ² μ μ©ν΄λ κ²°κ³Όκ° λμΌνλ©°, μμ λ λΆλΆμ΄ μλ€λ©΄ κ·Έ λΆλΆλ§ μλ‘κ² λ°μλ¨ )μ νΉμ§μ΄ μμΌλ©°, λ°μ΄ν° μ μ‘μ μν΄ OpenSSHλ₯Ό μ΄μ©νλ€.
β‘ μμ΄μ νΈλβ
λ€λ₯Έ νλ‘κ·Έλ¨ λλ μμ€ν κ³Ό ν΅μ νμ¬ μμ μ μννκ±°λ μ 보λ₯Ό μμ§νλ μννΈμ¨μ΄μ΄λ€. ν΄λΌμ΄μΈνΈκ° μλ²μ μμ²μ 보λ΄κ³ , μλ²λ κ·Έ μμ²μ λ°λΌ μμ μ μννκ³ κ²°κ³Όλ₯Ό λ°ννλλ° μμ΄μ νΈλ μ΄λ¬ν μμ²μ λ°μμ μμ μ μννλ νλ‘κ·Έλ¨μ λ§νλ€.
νμ§λ§, μ€μλΈμ SSHλ₯Ό ν΅ν΄ μ격 μμ€ν μ μ°κ²° λ° κ΄λ¦¬νλ―λ‘, μμ΄μ νΈλ₯Ό μ€μΉνκ±°λ ꡬμ±ν νμκ° μλ€.
Ansibleμ κΈ°λ³Έ κ°λ λ° μ©μ΄ π§
μ μ΄ λ
Έλ(Control node) β
β‘ μ€μλΈμ μ€ννλ λ
Έλμ΄λ€. μ μ΄ λ
Έλμμ λͺ
λ Ήμ΄λ‘ 맀λμ§λ λ
Έλλ€μ κ΄λ¦¬νλ€.
맀λμ§λ λ
Έλ(Managed node) β
β‘ μ€μλΈλ‘ κ΄λ¦¬νλ μλ² λ
Έλμ΄λ€. 맀λμ§λ λ
Έλλ νΈμ€νΈλΌκ³ λ νλ€.
Β γ맀λμ§λ λ
Έλμλ μ€μλΈμ΄ μ€μΉ λμ§ μλλ€.
μΈλ²€ν 리(Inventory) β
β‘ νΈμ€νΈ νμΌμ΄λΌκ³ λ νλ©°, 맀λμ§λ λ
Έλ λͺ©λ‘μ μΈλ²€ν 리λΌκ³ νλ€.
β‘ μ€μλΈμ μν΄ μ μ΄λ λμμ μ μνλ€. κ° λ§€λμ§λ λ
Έλμ λν IP μ£Όμ,
Β γνΈμ€νΈ μ 보, λ³μμ κ°μ μ 보λ₯Ό μ§μ ν μ μλ€.
β‘ μΈλ²€ν 리 yaml νμΌμ μμλ μλμ κ°λ€. π»
all:
hosts: // κ·Έλ£Ήμ ꡬμ±νκΈ° μν λͺ¨λ μλ²μ IP μ§μ
77.77.77.200:
77.77.77.201:
77.77.77.202:
children:
webservers: // μ΄λ¦ μ§κΈ° λλ¦ ( κ·Έλ£Ή μ΄λ¦ )
hosts: // μΉμλ²κ° 2κ°λΌλ©΄ μλμ²λΌ 2κ° μ μ μ μμ. μ¬λ¬κ° κ°λ₯
77.77.77.200:
77.77.77.201:
dbservers: // μ΄λ¦ μ§κΈ° λλ¦ ( κ·Έλ£Ή μ΄λ¦ )
hosts:
77.77.77.202:
νλ μ΄λΆ(Playbook) β
β‘ νλ μ΄λΆμ μΈλ²€ν 리 νμΌμμ μ μν λμλ€μ΄ 무μμ μνν κ²μΈμ§ μ μνλ
γμν μνλ©°, yaml νμΌ νμμΌλ‘ μμ±νλ€.
β‘ μ€μλΈμ μ¬μ©νλ €λ©΄ μ΄ νλ μ΄λΆμ μ λ€λ£°μ€ μμμΌνλ©°, λ¨λ
μΌλ‘ μ¬μ©λλ κ²μ΄
γμλ μΈλ²€ν 리μ νλ μ΄λΆμ μ‘°ν©μΌλ‘ κ°μ΄ μ¬μ©νλ€.
β‘ μ λ§ν λͺ
λ Ήμ΄μ λν νλ μ΄λΆμ ννμ΄μ§μμ μ°Ύμλ³Ό μ μμΌλ©°, λ§μ½ μλ€λ©΄
γshell
μ μ¬μ©νμ¬ λͺ
λ Ήμ΄λ₯Ό μ€νμν¬ μ μλ€.
β‘ νλ μ΄λΆ yaml νμΌμ μμλ μλμ κ°λ€.
- hosts: ["77.77.77.200"]
tasks:
- name: define hostname // μ μ ν μ΄λ¦ μμ μ§μ
shell: | // νλ μ΄λΆ λͺ
λ Ήμ΄κ° μμ λ λͺ
λ Ήμ΄λ₯Ό μ§μ μΉ λ μ¬μ©
hostnamectl set-hostname worker03
become: yes // κ΄λ¦¬μ κΆνμΌλ‘ μ€ν μλ―Έ
- name: stop firewalld // νλ μ΄λΆ λͺ
λ Ήμ΄ μ¬μ©
service:
name: firewalld
state: stopped
νμ€ν¬(Task) β
β‘ μ€μλΈμ μμ
λ¨μ. μ λν
(ad-hoc)λͺ
λ Ήμ μ¬μ©νμ¬ λ¨μΌ μμ
μ ν λ²
Β γμ€νν μ μλ€.
λͺ¨λ(Module) β
β‘ μ€μλΈμ΄ μ€ννλ μ½λ λ¨μ. νλ μ΄λΆμμ Taskκ° μ΄λ»κ² μνλ μ§λ₯Ό μ νλ€.
π¦ Ansible μ μ¬μ©νκΈ° μν κΈ°λ³Έ μ€μ
μ€μλΈμ SSHλ‘ μ μ΄λ Έλμ 맀λμ§λ λ Έλκ° μ°κ²°λλ€.
λ°λΌμ, μ€μλΈμ μ¬μ©νκΈ° μ μ κ° μλ²μ authorized_keys
λ₯Ό μΆκ°ν΄μ€λ€.
λλ CentOS 8 κ°μλ¨Έμ 2λλ₯Ό μ€λΉν΄λ¨λ€. ( IP μ€μ μλ£ )
①맀λμ§λ λ
Έλ : nginx / μ μ΄ λ
Έλ : ansible
1. μ μ΄ λ
Έλμμ SSHλ‘ μ μνλ€ : ssh root@[ 맀λμ§λ λ
Έλ IP μ£Όμ ]
β‘ μ μμ μ±κ³΅νλ©΄ μ μ΄λ Έλμμ 맀λμ§λ λ Έλλ‘ λ°λκ²μ μμ²λΌ λ³Ό μ μλ€.
2. μ μ΄λ Έλμμ ν€λ₯Ό μμ±νλ€.
μμ±νκΈ° μ , 맀λμ§λ λ
Έλμμ ν€λ₯Ό νμΈν΄λ³΄λ©΄ μλ€κ³ μλμ²λΌ μΆλ ₯λκ³ μλ€.
μ μ΄λ
Έλμμ ν€ μμ± : ssh-keygen
β‘ μ§λ¬Έμ΄ 2κ° μ λ λμ€λλ°, κ·Έλ₯ μ무κ²λ μ
λ ₯νμ§ μκ³ Enterλ₯Ό λλ₯΄λ©΄ λλ€.
3. μ μ΄λ
Έλμμ μμ±ν ν€λ₯Ό 볡μ¬νλ€. : ssh-copy-id root@[ 맀λμ§λ λ
Έλ IP μ£Όμ ]
①맀λμ§λ λ
Έλμμ .ssh νμΌμ νμΈν΄λ³΄λ©΄ authorized_keys
κ° μκ²Όμ κ²μ΄λ€.
πΌ Ansible μ€μΉνκΈ° ( μ μ΄ λ Έλ )
dnf -y install centos-release-ansible-29
sed -i -e "s/enabled=1/enabled=0/g" /etc/yum.repos.d/CentOS-SIG-ansible-29.repo
dnf --enablerepo=centos-ansible-29 -y install ansible
1. μ μ΄λ Έλμμ μΈλ²€ν 리 ( server.yml ) μμ±
all:
hosts:
77.77.77.200:
77.77.77.201:
children:
webservers:
hosts:
77.77.77.200:
77.77.77.201:
2. μΈλ²€ν 리 ν
μ€νΈ : ansible webservers -i server.yml -m ping
Β γβ‘ webservers : μΈλ²€ν 리μ μμ±ν κ·Έλ£Ήλͺ
Β γβ‘ server.yml : μΈλ²€ν 리λͺ
Β γβ‘ -m : λͺ¨λ μ€ν
Β γβ‘ ping : ν 보λ΄λ³΄λ λͺ λ Ήμ΄
3. μ μ΄ λ
Έλμμ νλ μ΄λΆ μμ± ( nginx μ€μΉ ) : vi nginx-playbook.yml
- hosts: ["77.77.77.200"]
tasks:
- name: install nginx
yum:
name: httpd
state: latest
4. νλ μ΄λΆ μ€ν : ansible-playbook -i server.yml ./nginx-playbook.yml
π· GitHub Action μ€μ΅νκΈ°
1. κΉνλΈ λ ν¬μ§ν 리 μμ±
2. AWS EC2 μμ± λ° μΈλ°μ΄λ κ·μΉ νΈμ§ ( 80λ² λ° 443λ² ν¬νΈ )
3. EC2 μμ± μ λ°κΈλ°μ .ppk
ν€ νμΌμ .pem
νμΌλ‘ λ³ν
γβ‘ μ΄μ : .ppk
νμΌμ Puttyμμ μ¬μ©ν λͺ©μ μΌλ‘ μμ±ν νμΌμ΄μ§λ§, κΉνλΈ μ‘μ
μ
Β γγγγγ리λ
μ€ νκ²½μμ μ€νλλ―λ‘, .pem
νμμ ν€λ₯Ό μ¬μ©νμ¬ SSH μ°κ²°μ μ€μ νλ€.
Β γ1) Puttygen νλ‘κ·Έλ¨ μ€ν
Β γ2) Load ν΄λ¦ ν λ°κΈλ°μ .ppk
νμΌ μ
λ ₯
Β γ3) Conversions ν΄λ¦ β‘ Export OpenSSH key ν΄λ¦ ν ν€ μ μ₯
2. μ¬μ©ν νκ²½λ³μ λ±λ‘
Β γ1) κΉνλΈ λ ν¬μ§ν 리μμ Settings ν΄λ¦
Β γ2) μΌμͺ½ λ©λ΄νμμ Secrets and variables - Actions ν΄λ¦
Β γ3) New repository secret ν΄λ¦ - μ¬μ©ν λ³μλͺ
κ³Ό κ° μ
λ ₯
Β Β γγβ‘ μ¬μ©ν λ³μλ§νΌ κ³μ μμ±νλ©΄ λλ€.
Β Β γγβ‘ λλ μ μ¬μ§κ³Ό κ°μ΄ οΌκ°μ νκ²½λ³μλ₯Ό μμ±νλ€.
Β Β Β γγγ1) REMOTE_HOST : EC2 IP μ£Όμ
Β Β Β γγγ2) REMOTE_PORT : 22Β γγ<-- SSH νλ‘ν μ½μ ν¬νΈλ²νΈ
Β Β Β γγγ3) REMOTE_USER : ubuntu
Β Β Β γγγ4) SSH_KEY : λ°κΈλ°μ .pem
ν€ νμΌ
Β Β γγγγγβ‘ νμΌμ μ μΌ μ -----BEGIN RSA PRIVATE KEY-----
λ°
Β Β Β γγγγγγμ μΌ μλ -----END RSA PRIVATE KEY-----
λ ν¬ν¨μμΌμΌ λλ€.
3. VS Code μ΄κ³ , μμ±ν κΉνλΈ λ ν¬μ§ν λ¦¬λ‘ μ격 μ μ₯μ μ€μ
4. test.html νμΌ μμ±
<!DOCTYPE html>
<html>
<head>
<title>TEST</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
TEST 1111111111
</body>
</html>
5. .github/workflows
λλ ν 리 μμ±
6. nginx μ€μΉ λ° μ€νμ μν νλ μ΄λΆ μμ± ( deploy.yml )
- hosts: ["EC2 IP μ£Όμ"]
tasks:
- name: Update APT package cache
apt:
update_cache: yes
become: yes
- name: Install Nginx
apt:
name: nginx
state: present
become: yes
- name: Start Nginx service
systemd:
name: nginx
state: started
enabled: yes
7. EC2μ μ μνμ¬ nginxμ νμ΄μ§λ₯Ό λ³κ²½νλ GitHub Action Workflow μμ±
name: devops test
on:
push:
branches: [main] // κΉνλΈλ‘ Push ν λΈλμΉ λͺ
jobs:
deploy:
name: Deploy to EC2
runs-on: ubuntu-latest
steps:
- name: Checkout Repository // Push ν λ΄μ©μ Pull ν΄μ€κΈ° μν μμ
uses: actions/checkout@v3
- name: Run Ansible playbook // EC2μμ ubuntu μ¬μ©μλ‘ μ μνκΈ° μν μμ
uses: dawidd6/action-ansible-playbook@v2.8.0
with:
playbook: deploy.yml
directory: ./
key: ${{secrets.SSH_KEY}}
inventory: |
[all]
43.200.163.229 ansible_ssh_user=ubuntu // EC2 IP μ£Όμλ‘ μμ±
- name: get code from github // Push ν λ΄μ©μΌλ‘ nginx νμ΄μ§λ₯Ό κ΅μ²΄νκΈ° μν μμ
uses: appleboy/ssh-action@v0.1.9
with:
host: ${{ secrets.REMOTE_HOST }}
username: ${{ secrets.REMOTE_USER }}
key: ${{ secrets.SSH_KEY }}
port: ${{ secrets.REMOTE_PORT }}
script: |
sudo rm -rf ./action // κΉνλΈ λ ν¬μ§ν 리λͺ
sudo git clone https://github.com/[κ³μ λͺ
]/[λ ν¬μ§ν 리λͺ
]
sudo mv -f ./action/*.html /var/www/html
β‘ μμ±ν κ²°κ³Όλ μλμ κ°λ€.
8. Commit λ° Push ν κΉνλΈ μ‘μ - Deploy EC2 μλ£ μ¬λΆ νμΈ
β‘ Pushμ λμμ, EC2μ nginxλ₯Ό μ€μΉ λ° μ€νμν€κ³ κΉνλΈμμ Pullλ‘ νμΌμ λΆλ¬μμ
Β γν΄λΉ html νμΌμ nginx νμ΄μ§λ‘ λ체νκ² λλ€.
β‘ μ±κ³΅μ μΌλ‘ μ€νλλ©΄, μλμ κ°μ΄ μΆλ ₯λλ€.
9. EC2 IPμ£Όμ:80/test.html URLλ‘ μ μνμ¬ VS Codeμμ μμ±ν html νμΌμ΄ μΆλ ₯λλμ§
Β γνμΈνλ€.
10. test.html νμΌμ λ³κ²½ ν, λ€μ κΉνλΈλ‘ Push νμ λ, ν΄λΉ νμ΄μ§κ° λ³κ²½λλμ§ νμΈ
deploy.yml
κ³Ό main.yml
μ λλ μ μμ±ν μ΄μ λ ν₯ν 볡μ‘ν μ½λ μμ± μ μμ
μ κ°λ
μ±κ³Ό μ μ§ λ³΄μμ±μ΄ ν₯μλ μ μκ³ , νμν κ²½μ° νΉμ μμ
λ¨κ³λ₯Ό μμ νκ±°λ μ¬μ¬μ©νλ κ²μ΄ κ°λ₯νκΈ° λλ¬Έμ΄λ€.