Ansible - 설치 및 기본 사용법

kimchigood·2024년 1월 10일
0

Ansible Study

목록 보기
1/8
post-thumbnail
post-custom-banner

본 포스팅은 Cloud@net 스터디 참여로 만든 내용임을 밝힌다.

Ansible?

Ansible is a suite of software tools that enables infrastructure as code. It is open-source and the suite includes software provisioning, configuration management, and application deployment functionality.

Ansible은 오픈소스 IaC 도구 중 하나다. Terraform으로 Cloud Infra를 구성한다면, Ansible로는 여러 VM에 동일한 환경을 적용할때 주로 쓰인다.
예를 들면, 여러 대의 VM에 배보된 tomcat을 업그레이드 해야하는 작업이 있을 수 있다.

위 그림과 같이 Control node에서 Managed nodes에 접근하여 같은 작업을 실행하게 되는데, 각 노드에는 Python이 설치되어 있어야 동작하게 된다.

실습환경 구성

CloudForamtion

Ansible Server Node: 1대
Ansible Managed Node: 3대

스터디에서 제공해준 CloudFormation을 통해 환경을 구성한다. KeyName과 SgIngressSshCidr를 자신의 환경에 맡게 세팅해준다.

아래와 같이 CLI를 통해서 세팅도 가능하니, 참고하도록 하자.

# YAML 파일 다운로드
curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/Ansible/a101-1w.yaml

# CloudFormation 스택 배포
# aws cloudformation deploy --template-file a101-1w.yaml --stack-name mylab --parameter-overrides KeyName=<My SSH Keyname> SgIngressSshCidr=<My Home Public IP Address>/32 --region ap-northeast-2
예시) aws cloudformation deploy --template-file a101-1w.yaml --stack-name mylab --parameter-overrides KeyName=kp-gasida SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 --region ap-northeast-2

## Tip. 인스턴스 타입 변경 : MyInstanceType=t3.xlarge
예시) aws cloudformation deploy --template-file a101-1w.yaml --stack-name mylab --parameter-overrides KeyName=kp-gasida SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 --region ap-northeast-2 MyInstanceType=t3.xlarge 

# CloudFormation 스택 배포 완료 후 작업용 EC2 IP 출력
aws cloudformation describe-stacks --stack-name mylab --query 'Stacks[*].Outputs[0].OutputValue' --output text --region ap-northeast-2

# Ansible Server EC2 SSH 접속
ssh -i ~/.ssh/kp-gasida.pem ubuntu@$(aws cloudformation describe-stacks --stack-name mylab --query 'Stacks[*].Outputs[0].OutputValue' --output text --region ap-northeast-2)

환경세팅이 완료되면, SSH로 EC2에 접근해보자.

# SSH 접속 : ubuntu 계정
ssh -i ~/.ssh/kp-gasida.pem ubuntu@$(aws cloudformation describe-stacks --stack-name mylab --query 'Stacks[*].Outputs[0].OutputValue' --output text --region ap-northeast-2)
------------------------

# 계정 정보 확인
whoami
id

# CPU, Mem, Disk 확인
htop
free -h
df -hT /

# /etc/hosts 확인
cat /etc/hosts

# 노드간 통신 확인
for i in {1..3}; do ping -c 1 tnode$i; done

배포된 EC2는 모두 root/qwe123 로 접속이 가능하다. 실습이니 root계정으로 실습을 하고, 아래와 같이 VSCode를 연동하도록 하자.

Host ansible-server
HostName 50.1.1.1 <- 각자 자신의 ansible-server 의 유동 공인 IP
User root

/root/my-ansible 폴더에 실습코드가 있으니 참고하도록 하자.

Ansible 설치 및 구성

# 작업 기본 디렉터리 확인
whoami
pwd
/root/my-ansible

# 파이썬 버전 확인
python3 --version
Python 3.10.12

# 설치
apt install software-properties-common -y
add-apt-repository --yes --update ppa:ansible/ansible
apt install ansible -y

ansible --version
ansible [core 2.15.8]
 config file = /etc/ansible/ansible.cfg
 configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
 ansible python module location = /usr/lib/python3/dist-packages/ansible
 ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
 executable location = /usr/bin/ansible
 python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/usr/bin/python3)
 jinja version = 3.0.3
 libyaml = True

cat /etc/ansible/ansible.cfg
which ansible

Playbook 실습

Ansible Server Node에서 Managed Node 접근을 위해 ssh 구성을 한다.

# 모니터링
tree ~/.ssh
watch -d 'tree ~/.ssh'

# Create SSH Keypair
ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa

다음으로 각 Managed Node에 Public Key를 복사해준다.

# 공개 키를 관리 노드에 복사
for i in {1..3}; do ssh-copy-id root@tnode$i; done

# 복사 확인
for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i cat ~/.ssh/authorized_keys; echo; done

# ssh 접속 테스트
# 공개 키를 관리 노드에 복사
for i in {1..3}; do ssh-copy-id root@tnode$i; done

# 복사 확인
for i in {1..3}; do echo ">> tnode$i <<"; ssh tnode$i cat ~/.ssh/authorized_keys; echo; done

# ssh 접속 테스트
ssh tnode1
whoami
exit

ssh tnode2
exit

ssh tnode3
exit

Inventory 작성

Ansible Server Node가 관리할 Managed Node를 inventory 파일에 작성해준다. 이 파일을 참조하여, 어떤 서버에 배포할지 미리 정할 수 있다.

# my-ansible/inventory
# inventory 파일 생성
# inventory 그룹 구성
cat <<EOT > inventory
[web]
tnode1
tnode2

[db]
tnode3

[all:children]
web
db
EOT

# inventory 검증
ansible-inventory -i ./inventory --list | jq
ansible-inventory -i ./inventory --graph

위 inventory처럼 ip가 아니라 host명으로도 세팅이 가능하다. 아래와 같이 다양하게 각 종류에 맞는 세팅도 가능하니 참고하자.

[webservers]
web1.example.com
web2.example.com
192.0.2.42

[db-servers]
db01.example.com
db02.example.com

[east-datacenter]
web1.example.com
db01.example.com

[west-datacenter]
web2.example.com
db02.example.com

[production]
web1.example.com
web2.example.com
db01.example.com
db02.example.com

[development]
192.168.0.42

# IP 범위 설정 : 192.168.4.0 ~ 192.168.4.255 사이의 IP 범위를 표현
[defaults]
192.168.4.[0:255]

# 호스트명 범위 설정 : com01.example.com ~ com20.example.com 의 범위를 표현
[compute]
com[01:20].example.com

# DNS 범위 설정 : a.dns.example.com , b.dns.example.com , c.dns.example.com 을 의미함
[dns]
[a:c].dns.example.com

# IPv6 범위 설정 : 2001:db08::a ~ 2001:db08::f 사이의 IPv6 범위를 표현
[ipv6]
2001:db8::[a:f]

디렉터리 내에 ansible.cfg 파일을 작성하면, -i 옵션으로 inventory 파일의 경로를 지정하지 않고 ansible.cfg 파일에 저장된 경로값을 가져올 수 있다.

# ansible.cfg 파일 생성
cat <<EOT > ansible.cfg
[defaults]
inventory = ./inventory
remote_user = root
ask_pass = false

[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
EOT

우선순위: 1. ansible.cfg (in the current directory) > 2.~/.ansible.cfg (in the home directory)

다음으로 실제 Managed Node와 통신을 하는지 알아보기 위해 ping module 테스트를 해보자.

ansible -m ping web

ansible -m ping db

# 암호 입력 후 실행
ansible -m ping --ask-pass web

--ask-pass 옵션을 주면, password 방식으로 접근도 가능하고, -u 옵션으로 다른 계정으로 접근 테스트를 할 수 있다.

위 테스트에서 ping은 ICMP 프로토콜을 사용한 것이 아니라, Ansible의 ping module 기능을 사용한 것이니 참고하자.



위 스샷은 Ansible로 ping을 날릴 때, 해당 Node에서 watch pstree를 한 화면이다. ICMP가 아닌 python3 모듈이 실행되는 것이 확인된다!

playbook 작성

그럼 가장 기본적인 기능을 실행해보기 위해, playbook을 만들어보자. playbook은 ansible 세팅값을 기반으로 특정 작업을 수행하는 스크립트 파일이다.

---
- hosts: all
  tasks:
    - name: Print message
      debug:
        msg: Hello CloudNet@ Ansible Study

validation check & execution

ansible-playbook --syntax-check first-playbook.yml
ansible-playbook first-playbook.yml

변수

Ansible에서 변수는 파라미터 변수, 플레이 변수, 호스트 변수, 그룹변수 총 4가지가 있다.
우선순위 : 추가변수 > 플레이 변수 > 호스트 변수 > 그룹 변수

그룹 변수

인벤토리 파일의 호스트 그룹에 세팅

[web]
tnode1
tnode2

[db]
tnode3

[all:children]
web
db

[all:vars]
user=ansible

# playbook.yml;
---

- hosts: all
  tasks:
  - name: Create User {{ user }}
    ansible.builtin.user:
      name: "{{ user }}"
      state: present

호스트 변수

인벤토리 파일의 특정 호스트 그룹에 세팅

[web]
tnode1
tnode2

[db]
tnode3 user=ansible1

[all:children]
web
db

[all:vars]
user=ansible

# playbook.yml
---

- hosts: db
  tasks:
  - name: Create User {{ user }}
    ansible.builtin.user:
      name: "{{ user }}"
      state: present

플레이이 변수

playbook 파일에 hosts 아래 작성

---

- hosts: all
  vars:
    user: ansible2

  tasks:
  - name: Create User {{ user }}
    ansible.builtin.user:
      name: "{{ user }}"
      state: present

추가 변수

playbook 파일 실행 시 변수 선언

ansible-playbook -e user=ansible4 create-user3.yml

Ansible Vault

Ansible 사용 시 민감정보를 암호화 하는 기능이다. 보안상 텍스트로 민감정보가 노출되는 것은 좋지 않으므로 Ansible Vault를 통해 데이터 파일을 암호화/복호화 할 수 있다.

그럼 바로 실습을 진행해보자.

# ansible-vault create 로 생성하려는 플레이북 파일 생성
ansible-vault -h
ansible-vault create mysecret.yml
New Vault password: P@ssw0rd!
Confirm New Vault password: P@ssw0rd!
user: ansible
password: P@ssword!

:wq

ansible-vault로 파일을 만들면, 바로 vim으로 작성을 하게 된다. 값을 입력 후 저장하면, 아래와 같이 암호화된 파일이 생성된다.

복호화도 간단하다. 처음 입력해준 Password를 입력하면 파일이 복호화된 파일을 볼 수 있다.

# 원래 파일 내용 확인(복호화)
ansible-vault view mysecret.yml
Vault password: P@ssword!

별도로 암호를 파일에 만들어서 사용할 수 도 있다.

echo 'P@ssw0rd!' > vault-pass
# ansible-vault create 로 생성하려는 플레이북 파일 생성
ansible-vault create --vault-pass-file ./vault-pass mysecret1.yml

이미 만들어져 있는 파일도 아래와 같이 암호화 할 수 있다.

# 기존 평문 파일 확인
ll create-user.yml
-rw-r--r-- 1 root root 131 Dec 26 14:16 create-user.yml

# 기존 평문 파일 암호화 설정
ansible-vault encrypt create-user.yml
New Vault password: P@ssw0rd!
Confirm New Vault password: P@ssw0rd!

# 암호화 설정 후 확인 : 파일소유자만 읽고 쓸수 있음
ll create-user.yml
-rw------- 1 root root 873 Dec 28 04:18 create-user.yml

cat create-user.yml

암호변경

# 패스워드 입력 파일을 이용해 패스워드 변경
cat vault-pass
P@ssw0rd!

ansible-vault rekey --new-vault-password-file=./vault-pass mysecret.yml

playbook에서 암호화된 변수 파일을 사용하는 방법도 있다.

# mysecret.yml 파일을 vars 디렉터리로 이동
mv ./mysecret.yml ./vars/

# view로 파일 내용 확인
ansible-vault view vars/mysecret.yml
Vault password: P@ssw0rd!
user: ansible
password: P@ssword!

---

- hosts: db
  vars_files:
    - vars/mysecret.yml

  tasks: 
  - name: Create User {{ user }}
    ansible.builtin.user:
      name: "{{ user }}"
      state: present

Facts

Facts를 통해서 Ansibe이 관리 호스트에서 자동으로 수집된 정보를 긁어오는 작업이다.

# my-ansible/facts.yml
---

- hosts: db

  tasks:
  - name: Print all facts
    ansible.builtin.debug:
      var: ansible_facts

tnode3 host의 모든 정보를 긁어온다. 이후 조건문 등을 활용하여, 특정 호스트, OS에 작업을 진행할 수 있다.

---

- hosts: db

  tasks:
  - name: Print all facts
    ansible.builtin.debug:
      msg: >
        The default IPv4 address of {{ ansible_facts.hostname }}
        is {{ ansible_facts.default_ipv4.address }}

특정 값만 가지고 올 수 도 있다.

facts 비활성화

facts를 사용할 수 없는 경우나, 호스트 부하 방지를 위해 facts 수집을 비활성화 할 수 있다.

---

- hosts: db
  gather_facts: no

  tasks:
  - name: Print all facts
    ansible.builtin.debug:
      msg: >
        The default IPv4 address of {{ ansible_facts.hostname }}
        is {{ ansible_facts.default_ipv4.address }}
profile
Shout out to Kubernetes⎈
post-custom-banner

0개의 댓글